/** * Intro menu. */ static void GameLoop_GameIntroAnimationMenu(void) { static const uint16 mainMenuStrings[][6] = { {STR_PLAY_A_GAME, STR_REPLAY_INTRODUCTION, STR_EXIT_GAME, STR_NULL, STR_NULL, STR_NULL}, /* Neither HOF nor save. */ {STR_PLAY_A_GAME, STR_REPLAY_INTRODUCTION, STR_LOAD_GAME, STR_EXIT_GAME, STR_NULL, STR_NULL}, /* Has a save game. */ {STR_PLAY_A_GAME, STR_REPLAY_INTRODUCTION, STR_EXIT_GAME, STR_HALL_OF_FAME, STR_NULL, STR_NULL}, /* Has a HOF. */ {STR_PLAY_A_GAME, STR_REPLAY_INTRODUCTION, STR_LOAD_GAME, STR_EXIT_GAME, STR_HALL_OF_FAME, STR_NULL} /* Has a HOF and a save game. */ }; bool loadGame = false; static bool drawMenu = true; static uint16 stringID = STR_REPLAY_INTRODUCTION; uint16 maxWidth; static bool hasSave = false; static bool hasFame = false; static const char *strings[6]; static uint16 index = 0xFFFF; if (index == 0xFFFF) { hasSave = File_Exists("_save000.dat"); hasFame = File_Exists("SAVEFAME.DAT"); index = (hasFame ? 2 : 0) + (hasSave ? 1 : 0); } if (hasSave || File_Exists("ONETIME.DAT")) g_canSkipIntro = true; switch (stringID) { case STR_REPLAY_INTRODUCTION: Music_Play(0); free(g_readBuffer); g_readBufferSize = (g_enableVoices == 0) ? 12000 : 28000; g_readBuffer = calloc(1, g_readBufferSize); GUI_Mouse_Hide_Safe(); Driver_Music_FadeOut(); GameLoop_GameIntroAnimation(); Sound_Output_Feedback(0xFFFE); File_ReadBlockFile("IBM.PAL", g_palette_998A, 256 * 3); memmove(g_palette1, g_palette_998A, 256 * 3); if (!g_canSkipIntro) { File_Create("ONETIME.DAT"); g_canSkipIntro = true; } Music_Play(0); free(g_readBuffer); g_readBufferSize = (g_enableVoices == 0) ? 12000 : 20000; g_readBuffer = calloc(1, g_readBufferSize); GUI_Mouse_Show_Safe(); Music_Play(28); drawMenu = true; break; case STR_EXIT_GAME: g_running = false; return; case STR_HALL_OF_FAME: GUI_HallOfFame_Show(0xFFFF); GFX_SetPalette(g_palette2); hasFame = File_Exists("SAVEFAME.DAT"); drawMenu = true; break; case STR_LOAD_GAME: GUI_Mouse_Hide_Safe(); GUI_SetPaletteAnimated(g_palette2, 30); GUI_ClearScreen(SCREEN_0); GUI_Mouse_Show_Safe(); GFX_SetPalette(g_palette1); if (GUI_Widget_SaveLoad_Click(false)) { loadGame = true; if (g_gameMode == GM_RESTART) break; g_gameMode = GM_NORMAL; } else { GFX_SetPalette(g_palette2); drawMenu = true; } break; default: break; } if (drawMenu) { uint16 i; g_widgetProperties[21].height = 0; for (i = 0; i < 6; i++) { strings[i] = NULL; if (mainMenuStrings[index][i] == 0) { if (g_widgetProperties[21].height == 0) g_widgetProperties[21].height = i; continue; } strings[i] = String_Get_ByIndex(mainMenuStrings[index][i]); } GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x22); maxWidth = 0; for (i = 0; i < g_widgetProperties[21].height; i++) { if (Font_GetStringWidth(strings[i]) <= maxWidth) continue; maxWidth = Font_GetStringWidth(strings[i]); } maxWidth += 7; g_widgetProperties[21].width = maxWidth >> 3; g_widgetProperties[13].width = g_widgetProperties[21].width + 2; g_widgetProperties[13].xBase = 19 - (maxWidth >> 4); g_widgetProperties[13].yBase = 160 - ((g_widgetProperties[21].height * g_fontCurrent->height) >> 1); g_widgetProperties[13].height = (g_widgetProperties[21].height * g_fontCurrent->height) + 11; Sprites_LoadImage(String_GenerateFilename("TITLE"), SCREEN_1, NULL); GUI_Mouse_Hide_Safe(); GUI_ClearScreen(SCREEN_0); GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0); GUI_SetPaletteAnimated(g_palette1, 30); GUI_DrawText_Wrapper("V1.07", 319, 192, 133, 0, 0x231, 0x39); GUI_DrawText_Wrapper(NULL, 0, 0, 0, 0, 0x22); Widget_SetCurrentWidget(13); GUI_Widget_DrawBorder(13, 2, 1); GameLoop_DrawMenu(strings); GUI_Mouse_Show_Safe(); drawMenu = false; } if (loadGame) return; stringID = GameLoop_HandleEvents(strings); if (stringID != 0xFFFF) stringID = mainMenuStrings[index][stringID]; GUI_PaletteAnimate(); if (stringID == STR_PLAY_A_GAME) g_gameMode = GM_PICKHOUSE; }
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); }