/** * Shows the end game "movie" */ void GameLoop_GameEndAnimation(void) { const HouseAnimation_Animation *animation; const HouseAnimation_Subtitle *subtitle; const HouseAnimation_SoundEffect *soundEffect; uint16 sound; Voice_LoadVoices(0xFFFE); switch (g_playerHouseID) { case HOUSE_HARKONNEN: animation = g_table_houseAnimation_animation[HOUSEANIMATION_LEVEL9_HARKONNEN]; subtitle = g_table_houseAnimation_subtitle[HOUSEANIMATION_LEVEL9_HARKONNEN]; soundEffect = g_table_houseAnimation_soundEffect[HOUSEANIMATION_LEVEL9_HARKONNEN]; sound = 0x1E; break; default: case HOUSE_ATREIDES: animation = g_table_houseAnimation_animation[HOUSEANIMATION_LEVEL9_ARTREIDES]; subtitle = g_table_houseAnimation_subtitle[HOUSEANIMATION_LEVEL9_ARTREIDES]; soundEffect = g_table_houseAnimation_soundEffect[HOUSEANIMATION_LEVEL9_ARTREIDES]; sound = 0x1F; break; case HOUSE_ORDOS: animation = g_table_houseAnimation_animation[HOUSEANIMATION_LEVEL9_ORDOS]; subtitle = g_table_houseAnimation_subtitle[HOUSEANIMATION_LEVEL9_ORDOS]; soundEffect = g_table_houseAnimation_soundEffect[HOUSEANIMATION_LEVEL9_ORDOS]; sound = 0x20; break; } GameLoop_PrepareAnimation(subtitle, 0xFFFF, soundEffect); Music_Play(sound); GameLoop_PlayAnimation(animation); Driver_Music_FadeOut(); GameLoop_FinishAnimation(); GameLoop_GameCredits(); }
/** * Main game loop. */ static void GameLoop_Main(void) { static uint32 l_timerNext = 0; static uint32 l_timerUnitStatus = 0; static int16 l_selectionState = -2; uint16 key; String_Init(); Sprites_Init(); Input_Flags_SetBits(INPUT_FLAG_KEY_REPEAT | INPUT_FLAG_UNKNOWN_0010 | INPUT_FLAG_UNKNOWN_0200 | INPUT_FLAG_UNKNOWN_2000); Input_Flags_ClearBits(INPUT_FLAG_KEY_RELEASE | INPUT_FLAG_UNKNOWN_0400 | INPUT_FLAG_UNKNOWN_0100 | INPUT_FLAG_UNKNOWN_0080 | INPUT_FLAG_UNKNOWN_0040 | INPUT_FLAG_UNKNOWN_0020 | INPUT_FLAG_UNKNOWN_0008 | INPUT_FLAG_UNKNOWN_0004 | INPUT_FLAG_NO_TRANSLATE); Timer_SetTimer(TIMER_GAME, true); Timer_SetTimer(TIMER_GUI, true); g_campaignID = 0; g_scenarioID = 1; g_playerHouseID = HOUSE_INVALID; g_debugScenario = false; g_selectionType = SELECTIONTYPE_MENTAT; g_selectionTypeNew = SELECTIONTYPE_MENTAT; g_palette1 = calloc(1, 256 * 3); g_palette2 = calloc(1, 256 * 3); g_readBufferSize = 12000; g_readBuffer = calloc(1, g_readBufferSize); ReadProfileIni("PROFILE.INI"); free(g_readBuffer); g_readBuffer = NULL; File_ReadBlockFile("IBM.PAL", g_palette_998A, 256 * 3); memmove(g_palette1, g_palette_998A, 256 * 3); GUI_ClearScreen(SCREEN_0); Video_SetPalette(g_palette1, 0, 256); GFX_SetPalette(g_palette1); GFX_SetPalette(g_palette2); g_paletteMapping1 = malloc(256); g_paletteMapping2 = malloc(256); GUI_Palette_CreateMapping(g_palette1, g_paletteMapping1, 0xC, 0x55); g_paletteMapping1[0xFF] = 0xFF; g_paletteMapping1[0xDF] = 0xDF; g_paletteMapping1[0xEF] = 0xEF; GUI_Palette_CreateMapping(g_palette1, g_paletteMapping2, 0xF, 0x55); g_paletteMapping2[0xFF] = 0xFF; g_paletteMapping2[0xDF] = 0xDF; g_paletteMapping2[0xEF] = 0xEF; Script_LoadFromFile("TEAM.EMC", g_scriptTeam, g_scriptFunctionsTeam, NULL); Script_LoadFromFile("BUILD.EMC", g_scriptStructure, g_scriptFunctionsStructure, NULL); GUI_Palette_CreateRemap(HOUSE_MERCENARY); g_cursorSpriteID = 0; Sprites_SetMouseSprite(0, 0, g_sprites[0]); while (g_mouseHiddenDepth > 1) { GUI_Mouse_Show_Safe(); } Window_WidgetClick_Create(); GameOptions_Load(); Unit_Init(); Team_Init(); House_Init(); Structure_Init(); GUI_Mouse_Show_Safe(); if (g_debugSkipDialogs) { Music_Play(0); free(g_readBuffer); g_readBufferSize = (g_enableVoices == 0) ? 12000 : 20000; g_readBuffer = calloc(1, g_readBufferSize); g_gameMode = GM_NORMAL; } for (;; sleepIdle()) { if (g_gameMode == GM_MENU) { GameLoop_GameIntroAnimationMenu(); if (!g_running) break; if (g_gameMode == GM_MENU) continue; GUI_Mouse_Hide_Safe(); g_canSkipIntro = false; GUI_DrawFilledRectangle(g_curWidgetXBase << 3, g_curWidgetYBase, (g_curWidgetXBase + g_curWidgetWidth) << 3, g_curWidgetYBase + g_curWidgetHeight, 12); Input_History_Clear(); if (s_enableLog != 0) Mouse_SetMouseMode((uint8)s_enableLog, "DUNE.LOG"); GFX_SetPalette(g_palette1); GUI_Mouse_Show_Safe(); } if (g_gameMode == GM_PICKHOUSE) { Music_Play(28); g_playerHouseID = HOUSE_MERCENARY; g_playerHouseID = GUI_PickHouse(); GUI_Mouse_Hide_Safe(); GFX_ClearBlock(SCREEN_0); Sprites_LoadTiles(); GUI_Palette_CreateRemap(g_playerHouseID); Voice_LoadVoices(g_playerHouseID); GUI_Mouse_Show_Safe(); g_gameMode = GM_RESTART; g_scenarioID = 1; g_campaignID = 0; g_strategicRegionBits = 0; } if (g_selectionTypeNew != g_selectionType) { GUI_ChangeSelectionType(g_selectionTypeNew); } GUI_PaletteAnimate(); if (g_gameMode == GM_RESTART) { GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT); Game_LoadScenario(g_playerHouseID, g_scenarioID); if (!g_debugScenario && !g_debugSkipDialogs) GUI_Mentat_ShowBriefing(); g_gameMode = GM_NORMAL; GUI_ChangeSelectionType(g_debugScenario ? SELECTIONTYPE_DEBUG : SELECTIONTYPE_STRUCTURE); Music_Play(Tools_RandomLCG_Range(0, 8) + 8); l_timerNext = g_timerGUI + 300; } if (l_selectionState != g_selectionState) { Map_SetSelectionObjectPosition(0xFFFF); Map_SetSelectionObjectPosition(g_selectionRectanglePosition); l_selectionState = g_selectionState; } if (!Driver_Voice_IsPlaying() && !Sound_StartSpeech()) { if (g_gameConfig.music == 0) { Music_Play(2); g_musicInBattle = 0; } else if (g_musicInBattle > 0) { Music_Play(Tools_RandomLCG_Range(0, 5) + 17); l_timerNext = g_timerGUI + 300; g_musicInBattle = -1; } else { g_musicInBattle = 0; if (g_enableSoundMusic != 0 && g_timerGUI > l_timerNext) { if (!Driver_Music_IsPlaying()) { Music_Play(Tools_RandomLCG_Range(0, 8) + 8); l_timerNext = g_timerGUI + 300; } } } } GFX_Screen_SetActive(SCREEN_0); key = GUI_Widget_HandleEvents(g_widgetLinkedListHead); if (g_selectionType == SELECTIONTYPE_TARGET || g_selectionType == SELECTIONTYPE_PLACE || g_selectionType == SELECTIONTYPE_UNIT || g_selectionType == SELECTIONTYPE_STRUCTURE) { if (g_unitSelected != NULL) { if (l_timerUnitStatus < g_timerGame) { Unit_DisplayStatusText(g_unitSelected); l_timerUnitStatus = g_timerGame + 300; } if (g_selectionType != SELECTIONTYPE_TARGET) { g_selectionPosition = Tile_PackTile(Tile_Center(g_unitSelected->o.position)); } } GUI_Widget_ActionPanel_Draw(false); InGame_Numpad_Move(key); GUI_DrawCredits(g_playerHouseID, 0); GameLoop_Team(); GameLoop_Unit(); GameLoop_Structure(); GameLoop_House(); GUI_DrawScreen(SCREEN_0); } GUI_DisplayText(NULL, 0); if (g_running && !g_debugScenario) { GameLoop_LevelEnd(); } if (!g_running) break; } GUI_Mouse_Hide_Safe(); if (s_enableLog != 0) Mouse_SetMouseMode(INPUT_MOUSE_MODE_NORMAL, "DUNE.LOG"); GUI_Mouse_Hide_Safe(); Widget_SetCurrentWidget(0); GFX_Screen_SetActive(SCREEN_1); GFX_ClearScreen(); GUI_Screen_FadeIn(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, SCREEN_1, SCREEN_0); }
/** * Prepare the map (after loading scenario or savegame). Does some basic * sanity-check and corrects stuff all over the place. */ void Game_Prepare(void) { PoolFindStruct find; uint16 oldSelectionType; Tile *t; int i; g_validateStrictIfZero++; oldSelectionType = g_selectionType; g_selectionType = SELECTIONTYPE_MENTAT; Structure_Recount(); Unit_Recount(); Team_Recount(); t = &g_map[0]; for (i = 0; i < 64 * 64; i++, t++) { Structure *s; Unit *u; u = Unit_Get_ByPackedTile(i); s = Structure_Get_ByPackedTile(i); if (u == NULL || !u->o.flags.s.used) t->hasUnit = false; if (s == NULL || !s->o.flags.s.used) t->hasStructure = false; if (t->isUnveiled) Map_UnveilTile(i, g_playerHouseID); } find.houseID = HOUSE_INVALID; find.index = 0xFFFF; find.type = 0xFFFF; while (true) { Unit *u; u = Unit_Find(&find); if (u == NULL) break; if (u->o.flags.s.isNotOnMap) continue; Unit_RemoveFog(u); Unit_UpdateMap(1, u); } find.houseID = HOUSE_INVALID; find.index = 0xFFFF; find.type = 0xFFFF; while (true) { Structure *s; s = Structure_Find(&find); if (s == NULL) break; if (s->o.type == STRUCTURE_SLAB_1x1 || s->o.type == STRUCTURE_SLAB_2x2 || s->o.type == STRUCTURE_WALL) continue; if (s->o.flags.s.isNotOnMap) continue; Structure_RemoveFog(s); if (s->o.type == STRUCTURE_STARPORT && s->o.linkedID != 0xFF) { Unit *u = Unit_Get_ByIndex(s->o.linkedID); if (!u->o.flags.s.used || !u->o.flags.s.isNotOnMap) { s->o.linkedID = 0xFF; s->countDown = 0; } else { Structure_SetState(s, STRUCTURE_STATE_READY); } } Script_Load(&s->o.script, s->o.type); if (s->o.type == STRUCTURE_PALACE) { House_Get_ByIndex(s->o.houseID)->palacePosition = s->o.position; } if ((House_Get_ByIndex(s->o.houseID)->palacePosition.x != 0) || (House_Get_ByIndex(s->o.houseID)->palacePosition.y != 0)) continue; House_Get_ByIndex(s->o.houseID)->palacePosition = s->o.position; } find.houseID = HOUSE_INVALID; find.index = 0xFFFF; find.type = 0xFFFF; while (true) { House *h; h = House_Find(&find); if (h == NULL) break; h->structuresBuilt = Structure_GetStructuresBuilt(h); House_UpdateCreditsStorage((uint8)h->index); House_CalculatePowerAndCredit(h); } GUI_Palette_CreateRemap(g_playerHouseID); Map_SetSelection(g_selectionPosition); if (g_structureActiveType != 0xFFFF) { Map_SetSelectionSize(g_table_structureInfo[g_structureActiveType].layout); } else { Structure *s = Structure_Get_ByPackedTile(g_selectionPosition); if (s != NULL) Map_SetSelectionSize(g_table_structureInfo[s->o.type].layout); } Voice_LoadVoices(g_playerHouseID); g_tickHousePowerMaintenance = max(g_timerGame + 70, g_tickHousePowerMaintenance); g_viewport_forceRedraw = true; g_playerCredits = 0xFFFF; g_selectionType = oldSelectionType; g_validateStrictIfZero--; }
/** * Logos at begin of intro. */ static void Gameloop_Logos(void) { Screen oldScreenID; void *wsa; uint16 frame; oldScreenID = GFX_Screen_SetActive(SCREEN_0); GFX_SetPalette(g_palette2); GFX_ClearScreen(); File_ReadBlockFile("WESTWOOD.PAL", g_palette_998A, 256 * 3); frame = 0; wsa = WSA_LoadFile("WESTWOOD.WSA", GFX_Screen_Get_ByIndex(SCREEN_1), GFX_Screen_GetSize_ByIndex(SCREEN_1) + GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3), true); WSA_DisplayFrame(wsa, frame++, 0, 0, SCREEN_0); GUI_SetPaletteAnimated(g_palette_998A, 60); Music_Play(0x24); g_timerTimeout = 360; while (WSA_DisplayFrame(wsa, frame++, 0, 0, SCREEN_0)) Timer_Sleep(6); WSA_Unload(wsa); if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit; Voice_LoadVoices(0xFFFF); for (; g_timerTimeout != 0; sleepIdle()) { if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit; } GUI_SetPaletteAnimated(g_palette2, 60); while (Driver_Music_IsPlaying()) sleepIdle(); GUI_SetPaletteAnimated(g_palette2, 60); GFX_ClearScreen(); Sprites_LoadImage(String_GenerateFilename("AND"), SCREEN_1, g_palette_998A); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0); GUI_SetPaletteAnimated(g_palette_998A, 30); for (g_timerTimeout = 60; g_timerTimeout != 0; sleepIdle()) { if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit; } GUI_SetPaletteAnimated(g_palette2, 30); GUI_ClearScreen(SCREEN_0); Sprites_LoadImage("VIRGIN.CPS", SCREEN_1, g_palette_998A); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0); GUI_SetPaletteAnimated(g_palette_998A, 30); for (g_timerTimeout = 180; g_timerTimeout != 0; sleepIdle()) { if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit; } logos_exit: GUI_SetPaletteAnimated(g_palette2, 30); GUI_ClearScreen(SCREEN_0); GFX_Screen_SetActive(oldScreenID); }