Example #1
0
void I_InitHardware ()
{
	UCVarValue val;

	val.Bool = !!Args.CheckParm ("-devparm");
	ticker.SetGenericRepDefault (val, CVAR_Bool);
	
	if ( OPENGL_GetCurrentRenderer( ) == RENDERER_OPENGL )
		Video = new OpenGLVideo( );
	else
		Video = new Win32Video (0);

	if (Video == NULL)
		I_FatalError ("Failed to initialize display");

	if (!initialized) // [ZDoomGL]
   {
	   atterm (I_ShutdownHardware);
   }

	Video->SetWindowedScale (vid_winscale);

   initialized = true; // [ZDoomGL]
}
Example #2
0
void FIWadManager::ParseIWadInfos(const char *fn)
{
	FResourceFile *resfile = FResourceFile::OpenResourceFile(fn, NULL, true);
	if (resfile != NULL)
	{
		DWORD cnt = resfile->LumpCount();
		for(int i=cnt-1; i>=0; i--)
		{
			FResourceLump *lmp = resfile->GetLump(i);

			if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "IWADINFO"))
			{
				// Found one!
				ParseIWadInfo(resfile->Filename, (const char*)lmp->CacheLump(), lmp->LumpSize);
				break;
			}
		}
		delete resfile;
	}
	if (mIWadNames.Size() == 0 || mIWads.Size() == 0)
	{
		I_FatalError("No IWAD definitions found");
	}
}
Example #3
0
//
// InitNetCommon
//
void InitNetCommon(void)
{
   unsigned long _true = true;

#ifdef _WIN32
   WSADATA   wsad;
   WSAStartup( MAKEWORD(2,2), &wsad );
#endif

   inet_socket = UDPsocket ();

    #ifdef ODA_HAVE_MINIUPNP
    init_upnp();
    #endif

   BindToLocalPort (inet_socket, localport);
   if (ioctlsocket (inet_socket, FIONBIO, &_true) == -1)
       I_FatalError ("UDPsocket: ioctl FIONBIO: %s", strerror(errno));

	// enter message information into message info structs
	InitNetMessageFormats();

   SZ_Clear(&net_message);
}
Example #4
0
static int NewFailure (size_t size)
{
	I_FatalError ("Failed to allocate %d bytes from process heap", size);
	return 0;
}
Example #5
0
//
// Z_IDCheckNB
// 
// Performs a fatal error condition check contingent on the definition
// of ZONEIDCHECK, in any context where a memblock pointer is not available.
//
static void Z_IDCheckNB(bool err, const char *errmsg,
                        const char *file, int line)
{
   if(err)
      I_FatalError(I_ERR_KILL, "%s\nSource: %s:%d\n", errmsg, file, line);
}
Example #6
0
//
// D_DoomMain
//
void D_DoomMain (void)
{
	unsigned p;
	extern std::string defdemoname;

	gamestate = GS_STARTUP;
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command

	Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);

	M_LoadDefaults ();					// load before initing other systems
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	const char* iwad = Args.CheckValue("-iwad");
	if (!iwad)
		iwad = "";

	std::vector<std::string> newwadfiles, newpatchfiles;
	newwadfiles.push_back(iwad);
	D_AddWadCommandLineFiles(newwadfiles);
	D_AddDehCommandLineFiles(newpatchfiles);

	D_LoadResourceFiles(newwadfiles, newpatchfiles);

	I_Init();

	V_Init();
	atterm(V_Close);

	#ifdef _WIN32
	const char *sdlv = getenv("SDL_VIDEODRIVER");
	Printf (PRINT_HIGH, "Using %s video driver.\n",sdlv);
	#endif

	C_InitConsole(screen->width, screen->height, true);
	atterm(C_ShutdownConsole);

	// SDL needs video mode set up first before input code can be used
	I_InitInput();

	D_Init();
	atterm(D_Shutdown);

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (GStrings(STARTUP1)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP1));
	if (GStrings(STARTUP2)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP2));
	if (GStrings(STARTUP3)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP3));
	if (GStrings(STARTUP4)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP4));
	if (GStrings(STARTUP5)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP5));

	// Nomonsters
	sv_nomonsters = Args.CheckParm("-nomonsters");

	// Respawn
	sv_monstersrespawn = Args.CheckParm("-respawn");

	// Fast
	sv_fastmonsters = Args.CheckParm("-fast");

    // developer mode
	devparm = Args.CheckParm ("-devparm");

	// Record a vanilla demo
	p = Args.CheckParm ("-record");
	if (p)
	{
		autorecord = true;
		autostart = true;
		demorecordfile = Args.GetArg (p+1);
	}

	// get skill / episode / map from parms
	strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

	// Check for -playdemo, play a single demo then quit.
	p = Args.CheckParm ("-playdemo");
	// Hack to check for +playdemo command, since if you just add it normally
	// it won't run because it's attempting to run a demo and still set up the
	// first map as normal.
	if (!p)
		p = Args.CheckParm ("+playdemo");
	if (p && p < Args.NumArgs()-1)
	{
		Printf (PRINT_HIGH, "Playdemo parameter found on command line.\n");
		singledemo = true;
		defdemoname = Args.GetArg (p+1);
	}

	// [SL] check for -timedemo (was removed at some point)
	p = Args.CheckParm("-timedemo");
	if (p && p < Args.NumArgs() - 1)
	{
		singledemo = true;
		G_TimeDemo(Args.GetArg(p + 1));
	}

	const char *val = Args.CheckValue ("-skill");
	if (val)
	{
		sv_skill.Set (val[0]-'0');
	}

	p = Args.CheckParm ("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi (Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy (startmap, CalcMapName (ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm ("+map");
	if (p && p < Args.NumArgs()-1)
	{
		strncpy (startmap, Args.GetArg (p+1), 8);
		((char *)Args.GetArg (p))[0] = '-';
		autostart = true;
	}
	if (devparm)
		Printf (PRINT_HIGH, "%s", GStrings(D_DEVSTR));        // D_DEVSTR

	// [RH] Now that all text strings are set up,
	// insert them into the level and cluster data.
	G_SetLevelStrings();

	// [RH] Parse through all loaded mapinfo lumps
	G_ParseMapInfo();

	// [ML] Parse musinfo lump
	G_ParseMusInfo();

	// [RH] Parse any SNDINFO lumps
	S_ParseSndInfo();

	// NOTE(jsd): Set up local player color
	EXTERN_CVAR(cl_color);
	R_BuildPlayerTranslation (0, V_GetColorFromString (NULL, cl_color.cstring()));

	I_FinishClockCalibration ();

	Printf (PRINT_HIGH, "D_CheckNetGame: Checking network game status.\n");
	D_CheckNetGame ();

	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems ();

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet ();

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams (false, false);

	Printf_Bold("\n\35\36\36\36\36 Odamex Client Initialized \36\36\36\36\37\n");
	if(gamestate != GS_CONNECTING)
		Printf(PRINT_HIGH, "Type connect <address> or use the Odamex Launcher to connect to a game.\n");
    Printf(PRINT_HIGH, "\n");

	setmodeneeded = false; // [Fly] we don't need to set a video mode here!
    //gamestate = GS_FULLCONSOLE;

	// [SL] allow the user to pass the name of a netdemo as the first argument.
	// This allows easy launching of netdemos from Windows Explorer or other GUIs.

	// [Xyltol]
	if (Args.GetArg(1))
	{
		std::string demoarg = Args.GetArg(1);
		if (demoarg.find(".odd") != std::string::npos)
			CL_NetDemoPlay(demoarg);
	}

	p = Args.CheckParm("-netplay");
	if (p)
	{
		if (Args.GetArg(p + 1))
		{
			std::string filename = Args.GetArg(p + 1);
			CL_NetDemoPlay(filename);
		}
		else
		{
			Printf(PRINT_HIGH, "No netdemo filename specified.\n");
		}
	}

	// denis - bring back the demos
    if ( gameaction != ga_loadgame )
    {
		if (autostart || netgame || singledemo)
		{
			if (singledemo)
				G_DoPlayDemo();
			else
			{
				if(autostart)
				{
					// single player warp (like in g_level)
					serverside = true;
                    sv_allowexit = "1";
                    sv_freelook = "1";
                    sv_allowjump = "1";
                    sv_allowredscreen = "1";
                    sv_gametype = GM_COOP;

					players.clear();
					players.push_back(player_t());
					players.back().playerstate = PST_REBORN;
					consoleplayer_id = displayplayer_id = players.back().id = 1;
				}

				G_InitNew (startmap);
				if (autorecord)
					if (G_RecordDemo(demorecordfile.c_str()))
						G_BeginRecording();
			}
		}
        else
		{
            if (gamestate != GS_CONNECTING)
                gamestate = GS_HIDECONSOLE;

			C_HideConsole();

			if (gamemode == commercial_bfg) // DOOM 2 BFG Edtion
                AddCommandString("menu_main");

			D_StartTitle (); // start up intro loop
		}
    }

	// denis - this will run a demo and quit
	p = Args.CheckParm ("+demotest");
	if (p && p < Args.NumArgs()-1)
	{
		demotest = 1;
		defdemoname = Args.GetArg (p+1);
		G_DoPlayDemo();

		while(demoplayback)
		{
			DObject::BeginFrame ();
			G_Ticker();
			DObject::EndFrame ();
			gametic++;
		}
	}
	else
	{
		demotest = 0;
		D_DoomLoop ();		// never returns
	}
}
Example #7
0
static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
{
	WadStuff wads[countof(IWADNames)];
	size_t foundwads[NUM_IWAD_TYPES] = { 0 };
	const char *iwadparm = Args->CheckValue ("-iwad");
	size_t numwads;
	int pickwad;
	size_t i;
	bool iwadparmfound = false;
	FString custwad;

	if (iwadparm == NULL && iwad != NULL && *iwad != 0)
	{
		iwadparm = iwad;
	}

	if (iwadparm)
	{
		custwad = iwadparm;
		FixPathSeperator (custwad);
		if (CheckIWAD (custwad, wads))
		{ // -iwad parameter was a directory
			iwadparm = NULL;
		}
		else
		{
			DefaultExtension (custwad, ".wad");
			iwadparm = custwad;
			IWADNames[0] = iwadparm;
			CheckIWAD ("", wads);
		}
	}

	if (iwadparm == NULL || wads[0].Path.IsEmpty())
	{
		if (GameConfig->SetSection ("IWADSearch.Directories"))
		{
			const char *key;
			const char *value;

			while (GameConfig->NextInSection (key, value))
			{
				if (stricmp (key, "Path") == 0)
				{
					FString nice = NicePath(value);
					FixPathSeperator(nice);
					CheckIWAD(nice, wads);
				}
			}
		}
#ifdef _WIN32
		FString steam_path = I_GetSteamPath();
		if (steam_path.IsNotEmpty())
		{
			static const char *const steam_dirs[] =
			{
				"doom 2/base",
				"final doom/base",
				"heretic shadow of the serpent riders/base",
				"hexen/base",
				"hexen deathkings of the dark citadel/base",
				"ultimate doom/base"
			};
			steam_path += "/SteamApps/common/";
			for (i = 0; i < countof(steam_dirs); ++i)
			{
				CheckIWAD (steam_path + steam_dirs[i], wads);
			}
		}
#endif
	}

	if (iwadparm != NULL && !wads[0].Path.IsEmpty())
	{
		iwadparmfound = true;
	}

	for (i = numwads = 0; i < countof(IWADNames); i++)
	{
		if (!wads[i].Path.IsEmpty())
		{
			if (i != numwads)
			{
				wads[numwads] = wads[i];
			}
			foundwads[wads[numwads].Type] = numwads + 1;
			numwads++;
		}
	}

	if (foundwads[IWAD_HexenDK] && !foundwads[IWAD_Hexen])
	{ // Cannot play Hexen DK without Hexen
		size_t kill = foundwads[IWAD_HexenDK];
		for (i = kill; i < numwads; ++i)
		{
			wads[i - 1] = wads[i];
		}
		numwads--;
		foundwads[IWAD_HexenDK] = 0;
		for (i = 0; i < NUM_IWAD_TYPES; ++i)
		{
			if (foundwads[i] > kill)
			{
				foundwads[i]--;
			}
		}
	}

	if (numwads == 0)
// [BB] Skulltag uses Rivecoder's IWAD setup screen now (only available under Windows).
#ifdef _WIN32
		throw CNoIWADError(); // [RC]
#else
	{
		I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n"
					  "Did you install "GAMENAME" properly? You can do either of the following:\n"
					  "\n"
					  "1. Place one or more of these wads in the same directory as "GAMENAME".\n"
					  "2. Edit your "GAMENAMELOWERCASE"-username.ini and add the directories of your iwads\n"
					  "to the list beneath [IWADSearch.Directories]");
	}
#endif

	pickwad = 0;

	if (!iwadparmfound && numwads > 1)
	{
		int defiwad = 0;

		// Locate the user's prefered IWAD, if it was found.
		if (defaultiwad[0] != '\0')
		{
			for (i = 0; i < numwads; ++i)
			{
				FString basename = ExtractFileBase (wads[i].Path);
				if (stricmp (basename, defaultiwad) == 0)
				{
					defiwad = (int)i;
					break;
				}
			}
		}
		pickwad = I_PickIWad (wads, (int)numwads, queryiwad, defiwad);
		if (pickwad >= 0)
		{
			// The newly selected IWAD becomes the new default
			FString basename = ExtractFileBase (wads[pickwad].Path);
			defaultiwad = basename;
		}
	}

	if (pickwad < 0)
		exit (0);

	// zdoom.pk3 must always be the first file loaded and the IWAD second.
	D_AddFile (wadfiles, zdoom_wad);

	if (wads[pickwad].Type == IWAD_HexenDK)
	{ // load hexen.wad before loading hexdd.wad
		D_AddFile (wadfiles, wads[foundwads[IWAD_Hexen]-1].Path);
	}

	D_AddFile (wadfiles, wads[pickwad].Path);

	if (wads[pickwad].Type == IWAD_Strife)
	{ // Try to load voices.wad along with strife1.wad
		long lastslash = wads[pickwad].Path.LastIndexOf ('/');
		FString path;

		if (lastslash == -1)
		{
			path = "";//  wads[pickwad].Path;
		}
		else
		{
			path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
		}
		path += "voices.wad";
		D_AddFile (wadfiles, path);
	}

	return wads[pickwad].Type;
}
Example #8
0
//
// [denis] D_DoomWadReboot
// change wads at runtime
// on 404, returns a vector of bad files
//
std::vector<size_t> D_DoomWadReboot(
	const std::vector<std::string> &wadnames,
    const std::vector<std::string> &patch_files,
    std::vector<std::string> needhashes
)
{
	std::vector<size_t> fails;
	size_t i;

	if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
		I_FatalError ("\nYou cannot switch WAD with the shareware version. Register!");

	SV_SendReconnectSignal();

	G_ExitLevel(0, 0);
	DThinker::DestroyAllThinkers();

	// Close all open WAD files
	W_Close();
	
	// [ML] 9/11/10: Reset custom wad level information from MAPINFO et al.
    // I have never used memset, I hope I am not invoking satan by doing this :(
	if (wadlevelinfos)
    {
		for (i = 0; i < numwadlevelinfos; i++)
			if (wadlevelinfos[i].snapshot)
			{
				delete wadlevelinfos[i].snapshot;
				wadlevelinfos[i].snapshot = NULL;
			}    	
        memset(wadlevelinfos,0,sizeof(wadlevelinfos));        
        numwadlevelinfos = 0;
    }
    
    if (wadclusterinfos)
    {
        memset(wadclusterinfos,0,sizeof(wadclusterinfos));
        numwadclusterinfos = 0;	        
    }
    
	// Restart the memory manager
	Z_Init();
	
	wadfiles.clear();
	modifiedgame = false;

	std::string custwad;
	if(wadnames.empty() == false)
		custwad = wadnames[0];

	D_AddDefWads(custwad);

	for(i = 0; i < wadnames.size(); i++)
	{
		std::string file = BaseFileSearch(wadnames[i], ".WAD");

		if(file.length())
			wadfiles.push_back(file);
		else
		{
			if (wadnames[i] != "") {
				Printf (PRINT_HIGH, "could not find WAD: %s\n", wadnames[i].c_str());
				fails.push_back(i);
			}
		}
	}

	if(wadnames.size() > 1)
		modifiedgame = true;

	wadhashes = W_InitMultipleFiles (wadfiles);
	SV_InitMultipleFiles (wadfiles);

	// get skill / episode / map from parms
	strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

    UndoDehPatch();
    patchfiles.clear();

	D_InitStrings ();
	D_DoDefDehackedPatch(patch_files);

	G_SetLevelStrings ();
	G_ParseMapInfo ();
	S_ParseSndInfo();

	R_Init();
	P_Init();

	return fails;
}
Example #9
0
//
// R_InitTextures
// Initializes the texture list
//	with the textures from the world map.
//
void R_InitTextures (void)
{
	maptexture_t*		mtexture;
	texture_t*			texture;
	mappatch_t* 		mpatch;
	texpatch_t* 		patch;

	int					i;
	int 				j;

	int*				maptex;
	int*				maptex2;
	int*				maptex1;

	int*				patchlookup;

	int 				totalwidth;
	int					nummappatches;
	int 				offset;
	int 				maxoff;
	int 				maxoff2;
	int					numtextures1;
	int					numtextures2;

	int*				directory;

	int					errors = 0;


	// Load the patch names from pnames.lmp.
	{
		char *names = (char *)W_CacheLumpName ("PNAMES", PU_STATIC);
		char *name_p = names+4;

		nummappatches = LELONG ( *((int *)names) );
		patchlookup = new int[nummappatches];

		for (i = 0; i < nummappatches; i++)
		{
			patchlookup[i] = W_CheckNumForName (name_p + i*8);
			if (patchlookup[i] == -1)
			{
				// killough 4/17/98:
				// Some wads use sprites as wall patches, so repeat check and
				// look for sprites this time, but only if there were no wall
				// patches found. This is the same as allowing for both, except
				// that wall patches always win over sprites, even when they
				// appear first in a wad. This is a kludgy solution to the wad
				// lump namespace problem.

				patchlookup[i] = W_CheckNumForName (name_p + i*8, ns_sprites);
			}
		}
		Z_Free (names);
	}

	// Load the map texture definitions from textures.lmp.
	// The data is contained in one or two lumps,
	//	TEXTURE1 for shareware, plus TEXTURE2 for commercial.
	maptex = maptex1 = (int *)W_CacheLumpName ("TEXTURE1", PU_STATIC);
	numtextures1 = LELONG(*maptex);
	maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
	directory = maptex+1;

	if (W_CheckNumForName ("TEXTURE2") != -1)
	{
		maptex2 = (int *)W_CacheLumpName ("TEXTURE2", PU_STATIC);
		numtextures2 = LELONG(*maptex2);
		maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
	}
	else
	{
		maptex2 = NULL;
		numtextures2 = 0;
		maxoff2 = 0;
	}

	// denis - fix memory leaks
	for (i = 0; i < numtextures; i++)
	{
		delete[] texturecolumnlump[i];
		delete[] texturecolumnofs[i];
	}

	// denis - fix memory leaks
	delete[] textures;
	delete[] texturecolumnlump;
	delete[] texturecolumnofs;
	delete[] texturecomposite;
	delete[] texturecompositesize;
	delete[] texturewidthmask;
	delete[] textureheight;
	delete[] texturescalex;
	delete[] texturescaley;

	numtextures = numtextures1 + numtextures2;

	textures = new texture_t *[numtextures];
	texturecolumnlump = new short *[numtextures];
	texturecolumnofs = new unsigned int *[numtextures];
	texturecomposite = new byte *[numtextures];
	texturecompositesize = new int[numtextures];
	texturewidthmask = new int[numtextures];
	textureheight = new fixed_t[numtextures];
	texturescalex = new fixed_t[numtextures];
	texturescaley = new fixed_t[numtextures];

	totalwidth = 0;

	for (i = 0; i < numtextures; i++, directory++)
	{
		if (i == numtextures1)
		{
			// Start looking in second texture file.
			maptex = maptex2;
			maxoff = maxoff2;
			directory = maptex+1;
		}

		offset = LELONG(*directory);

		if (offset > maxoff)
			I_FatalError ("R_InitTextures: bad texture directory");

		mtexture = (maptexture_t *) ( (byte *)maptex + offset);

		texture = textures[i] = (texture_t *)
			Z_Malloc (sizeof(texture_t)
					  + sizeof(texpatch_t)*(SAFESHORT(mtexture->patchcount)-1),
					  PU_STATIC, 0);

		texture->width = SAFESHORT(mtexture->width);
		texture->height = SAFESHORT(mtexture->height);
		texture->patchcount = SAFESHORT(mtexture->patchcount);

		strncpy (texture->name, mtexture->name, 9); // denis - todo string limit?
		std::transform(texture->name, texture->name + strlen(texture->name), texture->name, toupper);

		mpatch = &mtexture->patches[0];
		patch = &texture->patches[0];

		for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
		{
			patch->originx = LESHORT(mpatch->originx);
			patch->originy = LESHORT(mpatch->originy);
			patch->patch = patchlookup[LESHORT(mpatch->patch)];
			if (patch->patch == -1)
			{
				Printf (PRINT_HIGH, "R_InitTextures: Missing patch in texture %s\n", texture->name);
				errors++;
			}
		}
		texturecolumnlump[i] = new short[texture->width];
		texturecolumnofs[i] = new unsigned int[texture->width];

		for (j = 1; j*2 <= texture->width; j <<= 1)
			;
		texturewidthmask[i] = j-1;

		textureheight[i] = texture->height << FRACBITS;
			
		// [RH] Special for beta 29: Values of 0 will use the tx/ty cvars
		// to determine scaling instead of defaulting to 8. I will likely
		// remove this once I finish the betas, because by then, users
		// should be able to actually create scaled textures.
		texturescalex[i] = mtexture->scalex ? mtexture->scalex << (FRACBITS - 3) : FRACUNIT;
		texturescaley[i] = mtexture->scaley ? mtexture->scaley << (FRACBITS - 3) : FRACUNIT;

		totalwidth += texture->width;
	}
	delete[] patchlookup;

	Z_Free (maptex1);
	if (maptex2)
		Z_Free (maptex2);

	if (errors)
		I_FatalError ("%d errors in R_InitTextures.", errors);

	// [RH] Setup hash chains. Go from back to front so that if
	//		duplicates are found, the first one gets used instead
	//		of the last (thus mimicing the original behavior
	//		of R_CheckTextureNumForName().
	for (i = 0; i < numtextures; i++)
		textures[i]->index = -1;

	for (i = numtextures - 1; i >= 0; i--)
	{
		j = 0; //W_LumpNameHash (textures[i]->name) % (unsigned) numtextures;
		textures[i]->next = textures[j]->index;
		textures[j]->index = i;
	}

	if (clientside)		// server doesn't need to load patches ever
	{
		// Precalculate whatever possible.
		for (i = 0; i < numtextures; i++)
			R_GenerateLookup (i, &errors);
	}

//	if (errors)
//		I_FatalError ("%d errors encountered during texture generation.", errors);

	// Create translation table for global animation.

	delete[] texturetranslation;

	texturetranslation = new int[numtextures+1];

	for (i = 0; i < numtextures; i++)
		texturetranslation[i] = i;
}
Example #10
0
// [RH] Seperated out of R_InitSpriteDefs()
static void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe)
{
	int frame;
	int framestart;
	int rot;
//	int undefinedFix;

	if (maxframe == -1)
	{
		sprites[num].numframes = 0;
		return;
	}

	maxframe++;

	// [RH] If any frames are undefined, but there are some defined frames, map
	// them to the first defined frame. This is a fix for Doom Raider, which actually
	// worked with ZDoom 2.0.47, because of a bug here. It does not define frames A,
	// B, or C for the sprite PSBG, but because I had sprtemp[].rotate defined as a
	// bool, this code never detected that it was not actually present. After switching
	// to the unified texture system, this caused it to crash while loading the wad.

// [RH] Let undefined frames actually be blank because LWM uses this in at least
// one of her wads.
//	for (frame = 0; frame < maxframe && sprtemp[frame].rotate == -1; ++frame)
//	{ }
//
//	undefinedFix = frame;

	for (frame = 0; frame < maxframe; ++frame)
	{
		switch (sprtemp[frame].rotate)
		{
		case -1:
			// no rotations were found for that frame at all
			//I_FatalError ("R_InstallSprite: No patches found for %s frame %c", sprites[num].name, frame+'A');
			break;
			
		case 0:
			// only the first rotation is needed
			for (rot = 1; rot < 16; ++rot)
			{
				sprtemp[frame].Texture[rot] = sprtemp[frame].Texture[0];
			}
			// If the frame is flipped, they all should be
			if (sprtemp[frame].Flip & 1)
			{
				sprtemp[frame].Flip = 0xFFFF;
			}
			break;
					
		case 1:
			// must have all 8 frame pairs
			for (rot = 0; rot < 8; ++rot)
			{
				if (!sprtemp[frame].Texture[rot*2+1].isValid())
				{
					sprtemp[frame].Texture[rot*2+1] = sprtemp[frame].Texture[rot*2];
					if (sprtemp[frame].Flip & (1 << (rot*2)))
					{
						sprtemp[frame].Flip |= 1 << (rot*2+1);
					}
				}
				if (!sprtemp[frame].Texture[rot*2].isValid())
				{
					sprtemp[frame].Texture[rot*2] = sprtemp[frame].Texture[rot*2+1];
					if (sprtemp[frame].Flip & (1 << (rot*2+1)))
					{
						sprtemp[frame].Flip |= 1 << (rot*2);
					}
				}

			}
			for (rot = 0; rot < 16; ++rot)
			{
				if (!sprtemp[frame].Texture[rot].isValid())
					I_FatalError ("R_InstallSprite: Sprite %s frame %c is missing rotations",
									sprites[num].name, frame+'A');
			}
			break;
		}
	}

	for (frame = 0; frame < maxframe; ++frame)
	{
		if (sprtemp[frame].rotate == -1)
		{
			memset (&sprtemp[frame].Texture, 0, sizeof(sprtemp[0].Texture));
			sprtemp[frame].Flip = 0;
			sprtemp[frame].rotate = 0;
		}
	}
	
	// allocate space for the frames present and copy sprtemp to it
	sprites[num].numframes = maxframe;
	sprites[num].spriteframes = WORD(framestart = SpriteFrames.Reserve (maxframe));
	for (frame = 0; frame < maxframe; ++frame)
	{
		memcpy (SpriteFrames[framestart+frame].Texture, sprtemp[frame].Texture, sizeof(sprtemp[frame].Texture));
		SpriteFrames[framestart+frame].Flip = sprtemp[frame].Flip;
		SpriteFrames[framestart+frame].Voxel = sprtemp[frame].Voxel;
	}

	// Let the textures know about the rotations
	for (frame = 0; frame < maxframe; ++frame)
	{
		if (sprtemp[frame].rotate == 1)
		{
			for (int rot = 0; rot < 16; ++rot)
			{
				TexMan[sprtemp[frame].Texture[rot]]->Rotations = framestart + frame;
			}
		}
	}
}
Example #11
0
void FStringTable::LoadStrings (int lump, int expectedSize, bool enuOnly)
{
	BYTE *strData = (BYTE *)W_CacheLumpNum (lump, PU_CACHE);
	int lumpLen = LELONG(((Header *)strData)->FileSize);
	int nameCount = LESHORT(((Header *)strData)->NameCount);
	int nameLen = LESHORT(((Header *)strData)->NameLen);

	int languageStart = sizeof(Header) + nameCount*4 + nameLen;
	languageStart += (4 - languageStart) & 3;

	if (expectedSize >= 0 && nameCount != expectedSize)
	{
		char name[9];

		W_GetLumpName (name, lump);
		name[8] = 0;
		I_FatalError ("%s had %d strings.\nThis version of ZDoom expects it to have %d.",
			name, nameCount, expectedSize);
	}

	FreeStandardStrings ();

	NumStrings = nameCount;
	LumpNum = lump;
	if (Strings == NULL)
	{
		Strings = new char *[nameCount];
		StringStatus = new BYTE[(nameCount+7)/8];
		memset (StringStatus, 0, (nameCount+7)/8);	// 0 means: from wad (standard)
		memset (Strings, 0, sizeof(char *)*nameCount);
	}

	BYTE *const start = strData + languageStart;
	BYTE *const end = strData + lumpLen;
	int loadedCount, i;

	for (loadedCount = i = 0; i < NumStrings; ++i)
	{
		if (Strings[i] != NULL)
		{
			++loadedCount;
		}
	}

	if (!enuOnly)
	{
		for (i = 0; i < 4 && loadedCount != nameCount; ++i)
		{
			loadedCount += LoadLanguage (LanguageIDs[i], true, start, end);
			loadedCount += LoadLanguage (LanguageIDs[i] & MAKE_ID(0xff,0xff,0,0), true, start, end);
			loadedCount += LoadLanguage (LanguageIDs[i], false, start, end);
		}
	}

	// Fill in any missing strings with the default language (enu)
	if (loadedCount != nameCount)
	{
		loadedCount += LoadLanguage (MAKE_ID('e','n','u',0), true, start, end);
	}

	DoneLoading (start, end);

	if (loadedCount != nameCount)
	{
		I_FatalError ("Loaded %d strings (expected %d)", loadedCount, nameCount);
	}
}
Example #12
0
FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum)
: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false)
{
	union
	{
		const maptexture_t			*d;
		const strifemaptexture_t	*s;
	}
	mtexture;

	union
	{
		const mappatch_t			*d;
		const strifemappatch_t		*s;
	}
	mpatch;

	int i;

	mtexture.d = (const maptexture_t *)texdef;
	bMultiPatch = true;

	if (strife)
	{
		NumParts = SAFESHORT(mtexture.s->patchcount);
	}
	else
	{
		NumParts = SAFESHORT(mtexture.d->patchcount);
	}

	if (NumParts <= 0)
	{
		I_FatalError ("Bad texture directory");
	}

	UseType = FTexture::TEX_Wall;
	Parts = new TexPart[NumParts];
	Width = SAFESHORT(mtexture.d->width);
	Height = SAFESHORT(mtexture.d->height);
	strncpy (Name, (const char *)mtexture.d->name, 8);
	Name[8] = 0;

	CalcBitSize ();

	xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT;
	yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT;

	if (mtexture.d->Flags & MAPTEXF_WORLDPANNING)
	{
		bWorldPanning = true;
	}

	if (strife)
	{
		mpatch.s = &mtexture.s->patches[0];
	}
	else
	{
		mpatch.d = &mtexture.d->patches[0];
	}

	for (i = 0; i < NumParts; ++i)
	{
		if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum))
		{
			I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.",
				maxpatchnum, Name, LittleShort(mpatch.d->patch)+1);
		}
		Parts[i].OriginX = LittleShort(mpatch.d->originx);
		Parts[i].OriginY = LittleShort(mpatch.d->originy);
		Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture;
		if (Parts[i].Texture == NULL)
		{
			Printf ("Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name);
			NumParts--;
			i--;
		}
		if (strife)
			mpatch.s++;
		else
			mpatch.d++;
	}
	if (NumParts == 0)
	{
		Printf ("Texture %s is left without any patches\n", Name);
	}

	CheckForHacks ();

	// If this texture is just a wrapper around a single patch, we can simply
	// forward GetPixels() and GetColumn() calls to that patch.
	if (NumParts == 1)
	{
		if (Parts->OriginX == 0 && Parts->OriginY == 0 &&
			Parts->Texture->GetWidth() == Width &&
			Parts->Texture->GetHeight() == Height)
		{
			bRedirect = true;
		}
	}
	DefinitionLump = deflumpnum;
}
Example #13
0
void M_ParseMenuDefs()
{
	int lump, lastlump = 0;

	OptionSettings.mTitleColor = V_FindFontColor(gameinfo.mTitleColor);
	OptionSettings.mFontColor = V_FindFontColor(gameinfo.mFontColor);
	OptionSettings.mFontColorValue = V_FindFontColor(gameinfo.mFontColorValue);
	OptionSettings.mFontColorMore = V_FindFontColor(gameinfo.mFontColorMore);
	OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader);
	OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight);
	OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection);
	DefaultListMenuSettings.Reset();
	DefaultOptionMenuSettings.Reset();

	atterm(	DeinitMenus);
	DeinitMenus();
	while ((lump = Wads.FindLump ("MENUDEF", &lastlump)) != -1)
	{
		FScanner sc(lump);

		sc.SetCMode(true);
		while (sc.GetString())
		{
			if (sc.Compare("LISTMENU"))
			{
				ParseListMenu(sc);
			}
			else if (sc.Compare("DEFAULTLISTMENU"))
			{
				ParseListMenuBody(sc, &DefaultListMenuSettings);
				if (DefaultListMenuSettings.mItems.Size() > 0)
				{
					I_FatalError("You cannot add menu items to the menu default settings.");
				}
			}
			else if (sc.Compare("OPTIONVALUE"))
			{
				ParseOptionValue(sc);
			}
			else if (sc.Compare("OPTIONSTRING"))
			{
				ParseOptionString(sc);
			}
			else if (sc.Compare("OPTIONMENUSETTINGS"))
			{
				ParseOptionSettings(sc);
			}
			else if (sc.Compare("OPTIONMENU"))
			{
				ParseOptionMenu(sc);
			}
			else if (sc.Compare("DEFAULTOPTIONMENU"))
			{
				ParseOptionMenuBody(sc, &DefaultOptionMenuSettings);
				if (DefaultOptionMenuSettings.mItems.Size() > 0)
				{
					I_FatalError("You cannot add menu items to the menu default settings.");
				}
			}
			else
			{
				sc.ScriptError("Unknown keyword '%s'", sc.String);
			}
		}
	}
}
Example #14
0
//
// D_Display
//  draw current display, possibly wiping it from the previous
//
void D_Display (void)
{
    BOOL wipe;

    if (nodrawers)
        return; 				// for comparative timing / profiling

    BEGIN_STAT(D_Display);

    if (gamestate == GS_LEVEL && viewactive && consoleplayer().camera)
        R_SetFOV (consoleplayer().camera->player ?
                  consoleplayer().camera->player->fov : 90.0f);

    // [RH] change the screen mode if needed
    if (setmodeneeded)
    {
        int oldwidth = screen->width;
        int oldheight = screen->height;
        int oldbits = DisplayBits;

        // Change screen mode.
        if (!V_SetResolution (NewWidth, NewHeight, NewBits))
            if (!V_SetResolution (oldwidth, oldheight, oldbits))
                I_FatalError ("Could not change screen mode");

        // Recalculate various view parameters.
        setsizeneeded = true;
        // Trick status bar into rethinking its position
        st_scale.Callback ();
        // Refresh the console.
        C_NewModeAdjust ();
    }

    // change the view size if needed
    if (setsizeneeded)
    {
        R_ExecuteSetViewSize ();
        setmodeneeded = false;
    }

    I_BeginUpdate ();

    // [RH] Allow temporarily disabling wipes
    if (NoWipe)
    {
        NoWipe--;
        wipe = false;
        wipegamestate = gamestate;
    }
    else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE)
    {   // save the current screen if about to wipe
        wipe = true;
        wipe_StartScreen ();
        wipegamestate = gamestate;
    }
    else
    {
        wipe = false;
    }

    switch (gamestate)
    {
    case GS_FULLCONSOLE:
    case GS_DOWNLOAD:
    case GS_CONNECTING:
        C_DrawConsole ();
        M_Drawer ();
        I_FinishUpdate ();
        return;

    case GS_LEVEL:
        if (!gametic)
            break;

        // denis - freshen the borders (ffs..)
        R_DrawViewBorder ();    // erase old menu stuff

        if (viewactive)
            R_RenderPlayerView (&displayplayer());
        if (automapactive)
            AM_Drawer ();
        C_DrawMid ();
        CTF_DrawHud ();
        ST_Drawer ();
        HU_Drawer ();
        break;

    case GS_INTERMISSION:
        if (viewactive)
            R_RenderPlayerView (&displayplayer());
        C_DrawMid ();
        CTF_DrawHud ();
        WI_Drawer ();
        HU_Drawer ();
        break;

    case GS_FINALE:
        F_Drawer ();
        break;

    case GS_DEMOSCREEN:
        D_PageDrawer ();
        break;

    default:
        break;
    }

    // draw pause pic
    if (paused && !menuactive)
    {
        patch_t *pause = W_CachePatch ("M_PAUSE");
        int y;

        y = (automapactive && !viewactive) ? 4 : viewwindowy + 4;
        screen->DrawPatchCleanNoMove (pause, (screen->width-(pause->width())*CleanXfac)/2, y);
    }

    // [RH] Draw icon, if any
    if (D_DrawIcon)
    {
        int lump = W_CheckNumForName (D_DrawIcon);

        D_DrawIcon = NULL;
        if (lump >= 0)
        {
            patch_t *p = W_CachePatch (lump);

            screen->DrawPatchIndirect (p, 160-p->width()/2, 100-p->height()/2);
        }
        NoWipe = 10;
    }

    static bool live_wiping = false;

    if (!wipe)
    {
        if(live_wiping)
        {
            // wipe update online (multiple calls, not just looping here)
            C_DrawConsole ();
            wipe_EndScreen();
            live_wiping = !wipe_ScreenWipe (1);
            M_Drawer ();			// menu is drawn even on top of wipes
            I_FinishUpdate ();		// page flip or blit buffer
        }
        else
        {
            // normal update
            C_DrawConsole ();	// draw console
            M_Drawer ();		// menu is drawn even on top of everything
            I_FinishUpdate ();	// page flip or blit buffer
        }
    }
    else
    {
        if(!connected)
        {
            // wipe update offline
            int wipestart, wipecont, nowtime, tics;
            BOOL done;

            C_DrawConsole ();
            wipe_EndScreen ();
            I_FinishUpdateNoBlit ();

            extern int canceltics;

            wipestart = I_GetTime ();
            wipecont = wipestart - 1;

            do
            {
                do
                {
                    nowtime = I_GetTime ();
                    tics = nowtime - wipecont;
                } while (!tics);
                wipecont = nowtime;
                I_BeginUpdate ();
                done = wipe_ScreenWipe (tics);
                M_Drawer ();			// menu is drawn even on top of wipes
                I_FinishUpdate ();		// page flip or blit buffer
            } while (!done);

            if(!connected)
                canceltics += I_GetTime () - wipestart;
        }
        else
        {
            // wipe update online
            live_wiping = true;

            // wipe update online (multiple calls, not just looping here)
            C_DrawConsole ();
            wipe_EndScreen();
            live_wiping = !wipe_ScreenWipe (1);
            M_Drawer ();			// menu is drawn even on top of wipes
            I_FinishUpdate ();		// page flip or blit buffer
        }
    }

    END_STAT(D_Display);
}
Example #15
0
//
// D_DoomMain
//
void D_DoomMain (void)
{
    unsigned p;
    const char *iwad;
    extern std::string defdemoname;

    M_ClearRandom();

    gamestate = GS_STARTUP;
    SetLanguageIDs ();
    M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in

    if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
        I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command

    Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);

    M_LoadDefaults ();					// load before initing other systems
    C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

    iwad = Args.CheckValue("-iwad");
    if(!iwad)
        iwad = "";

    D_AddDefWads(iwad);
    D_AddCmdParameterFiles();

    wadhashes = W_InitMultipleFiles (wadfiles);

    // [RH] Initialize localizable strings.
    GStrings.LoadStrings (W_GetNumForName ("LANGUAGE"), STRING_TABLE_SIZE, false);
    GStrings.Compact ();

    // [RH] Initialize configurable strings.
    //D_InitStrings ();
    D_DoDefDehackedPatch ();

    // [RH] Moved these up here so that we can do most of our
    //		startup output in a fullscreen console.

    HU_Init ();
    I_Init ();
    V_Init ();

    // Base systems have been inited; enable cvar callbacks
    cvar_t::EnableCallbacks ();

    // [RH] User-configurable startup strings. Because BOOM does.
    if (GStrings(STARTUP1)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP1));
    if (GStrings(STARTUP2)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP2));
    if (GStrings(STARTUP3)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP3));
    if (GStrings(STARTUP4)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP4));
    if (GStrings(STARTUP5)[0])	Printf (PRINT_HIGH, "%s\n", GStrings(STARTUP5));

    // Nomonsters
    sv_nomonsters = Args.CheckParm("-nomonsters");

    // Respawn
    sv_monstersrespawn = Args.CheckParm("-respawn");

    // Fast
    sv_fastmonsters = Args.CheckParm("-fast");

    // developer mode
    devparm = Args.CheckParm ("-devparm");

    // Record a vanilla demo
    p = Args.CheckParm ("-record");
    if (p)
    {
        autorecord = true;
        autostart = true;
        demorecordfile = Args.GetArg (p+1);
    }

    // get skill / episode / map from parms
    strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

    // Check for -playdemo, play a single demo then quit.
    p = Args.CheckParm ("-playdemo");
    // Hack to check for +playdemo command, since if you just add it normally
    // it won't run because it's attempting to run a demo and still set up the
    // first map as normal.
    if (!p)
        p = Args.CheckParm ("+playdemo");
    if (p && p < Args.NumArgs()-1)
    {
        Printf (PRINT_HIGH, "Playdemo parameter found on command line.\n");
        singledemo = true;
        defdemoname = Args.GetArg (p+1);
    }

    const char *val = Args.CheckValue ("-skill");
    if (val)
    {
        sv_skill.Set (val[0]-'0');
    }

    p = Args.CheckParm ("-warp");
    if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
    {
        int ep, map;

        if (gameinfo.flags & GI_MAPxx)
        {
            ep = 1;
            map = atoi (Args.GetArg(p+1));
        }
        else
        {
            ep = Args.GetArg(p+1)[0]-'0';
            map = Args.GetArg(p+2)[0]-'0';
        }

        strncpy (startmap, CalcMapName (ep, map), 8);
        autostart = true;
    }

    // [RH] Hack to handle +map
    p = Args.CheckParm ("+map");
    if (p && p < Args.NumArgs()-1)
    {
        strncpy (startmap, Args.GetArg (p+1), 8);
        ((char *)Args.GetArg (p))[0] = '-';
        autostart = true;
    }
    if (devparm)
        Printf (PRINT_HIGH, "%s", GStrings(D_DEVSTR));        // D_DEVSTR

    // [RH] Now that all text strings are set up,
    // insert them into the level and cluster data.
    G_SetLevelStrings ();

    // [RH] Parse through all loaded mapinfo lumps
    G_ParseMapInfo ();

    // [ML] Parse musinfo lump
    G_ParseMusInfo ();

    // [RH] Parse any SNDINFO lumps
    S_ParseSndInfo();

    // Check for -file in shareware
    if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
        I_Error ("You cannot -file with the shareware version. Register!");

#ifdef WIN32
    const char *sdlv = getenv("SDL_VIDEODRIVER");
    Printf (PRINT_HIGH, "Using %s video driver.\n",sdlv);
#endif

    Printf (PRINT_HIGH, "M_Init: Init miscellaneous info.\n");
    M_Init ();

    Printf (PRINT_HIGH, "R_Init: Init DOOM refresh daemon.\n");
    R_Init ();

    Printf (PRINT_HIGH, "P_Init: Init Playloop state.\n");
    P_InitEffects();	// [ML] Do this here so we don't have to put particle crap in server
    P_Init ();

    Printf (PRINT_HIGH, "S_Init: Setting up sound.\n");
    Printf (PRINT_HIGH, "S_Init: default sfx volume is %g\n", (float)snd_sfxvolume);
    Printf (PRINT_HIGH, "S_Init: default music volume is %g\n", (float)snd_musicvolume);
    S_Init (snd_sfxvolume, snd_musicvolume);

    I_FinishClockCalibration ();

    Printf (PRINT_HIGH, "D_CheckNetGame: Checking network game status.\n");
    D_CheckNetGame ();

    Printf (PRINT_HIGH, "ST_Init: Init status bar.\n");
    ST_Init ();

    // [RH] Initialize items. Still only used for the give command. :-(
    InitItems ();

    // [RH] Lock any cvars that should be locked now that we're
    // about to begin the game.
    cvar_t::EnableNoSet ();

    // [RH] Now that all game subsystems have been initialized,
    // do all commands on the command line other than +set
    C_ExecCmdLineParams (false, false);

    Printf_Bold("\n\35\36\36\36\36 Odamex Client Initialized \36\36\36\36\37\n");
    if(gamestate != GS_CONNECTING)
        Printf(PRINT_HIGH, "Type connect <address> or use the Odamex Launcher to connect to a game.\n");
    Printf(PRINT_HIGH, "\n");

    setmodeneeded = false; // [Fly] we don't need to set a video mode here!
    //gamestate = GS_FULLCONSOLE;

    // [SL] allow the user to pass the name of a netdemo as the first argument.
    // This allows easy launching of netdemos from Windows Explorer or other GUIs.

    // [Xyltol]
    if (Args.GetArg(1))
    {
        std::string demoarg = Args.GetArg(1);
        if (demoarg.find(".odd") != std::string::npos)
            CL_NetDemoPlay(demoarg);
    }

    p = Args.CheckParm("-netplay");
    if (p)
    {
        if (Args.GetArg(p + 1))
        {
            std::string filename = Args.GetArg(p + 1);
            CL_NetDemoPlay(filename);
        }
        else
        {
            Printf(PRINT_HIGH, "No netdemo filename specified.\n");
        }
    }

    // denis - bring back the demos
    if ( gameaction != ga_loadgame )
    {
        if (autostart || netgame || singledemo)
        {
            if (singledemo)
                G_DoPlayDemo();
            else
            {
                if(autostart)
                {
                    // single player warp (like in g_level)
                    serverside = true;
                    sv_allowexit = "1";
                    sv_freelook = "1";
                    sv_allowjump = "1";
                    sv_allowredscreen = "1";
                    sv_gametype = GM_COOP;

                    players.clear();
                    players.push_back(player_t());
                    players.back().playerstate = PST_REBORN;
                    consoleplayer_id = displayplayer_id = players.back().id = 1;
                }

                G_InitNew (startmap);
                if (autorecord)
                    if (G_RecordDemo(demorecordfile.c_str()))
                        G_BeginRecording();
            }
        }
        else
        {
            if (gamestate != GS_CONNECTING)
                gamestate = GS_HIDECONSOLE;

            C_ToggleConsole();

            D_StartTitle (); // start up intro loop
        }
    }

    // denis - this will run a demo and quit
    p = Args.CheckParm ("+demotest");
    if (p && p < Args.NumArgs()-1)
    {
        demotest = 1;
        defdemoname = Args.GetArg (p+1);
        G_DoPlayDemo();

        while(demoplayback)
        {
            DObject::BeginFrame ();
            G_Ticker();
            DObject::EndFrame ();
            gametic++;
        }
    }
    else
    {
        demotest = 0;
        D_DoomLoop ();		// never returns
    }
}
Example #16
0
void D_DoomMain (void)
{
	M_ClearRandom();

	gamestate = GS_STARTUP;

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command

	I_Init ();

	D_CheckNetGame ();

	M_LoadDefaults ();			// load before initing other systems
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	//D_AddDefWads();
	//SV_InitMultipleFiles (wadfiles);
	//wadhashes = W_InitMultipleFiles (wadfiles);

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks ();

	// [RH] Initialize configurable strings.
	D_InitStrings ();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (STARTUP1[0])	Printf (PRINT_HIGH, "%s\n", STARTUP1);
	if (STARTUP2[0])	Printf (PRINT_HIGH, "%s\n", STARTUP2);
	if (STARTUP3[0])	Printf (PRINT_HIGH, "%s\n", STARTUP3);
	if (STARTUP4[0])	Printf (PRINT_HIGH, "%s\n", STARTUP4);
	if (STARTUP5[0])	Printf (PRINT_HIGH, "%s\n", STARTUP5);

	devparm = Args.CheckParm ("-devparm");

    // get skill / episode / map from parms
	strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

	const char *val = Args.CheckValue ("-skill");
	if (val)
	{
		skill.Set (val[0]-'0');
	}

	unsigned p = Args.CheckParm ("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi (Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy (startmap, CalcMapName (ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm ("+map");
	if (p && p < Args.NumArgs()-1)
	{
		strncpy (startmap, Args.GetArg (p+1), 8);
		((char *)Args.GetArg (p))[0] = '-';
		autostart = true;
	}
	if (devparm)
		Printf (PRINT_HIGH, "%s", Strings[0].builtin);	// D_DEVSTR

	const char *v = Args.CheckValue ("-timer");
	if (v)
	{
		double time = atof (v);
		Printf (PRINT_HIGH, "Levels will end after %g minute%s.\n", time, time > 1 ? "s" : "");
		timelimit.Set ((float)time);
	}

	const char *w = Args.CheckValue ("-avg");
	if (w)
	{
		Printf (PRINT_HIGH, "Austin Virtual Gaming: Levels will end after 20 minutes\n");
		timelimit.Set (20);
	}

	// Check for -file in shareware
	if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
		I_FatalError ("You cannot -file with the shareware version. Register!");

	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems ();

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet ();

	Printf(PRINT_HIGH, "========== Odamex Server Initialized ==========\n");

#ifdef UNIX
	if (Args.CheckParm("-background"))
            daemon_init();
#endif

	// Use wads mentioned on the commandline to start with
	std::vector<std::string> start_wads;

	std::string custwad;
	const char *iwadparm = Args.CheckValue ("-iwad");
	if (iwadparm)
	{
		custwad = iwadparm;
		FixPathSeparator (custwad);
		start_wads.push_back(custwad);
	}

	DArgs files = Args.GatherFiles ("-file", ".wad", true);
	if (files.NumArgs() > 0)
	{
		modifiedgame = true;
		for (size_t i = 0; i < files.NumArgs(); i++)
		{
			start_wads.push_back(files.GetArg (i));
		}
	}

	D_DoomWadReboot(start_wads);

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams (false, false);

	strncpy(level.mapname, startmap, sizeof(level.mapname));

    gamestate = GS_STARTUP;

	G_ChangeMap ();

	D_DoomLoop (); // never returns
}
Example #17
0
void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
{
	DThinker *thinker;
	BYTE stat;
	int statcount;
	int i;

	// Save lists of thinkers, but not by storing the first one and letting
	// the archiver catch the rest. (Which leads to buttloads of recursion
	// and makes the file larger.) Instead, we explicitly save each thinker
	// in sequence. When restoring an archive, we also have to maintain
	// the thinker lists here instead of relying on the archiver to do it
	// for us.

	if (arc.IsStoring())
	{
		for (statcount = i = 0; i <= MAX_STATNUM; i++)
		{
			statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty());
		}
		arc << statcount;
		for (i = 0; i <= MAX_STATNUM; i++)
		{
			if (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty())
			{
				stat = i;
				arc << stat;
				SaveList(arc, Thinkers[i].GetHead());
				SaveList(arc, FreshThinkers[i].GetHead());
				thinker = NULL;
				arc << thinker;		// Save a final NULL for this list
			}
		}
	}
	else
	{
		if (hubLoad)
			DestroyMostThinkers();
		else
			DestroyAllThinkers();

		// Prevent the constructor from inserting thinkers into a list.
		bSerialOverride = true;

		try
		{
			arc << statcount;
			while (statcount > 0)
			{
				arc << stat << thinker;
				while (thinker != NULL)
				{
					// This may be a player stored in their ancillary list. Remove
					// them first before inserting them into the new list.
					if (thinker->NextThinker != NULL)
					{
						thinker->Remove();
					}
					// Thinkers with the OF_JustSpawned flag set go in the FreshThinkers
					// list. Anything else goes in the regular Thinkers list.
					if (thinker->ObjectFlags & OF_EuthanizeMe)
					{
						// This thinker was destroyed during the loading process. Do
						// not link it in to any list.
					}
					else if (thinker->ObjectFlags & OF_JustSpawned)
					{
						FreshThinkers[stat].AddTail(thinker);
					}
					else
					{
						Thinkers[stat].AddTail(thinker);
					}
					arc << thinker;
				}
				statcount--;
			}
		}
		catch (class CDoomError &err)
		{
			bSerialOverride = false;

			// DestroyAllThinkers cannot be called here. It will try to delete the corrupted
			// object table left behind by the serializer and crash.
			// Trying to continue is not an option here because the garbage collector will 
			// crash the next time it runs.
			// Even making this a fatal error will crash but at least the message can be seen
			// before the crash - which is not the case with all other options.

			//DestroyAllThinkers();
			I_FatalError("%s", err.GetMessage());
			throw;
		}
		bSerialOverride = false;
	}
}
Example #18
0
GLVideo::GLVideo(int parm)
{
	if (SDL_InitSubSystem (SDL_INIT_VIDEO) == -1)
	{
		I_FatalError("Could not initialize SDL video.\n");
		return;
	}

	// [Russell] - A basic version string that will eventually get replaced
	//             better than "Odamex SDL Alpha Build 001" or something :P
	std::string title = "Odamex - v";
	title += DOTVERSIONSTR;

	// [Russell] - Update window caption with name
	SDL_WM_SetCaption (title.c_str(), title.c_str());

   sdlScreen = NULL;
   infullscreen = false;
   screenw = screenh = screenbits = 0;
   palettechanged = false;

   chainHead = new cChain(NULL);

   // Get Video modes
   SDL_PixelFormat fmt;
   fmt.palette = NULL;
   fmt.BitsPerPixel = 8;
   fmt.BytesPerPixel = 1;

   SDL_Rect **sdllist = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);

   vidModeList = NULL;
   vidModeCount = 0;

   if(!sdllist)
   {
	  // no fullscreen modes, but we could still try windowed
	  Printf(PRINT_HIGH, "SDL_ListModes returned NULL. No fullscreen video modes are available.\n");
      vidModeList = NULL;
	  vidModeCount = 0;
	  return;
   }
   else if(sdllist == (SDL_Rect **)-1)
   {
      I_FatalError("SDL_ListModes returned -1. Internal error.\n");
      return;
   }
   else
   {
      int i;
      for(i = 0; sdllist[i]; i++)
         ;

      vidModeList = new vidMode[i];
      vidModeCount = i;

      for(i = 0; sdllist[i]; i++)
      {
         vidModeList[i].width = sdllist[i]->w;
         vidModeList[i].height = sdllist[i]->h;
         vidModeList[i].bits = 8;
      }
   }
}
Example #19
0
static void STACK_ARGS NewFailure ()
{
    I_FatalError ("Failed to allocate memory from system heap");
}
Example #20
0
FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum)
: Pixels (0), Spans(0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false)
{
	union
	{
		const maptexture_t			*d;
		const strifemaptexture_t	*s;
	}
	mtexture;

	union
	{
		const mappatch_t			*d;
		const strifemappatch_t		*s;
	}
	mpatch;

	int i;

	mtexture.d = (const maptexture_t *)texdef;
	bMultiPatch = true;

	if (strife)
	{
		NumParts = SAFESHORT(mtexture.s->patchcount);
	}
	else
	{
		NumParts = SAFESHORT(mtexture.d->patchcount);
	}

	if (NumParts < 0)
	{
		I_FatalError ("Bad texture directory");
	}

	UseType = ETextureType::Wall;
	Parts = NumParts > 0 ? new TexPart[NumParts] : nullptr;
	Inits = NumParts > 0 ? new TexInit[NumParts] : nullptr;
	Width = SAFESHORT(mtexture.d->width);
	Height = SAFESHORT(mtexture.d->height);
	Name = (char *)mtexture.d->name;
	CalcBitSize ();

	Scale.X = mtexture.d->ScaleX ? mtexture.d->ScaleX / 8. : 1.;
	Scale.Y = mtexture.d->ScaleY ? mtexture.d->ScaleY / 8. : 1.;

	if (mtexture.d->Flags & MAPTEXF_WORLDPANNING)
	{
		bWorldPanning = true;
	}

	if (strife)
	{
		mpatch.s = &mtexture.s->patches[0];
	}
	else
	{
		mpatch.d = &mtexture.d->patches[0];
	}

	for (i = 0; i < NumParts; ++i)
	{
		if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum))
		{
			I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.",
				maxpatchnum, Name.GetChars(), LittleShort(mpatch.d->patch)+1);
		}
		Parts[i].OriginX = LittleShort(mpatch.d->originx);
		Parts[i].OriginY = LittleShort(mpatch.d->originy);
		Parts[i].Texture = nullptr;
		Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name;
		Inits[i].UseType = ETextureType::WallPatch;
		if (strife)
			mpatch.s++;
		else
			mpatch.d++;
	}
	if (NumParts == 0)
	{
		Printf ("Texture %s is left without any patches\n", Name.GetChars());
	}

	DefinitionLump = deflumpnum;
}
Example #21
0
void D_DoomMain (void)
{
	const char *iwad;
	
	M_ClearRandom();

	gamestate = GS_STARTUP;
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in	

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command
	
	// Always log by default
    if (!LOG.is_open())
    	C_DoCommand("logfile");

	Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);

	M_LoadDefaults ();			// load before initing other systems
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	iwad = Args.CheckValue("-iwad");
	if(!iwad)
		iwad = "";

	D_AddDefWads(iwad);
	D_AddCmdParameterFiles();

	wadhashes = W_InitMultipleFiles (wadfiles);
	SV_InitMultipleFiles (wadfiles);
	
	// [RH] Initialize configurable strings.
	D_InitStrings ();
	D_DoDefDehackedPatch();
	
	I_Init ();

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks ();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (STARTUP1[0])	Printf (PRINT_HIGH, "%s\n", STARTUP1);
	if (STARTUP2[0])	Printf (PRINT_HIGH, "%s\n", STARTUP2);
	if (STARTUP3[0])	Printf (PRINT_HIGH, "%s\n", STARTUP3);
	if (STARTUP4[0])	Printf (PRINT_HIGH, "%s\n", STARTUP4);
	if (STARTUP5[0])	Printf (PRINT_HIGH, "%s\n", STARTUP5);

	devparm = Args.CheckParm ("-devparm");

    // get skill / episode / map from parms
	strcpy (startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

	const char *val = Args.CheckValue ("-skill");
	if (val)
	{
		sv_skill.Set (val[0]-'0');
	}

	if (devparm)
		Printf (PRINT_HIGH, "%s", Strings[0].builtin);	// D_DEVSTR

	const char *v = Args.CheckValue ("-timer");
	if (v)
	{
		double time = atof (v);
		Printf (PRINT_HIGH, "Levels will end after %g minute%s.\n", time, time > 1 ? "s" : "");
		sv_timelimit.Set ((float)time);
	}

	const char *w = Args.CheckValue ("-avg");
	if (w)
	{
		Printf (PRINT_HIGH, "Austin Virtual Gaming: Levels will end after 20 minutes\n");
		sv_timelimit.Set (20);
	}
	
	// [RH] Now that all text strings are set up,
	// insert them into the level and cluster data.
	G_SetLevelStrings ();
	// [RH] Parse through all loaded mapinfo lumps
	G_ParseMapInfo ();	
	// [RH] Parse any SNDINFO lumps
	S_ParseSndInfo();

	// Check for -file in shareware
	if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
		I_FatalError ("You cannot -file with the shareware version. Register!");

	Printf (PRINT_HIGH, "R_Init: Init DOOM refresh daemon.\n");
	R_Init ();

	Printf (PRINT_HIGH, "P_Init: Init Playloop state.\n");
	P_Init ();
		
	Printf (PRINT_HIGH, "SV_InitNetwork: Checking network game status.\n");
    SV_InitNetwork();
		
	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems ();

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet ();

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams (false, false);
	
	Printf(PRINT_HIGH, "========== Odamex Server Initialized ==========\n");

#ifdef UNIX
	if (Args.CheckParm("-background"))
            daemon_init();
#endif

	// Use wads mentioned on the commandline to start with
	//std::vector<std::string> start_wads;
	//std::string custwad;

	//iwad = Args.CheckValue("-iwad");
	//D_DoomWadReboot(start_wads);


	unsigned p = Args.CheckParm ("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi (Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy (startmap, CalcMapName (ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm ("+map");
	if (p && p < Args.NumArgs()-1)
	{
		strncpy (startmap, Args.GetArg (p+1), 8);
		((char *)Args.GetArg (p))[0] = '-';
		autostart = true;
	}

	strncpy(level.mapname, startmap, sizeof(level.mapname));

	G_ChangeMap ();

	D_DoomLoop (); // never returns
}
bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight)
{
	if (gl_renderbuffers != BuffersActive)
	{
		if (BuffersActive)
			glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB);
		BuffersActive = gl_renderbuffers;
		GLRenderer->mShaderManager->ResetFixedColormap();
	}

	if (!IsEnabled())
		return false;
		
	if (width <= 0 || height <= 0)
		I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height);

	int samples = clamp((int)gl_multisample, 0, mMaxSamples);
	bool needsSceneTextures = (gl_ssao != 0);

	GLint activeTex;
	GLint textureBinding;
	glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
	glActiveTexture(GL_TEXTURE0);
	glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);

	if (width != mWidth || height != mHeight)
		CreatePipeline(width, height);

	if (width != mWidth || height != mHeight || mSamples != samples || mSceneUsesTextures != needsSceneTextures)
		CreateScene(width, height, samples, needsSceneTextures);

	mWidth = width;
	mHeight = height;
	mSamples = samples;
	mSceneUsesTextures = needsSceneTextures;

	// Bloom bluring buffers need to match the scene to avoid bloom bleeding artifacts
	if (mSceneWidth != sceneWidth || mSceneHeight != sceneHeight)
	{
		CreateBloom(sceneWidth, sceneHeight);
		CreateExposureLevels(sceneWidth, sceneHeight);
		CreateAmbientOcclusion(sceneWidth, sceneHeight);
		mSceneWidth = sceneWidth;
		mSceneHeight = sceneHeight;
	}

	glBindTexture(GL_TEXTURE_2D, textureBinding);
	glActiveTexture(activeTex);
	glBindRenderbuffer(GL_RENDERBUFFER, 0);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	if (FailedCreate)
	{
		ClearScene();
		ClearPipeline();
		ClearEyeBuffers();
		ClearBloom();
		ClearExposureLevels();
		mWidth = 0;
		mHeight = 0;
		mSamples = 0;
		mSceneWidth = 0;
		mSceneHeight = 0;
	}

	return !FailedCreate;
}
Example #23
0
//
// D_Display
//  draw current display, possibly wiping it from the previous
//
void D_Display (void)
{
	if (nodrawers)
		return; 				// for comparative timing / profiling

	BEGIN_STAT(D_Display);

	// [RH] change the screen mode if needed
	if (setmodeneeded)
	{
		// Change screen mode.
		if (!V_SetResolution (NewWidth, NewHeight, NewBits))
			I_FatalError ("Could not change screen mode");

		// Recalculate various view parameters.
		setsizeneeded = true;
		// Trick status bar into rethinking its position
		st_scale.Callback ();
		// Refresh the console.
		C_NewModeAdjust ();
	}

	// [AM] Moved to below setmodeneeded so we have accurate screen size info.
	if (gamestate == GS_LEVEL && viewactive && consoleplayer().camera)
	{
		if (consoleplayer().camera->player)
			R_SetFOV(consoleplayer().camera->player->fov, setmodeneeded || setsizeneeded);
		else
			R_SetFOV(90.0f, setmodeneeded || setsizeneeded);
	}

	// change the view size if needed
	if (setsizeneeded)
	{
		R_ExecuteSetViewSize ();
		setmodeneeded = false;
	}

	I_BeginUpdate ();

	// [RH] Allow temporarily disabling wipes
	if (NoWipe)
	{
		NoWipe--;
		wipegamestate = gamestate;
	}
	else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE)
	{
		wipegamestate = gamestate;
		Wipe_Start();
		wiping_screen = true;
	}

	switch (gamestate)
	{
		case GS_FULLCONSOLE:
		case GS_DOWNLOAD:
		case GS_CONNECTING:
        case GS_CONNECTED:
			C_DrawConsole ();
			M_Drawer ();
			I_FinishUpdate ();
			return;

		case GS_LEVEL:
			if (!gametic)
				break;

			V_DoPaletteEffects();
			if (viewactive)
				R_RenderPlayerView(&displayplayer());
			if (automapactive)
				AM_Drawer();
			V_RestorePalettes();
			R_DrawViewBorder();
			C_DrawMid ();
			C_DrawGMid();
			CTF_DrawHud ();
			ST_Drawer ();
			HU_Drawer ();
			break;

		case GS_INTERMISSION:
			if (viewactive)
				R_RenderPlayerView(&displayplayer());
			C_DrawMid ();
			CTF_DrawHud ();
			WI_Drawer ();
			HU_Drawer ();
			break;

		case GS_FINALE:
			F_Drawer ();
			break;

		case GS_DEMOSCREEN:
			D_PageDrawer ();
			break;

	default:
	    break;
	}

	// draw pause pic
	if (paused && !menuactive)
	{
		const Texture* texture = R_LoadTexture("M_PAUSE");
		int x = (screen->width - texture->getWidth() * CleanXfac) / 2;
		int y = (automapactive && !viewactive) ? 4 : viewwindowy + 4;
		screen->DrawTextureCleanNoMove(texture, x, y);
	}

	// [RH] Draw icon, if any
	if (D_DrawIcon)
	{
		texhandle_t texhandle = texturemanager.getHandle(D_DrawIcon, Texture::TEX_PATCH);
		const Texture* texture = texturemanager.getTexture(texhandle);
		D_DrawIcon = NULL;

		int x = 160 - texture->getWidth() / 2;
		int y = 100 - texture->getHeight() / 2;
		screen->DrawTextureIndirect(texture, x, y);
		NoWipe = 10;
	}

	if (wiping_screen)
		Wipe_Drawer();

	C_DrawConsole();	// draw console
	M_Drawer();			// menu is drawn even on top of everything
	I_FinishUpdate();	// page flip or blit buffer

	END_STAT(D_Display);
}
Example #24
0
void*
Z_Malloc
( size_t	size,
  int		tag,
  void*		user )
{
	int 		extra;
	memblock_t	*start;
	memblock_t	*rover;
	memblock_t	*newblock;
	memblock_t	*base;

//#ifdef _DEBUG
//	Z_CheckHeap ();
//#endif

	size = (size + ALIGN - 1) & ~(ALIGN - 1);

    // scan through the block list,
    // looking for the first free block
    // of sufficient size,
    // throwing out any purgable blocks along the way.
	
	// account for size of block header
	size += sizeof(memblock_t);

    // if there is a free block behind the rover,
    //  back up over them
	base = mainzone->rover;
	if (!base->prev->user)
		base = base->prev;

	rover = base;
	start = base->prev;

	do
	{
		if (rover == start)
		{
			// scanned all the way around the list
			I_FatalError ("Z_Malloc: failed on allocation of %i bytes", size);
		}
		
		if (rover->user)
		{
			if (rover->tag < PU_PURGELEVEL)
			{
				// hit a block that can't be purged,
				//  so move past it
				base = rover = rover->next;
			}
			else
			{
				// free the rover block (adding the size to base)
				
				// the rover can be the base block
				base = base->prev;
				Z_Free ((byte *)rover+sizeof(memblock_t));
				base = base->next;
				rover = base->next;
			}
		}
		else
			rover = rover->next;
	} while (base->user || base->size < size);

	// found a block big enough
	extra = base->size - size;
	
	if (extra > MINFRAGMENT)
	{
		// there will be a free fragment after the allocated block
		newblock = (memblock_t *) ((byte *)base + size );
		newblock->size = extra;
		
		// NULL indicates free block.
		newblock->user = NULL;	
		newblock->tag = 0;
		newblock->prev = base;
		newblock->next = base->next;
		newblock->next->prev = newblock;

		base->next = newblock;
		base->size = size;
	}
		
	if (user)
	{
		// mark as an in use block
		base->user = (void **)user;
		*(void **)user = (void *) ((byte *)base + sizeof(memblock_t));
	}
	else
	{
		if (tag >= PU_PURGELEVEL)
			I_FatalError ("Z_Malloc: an owner is required for purgable blocks");

		// mark as in use, but unowned
		base->user = (void **)2;
	}
	base->tag = tag;

	// next allocation will start looking here
	mainzone->rover = base->next;

	base->id = ZONEID;

//#ifdef _DEBUG
//	Z_CheckHeap ();
//#endif

	return (void *) ((byte *)base + sizeof(memblock_t));
}
Example #25
0
FBaseCVar::FBaseCVar (const FBaseCVar &var)
{
	I_FatalError ("Use of cvar copy constructor");
}
Example #26
0
void Win32Video::InitDDraw ()
{
	DIRECTDRAWCREATEFUNC directdraw_create;
	LPDIRECTDRAW ddraw1;
	STARTLOG;

	HRESULT dderr;

	// Load the DirectDraw library.
	if ((DDraw_dll = LoadLibraryA ("ddraw.dll")) == NULL)
	{
		I_FatalError ("Could not load ddraw.dll");
	}

	// Obtain an IDirectDraw interface.
	if ((directdraw_create = (DIRECTDRAWCREATEFUNC)GetProcAddress (DDraw_dll, "DirectDrawCreate")) == NULL)
	{
		I_FatalError ("The system file ddraw.dll is missing the DirectDrawCreate export");
	}

	dderr = directdraw_create (NULL, &ddraw1, NULL);

	if (FAILED(dderr))
		I_FatalError ("Could not create DirectDraw object: %08lx", dderr);

	dderr = ddraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DDraw);
	if (FAILED(dderr))
	{
		ddraw1->Release ();
		DDraw = NULL;
		I_FatalError ("Could not initialize IDirectDraw2 interface: %08lx", dderr);
	}

	// Okay, we have the IDirectDraw2 interface now, so we can release the
	// really old-fashioned IDirectDraw one.
	ddraw1->Release ();

	DDraw->SetCooperativeLevel (Window, DDSCL_NORMAL);
	FreeModes ();
	dderr = DDraw->EnumDisplayModes (0, NULL, this, EnumDDModesCB);
	if (FAILED(dderr))
	{
		DDraw->Release ();
		DDraw = NULL;
		I_FatalError ("Could not enumerate display modes: %08lx", dderr);
	}
	if (m_Modes == NULL)
	{
		DDraw->Release ();
		DDraw = NULL;
		I_FatalError ("DirectDraw returned no display modes.\n\n"
					"If you started ZDoom from a fullscreen DOS box, run it from "
					"a DOS window instead. If that does not work, you may need to reboot.");
	}
	if (Args->CheckParm ("-2"))
	{ // Force all modes to be pixel-doubled.
		ScaleModes(1);
	}
	else if (Args->CheckParm ("-4"))
	{ // Force all modes to be pixel-quadrupled.
		ScaleModes(2);
	}
	else
	{
		if (OSPlatform == os_Win95)
		{
			// Windows 95 will let us use Mode X. If we didn't find any linear
			// modes in the loop above, add the Mode X modes here.
			AddMode (320, 200, 8, 200, 0);
			AddMode (320, 240, 8, 240, 0);
		}
		AddLowResModes ();
	}
	AddLetterboxModes ();
}
Example #27
0
//
// Z_Realloc
//
// For the native heap, this can easily behave as a real realloc, and not
// just an ignorant copy-and-free.
//
void *(Z_Realloc)(void *ptr, size_t n, int tag, void **user,
                  const char *file, int line)
{
   void *p;
   memblock_t *block, *newblock, *origblock;

   // if not allocated at all, defer to Z_Malloc
   if(!ptr)
      return (Z_Malloc)(n, tag, user, file, line);

   // size == 0 is a special case that cannot be handled below
   if(n == 0)
   {
      (Z_Free)(ptr, file, line);
      return NULL;
   }

   DEBUG_CHECKHEAP();

   block = origblock = (memblock_t *)((byte *)ptr - header_size);

   Z_IDCheck(IDBOOL(block->id != ZONEID),
             "Z_Realloc: Reallocated a block without ZONEID\n", 
             block, file, line);

   // haleyjd: realloc cannot change the tag of a permanent block
   if(block->tag == PU_PERMANENT)
      tag = PU_PERMANENT;

   // nullify current user, if any
   if(block->user)
      *(block->user) = NULL;

   // detach from list before reallocation
   if((*block->prev = block->next))
      block->next->prev = block->prev;

   block->next = NULL;
   block->prev = NULL;

   INSTRUMENT(memorybytag[block->tag] -= block->size);

   if(!(newblock = (memblock_t *)(realloc(block, n + header_size))))
   {
      // haleyjd 07/09/10: Note that unlinking the block above makes this safe 
      // even if the current block is PU_CACHE; Z_FreeTags won't find it.
      if(blockbytag[PU_CACHE])
      {
         Z_FreeTags(PU_CACHE, PU_CACHE);
         newblock = (memblock_t *)(realloc(block, n + header_size));
      }
   }

   if(!(block = newblock))
   {
      if(origblock->size >= n)
      {
         block = origblock; // restore original block if size was equal or smaller
         n = block->size;   // keep same size in this event
      }
      else
      {
         I_FatalError(I_ERR_KILL, "Z_Realloc: Failure trying to allocate %u bytes\n"
                                  "Source: %s:%d\n", (unsigned int)n, file, line);
      }
   }

   block->size = n;
   block->tag  = tag;

   p = (byte *)block + header_size;

   // set new user, if any
   block->user = user;
   if(user)
      *user = p;

   // reattach to list at possibly new address, new tag
   if((block->next = blockbytag[tag]))
      block->next->prev = &block->next;
   blockbytag[tag] = block;
   block->prev = &blockbytag[tag];

   INSTRUMENT(memorybytag[tag] += block->size);
   INSTRUMENT(block->file = file);
   INSTRUMENT(block->line = line);

   Z_LogPrintf("* %p = Z_Realloc(ptr=%p, n=%lu, tag=%d, user=%p, source=%s:%d)\n", 
               p, ptr, n, tag, user, file, line);

   return p;
}
Example #28
0
DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old)
{
	static int retry = 0;
	static int owidth, oheight;

	BaseWinFB *fb;
	PalEntry flashColor;
	int flashAmount;

	LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old);

	if (old != NULL)
	{ // Reuse the old framebuffer if its attributes are the same
		BaseWinFB *fb = static_cast<BaseWinFB *> (old);
		if (fb->Width == width &&
			fb->Height == height &&
			fb->Windowed == !fullscreen)
		{
			return old;
		}
		old->GetFlash (flashColor, flashAmount);
		old->ObjectFlags |= OF_YesReallyDelete;
		if (old == screen) screen = NULL;
		delete old;
	}
	else
	{
		flashColor = 0;
		flashAmount = 0;
	}

	if (D3D != NULL)
	{
		fb = new D3DFB (width, height, fullscreen);
	}
	else
	{
		fb = new DDrawFB (width, height, fullscreen);
	}
	LOG1 ("New fb created @ %p\n", fb);

	// If we could not create the framebuffer, try again with slightly
	// different parameters in this order:
	// 1. Try with the closest size
	// 2. Try in the opposite screen mode with the original size
	// 3. Try in the opposite screen mode with the closest size
	// This is a somewhat confusing mass of recursion here.

	while (fb == NULL || !fb->IsValid ())
	{
		static HRESULT hr;

		if (fb != NULL)
		{
			if (retry == 0)
			{
				hr = fb->GetHR ();
			}
			delete fb;

			LOG1 ("fb is bad: %08lx\n", hr);
		}
		else
		{
			LOG ("Could not create fb at all\n");
		}
		screen = NULL;

		LOG1 ("Retry number %d\n", retry);

		switch (retry)
		{
		case 0:
			owidth = width;
			oheight = height;
		case 2:
			// Try a different resolution. Hopefully that will work.
			I_ClosestResolution (&width, &height, 8);
			LOG2 ("Retry with size %d,%d\n", width, height);
			break;

		case 1:
			// Try changing fullscreen mode. Maybe that will work.
			width = owidth;
			height = oheight;
			fullscreen = !fullscreen;
			LOG1 ("Retry with fullscreen %d\n", fullscreen);
			break;

		default:
			// I give up!
			LOG3 ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr);
			I_FatalError ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr);
		}

		++retry;
		fb = static_cast<DDrawFB *>(CreateFrameBuffer (width, height, fullscreen, NULL));
	}
	retry = 0;

	fb->SetFlash (flashColor, flashAmount);

	return fb;
}
Example #29
0
void DoMain (HINSTANCE hInstance)
{
	LONG WinWidth, WinHeight;
	int height, width, x, y;
	RECT cRect;
	TIMECAPS tc;
	DEVMODE displaysettings;

	try
	{
#ifdef _MSC_VER
		_set_new_handler (NewFailure);
#endif

		Args = new DArgs(__argc, __argv);

		// Load Win32 modules
		Kernel32Module.Load({"kernel32.dll"});
		Shell32Module.Load({"shell32.dll"});
		User32Module.Load({"user32.dll"});

		// Under XP, get our session ID so we can know when the user changes/locks sessions.
		// Since we need to remain binary compatible with older versions of Windows, we
		// need to extract the ProcessIdToSessionId function from kernel32.dll manually.
		HMODULE kernel = GetModuleHandle ("kernel32.dll");

		if (Args->CheckParm("-stdout"))
		{
			// As a GUI application, we don't normally get a console when we start.
			// If we were run from the shell and are on XP+, we can attach to its
			// console. Otherwise, we can create a new one. If we already have a
			// stdout handle, then we have been redirected and should just use that
			// handle instead of creating a console window.

			StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
			if (StdOut != NULL)
			{
				// It seems that running from a shell always creates a std output
				// for us, even if it doesn't go anywhere. (Running from Explorer
				// does not.) If we can get file information for this handle, it's
				// a file or pipe, so use it. Otherwise, pretend it wasn't there
				// and find a console to use instead.
				BY_HANDLE_FILE_INFORMATION info;
				if (!GetFileInformationByHandle(StdOut, &info))
				{
					StdOut = NULL;
				}
			}
			if (StdOut == NULL)
			{
				// AttachConsole was introduced with Windows XP. (OTOH, since we
				// have to share the console with the shell, I'm not sure if it's
				// a good idea to actually attach to it.)
				typedef BOOL (WINAPI *ac)(DWORD);
				ac attach_console = kernel != NULL ? (ac)GetProcAddress(kernel, "AttachConsole") : NULL;
				if (attach_console != NULL && attach_console(ATTACH_PARENT_PROCESS))
				{
					StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
					DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL);
					AttachedStdOut = true;
				}
				if (StdOut == NULL && AllocConsole())
				{
					StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
				}
				FancyStdOut = true;
			}
		}

		// Set the timer to be as accurate as possible
		if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR)
			TimerPeriod = 1;	// Assume minimum resolution of 1 ms
		else
			TimerPeriod = tc.wPeriodMin;

		timeBeginPeriod (TimerPeriod);

		/*
		killough 1/98:

		This fixes some problems with exit handling
		during abnormal situations.

		The old code called I_Quit() to end program,
		while now I_Quit() is installed as an exit
		handler and exit() is called to exit, either
		normally or abnormally.
		*/

		atexit (call_terms);

		atterm (I_Quit);

		// Figure out what directory the program resides in.
		char *program;

#ifdef _MSC_VER
		if (_get_pgmptr(&program) != 0)
		{
			I_FatalError("Could not determine program location.");
		}
#else
		char progbuff[1024];
		GetModuleFileName(0, progbuff, sizeof(progbuff));
		progbuff[1023] = '\0';
		program = progbuff;
#endif

		progdir = program;
		program = progdir.LockBuffer();
		*(strrchr(program, '\\') + 1) = '\0';
		FixPathSeperator(program);
		progdir.Truncate((long)strlen(program));
		progdir.UnlockBuffer();

		HDC screenDC = GetDC(0);
		int dpi = GetDeviceCaps(screenDC, LOGPIXELSX);
		ReleaseDC(0, screenDC);
		width = (512 * dpi + 96 / 2) / 96;
		height = (384 * dpi + 96 / 2) / 96;

		// Many Windows structures that specify their size do so with the first
		// element. DEVMODE is not one of those structures.
		memset (&displaysettings, 0, sizeof(displaysettings));
		displaysettings.dmSize = sizeof(displaysettings);
		EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings);
		x = (displaysettings.dmPelsWidth - width) / 2;
		y = (displaysettings.dmPelsHeight - height) / 2;

		if (Args->CheckParm ("-0"))
		{
			x = y = 0;
		}

		WNDCLASS WndClass;
		WndClass.style			= 0;
		WndClass.lpfnWndProc	= LConProc;
		WndClass.cbClsExtra		= 0;
		WndClass.cbWndExtra		= 0;
		WndClass.hInstance		= hInstance;
		WndClass.hIcon			= LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1));
		WndClass.hCursor		= LoadCursor (NULL, IDC_ARROW);
		WndClass.hbrBackground	= NULL;
		WndClass.lpszMenuName	= NULL;
		WndClass.lpszClassName	= (LPCTSTR)WinClassName;
		
		/* register this new class with Windows */
		if (!RegisterClass((LPWNDCLASS)&WndClass))
			I_FatalError ("Could not register window class");
		
		/* create window */
		char caption[100];
		mysnprintf(caption, countof(caption), "" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime());
		Window = CreateWindowEx(
				WS_EX_APPWINDOW,
				(LPCTSTR)WinClassName,
				(LPCTSTR)caption,
				WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
				x, y, width, height,
				(HWND)   NULL,
				(HMENU)  NULL,
						hInstance,
				NULL);

		if (!Window)
			I_FatalError ("Could not open window");

		if (kernel != NULL)
		{
			typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
			pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId");
			if (pidsid != 0)
			{
				if (!pidsid (GetCurrentProcessId(), &SessionID))
				{
					SessionID = 0;
				}
				hwtsapi32 = LoadLibraryA ("wtsapi32.dll");
				if (hwtsapi32 != 0)
				{
					FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification");
					if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION))
					{
						FreeLibrary (hwtsapi32);
						hwtsapi32 = 0;
					}
					else
					{
						atterm (UnWTS);
					}
				}
			}
		}

		GetClientRect (Window, &cRect);

		WinWidth = cRect.right;
		WinHeight = cRect.bottom;

		CoInitialize (NULL);
		atterm (UnCOM);

		C_InitConsole (((WinWidth / 8) + 2) * 8, (WinHeight / 12) * 8, false);

		I_DetectOS ();
		D_DoomMain ();
	}
	catch (class CNoRunExit &)
	{
		I_ShutdownGraphics();
		if (!batchrun)
		{
			if (FancyStdOut && !AttachedStdOut)
			{ // Outputting to a new console window: Wait for a keypress before quitting.
				DWORD bytes;
				HANDLE stdinput = GetStdHandle(STD_INPUT_HANDLE);

				ShowWindow(Window, SW_HIDE);
				WriteFile(StdOut, "Press any key to exit...", 24, &bytes, NULL);
				FlushConsoleInputBuffer(stdinput);
				SetConsoleMode(stdinput, 0);
				ReadConsole(stdinput, &bytes, 1, &bytes, NULL);
			}
			else if (StdOut == NULL)
			{
				ShowErrorPane(NULL);
			}
		}
		exit(0);
	}
	catch (class CDoomError &error)
	{
		I_ShutdownGraphics ();
		RestoreConView ();
		I_FlushBufferedConsoleStuff();
		if (error.GetMessage ())
		{
			if (!batchrun)
			{
				ShowErrorPane(error.GetMessage());
			}
			else
			{
				Printf("%s\n", error.GetMessage());
			}
		}
		exit (-1);
	}
}
Example #30
0
//
// D_AddDefWads
//
void D_AddDefWads (std::string iwad)
{
	{
		// [RH] Make sure zdoom.wad is always loaded,
		// as it contains magic stuff we need.
		std::string wad = BaseFileSearch ("odamex.wad");
		if (wad.length())
			wadfiles.push_back(wad);
		else
			I_FatalError ("Cannot find odamex.wad");
	}

	I_SetTitleString (IdentifyVersion(iwad).c_str());

	// [RH] Add any .wad files in the skins directory
/*#ifndef UNIX // denis - fixme - 1) _findnext not implemented on linux or osx, use opendir 2) server does not need skins, does it?
	{
		char curdir[256];

		if (getcwd (curdir, 256))
		{
			char skindir[256];
			findstate_t findstate; // denis - fixme - win32 dependency == BAD!!! this is solved in later csdooms with BaseFileSearch - that could be implemented better with posix opendir stuff
			long handle;
			int stuffstart;

			std::string pd = progdir;
			if(pd[pd.length() - 1] != '/')
				pd += '/';

			stuffstart = sprintf (skindir, "%sskins", pd.c_str());

			if (!chdir (skindir))
			{
				skindir[stuffstart++] = '/';
				if ((handle = I_FindFirst ("*.wad", &findstate)) != -1)
				{
					do
					{
						if (!(I_FindAttr (&findstate) & FA_DIREC))
						{
							strcpy (skindir + stuffstart,
									I_FindName (&findstate));
							wadfiles.push_back(skindir);
						}
					} while (I_FindNext (handle, &findstate) == 0);
					I_FindClose (handle);
				}
			}

			const char *home = getenv ("HOME");
			if (home)
			{
				stuffstart = sprintf (skindir, "%s%s.odamex/skins", home,
									  home[strlen(home)-1] == '/' ? "" : "/");
				if (!chdir (skindir))
				{
					skindir[stuffstart++] = '/';
					if ((handle = I_FindFirst ("*.wad", &findstate)) != -1)
					{
						do
						{
							if (!(I_FindAttr (&findstate) & FA_DIREC))
							{
								strcpy (skindir + stuffstart,
										I_FindName (&findstate));
								wadfiles.push_back(skindir);
							}
						} while (I_FindNext (handle, &findstate) == 0);
						I_FindClose (handle);
					}
				}
			}
			chdir (curdir);
		}
	}
#endif*/

	modifiedgame = false;
}