static bool GUI_YesNo(uint16 stringID) { WindowDesc *desc = &g_yesNoWindowDesc; bool loop; bool ret = false; desc->stringID = stringID; GUI_Window_BackupScreen(desc); GUI_Window_Create(desc); for (loop = true; loop; sleepIdle()) { uint16 key = GUI_Widget_HandleEvents(g_widgetLinkedListTail); if ((key & 0x8000) != 0) { switch (key & 0x7FFF) { case 0x1E: ret = true; break; case 0x1F: ret = false; break; default: break; } loop = false; } GUI_PaletteAnimate(); } GUI_Window_RestoreScreen(desc); return ret; }
/** * Handles Click event for "Game controls" button. * * @param w The widget. */ static void GUI_Widget_GameControls_Click(Widget *w) { WindowDesc *desc = &g_gameControlWindowDesc; bool loop; GUI_Window_BackupScreen(desc); GUI_Window_Create(desc); loop = true; while (loop) { Widget *w2 = g_widgetLinkedListTail; uint16 key = GUI_Widget_HandleEvents(w2); if ((key & 0x8000) != 0) { w = GUI_Widget_Get_ByIndex(w2, key & 0x7FFF); switch ((key & 0x7FFF) - 0x1E) { case 0: g_gameConfig.music ^= 0x1; if (g_gameConfig.music == 0) Driver_Music_Stop(); break; case 1: g_gameConfig.sounds ^= 0x1; if (g_gameConfig.sounds == 0) Driver_Sound_Stop(); break; case 2: if (++g_gameConfig.gameSpeed >= 5) g_gameConfig.gameSpeed = 0; break; case 3: g_gameConfig.hints ^= 0x1; break; case 4: g_gameConfig.autoScroll ^= 0x1; break; case 5: loop = false; break; default: break; } GUI_Widget_MakeNormal(w, false); GUI_Widget_Draw(w); } GUI_PaletteAnimate(); sleepIdle(); } GUI_Window_RestoreScreen(desc); }
void async_GUI_Mentat_ShowLoop() { GUI_Widget_DrawAll(asyncMentatShow.w); asyncMentatShow.ret = GUI_Widget_HandleEvents(asyncMentatShow.w); GUI_PaletteAnimate(); GUI_Mentat_Animation(0); sleepIdle(); }
/** * Show the Mentat screen. * @param spriteBuffer The buffer of the strings. * @param wsaFilename The WSA to show. * @param w The widgets to handle. Can be NULL for no widgets. * @param unknown A boolean. * @return Return value of GUI_Widget_HandleEvents() or f__B4DA_0AB8_002A_AAB2() (latter when no widgets). */ uint16 GUI_Mentat_Show(char *stringBuffer, const char *wsaFilename, Widget *w, bool unknown) { uint16 ret; Sprites_UnloadTiles(); GUI_Mentat_Display(wsaFilename, g_playerHouseID); GFX_Screen_SetActive(SCREEN_1); Widget_SetAndPaintCurrentWidget(8); if (wsaFilename != NULL) { void *wsa; wsa = WSA_LoadFile(wsaFilename, GFX_Screen_Get_ByIndex(SCREEN_2), GFX_Screen_GetSize_ByIndex(SCREEN_2), false); WSA_DisplayFrame(wsa, 0, g_curWidgetXBase * 8, g_curWidgetYBase, SCREEN_1); WSA_Unload(wsa); } GUI_DrawSprite(SCREEN_1, g_sprites[397 + g_playerHouseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GFX_Screen_SetActive(SCREEN_0); GUI_Mouse_Hide_Safe(); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0); GUI_Mouse_Show_Safe(); GUI_SetPaletteAnimated(g_palette1, 15); ret = GUI_Mentat_Loop(wsaFilename, NULL, stringBuffer, true, NULL); if (w != NULL) { do { GUI_Widget_DrawAll(w); ret = GUI_Widget_HandleEvents(w); GUI_PaletteAnimate(); GUI_Mentat_Animation(0); sleepIdle(); } while ((ret & 0x8000) == 0); } Input_History_Clear(); if (unknown) { Load_Palette_Mercenaries(); Sprites_LoadTiles(); } return ret; }
/** * 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); }
static void GUI_Mentat_HelpListLoop(void) { uint16 key; for (key = 0; key != 0x8001; sleepIdle()) { Widget *w = g_widgetMentatTail; GUI_Mentat_Animation(0); key = GUI_Widget_HandleEvents(w); if ((key & 0x800) != 0) key = 0; if (key == 0x8001) break; key &= 0x80FF; s_selectMentatHelp = true; switch (key) { case 0x0053: case 0x0060: /* NUMPAD 8 / ARROW UP */ case 0x0453: case 0x0460: if (s_selectedHelpSubject != 0) { GUI_Mentat_List_Click(GUI_Widget_Get_ByIndex(w, s_selectedHelpSubject + 2)); break; } GUI_Widget_Scrollbar_ArrowUp_Click(g_widgetMentatScrollbar); break; case 0x0054: case 0x0062: /* NUMPAD 2 / ARROW DOWN */ case 0x0454: case 0x0462: if (s_selectedHelpSubject < 10) { GUI_Mentat_List_Click(GUI_Widget_Get_ByIndex(w, s_selectedHelpSubject + 4)); break; } GUI_Widget_Scrollbar_ArrowDown_Click(g_widgetMentatScrollbar); break; case 0x0055: case 0x0065: /* NUMPAD 9 / PAGE UP */ case 0x0455: case 0x0465: { uint8 i; for (i = 0; i < 11; i++) GUI_Widget_Scrollbar_ArrowUp_Click(g_widgetMentatScrollbar); } break; case 0x0056: case 0x0067: /* NUMPAD 3 / PAGE DOWN */ case 0x0456: case 0x0467: { uint8 i; for (i = 0; i < 11; i++) GUI_Widget_Scrollbar_ArrowDown_Click(g_widgetMentatScrollbar); } break; case 0x0041: /* MOUSE LEFT BUTTON */ break; case 0x002B: /* NUMPAD 5 / RETURN */ case 0x003D: /* SPACE */ case 0x042B: case 0x043D: GUI_Mentat_List_Click(GUI_Widget_Get_ByIndex(w, s_selectedHelpSubject + 3)); break; default: break; } s_selectMentatHelp = false; } }
uint16 GUI_Mentat_Loop(const char *wsaFilename, char *pictureDetails, char *text, bool arg12, Widget *w) { Screen oldScreenID; uint16 old07AE; void *wsa; uint16 descLines; bool dirty; bool done; bool textDone; uint16 frame; uint32 descTick; uint16 mentatSpeakingMode; uint16 result; uint32 textTick; uint32 textDelay; uint16 lines; uint16 textLines; uint16 step; dirty = false; textTick = 0; textDelay = 0; old07AE = Widget_SetCurrentWidget(8); oldScreenID = GFX_Screen_SetActive(SCREEN_2); wsa = NULL; if (wsaFilename != NULL) { wsa = WSA_LoadFile(wsaFilename, GFX_Screen_Get_ByIndex(SCREEN_1), GFX_Screen_GetSize_ByIndex(SCREEN_1), false); } step = 0; if (wsa == NULL) { Widget_PaintCurrentWidget(); step = 1; } GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x31); descLines = GUI_SplitText(pictureDetails, (g_curWidgetWidth << 3) + 10, '\0'); GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x32); textLines = GUI_Mentat_SplitText(text, 304); mentatSpeakingMode = 2; lines = 0; frame = 0; g_timerTimeout = 0; descTick = g_timerGUI + 30; Input_History_Clear(); textDone = false; result = 0; for (done = false; !done; sleepIdle()) { uint16 key; GFX_Screen_SetActive(SCREEN_0); key = GUI_Widget_HandleEvents(w); GUI_PaletteAnimate(); if (key != 0) { if ((key & 0x800) == 0) { if (w != NULL) { if ((key & 0x8000) != 0 && result == 0) result = key; } else { if (textDone) result = key; } } else { key = 0; } } switch (step) { case 0: if (key == 0) break; step = 1; /* FALL-THROUGH */ case 1: if (key != 0) { if (result != 0) { step = 5; break; } lines = descLines; dirty = true; } else { if (g_timerGUI > descTick) { descTick = g_timerGUI + 15; lines++; dirty = true; } } if (lines < descLines && lines <= 12) break; step = (text != NULL) ? 2 : 4; lines = descLines; break; case 2: GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 0, 0, 160, SCREEN_WIDTH / 8, 40, SCREEN_0, SCREEN_2); GUI_Mouse_Show_InRegion(); step = 3; key = 1; /* FALL-THROUGH */ case 3: if (mentatSpeakingMode == 2 && textTick < g_timerGUI) key = 1; if ((key != 0 && textDone) || result != 0) { GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 160, 0, 0, SCREEN_WIDTH / 8, 40, SCREEN_2, SCREEN_0); GUI_Mouse_Show_InRegion(); step = 4; mentatSpeakingMode = 0; break; } if (key != 0) { GUI_Screen_Copy(0, 160, 0, 0, SCREEN_WIDTH / 8, 40, SCREEN_2, SCREEN_2); if (textLines-- != 0) { GFX_Screen_SetActive(SCREEN_2); GUI_DrawText_Wrapper(text, 4, 1, g_curWidgetFGColourBlink, 0, 0x32); mentatSpeakingMode = 1; textDelay = (uint32)strlen(text) * 4; textTick = g_timerGUI + textDelay; if (textLines != 0) { while (*text++ != '\0') {} } else { textDone = true; } GFX_Screen_SetActive(SCREEN_0); } GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, 40, SCREEN_2, SCREEN_0); GUI_Mouse_Show_InRegion(); break; } if (mentatSpeakingMode == 0 || textTick > g_timerGUI) break; mentatSpeakingMode = 2; textTick += textDelay + textDelay / 2; break; case 4: if (result != 0 || w == NULL) step = 5; break; case 5: dirty = true; done = true; break; default: break; } GUI_Mentat_Animation(mentatSpeakingMode); if (wsa != NULL && g_timerTimeout == 0) { g_timerTimeout = 7; do { if (step == 0 && frame > 4) step = 1; if (!WSA_DisplayFrame(wsa, frame++, g_curWidgetXBase << 3, g_curWidgetYBase, SCREEN_2)) { if (step == 0) step = 1; if (arg12 != 0) { frame = 0; } else { WSA_Unload(wsa); wsa = NULL; } } } while (frame == 0); dirty = true; } if (!dirty) continue; GUI_Mentat_DrawInfo(pictureDetails, (g_curWidgetXBase << 3) + 5, g_curWidgetYBase + 3, 8, 0, lines, 0x31); GUI_DrawSprite(SCREEN_2, g_sprites[397 + g_playerHouseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GUI_Mouse_Hide_InWidget(g_curWidgetIndex); GUI_Screen_Copy(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, SCREEN_2, SCREEN_0); GUI_Mouse_Show_InWidget(); dirty = false; } if (wsa != NULL) WSA_Unload(wsa); GFX_Screen_SetActive(SCREEN_2); GUI_DrawSprite(SCREEN_2, g_sprites[397 + g_playerHouseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GUI_Mouse_Hide_InWidget(g_curWidgetIndex); GUI_Screen_Copy(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, SCREEN_2, SCREEN_0); GUI_Mouse_Show_InWidget(); Widget_SetCurrentWidget(old07AE); GFX_Screen_SetActive(oldScreenID); Input_History_Clear(); return result; }
/** * Handles Click event for "Save Game" or "Load Game" button. * * @param save Wether to save or load. * @return True if a game has been saved or loaded, False otherwise. */ bool GUI_Widget_SaveLoad_Click(bool save) { WindowDesc *desc = &g_saveLoadWindowDesc; bool loop; s_savegameCountOnDisk = GetSavegameCount(); s_savegameIndexBase = max(0, s_savegameCountOnDisk - (save ? 0 : 1)); FillSavegameDesc(save); desc->stringID = save ? STR_SELECT_A_POSITION_TO_SAVE_TO : STR_SELECT_A_SAVED_GAME_TO_LOAD; GUI_Window_BackupScreen(desc); GUI_Window_Create(desc); UpdateArrows(save, true); for (loop = true; loop; sleepIdle()) { Widget *w = g_widgetLinkedListTail; uint16 key = GUI_Widget_HandleEvents(w); UpdateArrows(save, false); if ((key & 0x8000) != 0) { Widget *w2; key &= 0x7FFF; w2 = GUI_Widget_Get_ByIndex(w, key); switch (key) { case 0x25: s_savegameIndexBase = min(s_savegameCountOnDisk - (save ? 0 : 1), s_savegameIndexBase + 1); FillSavegameDesc(save); GUI_Widget_DrawAll(w); break; case 0x26: s_savegameIndexBase = max(0, s_savegameIndexBase - 1); FillSavegameDesc(save); GUI_Widget_DrawAll(w); break; case 0x23: loop = false; break; default: { GUI_Window_RestoreScreen(desc); key -= 0x1E; if (!save) { LoadFile(GenerateSavegameFilename(s_savegameIndexBase - key)); return true; } if (GUI_Widget_Savegame_Click(key)) return true; GUI_Window_BackupScreen(desc); UpdateArrows(save, true); GUI_Window_Create(desc); UpdateArrows(save, true); } break; } GUI_Widget_MakeNormal(w2, false); } GUI_PaletteAnimate(); } GUI_Window_RestoreScreen(desc); return false; }
/** * Handles Click event for "Options" button. * * @param w The widget. * @return False, always. */ bool GUI_Widget_Options_Click(Widget *w) { WindowDesc *desc = &g_optionsWindowDesc; uint16 cursor = g_cursorSpriteID; bool loop; g_cursorSpriteID = 0; Sprites_SetMouseSprite(0, 0, g_sprites[0]); Sprites_UnloadTiles(); memmove(g_palette_998A, g_paletteActive, 256 * 3); Driver_Voice_Play(NULL, 0xFF); Timer_SetTimer(TIMER_GAME, false); GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x22); ShadeScreen(); GUI_Window_BackupScreen(desc); GUI_Window_Create(desc); for (loop = true; loop; sleepIdle()) { Widget *w2 = g_widgetLinkedListTail; uint16 key = GUI_Widget_HandleEvents(w2); if ((key & 0x8000) != 0) { w = GUI_Widget_Get_ByIndex(w2, key); GUI_Window_RestoreScreen(desc); switch ((key & 0x7FFF) - 0x1E) { case 0: if (GUI_Widget_SaveLoad_Click(false)) loop = false; break; case 1: if (GUI_Widget_SaveLoad_Click(true)) loop = false; break; case 2: GUI_Widget_GameControls_Click(w); break; case 3: /* "Are you sure you wish to restart?" */ if (!GUI_YesNo(0x76)) break; loop = false; g_gameMode = GM_RESTART; break; case 4: /* "Are you sure you wish to pick a new house?" */ if (!GUI_YesNo(0x77)) break; loop = false; Driver_Music_FadeOut(); g_gameMode = GM_PICKHOUSE; break; case 5: loop = false; break; case 6: /* "Are you sure you want to quit playing?" */ loop = !GUI_YesNo(0x65); g_running = loop; Sound_Output_Feedback(0xFFFE); while (Driver_Voice_IsPlaying()) sleepIdle(); break; default: break; } if (g_running && loop) { GUI_Window_BackupScreen(desc); GUI_Window_Create(desc); } } GUI_PaletteAnimate(); } g_textDisplayNeedsUpdate = true; Sprites_LoadTiles(); GUI_DrawInterfaceAndRadar(SCREEN_0); UnshadeScreen(); GUI_Widget_MakeSelected(w, false); Timer_SetTimer(TIMER_GAME, true); GameOptions_Save(); Structure_Recount(); Unit_Recount(); g_cursorSpriteID = cursor; Sprites_SetMouseSprite(0, 0, g_sprites[cursor]); return false; }
static void GUI_Purchase_ShowInvoice(void) { Widget *w = g_widgetInvoiceTail; Screen oldScreenID; uint16 y = 48; uint16 total = 0; uint16 x; char textBuffer[12]; oldScreenID = GFX_Screen_SetActive(SCREEN_1); GUI_DrawFilledRectangle(128, 48, 311, 159, 20); GUI_DrawText_Wrapper(String_Get_ByIndex(STR_ITEM_NAME_QTY_TOTAL), 128, y, 12, 0, 0x11); y += 7; GUI_DrawLine(129, y, 310, y, 12); y += 2; if (g_factoryWindowOrdered != 0) { uint16 i; for (i = 0; i < g_factoryWindowTotal; i++) { ObjectInfo *oi; uint16 amount; if (g_factoryWindowItems[i].amount == 0) continue; amount = g_factoryWindowItems[i].amount * g_factoryWindowItems[i].credits; total += amount; snprintf(textBuffer, sizeof(textBuffer), "%02d %5d", g_factoryWindowItems[i].amount, amount); oi = g_factoryWindowItems[i].objectInfo; GUI_DrawText_Wrapper(String_Get_ByIndex(oi->stringID_full), 128, y, 8, 0, 0x11); GUI_DrawText_Monospace(textBuffer, 311 - strlen(textBuffer) * 6, y, 15, 0, 6); y += 8; } } else { GUI_DrawText_Wrapper(String_Get_ByIndex(STR_NO_UNITS_ON_ORDER), 220, 99, 6, 0, 0x112); } GUI_DrawLine(129, 148, 310, 148, 12); GUI_DrawLine(129, 150, 310, 150, 12); snprintf(textBuffer, sizeof(textBuffer), "%d", total); x = 311 - strlen(textBuffer) * 6; /* "Total Cost :" */ GUI_DrawText_Wrapper(GUI_String_Get_ByIndex(STR_TOTAL_COST_), x - 3, 152, 11, 0, 0x211); GUI_DrawText_Monospace(textBuffer, x, 152, 11, 0, 6); GUI_Mouse_Hide_Safe(); GUI_Screen_Copy(16, 48, 16, 48, 23, 112, SCREEN_1, SCREEN_0); GUI_Mouse_Show_Safe(); GFX_Screen_SetActive(SCREEN_0); GUI_FactoryWindow_DrawCaption(String_Get_ByIndex(STR_INVOICE_OF_UNITS_ON_ORDER)); Input_History_Clear(); for (; GUI_Widget_HandleEvents(w) == 0; sleepIdle()) { GUI_DrawCredits(g_playerHouseID, 0); GUI_FactoryWindow_UpdateSelection(false); GUI_PaletteAnimate(); } GFX_Screen_SetActive(oldScreenID); w = GUI_Widget_Get_ByIndex(w, 10); if (w != NULL && Mouse_InsideRegion(w->offsetX, w->offsetY, w->offsetX + w->width, w->offsetY + w->height) != 0) { while (Input_Test(0x41) != 0 || Input_Test(0x42) != 0) sleepIdle(); Input_History_Clear(); } if (g_factoryWindowResult == FACTORY_CONTINUE) GUI_FactoryWindow_DrawDetails(); }
/** * Show an EditBox and handles the input. * @param text The text to edit. Uses the pointer to make the modifications. * @param maxLength The maximum length of the text. * @param unknown1 Unknown. * @param w The widget this editbox is attached to. * @param tickProc The function to call every tick, for animation etc. * @param unknown4 Unknown. * @return Unknown. */ uint16 GUI_EditBox(char *text, uint16 maxLength, uint16 unknown1, Widget *w, uint16 (*tickProc)(void), uint16 unknown4) { Screen oldScreenID; uint16 oldValue_07AE_0000; uint16 positionX; uint16 maxWidth; uint16 textWidth; uint16 textLength; uint16 returnValue; char *t; /* Initialize */ { Input_Flags_SetBits(INPUT_FLAG_NO_TRANSLATE); Input_Flags_ClearBits(INPUT_FLAG_UNKNOWN_2000); oldScreenID = GFX_Screen_SetActive(SCREEN_0); oldValue_07AE_0000 = Widget_SetCurrentWidget(unknown1); returnValue = 0x0; } positionX = g_curWidgetXBase << 3; textWidth = 0; textLength = 0; maxWidth = (g_curWidgetWidth << 3) - Font_GetCharWidth('W') - 1; t = text; /* Calculate the length and width of the current string */ for (; *t != '\0'; t++) { textWidth += Font_GetCharWidth(*t); textLength++; if (textWidth >= maxWidth) break; } *t = '\0'; if ((unknown4 & 0x1) != 0) { unknown4 |= 0x4; } GUI_Mouse_Hide_Safe(); if ((unknown4 & 0x4) != 0) Widget_PaintCurrentWidget(); GUI_DrawText_Wrapper(text, positionX, g_curWidgetYBase, g_curWidgetFGColourBlink, g_curWidgetFGColourNormal, 0); GUI_EditBox_BlinkCursor(positionX + textWidth, false); GUI_Mouse_Show_Safe(); for (;; sleepIdle()) { uint16 keyWidth; uint16 key; if (tickProc != NULL) { returnValue = tickProc(); if (returnValue != 0) break; } key = GUI_Widget_HandleEvents(w); GUI_EditBox_BlinkCursor(positionX + textWidth, false); if (key == 0x0) continue; if ((key & 0x8000) != 0) { returnValue = key; break; } if (key == 0x2B) { returnValue = 0x2B; break; } if (key == 0x6E) { *t = '\0'; returnValue = 0x6B; break; } /* Handle backspace */ if (key == 0x0F) { if (textLength == 0) continue; GUI_EditBox_BlinkCursor(positionX + textWidth, true); textWidth -= Font_GetCharWidth(*(t - 1)); textLength--; *(--t) = '\0'; GUI_EditBox_BlinkCursor(positionX + textWidth, false); continue; } key = Input_Keyboard_HandleKeys(key) & 0xFF; /* Names can't start with a space, and should be alpha-numeric */ if ((key == 0x20 && textLength == 0) || key < 0x20 || key > 0x7E) continue; keyWidth = Font_GetCharWidth(key & 0xFF); if (textWidth + keyWidth >= maxWidth || textLength >= maxLength) continue; /* Add char to the text */ *t = key & 0xFF; *(++t) = '\0'; textLength++; GUI_Mouse_Hide_Safe(); GUI_EditBox_BlinkCursor(positionX + textWidth, true); /* Draw new character */ GUI_DrawText_Wrapper(text + textLength - 1, positionX + textWidth, g_curWidgetYBase, g_curWidgetFGColourBlink, g_curWidgetFGColourNormal, 0x020); GUI_Mouse_Show_Safe(); textWidth += keyWidth; GUI_EditBox_BlinkCursor(positionX + textWidth, false); } /* Deinitialize */ { Input_Flags_ClearBits(INPUT_FLAG_NO_TRANSLATE); Input_Flags_SetBits(INPUT_FLAG_UNKNOWN_2000); Widget_SetCurrentWidget(oldValue_07AE_0000); GFX_Screen_SetActive(oldScreenID); } return returnValue; }
void async_GUI_Mentat_Loop() { uint16 key; GFX_Screen_SetActive(0); key = GUI_Widget_HandleEvents(asyncMentatLoop.w); GUI_PaletteAnimate(); if (key != 0) { if ((key & 0x800) == 0) { if (asyncMentatLoop.w != NULL) { if ((key & 0x8000) != 0 && asyncMentatLoop.result == 0) asyncMentatLoop.result = key; } else { if (asyncMentatLoop.textDone) asyncMentatLoop.result = key; } } else { key = 0; } } switch (asyncMentatLoop.step) { case 0: if (key == 0) break; asyncMentatLoop.step = 1; /* FALL-THROUGH */ case 1: if (key != 0) { if (asyncMentatLoop.result != 0) { asyncMentatLoop.step = 5; break; } asyncMentatLoop.lines = asyncMentatLoop.descLines; asyncMentatLoop.dirty = true; } else { if (g_timerGUI > asyncMentatLoop.descTick) { asyncMentatLoop.descTick = g_timerGUI + 15; asyncMentatLoop.lines++; asyncMentatLoop.dirty = true; } } if (asyncMentatLoop.lines < asyncMentatLoop.descLines && asyncMentatLoop.lines <= 12) break; asyncMentatLoop.step = (asyncMentatLoop.text != NULL) ? 2 : 4; asyncMentatLoop.lines = asyncMentatLoop.descLines; break; case 2: GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 0, 0, 160, SCREEN_WIDTH / 8, 40, 0, 4); GUI_Mouse_Show_InRegion(); asyncMentatLoop.step = 3; key = 1; /* FALL-THROUGH */ case 3: if (asyncMentatLoop.mentatSpeakingMode == 2 && asyncMentatLoop.textTick < g_timerGUI) key = 1; if ((key != 0 && asyncMentatLoop.textDone) || asyncMentatLoop.result != 0) { GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 160, 0, 0, SCREEN_WIDTH / 8, 40, 4, 0); GUI_Mouse_Show_InRegion(); asyncMentatLoop.step = 4; asyncMentatLoop.mentatSpeakingMode = 0; break; } if (key != 0) { GUI_Screen_Copy(0, 160, 0, 0, SCREEN_WIDTH / 8, 40, 4, 4); if (asyncMentatLoop.textLines-- != 0) { GFX_Screen_SetActive(4); GUI_DrawText_Wrapper(asyncMentatLoop.text, 4, 1, g_curWidgetFGColourBlink, 0, 0x32); asyncMentatLoop.mentatSpeakingMode = 1; asyncMentatLoop.textDelay = strlen(asyncMentatLoop.text) * 4; asyncMentatLoop.textTick = g_timerGUI + asyncMentatLoop.textDelay; if (asyncMentatLoop.textLines != 0) { while (*asyncMentatLoop.text++ != '\0') {} } else { asyncMentatLoop.textDone = true; } GFX_Screen_SetActive(0); } GUI_Mouse_Hide_InRegion(0, 0, SCREEN_WIDTH, 40); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, 40, 4, 0); GUI_Mouse_Show_InRegion(); break; } if (asyncMentatLoop.mentatSpeakingMode == 0 || asyncMentatLoop.textTick > g_timerGUI) break; asyncMentatLoop.mentatSpeakingMode = 2; asyncMentatLoop.textTick += asyncMentatLoop.textDelay + asyncMentatLoop.textDelay / 2; break; case 4: if (asyncMentatLoop.result != 0 || asyncMentatLoop.w == NULL) asyncMentatLoop.step = 5; break; case 5: asyncMentatLoop.dirty = true; asyncMentatLoop.done = true; break; default: break; } GUI_Mentat_Animation(asyncMentatLoop.mentatSpeakingMode); if (asyncMentatLoop.wsa != NULL && g_timerTimeout == 0) { g_timerTimeout = 7; do { if (asyncMentatLoop.step == 0 && asyncMentatLoop.frame > 4) asyncMentatLoop.step = 1; if (!WSA_DisplayFrame(asyncMentatLoop.wsa, asyncMentatLoop.frame++, g_curWidgetXBase << 3, g_curWidgetYBase, 4)) { if (asyncMentatLoop.step == 0) asyncMentatLoop.step = 1; if (asyncMentatLoop.arg12 != 0) { asyncMentatLoop.frame = 0; } else { WSA_Unload(asyncMentatLoop.wsa); asyncMentatLoop.wsa = NULL; } } } while (asyncMentatLoop.frame == 0); asyncMentatLoop.dirty = true; } if (!asyncMentatLoop.dirty) { sleepIdle(); return; } GUI_Mentat_DrawInfo(asyncMentatLoop.pictureDetails, (g_curWidgetXBase << 3) + 5, g_curWidgetYBase + 3, 8, 0, asyncMentatLoop.lines, 0x31); GUI_DrawSprite(4, g_sprites[397 + g_playerHouseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GUI_Mouse_Hide_InWidget(g_curWidgetIndex); GUI_Screen_Copy(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, 4, 0); GUI_Mouse_Show_InWidget(); asyncMentatLoop.dirty = false; sleepIdle(); }
/** * Main game loop. */ void GameLoop_Main(bool new_game, const char* scenario) { static int64_t l_timerNext = 0; static int64_t l_timerUnitStatus = 0; static int16 l_selectionState = -2; int frames_skipped = 0; Mouse_TransformFromDiv(SCREENDIV_MENU, &g_mouseX, &g_mouseY); Sprites_UnloadTiles(); Sprites_LoadTiles(); Viewport_Init(); if (new_game) { if (scenario) { if (!Game_LoadScenario(scenario)) goto end; } else Game_LoadScenario(g_playerHouseID, g_scenarioID); GUI_ChangeSelectionType(g_debugScenario ? SELECTIONTYPE_DEBUG : SELECTIONTYPE_STRUCTURE); } GUI_Palette_CreateRemap(g_table_houseInfo[g_playerHouseID].spriteColor); Audio_LoadSampleSet(g_table_houseInfo[g_playerHouseID].sampleSet); Timer_ResetScriptTimers(); Timer_SetTimer(TIMER_GAME, true); /* Note: original game chose only MUSIC_IDLE1 .. MUSIC_IDLE6. */ Audio_PlayMusic(MUSIC_RANDOM_IDLE); l_timerNext = Timer_GetTicks() + 300; g_musicInBattle = 0; g_gameMode = GM_NORMAL; g_gameOverlay = GAMEOVERLAY_NONE; Timer_RegisterSource(); while (g_gameMode == GM_NORMAL) { Timer_WaitForEvent(); const int64_t curr_ticks = Timer_GameTicks(); if (g_gameOverlay == GAMEOVERLAY_NONE) { Input_Tick(false); uint16 key = GUI_Widget_HandleEvents(g_widgetLinkedListHead); GameLoop_ProcessUnhandledInput(key); if (g_mousePanning) Video_WarpCursor(TRUE_DISPLAY_WIDTH / 2, TRUE_DISPLAY_HEIGHT / 2); } else if (g_gameOverlay == GAMEOVERLAY_MENTAT) { Input_Tick(true); MenuBar_TickMentatOverlay(); } else { Input_Tick(true); MenuBar_TickOptionsOverlay(); } if (g_gameOverlay == GAMEOVERLAY_NONE && g_timerGame != curr_ticks) g_timerGame = curr_ticks; else if (g_gameOverlay == GAMEOVERLAY_NONE) continue; if (g_selectionTypeNew != g_selectionType) GUI_ChangeSelectionType(g_selectionTypeNew); GUI_PaletteAnimate(); if (l_selectionState != g_selectionState) { Map_SetSelectionObjectPosition(0xFFFF); Map_SetSelectionObjectPosition(g_selectionRectanglePosition); l_selectionState = g_selectionState; } const bool narrator_speaking = Audio_Poll(); if (!narrator_speaking) { if (!g_enable_audio || !g_enable_music) { g_musicInBattle = 0; } else if (g_musicInBattle > 0) { Audio_PlayMusic(MUSIC_RANDOM_ATTACK); l_timerNext = Timer_GetTicks() + 300; g_musicInBattle = -1; } else { if (Timer_GetTicks() > l_timerNext) { if (!Audio_MusicIsPlaying()) { if (g_gameOverlay == GAMEOVERLAY_MENTAT) Audio_PlayMusic((MusicID)g_table_houseInfo[g_playerHouseID].musicBriefing); else Audio_PlayMusic(MUSIC_RANDOM_IDLE); l_timerNext = Timer_GetTicks() + 300; g_musicInBattle = 0; } } } } GFX_Screen_SetActive(SCREEN_0); if ((g_gameOverlay == GAMEOVERLAY_NONE) && (g_selectionType == SELECTIONTYPE_TARGET || g_selectionType == SELECTIONTYPE_PLACE || g_selectionType == SELECTIONTYPE_UNIT || g_selectionType == SELECTIONTYPE_STRUCTURE)) { if (Unit_AnySelected()) { if (l_timerUnitStatus < g_timerGame) { Unit_DisplayGroupStatusText(); l_timerUnitStatus = g_timerGame + 300; } if (g_selectionType != SELECTIONTYPE_TARGET) { const Unit* u = Unit_FirstSelected(NULL); g_selectionPosition = Tile_PackTile(Tile_Center(u->o.position)); } } UnitAI_SquadLoop(); GameLoop_Team(); GameLoop_Unit(); GameLoop_Structure(); GameLoop_House(); } if (g_running && !g_debugScenario) GameLoop_LevelEnd(); if (!g_running) break; if (frames_skipped > 4 || Timer_QueueIsEmpty()) { frames_skipped = 0; if (g_gameOverlay == GAMEOVERLAY_NONE) GUI_DrawInterfaceAndRadar(); else if (g_gameOverlay == GAMEOVERLAY_MENTAT) MenuBar_DrawMentatOverlay(); else { GUI_DrawInterfaceAndRadar(); MenuBar_DrawOptionsOverlay(); } Video_Tick(); A5_UseTransform(SCREENDIV_MAIN); } else frames_skipped++; } end: Timer_UnregisterSource(); Audio_PlayVoice(VOICE_STOP); Widget_SetCurrentWidget(0); g_selectionPosition = 0xFFFF; Unit_UnselectAll(); if (g_gameOverlay == GAMEOVERLAY_NONE) Mouse_TransformToDiv(SCREENDIV_MENU, &g_mouseX, &g_mouseY); }