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; }
uint16 GUI_Mentat_Tick(void) { GUI_Mentat_Animation((g_interrogationTimer < g_timerGUI) ? 0 : 1); return 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; }
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; }