/** * 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); }
/** * Draw sprites and handle mouse in a mentat screen. * @param speakingMode If \c 1, the mentat is speaking. */ void GUI_Mentat_Animation(uint16 speakingMode) { static uint32 movingEyesTimer = 0; /* Timer when to change the eyes sprite. */ static uint16 movingEyesSprite = 0; /* Index in _mentatSprites of the displayed moving eyes. */ static uint16 movingEyesNextSprite = 0; /* If not 0, it decides the movingEyesNextSprite */ static uint32 movingMouthTimer = 0; static uint16 movingMouthSprite = 0; static uint32 movingOtherTimer = 0; static int16 otherSprite = 0; bool partNeedsRedraw; uint16 i; if (movingOtherTimer < g_timerGUI && !g_disableOtherMovement) { if (movingOtherTimer != 0) { uint8 *sprite; if (s_mentatSprites[2][1 + abs(otherSprite)] == NULL) { otherSprite = 1 - otherSprite; } else { otherSprite++; } sprite = s_mentatSprites[2][abs(otherSprite)]; GUI_Mouse_Hide_InRegion(s_otherLeft, s_otherTop, s_otherLeft + Sprite_GetWidth(sprite), s_otherTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(SCREEN_0, sprite, s_otherLeft, s_otherTop, 0, 0); GUI_Mouse_Show_InRegion(); } switch (g_playerHouseID) { case HOUSE_HARKONNEN: movingOtherTimer = g_timerGUI + 300 * 60; break; case HOUSE_ATREIDES: movingOtherTimer = g_timerGUI + 60 * Tools_RandomLCG_Range(1,3); break; case HOUSE_ORDOS: if (otherSprite != 0) { movingOtherTimer = g_timerGUI + 6; } else { movingOtherTimer = g_timerGUI + 60 * Tools_RandomLCG_Range(10, 19); } break; default: break; } } if (speakingMode == 1) { if (movingMouthTimer < g_timerGUI) { uint8 *sprite; movingMouthSprite = Tools_RandomLCG_Range(0, 4); sprite = s_mentatSprites[1][movingMouthSprite]; GUI_Mouse_Hide_InRegion(s_mouthLeft, s_mouthTop, s_mouthLeft + Sprite_GetWidth(sprite), s_mouthTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(SCREEN_0, sprite, s_mouthLeft, s_mouthTop, 0, 0); GUI_Mouse_Show_InRegion(); switch (movingMouthSprite) { case 0: movingMouthTimer = g_timerGUI + Tools_RandomLCG_Range(7, 30); break; case 1: case 2: case 3: movingMouthTimer = g_timerGUI + Tools_RandomLCG_Range(6, 10); break; case 4: movingMouthTimer = g_timerGUI + Tools_RandomLCG_Range(5, 6); break; default: break; } } } else { partNeedsRedraw = false; if (Input_Test(0x41) == 0 && Input_Test(0x42) == 0) { if (movingMouthSprite != 0) { movingMouthSprite = 0; movingMouthTimer = 0; partNeedsRedraw = true; } } else if (Mouse_InsideRegion(s_mouthLeft, s_mouthTop, s_mouthRight, s_mouthBottom) != 0) { if (movingMouthTimer != 0xFFFFFFFF) { movingMouthTimer = 0xFFFFFFFF; movingMouthSprite = Tools_RandomLCG_Range(1, 4); partNeedsRedraw = true; } } else { if (movingMouthSprite != 0) { movingMouthSprite = 0; movingMouthTimer = 0; partNeedsRedraw = true; } } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[1][movingMouthSprite]; GUI_Mouse_Hide_InRegion(s_mouthLeft, s_mouthTop, s_mouthLeft + Sprite_GetWidth(sprite), s_mouthTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(SCREEN_0, sprite, s_mouthLeft, s_mouthTop, 0, 0); GUI_Mouse_Show_InRegion(); } } partNeedsRedraw = false; if (Input_Test(0x41) != 0 || Input_Test(0x42) != 0) { if (Mouse_InsideRegion(s_eyesLeft, s_eyesTop, s_eyesRight, s_eyesBottom) != 0) { if (movingEyesSprite != 0x4) { partNeedsRedraw = true; movingEyesSprite = (movingEyesSprite == 3) ? 4 : 3; movingEyesNextSprite = 0; movingEyesTimer = 0; } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[0][movingEyesSprite]; GUI_Mouse_Hide_InRegion(s_eyesLeft, s_eyesTop, s_eyesLeft + Sprite_GetWidth(sprite), s_eyesTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(SCREEN_0, sprite, s_eyesLeft, s_eyesTop, 0, 0); GUI_Mouse_Show_InRegion(); } return; } } if (Mouse_InsideRegion((int16)s_eyesLeft - 16, (int16)s_eyesTop - 8, s_eyesRight + 16, s_eyesBottom + 24) != 0) { if (Mouse_InsideRegion((int16)s_eyesLeft - 8, s_eyesBottom, s_eyesRight + 8, SCREEN_HEIGHT - 1) != 0) { i = 3; } else { if (Mouse_InsideRegion(s_eyesRight, (int16)s_eyesTop - 8, s_eyesRight + 16, s_eyesBottom + 8) != 0) { i = 2; } else { i = (Mouse_InsideRegion((int16)s_eyesLeft - 16, (int16)s_eyesTop - 8, s_eyesLeft, s_eyesBottom + 8) == 0) ? 0 : 1; } } if (i != movingEyesSprite) { partNeedsRedraw = true; movingEyesSprite = i; movingEyesNextSprite = 0; movingEyesTimer = g_timerGUI; } } else { if (movingEyesTimer >= g_timerGUI) return; partNeedsRedraw = true; if (movingEyesNextSprite != 0) { movingEyesSprite = movingEyesNextSprite; movingEyesNextSprite = 0; if (movingEyesSprite != 4) { movingEyesTimer = g_timerGUI + Tools_RandomLCG_Range(20, 180); } else { movingEyesTimer = g_timerGUI + Tools_RandomLCG_Range(12, 30); } } else { i = 0; switch (speakingMode) { case 0: i = Tools_RandomLCG_Range(0, 7); if (i > 5) { i = 1; } else { if (i == 5) { i = 4; } } break; case 1: if (movingEyesSprite != ((!g_interrogation) ? 0 : 3)) { i = 0; } else { i = Tools_RandomLCG_Range(0, 17); if (i > 9) { i = 0; } else { if (i >= 5) { i = 4; } } } break; default: i = Tools_RandomLCG_Range(0, 15); if (i > 10) { i = 2; } else { if (i >= 5) { i = 4; } } break; } if ((i == 2 && movingEyesSprite == 1) || (i == 1 && movingEyesSprite == 2)) { movingEyesNextSprite = i; movingEyesSprite = 0; movingEyesTimer = g_timerGUI + Tools_RandomLCG_Range(1, 5); } else { if (i != movingEyesSprite && (i == 4 || movingEyesSprite == 4)) { movingEyesNextSprite = i; movingEyesSprite = 3; movingEyesTimer = g_timerGUI; } else { movingEyesSprite = i; if (i != 4) { movingEyesTimer = g_timerGUI + Tools_RandomLCG_Range(15, 180); } else { movingEyesTimer = g_timerGUI + Tools_RandomLCG_Range(6, 60); } } } if (g_interrogation && movingEyesSprite == 0) movingEyesSprite = 3; } } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[0][movingEyesSprite]; GUI_Mouse_Hide_InRegion(s_eyesLeft, s_eyesTop, s_eyesLeft + Sprite_GetWidth(sprite), s_eyesTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(SCREEN_0, sprite, s_eyesLeft, s_eyesTop, 0, 0); GUI_Mouse_Show_InRegion(); } }
int Sprite::GetHeight() { return obj ? Sprite_GetHeight(obj) : 0; }
static void GameCredits_Play(char *data, uint16 windowID, Screen memory, Screen screenID, uint16 delay) { uint16 loc02; uint16 stringCount = 0; uint32 loc0C; uint16 spriteID = 514; bool loc10 = false; uint16 spriteX; uint16 spriteY; uint16 spritePos = 0; struct { uint16 x; int16 y; char *text; uint8 separator; uint8 charHeight; uint8 type; } strings[33]; struct { uint16 x; uint16 y; } positions[6]; uint16 stage = 4; uint16 counter = 60; Widget_SetCurrentWidget(windowID); spriteX = (g_curWidgetWidth << 3) - Sprite_GetWidth(g_sprites[spriteID]); spriteY = g_curWidgetHeight - Sprite_GetHeight(g_sprites[spriteID]); positions[0].x = spriteX; positions[0].y = 0; positions[1].x = 0; positions[1].y = spriteY / 2; positions[2].x = spriteX; positions[2].y = spriteY; positions[3].x = 0; positions[3].y = 0; positions[4].x = spriteX; positions[4].y = spriteY / 2; positions[5].x = 0; positions[5].y = spriteY; GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_0, memory); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, memory, screenID); GameCredits_SwapScreen(g_curWidgetYBase, g_curWidgetHeight, memory, s_buffer_182E); GFX_Screen_SetActive(SCREEN_0); loc0C = g_timerSleep; Input_History_Clear(); while (true) { while (loc0C > g_timerSleep) sleepIdle(); loc0C = g_timerSleep + delay; while ((g_curWidgetHeight / 6) + 2 > stringCount && *data != 0) { char *text = data; uint16 y; if (stringCount != 0) { y = strings[stringCount - 1].y; if (strings[stringCount - 1].separator != 5) y += strings[stringCount - 1].charHeight + strings[stringCount - 1].charHeight / 8; } else { y = g_curWidgetHeight; } text = data; data = strpbrk(data, "\x05\r"); if (data == NULL) data = strchr(text, '\0'); strings[stringCount].separator = *data; *data = '\0'; if (strings[stringCount].separator != 0) data++; strings[stringCount].type = 0; if (*text == 3 || *text == 4) strings[stringCount].type = *text++; if (*text == 1) { text++; Font_Select(g_fontNew6p); } else if (*text == 2) { text++; Font_Select(g_fontNew8p); } strings[stringCount].charHeight = g_fontCurrent->height; switch (strings[stringCount].type) { case 3: strings[stringCount].x = 157 - Font_GetStringWidth(text); break; case 4: strings[stringCount].x = 161; break; default: strings[stringCount].x = 1 + (SCREEN_WIDTH - Font_GetStringWidth(text)) / 2; break; } strings[stringCount].y = y; strings[stringCount].text = text; stringCount++; } switch (stage) { case 0: GUI_ClearScreen(memory); if (spriteID == 514) GUI_ClearScreen(screenID); stage++; counter = 2; break; case 1: case 4: if (counter-- == 0) { counter = 0; stage++; } break; case 2: if (spriteID == 525) spriteID = 514; GUI_DrawSprite(memory, g_sprites[spriteID], positions[spritePos].x, positions[spritePos].y, windowID, 0x4000); counter = 8; stage++; spriteID++; if (++spritePos > 5) spritePos = 0;; break; case 3: if (counter < 8) GFX_SetPalette(g_palette1 + 256 * 3 * counter); if (counter-- == 0) { stage++; counter = 20; } break; case 5: if (counter > 0) GFX_SetPalette(g_palette1 + 256 * 3 * counter); if (counter++ >= 8) stage = 0; break; default: break; } GUI_Screen_Copy(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, memory, screenID); for (loc02 = 0; loc02 < stringCount; loc02++) { if ((int16)strings[loc02].y < g_curWidgetHeight) { GFX_Screen_SetActive(screenID); Font_Select(g_fontNew8p); if (strings[loc02].charHeight != g_fontCurrent->height) Font_Select(g_fontNew6p); GUI_DrawText(strings[loc02].text, strings[loc02].x, strings[loc02].y + g_curWidgetYBase, 255, 0); GFX_Screen_SetActive(SCREEN_0); } strings[loc02].y--; } GameCredits_SwapScreen(g_curWidgetYBase, g_curWidgetHeight, screenID, s_buffer_182E); if ((int16)strings[0].y < -10) { strings[0].text += strlen(strings[0].text); *strings[0].text = strings[0].separator; stringCount--; memcpy(&strings[0], &strings[1], stringCount * sizeof(*strings)); } if ((g_curWidgetHeight / 6 + 2) > stringCount) { if (strings[stringCount - 1].y + strings[stringCount - 1].charHeight < g_curWidgetYBase + g_curWidgetHeight) loc10 = true; } if (loc10 && stage == 0) break; if (Input_Keyboard_NextKey() != 0) break; } GUI_SetPaletteAnimated(g_palette2, 120); GUI_ClearScreen(SCREEN_0); GUI_ClearScreen(memory); GUI_ClearScreen(screenID); }