/** * Load a scenario in a safe way, and prepare the game. * @param houseID The House which is going to play the game. * @param scenarioID The Scenario to load. */ void Game_LoadScenario(uint8 houseID, uint16 scenarioID) { Audio_PlayVoice(VOICE_STOP); Game_Init(); g_validateStrictIfZero++; g_scenarioID = scenarioID; if (!Scenario_Load(scenarioID, houseID)) { GUI_DisplayModalMessage("No more scenarios!", 0xFFFF); PrepareEnd(); exit(0); } Game_Prepare(); if (scenarioID < 5) { g_hintsShown1 = 0; g_hintsShown2 = 0; } g_validateStrictIfZero--; }
/** * Checks if the level comes to an end. If so, it shows all end-level stuff, * and prepares for the next level. */ static void GameLoop_LevelEnd() { static uint32 levelEndTimer = 0; if (levelEndTimer >= g_timerGame && !s_debugForceWin) return; if (GameLoop_IsLevelFinished()) { Audio_PlayMusic(MUSIC_STOP); Audio_PlayVoice(VOICE_STOP); Video_SetCursor(SHAPE_CURSOR_NORMAL); if (GameLoop_IsLevelWon()) { Audio_PlayVoice(VOICE_YOUR_MISSION_IS_COMPLETE); GUI_DisplayModalMessage(String_Get_ByIndex(STR_MISSION_WON), 0xFFFF); g_gameMode = GM_WIN; } else { Audio_PlayVoice(VOICE_YOU_HAVE_FAILED_YOUR_MISSION); GUI_DisplayModalMessage(String_Get_ByIndex(STR_MISSION_FAILED), 0xFFFF); g_gameMode = GM_LOSE; } GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT); g_playerHouse->flags.doneFullScaleAttack = false; s_debugForceWin = false; return; } levelEndTimer = g_timerGame + 300; }
/** * Load a scenario in a safe way, and prepare the game. * @param houseID The House which is going to play the game. * @param scenarioID The Scenario to load. */ void Game_LoadScenario(uint8 houseID, uint16 scenarioID) { Sound_Output_Feedback(0xFFFE); Game_Init(); g_validateStrictIfZero++; if (!Scenario_Load(scenarioID, houseID)) { GUI_DisplayModalMessage("No more scenarios!", 0xFFFF); PrepareEnd(); exit(0); } Game_Prepare(); if (scenarioID < 5) { g_hintsShown1 = 0; g_hintsShown2 = 0; } g_validateStrictIfZero--; }
/** * Checks if the level comes to an end. If so, it shows all end-level stuff, * and prepares for the next level. */ static void GameLoop_LevelEnd(void) { static uint32 levelEndTimer = 0; if (levelEndTimer >= g_timerGame && !s_debugForceWin) return; if (GameLoop_IsLevelFinished()) { Music_Play(0); g_cursorSpriteID = 0; Sprites_SetMouseSprite(0, 0, g_sprites[0]); Sound_Output_Feedback(0xFFFE); GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT); if (GameLoop_IsLevelWon()) { Sound_Output_Feedback(40); GUI_DisplayModalMessage(String_Get_ByIndex(STR_YOU_HAVE_SUCCESSFULLY_COMPLETED_YOUR_MISSION), 0xFFFF); GUI_Mentat_ShowWin(); Sprites_UnloadTiles(); g_campaignID++; GUI_EndStats_Show(g_scenario.killedAllied, g_scenario.killedEnemy, g_scenario.destroyedAllied, g_scenario.destroyedEnemy, g_scenario.harvestedAllied, g_scenario.harvestedEnemy, g_scenario.score, g_playerHouseID); if (g_campaignID == 9) { GUI_Mouse_Hide_Safe(); GUI_SetPaletteAnimated(g_palette2, 15); GUI_ClearScreen(SCREEN_0); GameLoop_GameEndAnimation(); PrepareEnd(); exit(0); } GUI_Mouse_Hide_Safe(); GameLoop_LevelEndAnimation(); GUI_Mouse_Show_Safe(); File_ReadBlockFile("IBM.PAL", g_palette1, 256 * 3); g_scenarioID = GUI_StrategicMap_Show(g_campaignID, true); GUI_SetPaletteAnimated(g_palette2, 15); if (g_campaignID == 1 || g_campaignID == 7) { if (!GUI_Security_Show()) { PrepareEnd(); exit(0); } } } else { Sound_Output_Feedback(41); GUI_DisplayModalMessage(String_Get_ByIndex(STR_YOU_HAVE_FAILED_YOUR_MISSION), 0xFFFF); GUI_Mentat_ShowLose(); Sprites_UnloadTiles(); g_scenarioID = GUI_StrategicMap_Show(g_campaignID, false); } g_playerHouse->flags.doneFullScaleAttack = false; Sprites_LoadTiles(); g_gameMode = GM_RESTART; s_debugForceWin = false; } levelEndTimer = g_timerGame + 300; }
static bool Load_Main(FILE *fp) { uint32 position; uint32 length; uint32 header; uint16 version; /* All OpenDUNE / Dune2 savegames should start with 'FORM' */ if (fread(&header, sizeof(uint32), 1, fp) != 1) return false; if (BETOH32(header) != 'FORM') { Error("Invalid magic header in savegame. Not an OpenDUNE / Dune2 savegame."); return false; } /* The total length field, which is ignored */ if (fread(&length, sizeof(uint32), 1, fp) != 1) return false; /* The next 'chunk' is fake, and has no length field */ if (fread(&header, sizeof(uint32), 1, fp) != 1) return false; if (BETOH32(header) != 'SCEN') return false; position = ftell(fp); /* Find the 'INFO' chunk, as it contains the savegame version */ version = 0; length = Load_FindChunk(fp, 'INFO'); if (length == 0) return false; /* Read the savegame version */ if (fread(&version, sizeof(uint16), 1, fp) != 1) return false; length -= 2; if (version == 0) return false; if (version != 0x0290) { /* Get the scenarioID / campaignID */ if (!Info_LoadOld(fp, length)) return false; g_gameMode = GM_RESTART; /* Find the 'PLYR' chunk */ fseek(fp, position, SEEK_SET); length = Load_FindChunk(fp, 'PLYR'); if (length == 0) return false; /* Find the human player */ if (!House_LoadOld(fp, length)) return false; GUI_DisplayModalMessage(String_Get_ByIndex(STR_WARNING_ORIGINAL_SAVED_GAMES_ARE_INCOMPATABLE_WITH_THE_NEW_VERSION_THE_BATTLE_WILL_BE_RESTARTED), 0xFFFF); return true; } /* Load the 'INFO' chunk'. It has to be the first chunk loaded */ if (!Info_Load(fp, length)) return false; /* Rewind, and read other chunks */ fseek(fp, position, SEEK_SET); while (fread(&header, sizeof(uint32), 1, fp) == 1) { if (fread(&length, sizeof(uint32), 1, fp) != 1) return false; length = BETOH32(length); switch (BETOH32(header)) { case 'NAME': break; /* 'NAME' chunk is of no interest to us */ case 'INFO': break; /* 'INFO' chunk is already read */ case 'MAP ': if (!Map_Load (fp, length)) return false; break; case 'PLYR': if (!House_Load (fp, length)) return false; break; case 'UNIT': if (!Unit_Load (fp, length)) return false; break; case 'BLDG': if (!Structure_Load(fp, length)) return false; break; case 'TEAM': if (!Team_Load (fp, length)) return false; break; case 'ODUN': if (!UnitNew_Load (fp, length)) return false; break; default: Error("Unknown chunk in savegame: %c%c%c%c (length: %d). Skipped.\n", header, header >> 8, header >> 16, header >> 24, length); break; } /* Savegames are word aligned */ position += length + 8 + (length & 1); fseek(fp, position, SEEK_SET); } return true; }