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(); }