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] }
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"); } }
// // 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); }
static int NewFailure (size_t size) { I_FatalError ("Failed to allocate %d bytes from process heap", size); return 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); }
// // 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 } }
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; }
// // [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; }
// // 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; }
// [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; } } } }
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); } }
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; }
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); } } } }
// // 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); }
// // 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 } }
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 }
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; } }
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; } } }
static void STACK_ARGS NewFailure () { I_FatalError ("Failed to allocate memory from system heap"); }
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; }
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; }
// // 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); }
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)); }
FBaseCVar::FBaseCVar (const FBaseCVar &var) { I_FatalError ("Use of cvar copy constructor"); }
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 (); }
// // 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; }
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; }
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); } }
// // 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; }