static int ReadLevelInfo (CFile& cf) { if (gameTopFileInfo.fileinfoVersion >= 31) { //load mine filename // read newline-terminated string, not sure what version this changed. cf.GetS (gameData.missions.szCurrentLevel, sizeof (gameData.missions.szCurrentLevel)); if (gameData.missions.szCurrentLevel [strlen (gameData.missions.szCurrentLevel) - 1] == '\n') gameData.missions.szCurrentLevel [strlen (gameData.missions.szCurrentLevel) - 1] = 0; } else if (gameTopFileInfo.fileinfoVersion >= 14) { //load mine filename // read null-terminated string char *p = gameData.missions.szCurrentLevel; //must do read one char at a time, since no cf.GetS() do { *p = cf.GetC (); } while (*p++); } else gameData.missions.szCurrentLevel [0] = 0; if (gameTopFileInfo.fileinfoVersion >= 19) { //load pof names nSavePOFNames = cf.ReadShort (); if ((nSavePOFNames != 0x614d) && (nSavePOFNames != 0x5547)) { // "Ma"de w/DMB beta/"GU"ILE if (nSavePOFNames >= MAX_POLYGON_MODELS) return -1; cf.Read (szSavePOFNames, nSavePOFNames, SHORT_FILENAME_LEN); } } return 0; }
// ---------------------------------------------------------------------------- //loads a level (.LVL) file from disk //returns 0 if success, else error code int LoadLevelData (char * pszFilename, int nLevel) { CFile cf; char filename [128]; int sig, nMineDataOffset, nGameDataOffset; int nError; SetDataVersion (-1); gameData.segs.bHaveSlideSegs = 0; if (gameData.app.nGameMode & GM_NETWORK) { gameData.multiplayer.maxPowerupsAllowed.Clear (0); gameData.multiplayer.powerupsInMine.Clear (0); } #if DBG Level_being_loaded = pszFilename; #endif gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality; for (;;) { strcpy (filename, pszFilename); if (!cf.Open (filename, "", "rb", gameStates.app.bD1Mission)) return 1; strcpy(gameData.segs.szLevelFilename, filename); // #ifdef NEWDEMO // if (gameData.demo.nState == ND_STATE_RECORDING) // NDRecordStartDemo(); // #endif sig = cf.ReadInt (); gameData.segs.nLevelVersion = cf.ReadInt (); gameStates.app.bD2XLevel = (gameData.segs.nLevelVersion >= 10); #if TRACE console.printf (CON_DBG, "gameData.segs.nLevelVersion = %d\n", gameData.segs.nLevelVersion); #endif nMineDataOffset = cf.ReadInt (); nGameDataOffset = cf.ReadInt (); Assert(sig == MAKE_SIG('P','L','V','L')); if (gameData.segs.nLevelVersion >= 8) { //read dummy data cf.ReadInt (); cf.ReadShort (); cf.ReadByte (); } if (gameData.segs.nLevelVersion < 5) cf.ReadInt (); //was hostagetext_offset if (gameData.segs.nLevelVersion > 1) { cf.GetS (szCurrentLevelPalette, sizeof (szCurrentLevelPalette)); if (szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] == '\n') szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] = 0; } if ((gameData.segs.nLevelVersion <= 1) || (szCurrentLevelPalette [0] == 0)) // descent 1 level strcpy (szCurrentLevelPalette, DEFAULT_LEVEL_PALETTE); //D1_PALETTE if (gameData.segs.nLevelVersion >= 3) gameStates.app.nBaseCtrlCenExplTime = cf.ReadInt (); else gameStates.app.nBaseCtrlCenExplTime = DEFAULT_CONTROL_CENTER_EXPLOSION_TIME; if (gameData.segs.nLevelVersion >= 4) gameData.reactor.nStrength = cf.ReadInt (); else gameData.reactor.nStrength = -1; //use old defaults if (gameData.segs.nLevelVersion >= 7) { #if TRACE console.printf (CON_DBG, " loading dynamic lights ...\n"); #endif if (0 > ReadVariableLights (cf)) { cf.Close (); return 5; } } if (gameData.segs.nLevelVersion < 6) { gameData.segs.secret.nReturnSegment = 0; gameData.segs.secret.returnOrient = CFixMatrix::IDENTITY; } else { gameData.segs.secret.nReturnSegment = cf.ReadInt (); for (int i = 0; i < 9; i++) gameData.segs.secret.returnOrient [i] = cf.ReadInt (); } //NOTE LINK TO ABOVE!! cf.Seek (nGameDataOffset, SEEK_SET); nError = LoadMineDataCompiled (cf, 1); cf.Seek (nMineDataOffset, SEEK_SET); nError = LoadMineSegmentsCompiled (cf); if (nError == -1) { //error!! cf.Close (); return 2; } cf.Seek (nGameDataOffset, SEEK_SET); gameData.objs.lists.Init (); nError = LoadMineDataCompiled (cf, 0); if (nError == -1) { //error!! cf.Close (); return 3; } cf.Close (); networkData.nSegmentCheckSum = CalcSegmentCheckSum (); if (meshBuilder.Build (nLevel)) break; if (gameStates.render.nMeshQuality <= 0) return 6; gameStates.render.nMeshQuality--; } gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality; #if 0 if (!(gameData.render.lights.Create () && gameData.render.color.Create () && gameData.render.shadows.Create ())) return 7; #endif if (!gameData.render.mine.Create ()) return 4; lightManager.Setup (nLevel); //moved to loadgame.cpp::LoadLevel() SetAmbientSoundFlags (); return 0; }
//if filename passed is NULL, show Normal credits void ShowCredits(char *credits_filename) { int i, j, l, bDone; CFile cf; char buffer [NUM_LINES_HIRES][80]; grsBitmap bmBackdrop; int nPcxError; unsigned int nLine = 0; unsigned int nXlLine = 0; fix xTimeout, xDelay = X2I (2800 * 1000); int nFirstLineOffs, nExtraInc = 0; int bBinary = 0; char *pszTemp; char filename [32]; int xOffs, yOffs; box dirtyBox [NUM_LINES_HIRES]; gsrCanvas *creditsOffscreenBuf = NULL; gsrCanvas *saveCanv = grdCurCanv; // Clear out all tex buffer lines. memset (buffer, 0, sizeof (buffer)); memset (dirtyBox, 0, sizeof (dirtyBox)); sprintf(filename, "%s", CREDITS_FILE); bBinary = 0; if (credits_filename) { strcpy(filename,credits_filename); bBinary = 1; } if (!cf.Open (filename, gameFolders.szDataDir, "rb", 0)) { char nfile [32]; if (credits_filename) return; //ok to not find special filename if ((pszTemp = strchr (filename, '.'))) *pszTemp = '\0'; sprintf (nfile, "%s.txb", filename); if (!cf.Open (nfile, gameFolders.szDataDir, "rb", 0)) Error("Missing CREDITS.TEX and CREDITS.TXB &cf\n"); bBinary = 1; } SetScreenMode(SCREEN_MENU); xOffs = (grdCurCanv->cvBitmap.bmProps.w - 640) / 2; yOffs = (grdCurCanv->cvBitmap.bmProps.h - 480) / 2; if (xOffs < 0) xOffs = 0; if (yOffs < 0) yOffs = 0; creditsPalette = GrUsePaletteTable("credits.256", NULL); GrPaletteStepLoad (NULL); header_font = GrInitFont(gameStates.menus.bHires ? (char *) "font1-1h.fnt" : (char *) "font1-1.fnt"); title_font = GrInitFont(gameStates.menus.bHires ? (char *) "font2-3h.fnt" : (char *) "font2-3.fnt"); names_font = GrInitFont(gameStates.menus.bHires ? (char *) "font2-2h.fnt" : (char *) "font2-2.fnt"); bmBackdrop.bmTexBuf = NULL; bmBackdrop.bmPalette = NULL; //MWA Made bmBackdrop bitmap linear since it should always be. the current canvas may not //MWA be linear, so we can't rely on grdCurCanv->cvBitmap->bmProps.nType. nPcxError = PCXReadBitmap ((char *) CREDITS_BACKGROUND_FILENAME, &bmBackdrop, BM_LINEAR, 0); if (nPcxError != PCX_ERROR_NONE) { cf.Close(); return; } SongsPlaySong(SONG_CREDITS, 1); GrRemapBitmapGood(&bmBackdrop, NULL, -1, -1); if (!gameOpts->menus.nStyle) { GrSetCurrentCanvas(NULL); GrBitmap(xOffs,yOffs,&bmBackdrop); if ((grdCurCanv->cvBitmap.bmProps.w > 640) || (grdCurCanv->cvBitmap.bmProps.h > 480)) { GrSetColorRGBi (RGBA_PAL (0,0,32)); GrUBox(xOffs,yOffs,xOffs+bmBackdrop.bmProps.w+1,yOffs+bmBackdrop.bmProps.h+1); } } GrPaletteFadeIn(NULL, 32, 0); // Create a new offscreen buffer for the credits screen //MWA Let's be a little smarter about this and check the VR_offscreen buffer //MWA for size to determine if we can use that buffer. If the game size //MWA matches what we need, then lets save memory. if (gameStates.menus.bHires && !gameOpts->menus.nStyle && gameStates.render.vr.buffers.offscreen->cv_w == 640) creditsOffscreenBuf = gameStates.render.vr.buffers.offscreen; else if (gameStates.menus.bHires) creditsOffscreenBuf = GrCreateCanvas(640,480); else creditsOffscreenBuf = GrCreateCanvas(320,200); if (!creditsOffscreenBuf) Error("Not enough memory to allocate Credits Buffer."); creditsOffscreenBuf->cvBitmap.bmPalette = grdCurCanv->cvBitmap.bmPalette; if (gameOpts->menus.nStyle) creditsOffscreenBuf->cvBitmap.bmProps.flags |= BM_FLAG_TRANSPARENT; KeyFlush (); bDone = 0; nFirstLineOffs = 0; xTimeout = SDL_GetTicks () + xDelay; glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gameStates.menus.nInMenu = 1; while (1) { int k; do { nLine = (nLine + 1) % NUM_LINES; get_line:; if (cf.GetS (buffer [nLine], 80)) { char *p = buffer [nLine]; if (bBinary) // is this a binary tbl &cf for (i = (int) strlen (buffer [nLine]); i > 0; i--, p++) *p = EncodeRotateLeft ((char) (EncodeRotateLeft (*p) ^ BITMAP_TBL_XOR)); p = buffer [nLine]; if (*p == ';') goto get_line; if (*p == '%') { if (p [1] == ALLOWED_CHAR) strcpy (p, p + 2); else goto get_line; } if ((p = strchr (buffer [nLine], '\n'))) *p = '\0'; } else if (nXlLine < NUM_XL_LINES) { strcpy (buffer [nLine], xlCredits [nXlLine++]); } else { //fseek(&cf, 0, SEEK_SET); buffer [nLine][0] = 0; bDone++; } } while (nExtraInc--); nExtraInc = 0; //PrintLog ("%s\n", buffer [nLine]); for (i = 0; i < ROW_SPACING; i += gameStates.menus.bHires + 1) { int y; if (gameOpts->menus.nStyle) { GrSetCurrentCanvas (NULL); ShowFullscreenImage (&bmBackdrop); // GrUpdate (0); #if 0 if ((grdCurCanv->cvBitmap.bmProps.w > 640) || (grdCurCanv->cvBitmap.bmProps.h > 480)) { GrSetColorRGBi (RGBA_PAL (0,0,32)); GrUBox (xOffs, yOffs, xOffs + bmBackdrop. bmProps.w + 1, yOffs + bmBackdrop.bmProps.h + 1); } #endif } y = nFirstLineOffs - i; GrSetCurrentCanvas (creditsOffscreenBuf); if (gameOpts->menus.nStyle) GrClearCanvas (0); else GrBitmap (0, 0, &bmBackdrop); for (j = 0; j < NUM_LINES; j++) { char *s; l = (nLine + j + 1) % NUM_LINES; s = buffer [l]; if (s[0] == '!') s++; else if (s[0] == '$') { grdCurCanv->cvFont = header_font; s++; } else if (s[0] == '*') { grdCurCanv->cvFont = title_font; s++; } else grdCurCanv->cvFont = names_font; grBitBltFadeTable = (gameStates.menus.bHires ? fadeValues_hires : fadeValues); pszTemp = strchr (s, '\t'); if (pszTemp) { // Wacky Credits thing int w, h, aw, w2, x1, x2; *pszTemp = 0; GrGetStringSize(s, &w, &h, &aw); x1 = ((gameStates.menus.bHires?320:160)-w)/2; cr_gr_printf (x1 , y, s); GrGetStringSize (pszTemp + 1, &w2, &h, &aw); x2 = (gameStates.menus.bHires ? 320 : 160) + (((gameStates.menus.bHires ? 320 : 160) - w2) / 2); cr_gr_printf(x2, y, &pszTemp[1]); dirtyBox [j].left = ((gameStates.menus.bHires?320:160)-w)/2; dirtyBox [j].top = y; dirtyBox [j].width =(x2+w2)-x1; dirtyBox [j].height = h; *pszTemp = '\t'; } else { // Wacky Fast Credits thing int w, h, aw; GrGetStringSize (s, &w, &h, &aw); dirtyBox [j].width = w; dirtyBox [j].height = h; dirtyBox [j].top = y; dirtyBox [j].left = ((gameStates.menus.bHires?640:320) - w) / 2; cr_gr_printf (0x8000, y, s); } grBitBltFadeTable = NULL; if (buffer[l][0] == '!') y += ROW_SPACING / 2; else y += ROW_SPACING; } if (gameOpts->menus.nStyle) GrSetCurrentCanvas (NULL); { // Wacky Fast Credits Thing box *newBox; grsBitmap *tempBmP; for (j = 0; j < NUM_LINES; j++) { newBox = dirtyBox + j; tempBmP = &creditsOffscreenBuf->cvBitmap; GrBmBitBlt (newBox->width + 1, newBox->height +4, newBox->left + xOffs, newBox->top + yOffs, newBox->left, newBox->top, tempBmP, &grdCurScreen->scCanvas.cvBitmap); } } GrUpdate (0); #if 1 { int t = xTimeout - SDL_GetTicks (); if (t > 0) G3_SLEEP (t); xTimeout = SDL_GetTicks () + xDelay; } #endif //see if redbook song needs to be restarted SongsCheckRedbookRepeat(); k = KeyInKey (); #if DBG if (k == KEY_BACKSP) { Int3(); k = 0; } #endif if ((k == KEY_PRINT_SCREEN) || (k == KEY_ALTED+KEY_F9)) { gameStates.app.bSaveScreenshot = 1; SaveScreenShot (NULL, 0); k = 0; } else if (k == KEY_PADPLUS) xDelay /= 2; else if (k == KEY_PADMINUS) { if (xDelay) xDelay *= 2; else xDelay = 1; } else if ((k == KEY_ESC) || (bDone > NUM_LINES)) { GrCloseFont (header_font); GrCloseFont (title_font); GrCloseFont (names_font); GrPaletteFadeOut (NULL, 32, 0); GrUsePaletteTable (D2_DEFAULT_PALETTE, NULL); D2_FREE (bmBackdrop.bmTexBuf); cf.Close (); GrSetCurrentCanvas (saveCanv); SongsPlaySong (SONG_TITLE, 1); if (creditsOffscreenBuf != gameStates.render.vr.buffers.offscreen) GrFreeCanvas (creditsOffscreenBuf); glDisable (GL_BLEND); gameStates.menus.nInMenu = 0; return; } } if (buffer [(nLine + 1) % NUM_LINES][0] == '!') { nFirstLineOffs -= ROW_SPACING - ROW_SPACING / 2; if (nFirstLineOffs <= -ROW_SPACING) { nFirstLineOffs += ROW_SPACING; nExtraInc++; } } } }
int ReadConfigFile (void) { CFile cf; char line [80], *token, *value, *ptr; ubyte gamma; tJoyAxisCal cal [7]; int i; strcpy (gameConfig.szLastPlayer, ""); memset (cal, 0, sizeof (cal)); JoySetCalVals (cal, sizeofa (cal)); gameConfig.nDigiVolume = 8; gameConfig.nMidiVolume = 8; gameConfig.nRedbookVolume = 8; gameConfig.nControlType = 0; gameConfig.bReverseChannels = 0; //set these here in case no cfg file bHiresMoviesSave = gameOpts->movies.bHires; bRedbookEnabledSave = redbook.Enabled (); if (!cf.Open ("descent.cfg", gameFolders.szConfigDir, "rt", 0)) return 1; while (!cf.EoF ()) { memset (line, 0, 80); cf.GetS (line, 80); ptr = line; while (::isspace (*ptr)) ptr++; if (*ptr != '\0') { token = strtok (ptr, "="); value = strtok (NULL, "="); if (!(value && token)) { PrintLog ("configuration file (descent.cfg) looks messed up.\n"); continue; } if (value [strlen (value) - 1] == '\n') value [strlen (value) - 1] = 0; if (!strcmp (token, pszDigiVolume)) gameConfig.nDigiVolume = (ubyte) strtol (value, NULL, 10); else if (!strcmp (token, pszMidiVolume)) gameConfig.nMidiVolume = (ubyte) strtol (value, NULL, 10); else if (!strcmp (token, pszRedbookEnabled)) redbook.Enable (bRedbookEnabledSave = strtol (value, NULL, 10)); else if (!strcmp (token, pszRedbookVolume)) gameConfig.nRedbookVolume = (ubyte) strtol (value, NULL, 10); else if (!strcmp (token, pszStereoRev)) gameConfig.bReverseChannels = (ubyte) strtol (value, NULL, 10); else if (!strcmp (token, pszGammaLevel)) { gamma = (ubyte) strtol (value, NULL, 10); paletteManager.SetGamma (gamma); } else if (!strcmp (token, pszDetailLevel)) { gameStates.app.nDetailLevel = strtol (value, NULL, 10); if (gameStates.app.nDetailLevel == NUM_DETAIL_LEVELS-1) { int count,dummy,oc,od,wd,wrd,da,sc; count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n", &dummy, &oc, &od, &wd, &wrd, &da, &sc); if (count == 7) { gameStates.render.detail.nObjectComplexity = oc; gameStates.render.detail.nObjectDetail = od; gameStates.render.detail.nWallDetail = wd; gameStates.render.detail.nWallRenderDepth = wrd; gameStates.render.detail.nDebrisAmount = da; gameStates.sound.nSoundChannels = sc; InitCustomDetails (); } } } else if (!strcmp (token, pszJoystickMin)) sscanf (value, "%d,%d,%d,%d", &cal [0].nMin, &cal [1].nMin, &cal [2].nMin, &cal [3].nMin); else if (!strcmp (token, pszJoystickMax)) sscanf (value, "%d,%d,%d,%d", &cal [0].nMax, &cal [1].nMax, &cal [2].nMax, &cal [3].nMax); else if (!strcmp (token, pszJoystickCen)) sscanf (value, "%d,%d,%d,%d", &cal [0].nCenter, &cal [1].nCenter, &cal [2].nCenter, &cal [3].nCenter); else if (!strcmp (token, pszLastPlayer)) { char * p; strncpy (gameConfig.szLastPlayer, value, CALLSIGN_LEN); p = strchr (gameConfig.szLastPlayer, '\n'); if (p) *p = 0; } else if (!strcmp (token, pszLastMission)) { int j = MsnHasGameVer (value) ? 4 : 0; strncpy (gameConfig.szLastMission, value + j, MISSION_NAME_LEN); char *p = strchr (gameConfig.szLastMission, '\n'); if (p) *p = 0; } else if (!strcmp (token, pszVrType)) gameConfig.vrType = strtol (value, NULL, 10); else if (!strcmp (token, pszVrResolution)) gameConfig.vrResolution = strtol (value, NULL, 10); else if (!strcmp (token, pszVrTracking)) gameConfig.vrTracking = strtol (value, NULL, 10); else if (!strcmp (token, pszD2XVersion)) gameConfig.nVersion = strtoul (value, NULL, 10); else if (!strcmp (token, pszHiresMovies) && gameStates.app.bNostalgia) bHiresMoviesSave = gameOpts->movies.bHires = strtol (value, NULL, 10); } } cf.Close (); i = FindArg ("-volume"); if (i > 0) { i = atoi (pszArgList [i + 1]); if (i < 0) i = 0; else if (i > 100) i = 100; gameConfig.nDigiVolume = gameConfig.nMidiVolume = gameConfig.nRedbookVolume = (i * 8) / 100; } if (gameConfig.nDigiVolume > 8) gameConfig.nDigiVolume = 8; if (gameConfig.nMidiVolume > 8) gameConfig.nMidiVolume = 8; if (gameConfig.nRedbookVolume > 8) gameConfig.nRedbookVolume = 8; audio.SetVolumes ((gameConfig.nDigiVolume * 32768) / 8, (gameConfig.nMidiVolume * 128) / 8); if (cf.Open ("descentw.cfg", gameFolders.szConfigDir, "rt", 0)) { while (!cf.EoF ()) { memset (line, 0, 80); cf.GetS (line, 80); ptr = line; while (::isspace(*ptr)) ptr++; if (*ptr != '\0') { token = strtok(ptr, "="); value = strtok(NULL, "="); if (!(value && token)) { PrintLog ("configuration file (descentw.cfg) looks messed up.\n"); continue; } if (value [strlen(value)-1] == '\n') value [strlen(value)-1] = 0; if (!strcmp (token, pszJoystickMin)) sscanf (value, "%d,%d,%d,%d,%d,%d,%d", &cal [0].nMin, &cal [1].nMin, &cal [2].nMin, &cal [3].nMin, &cal [4].nMin, &cal [5].nMin, &cal [6].nMin); else if (!strcmp (token, pszJoystickMax)) sscanf (value, "%d,%d,%d,%d,%d,%d,%d", &cal [0].nMax, &cal [1].nMax, &cal [2].nMax, &cal [3].nMax, &cal [4].nMax, &cal [5].nMax, &cal [6].nMax); else if (!strcmp (token, pszJoystickCen)) sscanf (value, "%d,%d,%d,%d,%d,%d,%d", &cal [0].nCenter, &cal [1].nCenter, &cal [2].nCenter, &cal [3].nCenter, &cal [4].nCenter, &cal [5].nCenter, &cal [6].nCenter); } } cf.Close (); } JoySetCalVals (cal, sizeofa (cal)); return 0; }