/** * Display a mentat. * @param houseFilename Filename of the house. * @param houseID ID of the house. */ void GUI_Mentat_Display(const char *wsaFilename, uint8 houseID) { char textBuffer[16]; Screen oldScreenID; int i; snprintf(textBuffer, sizeof(textBuffer), "MENTAT%c.CPS", g_table_houseInfo[houseID].name[0]); Sprites_LoadImage(textBuffer, SCREEN_1, g_palette_998A); oldScreenID = GFX_Screen_SetActive(SCREEN_1); if (houseID == HOUSE_MERCENARY) { File_ReadBlockFile("BENE.PAL", g_palette1, 256 * 3); } memset(s_mentatSprites, 0, sizeof(s_mentatSprites)); s_eyesLeft = s_eyesRight = s_unknownHouseData[houseID][0]; s_eyesTop = s_eyesBottom = s_unknownHouseData[houseID][1]; for (i = 0; i < 5; i++) { s_mentatSprites[0][i] = g_sprites[387 + houseID * 15 + i]; } s_eyesRight += Sprite_GetWidth(s_mentatSprites[0][0]); s_eyesBottom += Sprite_GetHeight(s_mentatSprites[0][0]); s_mouthLeft = s_mouthRight = s_unknownHouseData[houseID][2]; s_mouthTop = s_mouthBottom = s_unknownHouseData[houseID][3]; for (i = 0; i < 5; i++) { s_mentatSprites[1][i] = g_sprites[392 + houseID * 15 + i]; } s_mouthRight += Sprite_GetWidth(s_mentatSprites[1][0]); s_mouthBottom += Sprite_GetHeight(s_mentatSprites[1][0]); s_otherLeft = s_unknownHouseData[houseID][4]; s_otherTop = s_unknownHouseData[houseID][5]; for (i = 0; i < 4; i++) { s_mentatSprites[2][i] = g_sprites[398 + houseID * 15 + i]; } g_shoulderLeft = s_unknownHouseData[houseID][6]; g_shoulderTop = s_unknownHouseData[houseID][7]; 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 + houseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GFX_Screen_SetActive(oldScreenID); }
void async_GUI_Mentat_ShowOpen() { Sprites_UnloadTiles(); GUI_Mentat_Display(asyncMentatShow.wsaFilename, g_playerHouseID); GFX_Screen_SetActive(2); Widget_SetAndPaintCurrentWidget(8); if (asyncMentatShow.wsaFilename != NULL) { void *wsa; wsa = WSA_LoadFile(asyncMentatShow.wsaFilename, GFX_Screen_Get_ByIndex(5), GFX_Screen_GetSize_ByIndex(5), false); WSA_DisplayFrame(wsa, 0, g_curWidgetXBase * 8, g_curWidgetYBase, 2); WSA_Unload(wsa); } GUI_DrawSprite(2, g_sprites[397 + g_playerHouseID * 15], g_shoulderLeft, g_shoulderTop, 0, 0); GFX_Screen_SetActive(0); GUI_Mouse_Hide_Safe(); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, 2, 0); GUI_Mouse_Show_Safe(); GUI_SetPaletteAnimated(g_palette1, 15); Async_GUI_Mentat_Loop(asyncMentatShow.wsaFilename, NULL, asyncMentatShow.stringBuffer, true, NULL); Async_Storage_uint16(&asyncMentatShow.ret); }
/** * Updates the radar state for the given house. * @param h The house. * @return True if and only if the radar has been activated. */ bool House_UpdateRadarState(House *h) { void *wsa; uint16 frame; uint16 frameCount; bool activate; if (h == NULL || h->index != g_playerHouseID) return false; wsa = NULL; activate = h->flags.radarActivated; if (h->flags.radarActivated) { /* Deactivate radar */ if ((h->structuresBuilt & (1 << STRUCTURE_OUTPOST)) == 0 || h->powerProduction < h->powerUsage) activate = false; } else { /* Activate radar */ if ((h->structuresBuilt & (1 << STRUCTURE_OUTPOST)) != 0 && h->powerProduction >= h->powerUsage) activate = true; } if (h->flags.radarActivated == activate) return false; wsa = WSA_LoadFile("STATIC.WSA", GFX_Screen_Get_ByIndex(3), GFX_Screen_GetSize_ByIndex(3), true); frameCount = WSA_GetFrameCount(wsa); g_textDisplayNeedsUpdate = true; GUI_Mouse_Hide_Safe(); while (Driver_Voice_IsPlaying()) sleepIdle(); Voice_Play(62); Sound_Output_Feedback(activate ? 28 : 29); frameCount = WSA_GetFrameCount(wsa); for (frame = 0; frame < frameCount; frame++) { WSA_DisplayFrame(wsa, activate ? frameCount - frame : frame, 256, 136, 0); GUI_PaletteAnimate(); g_timerTimeout = 3; while (g_timerTimeout != 0) sleepIdle(); } h->flags.radarActivated = activate; WSA_Unload(wsa); g_viewport_forceRedraw = true; GUI_Mouse_Show_Safe(); GUI_Widget_Viewport_RedrawMap(0); return activate; }
/** * 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; }
void async_GUI_Mentat_LoopClose() { if (asyncMentatLoop.wsa != NULL) WSA_Unload(asyncMentatLoop.wsa); GFX_Screen_SetActive(4); 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(); Widget_SetCurrentWidget(asyncMentatLoop.old07AE); GFX_Screen_SetActive(asyncMentatLoop.oldScreenID); Input_History_Clear(); Async_StorageSet_uint16(asyncMentatLoop.result); }
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; }
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(); }
/** * Ask the security question to the user. Give him 3 times. If he fails, * return false, otherwise true. * @return True if and only if the user answered one of the three questions * correct. */ bool GUI_Security_Show(void) { const char *wsaHouseFilename; uint16 questionsCount; uint16 oldCurrentWidget; Screen oldScreenID; uint16 i; bool valid; g_disableOtherMovement = true; g_interrogation = true; wsaHouseFilename = House_GetWSAHouseFilename(g_playerHouseID); if (wsaHouseFilename == NULL) return true; GUI_SetPaletteAnimated(g_palette2, 15); GUI_Mentat_Display(wsaHouseFilename, g_playerHouseID); 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); strncpy(g_readBuffer, String_Get_ByIndex(STR_SECURITY_TEXT_HARKONNEN + g_playerHouseID * 3), g_readBufferSize); GUI_Mentat_Loop(wsaHouseFilename, NULL, g_readBuffer, true, NULL); questionsCount = atoi(String_Get_ByIndex(STR_SECURITY_COUNT)); oldCurrentWidget = Widget_SetCurrentWidget(8); oldScreenID = GFX_Screen_SetActive(SCREEN_2); for (i = 0, valid = false; i < 3 && !valid; i++) { void *wsa; uint16 questionIndex; uint32 tickWaitTill; char buffer[81]; questionIndex = Tools_RandomLCG_Range(0, questionsCount - 1) * 3 + STR_SECURITY_QUESTIONS; Widget_SetCurrentWidget(8); wsa = WSA_LoadFile(String_Get_ByIndex(questionIndex + 1), GFX_Screen_Get_ByIndex(SCREEN_1), GFX_Screen_GetSize_ByIndex(SCREEN_1), false); WSA_DisplayFrame(wsa, 0, g_curWidgetXBase << 3, g_curWidgetYBase, SCREEN_2); WSA_Unload(wsa); 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(); strncpy(g_readBuffer, String_Get_ByIndex(questionIndex), g_readBufferSize); GUI_Security_DrawText(g_readBuffer); g_interrogationTimer = g_timerGUI + (uint32)strlen(g_readBuffer) * 4; Widget_SetCurrentWidget(9); GUI_Mouse_Hide_Safe(); GUI_Screen_Copy(g_curWidgetXBase - 1, g_curWidgetYBase - 8, 0, 0, g_curWidgetWidth + 2, g_curWidgetHeight + 16, SCREEN_0, SCREEN_2); GUI_Mouse_Show_Safe(); GFX_Screen_SetActive(SCREEN_0); GUI_Mouse_Hide_Safe(); GUI_DrawBorder((g_curWidgetXBase << 3) - 6, g_curWidgetYBase - 6, (g_curWidgetWidth << 3) + 12, g_curWidgetHeight + 12, 1, true); GUI_DrawBorder((g_curWidgetXBase << 3) - 2, g_curWidgetYBase - 2, (g_curWidgetWidth << 3) + 4, g_curWidgetHeight + 4, 2, false); GUI_Mouse_Show_Safe(); Input_History_Clear(); buffer[0] = 0; GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x22); GUI_EditBox(buffer, sizeof(buffer) - 1, 9, NULL, &GUI_Mentat_Tick, 0); GUI_Security_UndrawText(); GUI_Mouse_Hide_Safe(); GUI_Screen_Copy(0, 0, g_curWidgetXBase - 1, g_curWidgetYBase - 8, g_curWidgetWidth + 2, g_curWidgetHeight + 16, SCREEN_2, SCREEN_0); GUI_Mouse_Show_Safe(); GUI_Security_NormaliseText(buffer); strncpy(g_readBuffer, String_Get_ByIndex(questionIndex + 2), g_readBufferSize); GUI_Security_NormaliseText(g_readBuffer); if (strcasecmp(g_readBuffer, buffer) != 0) { strncpy(g_readBuffer, String_Get_ByIndex(STR_SECURITY_WRONG_HARKONNEN + g_playerHouseID * 3), g_readBufferSize); } else { strncpy(g_readBuffer, String_Get_ByIndex(STR_SECURITY_CORRECT_HARKONNEN + g_playerHouseID * 3), g_readBufferSize); valid = true; } GUI_Security_DrawText(g_readBuffer); tickWaitTill = g_timerGUI + (uint32)strlen(g_readBuffer) * 4; Input_History_Clear(); /* ENHANCEMENT -- In Dune2, the + 120 is on the other side, causing the 'You are wrong! / Well done.' screen to appear very short (close to invisible, so to say) */ while (g_timerGUI + (g_dune2_enhanced ? 0 : 120) < tickWaitTill + (g_dune2_enhanced ? 120 : 0)) { if (Input_Keyboard_NextKey() != 0) break; if (g_timerGUI < tickWaitTill) { GUI_Mentat_Animation(1); } else { GUI_Mentat_Animation(0); } } GUI_Security_UndrawText(); } Widget_SetCurrentWidget(oldCurrentWidget); GFX_Screen_SetActive(oldScreenID); Input_History_Clear(); Load_Palette_Mercenaries(); g_disableOtherMovement = false; g_interrogation = false; return valid; }
/** * 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); }
static void GameLoop_PlayAnimation(const HouseAnimation_Animation *animation) { uint8 animationMode = 0; while (animation->duration != 0) { uint16 frameCount; uint16 posX = 0; uint16 posY = 0; uint32 timeout = g_timerGUI + animation->duration * 6; uint32 timeout2 = timeout + 30; /* timeout + 0.5 s */ uint32 timeLeftForFrame; uint32 timeLeft; uint16 mode = animation->flags & 0x3; uint16 addFrameCount; /* additional frame count */ uint16 frame; void *wsa; if ((animation->flags & 0x20) == 0) { posX = 8; posY = 24; } s_var_8068 = 0; if (mode == 0) { wsa = NULL; frame = 0; } else { char filenameBuffer[16]; uint32 wsaSize; bool wsaReservedDisplayFrame; if (mode == 3) { frame = animation->frameCount; wsaReservedDisplayFrame = true; } else { frame = 0; wsaReservedDisplayFrame = ((animation->flags & 0x40) != 0) ? true : false; } if ((animation->flags & 0x480) != 0) { GUI_ClearScreen(SCREEN_1); wsa = GFX_Screen_Get_ByIndex(SCREEN_2); wsaSize = GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3); wsaReservedDisplayFrame = false; } else { wsa = GFX_Screen_Get_ByIndex(SCREEN_1); wsaSize = GFX_Screen_GetSize_ByIndex(SCREEN_1) + GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3); } snprintf(filenameBuffer, sizeof(filenameBuffer), "%s.WSA", animation->string); wsa = WSA_LoadFile(filenameBuffer, wsa, wsaSize, wsaReservedDisplayFrame); } addFrameCount = 0; if ((animation->flags & 0x8) != 0) { timeout -= 45; addFrameCount++; } else if ((animation->flags & 0x10) != 0) { timeout -= 15; addFrameCount++; } if ((animation->flags & 0x4) != 0) { GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); GameLoop_PalettePart_Update(true); memcpy(&g_palette1[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette1, 45); addFrameCount++; } else { if ((animation->flags & 0x480) != 0) { GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_1); addFrameCount++; if ((animation->flags & 0x480) == 0x80) { GUI_Screen_FadeIn2(8, 24, 304, 120, SCREEN_1, SCREEN_0, 1, false); } else if ((animation->flags & 0x480) == 0x400) { GUI_Screen_FadeIn(1, 24, 1, 24, 38, 120, SCREEN_1, SCREEN_0); } } } timeLeft = timeout - g_timerGUI; timeLeftForFrame = 0; frameCount = 1; switch (mode) { case 0: frameCount = animation->frameCount - addFrameCount; timeLeftForFrame = timeLeft / frameCount; break; case 1: frameCount = WSA_GetFrameCount(wsa); timeLeftForFrame = timeLeft / animation->frameCount; break; case 2: frameCount = WSA_GetFrameCount(wsa) - addFrameCount; timeLeftForFrame = timeLeft / frameCount; timeout -= timeLeftForFrame; break; case 3: frame = animation->frameCount; frameCount = 1; timeLeftForFrame = timeLeft / 20; break; default: PrepareEnd(); Error("Bad mode in animation #%i.\n", animationMode); exit(0); } while (timeout > g_timerGUI) { g_timerTimeout = timeLeftForFrame; GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); if (mode == 1 && frame == frameCount) { frame = 0; } else { if (mode == 3) frame--; } if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) { WSA_Unload(wsa); return; } do { GameLoop_PalettePart_Update(false); sleepIdle(); } while (g_timerTimeout != 0 && timeout > g_timerGUI); } if (mode == 2) { bool displayed; do { GameLoop_PlaySubtitle(animationMode); displayed = WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); } while (displayed); } if ((animation->flags & 0x10) != 0) { memset(&g_palette_998A[3 * 1], 63, 255 * 3); memcpy(&g_palette_998A[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette_998A, 15); memcpy(g_palette_998A, g_palette1, 256 * 3); } if ((animation->flags & 0x8) != 0) { GameLoop_PalettePart_Update(true); memcpy(&g_palette_998A[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette_998A, 45); } WSA_Unload(wsa); animationMode++; animation++; while (timeout2 > g_timerGUI) sleepIdle(); } }
static void GameLoop_PlayAnimation(void) { const HouseAnimation_Animation *animation; uint8 animationMode = 0; animation = s_houseAnimation_animation; while (animation->duration != 0) { uint16 loc04; uint16 posX = 0; uint16 posY = 0; uint32 loc10 = g_timerGUI + animation->duration * 6; uint32 loc14 = loc10 + 30; uint32 loc18; uint32 loc1C; uint16 mode = animation->flags & 0x3; bool loc20; uint32 loc24; uint16 locdi; uint16 frame; void *wsa; if ((animation->flags & 0x20) == 0) { posX = 8; posY = 24; } s_var_8068 = 0; if (mode == 0) { wsa = NULL; frame = 0; } else { char filenameBuffer[16]; if (mode == 3) { frame = animation->frameCount; loc20 = true; } else { frame = 0; loc20 = ((animation->flags & 0x40) != 0) ? true : false; } if ((animation->flags & 0x480) != 0) { GUI_ClearScreen(SCREEN_1); wsa = GFX_Screen_Get_ByIndex(SCREEN_2); loc24 = GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3); loc20 = false; } else { wsa = GFX_Screen_Get_ByIndex(SCREEN_1); loc24 = GFX_Screen_GetSize_ByIndex(SCREEN_1) + GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3); } snprintf(filenameBuffer, sizeof(filenameBuffer), "%s.WSA", animation->string); wsa = WSA_LoadFile(filenameBuffer, wsa, loc24, loc20); } locdi = 0; if ((animation->flags & 0x8) != 0) { loc10 -= 45; locdi++; } else { if ((animation->flags & 0x10) != 0) { loc10 -= 15; locdi++; } } if ((animation->flags & 0x4) != 0) { GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); GameLoop_PalettePart_Update(true); memcpy(&g_palette1[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette1, 45); locdi++; } else { if ((animation->flags & 0x480) != 0) { GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_1); locdi++; if ((animation->flags & 0x480) == 0x80) { GUI_Screen_FadeIn2(8, 24, 304, 120, SCREEN_1, SCREEN_0, 1, false); } else if ((animation->flags & 0x480) == 0x400) { GUI_Screen_FadeIn(1, 24, 1, 24, 38, 120, SCREEN_1, SCREEN_0); } } } loc1C = loc10 - g_timerGUI; loc18 = 0; loc04 = 1; switch (mode) { case 0: loc04 = animation->frameCount - locdi; loc18 = loc1C / loc04; break; case 1: loc04 = WSA_GetFrameCount(wsa); loc18 = loc1C / animation->frameCount; break; case 2: loc04 = WSA_GetFrameCount(wsa) - locdi; loc18 = loc1C / loc04; loc10 -= loc18; break; case 3: frame = animation->frameCount; loc04 = 1; loc18 = loc1C / 20; break; default: PrepareEnd(); Error("Bad mode in animation #%i.\n", animationMode); exit(0); } while (loc10 > g_timerGUI) { g_timerTimeout = loc18; GameLoop_PlaySubtitle(animationMode); WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); if (mode == 1 && frame == loc04) { frame = 0; } else { if (mode == 3) frame--; } if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) { WSA_Unload(wsa); return; } do { GameLoop_PalettePart_Update(false); sleepIdle(); } while (g_timerTimeout != 0 && loc10 > g_timerGUI); } if (mode == 2) { bool displayed; do { GameLoop_PlaySubtitle(animationMode); displayed = WSA_DisplayFrame(wsa, frame++, posX, posY, SCREEN_0); } while (displayed); } if ((animation->flags & 0x10) != 0) { memset(&g_palette_998A[3 * 1], 63, 255 * 3); memcpy(&g_palette_998A[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette_998A, 15); memcpy(g_palette_998A, g_palette1, 256 * 3); } if ((animation->flags & 0x8) != 0) { GameLoop_PalettePart_Update(true); memcpy(&g_palette_998A[215 * 3], s_palettePartCurrent, 18); GUI_SetPaletteAnimated(g_palette_998A, 45); } WSA_Unload(wsa); animationMode++; animation++; while (loc14 > g_timerGUI) sleepIdle(); } }