Пример #1
0
static void ShowCrashlogWindow()
{
	PrepareEnd();
	ShowCursor(TRUE);
	MessageBox(NULL, s_crashText, _T("Fatal Application Failure"), MB_ICONERROR);
	exit(2);
}
Пример #2
0
/**
 * Load a scenario in a safe way, and prepare the game.
 * @param houseID The House which is going to play the game.
 * @param scenarioID The Scenario to load.
 */
void Game_LoadScenario(uint8 houseID, uint16 scenarioID)
{
	Audio_PlayVoice(VOICE_STOP);
	Game_Init();
	g_validateStrictIfZero++;

	g_scenarioID = scenarioID;
	if (!Scenario_Load(scenarioID, houseID))
	{
		GUI_DisplayModalMessage("No more scenarios!", 0xFFFF);

		PrepareEnd();
		exit(0);
	}

	Game_Prepare();

	if (scenarioID < 5)
	{
		g_hintsShown1 = 0;
		g_hintsShown2 = 0;
	}

	g_validateStrictIfZero--;
}
Пример #3
0
int main(int argc, char **argv)
#endif /* __APPLE__ */
{
	bool commit_dune_cfg = false;
#if defined(_WIN32)
	#if defined(__MINGW32__) && defined(__STRICT_ANSI__)
		int __cdecl __MINGW_NOTHROW _fileno (FILE*);
	#endif
	FILE *err = fopen("error.log", "w");
	FILE *out = fopen("output.log", "w");

	#if defined(_MSC_VER)
		_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
	#endif

	if (err != NULL) _dup2(_fileno(err), _fileno(stderr));
	if (out != NULL) _dup2(_fileno(out), _fileno(stdout));
	FreeConsole();
#endif
	CrashLog_Init();

	VARIABLE_NOT_USED(argc);
	VARIABLE_NOT_USED(argv);

	if (!File_Init()) {
		Error("Cannot initialise files. Does %s directory exist ?\n", DATA_DIR);
		exit(1);
	}

	/* Loading / writing config from/to dune.cfg */
	if (!Config_Read("dune.cfg", &g_config)) {
		Config_Default(&g_config);
		commit_dune_cfg = true;
	}
	if (commit_dune_cfg && !Config_Write("dune.cfg", &g_config)) {
		Error("Error writing to dune.cfg file.\n");
		exit(1);
	}

	Input_Init();

	Drivers_All_Init();

	if (!Unknown_25C4_000E()) exit(1);

	g_var_7097 = 0;

	GameLoop_Main();

	printf("%s\n", String_Get_ByIndex(STR_THANK_YOU_FOR_PLAYING_DUNE_II));

	PrepareEnd();
	exit(0);
}
Пример #4
0
static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
{
	if (s_handlingException) {
		PrepareEnd();
		exit(2);
	}

	s_handlingException = true;
	s_ep = ep;
	s_crashlog[0] = '\0';

	CrashLog_Fill(s_crashlog);

	_sntprintf(s_crashText, sizeof(s_crashText),
		_T("A serious fault condition occurred in the game. The game will shut down.\n")
		_T("Please send the crash information and the crash.dmp file (if any) to the developers.\n")
		_T("This will greatly help debugging. The correct place to do this is http://bugs.opendune.org. ")
		_T("Generated file(s):\n")
	);

#if defined(_MSC_VER)
	AppendDecodedStacktrace(s_crashlog);
	if (WriteCrashDump()) _tcscat(s_crashText, "crash.dmp\n");
#endif /* _MSC_VER */

	if (CrashLog_WriteCrashLog(s_crashlog)) _tcscat(s_crashText, _T("crash.log\n"));

	if (s_safe_esp != NULL) {
#ifdef _M_AMD64
		ep->ContextRecord->Rip = (DWORD64)ShowCrashlogWindow;
		ep->ContextRecord->Rsp = (DWORD64)s_safe_esp;
#else
		ep->ContextRecord->Eip = (DWORD)ShowCrashlogWindow;
		ep->ContextRecord->Esp = (DWORD)s_safe_esp;
#endif
		return EXCEPTION_CONTINUE_EXECUTION;
	}

	PrepareEnd();
	return EXCEPTION_EXECUTE_HANDLER;
}
Пример #5
0
int main(int argc, char** argv)
{
	UNUSED(argc);
	UNUSED(argv);

	FileHash_Init();
	Mouse_Init();

	if (A5_InitOptions() == false)
		exit(1);

	char filename[1024];

	snprintf(filename, sizeof(filename), "%s/error.log", g_dune_data_dir);
	FILE* err = fopen(filename, "w");

	snprintf(filename, sizeof(filename), "%s/output.log", g_dune_data_dir);
	FILE* out = fopen(filename, "w");

	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

	if (err != NULL)
		_dup2(_fileno(err), _fileno(stderr));
	if (out != NULL)
		_dup2(_fileno(out), _fileno(stdout));
	FreeConsole();

	if (!Unknown_25C4_000E())
		exit(1);

	if (A5_Init() == false)
		exit(1);

	Scenario_InitTables();
	Input_Init();
	Audio_LoadSampleSet(SAMPLESET_INVALID);
	String_Init();
	Sprites_Init();
	Sprites_LoadTiles();
	VideoA5_InitSprites();
	GameLoop_TweakWidgetDimensions();
	Audio_PlayVoice(VOICE_STOP);
	GameLoop_GameIntroAnimationMenu();

	printf("%s\n", String_Get_ByIndex(STR_THANK_YOU_FOR_PLAYING_DUNE_II));

	PrepareEnd();
	exit(0);
}
Пример #6
0
/**
 * Load a scenario in a safe way, and prepare the game.
 * @param houseID The House which is going to play the game.
 * @param scenarioID The Scenario to load.
 */
void Game_LoadScenario(uint8 houseID, uint16 scenarioID)
{
	Sound_Output_Feedback(0xFFFE);

	Game_Init();

	g_validateStrictIfZero++;

	if (!Scenario_Load(scenarioID, houseID)) {
		GUI_DisplayModalMessage("No more scenarios!", 0xFFFF);

		PrepareEnd();
		exit(0);
	}

	Game_Prepare();

	if (scenarioID < 5) {
		g_hintsShown1 = 0;
		g_hintsShown2 = 0;
	}

	g_validateStrictIfZero--;
}
Пример #7
0
/**
 * Checks if the level comes to an end. If so, it shows all end-level stuff,
 *  and prepares for the next level.
 */
static void GameLoop_LevelEnd(void)
{
	static uint32 levelEndTimer = 0;

	if (levelEndTimer >= g_timerGame && !s_debugForceWin) return;

	if (GameLoop_IsLevelFinished()) {
		Music_Play(0);

		g_cursorSpriteID = 0;

		Sprites_SetMouseSprite(0, 0, g_sprites[0]);

		Sound_Output_Feedback(0xFFFE);

		GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT);

		if (GameLoop_IsLevelWon()) {
			Sound_Output_Feedback(40);

			GUI_DisplayModalMessage(String_Get_ByIndex(STR_YOU_HAVE_SUCCESSFULLY_COMPLETED_YOUR_MISSION), 0xFFFF);

			GUI_Mentat_ShowWin();

			Sprites_UnloadTiles();

			g_campaignID++;

			GUI_EndStats_Show(g_scenario.killedAllied, g_scenario.killedEnemy, g_scenario.destroyedAllied, g_scenario.destroyedEnemy, g_scenario.harvestedAllied, g_scenario.harvestedEnemy, g_scenario.score, g_playerHouseID);

			if (g_campaignID == 9) {
				GUI_Mouse_Hide_Safe();

				GUI_SetPaletteAnimated(g_palette2, 15);
				GUI_ClearScreen(SCREEN_0);
				GameLoop_GameEndAnimation();
				PrepareEnd();
				exit(0);
			}

			GUI_Mouse_Hide_Safe();
			GameLoop_LevelEndAnimation();
			GUI_Mouse_Show_Safe();

			File_ReadBlockFile("IBM.PAL", g_palette1, 256 * 3);

			g_scenarioID = GUI_StrategicMap_Show(g_campaignID, true);

			GUI_SetPaletteAnimated(g_palette2, 15);

			if (g_campaignID == 1 || g_campaignID == 7) {
				if (!GUI_Security_Show()) {
					PrepareEnd();
					exit(0);
				}
			}
		} else {
			Sound_Output_Feedback(41);

			GUI_DisplayModalMessage(String_Get_ByIndex(STR_YOU_HAVE_FAILED_YOUR_MISSION), 0xFFFF);

			GUI_Mentat_ShowLose();

			Sprites_UnloadTiles();

			g_scenarioID = GUI_StrategicMap_Show(g_campaignID, false);
		}

		g_playerHouse->flags.doneFullScaleAttack = false;

		Sprites_LoadTiles();

		g_gameMode = GM_RESTART;
		s_debugForceWin = false;
	}

	levelEndTimer = g_timerGame + 300;
}
Пример #8
0
/**
 * Runs every tick to handle video driver updates.
 */
void Video_Tick()
{
	SDL_Event event;

	if (!s_video_initialized) return;

	if (g_fileOperation != 0) return;

	if (s_video_lock) return;
	s_video_lock = true;

	while (SDL_PollEvent(&event)) {
		uint8 keyup = 1;

		switch (event.type) {
			case SDL_QUIT: {
				s_video_lock = false;
				PrepareEnd();
				exit(0);
			} break;

			case SDL_MOUSEMOTION:
				Video_Mouse_Move(event.motion.x, event.motion.y);
				break;

			case SDL_MOUSEBUTTONDOWN:
				if (event.button.button == SDL_BUTTON_LEFT)  Video_Mouse_Button(true,  true);
				if (event.button.button == SDL_BUTTON_RIGHT) Video_Mouse_Button(false, true);
				break;
			case SDL_MOUSEBUTTONUP:
				if (event.button.button == SDL_BUTTON_LEFT)  Video_Mouse_Button(true,  false);
				if (event.button.button == SDL_BUTTON_RIGHT) Video_Mouse_Button(false, false);
				break;

			case SDL_KEYDOWN:
				keyup = 0;
				/* Fall Through */
			case SDL_KEYUP:
			{
				if (event.key.keysym.sym >= sizeof(s_SDL_keymap)) continue;
				if (s_SDL_keymap[event.key.keysym.sym] == 0) {
					Error("ERROR: unhandled key %X\n", event.key.keysym.sym);
					continue;
				}
				Video_Key_Callback(s_SDL_keymap[event.key.keysym.sym] | (keyup ? 0x80 : 0x0));
			} break;
		}
	}

	/* Do a quick compare to see if the screen changed at all */
	if (memcmp(GFX_Screen_Get_ByIndex(0), s_gfx_screen8, SCREEN_WIDTH * SCREEN_HEIGHT) == 0) {
		s_video_lock = false;
		return;
	}
	memcpy(s_gfx_screen8, GFX_Screen_Get_ByIndex(0), SCREEN_WIDTH * SCREEN_HEIGHT);

	Video_DrawScreen();

	SDL_UpdateRect(s_gfx_surface, 0, 0, 0, 0);

	s_video_lock = false;
}
Пример #9
0
int main(int argc, char **argv)
#endif /* __APPLE__ */
{
	bool commit_dune_cfg = false;
	VideoScaleFilter scale_filter = FILTER_NEAREST_NEIGHBOR;
	int scaling_factor = 2;
	char filter_text[64];
#if defined(_WIN32)
	#if defined(__MINGW32__) && defined(__STRICT_ANSI__)
		int __cdecl __MINGW_NOTHROW _fileno (FILE*);
	#endif
	FILE *err = fopen("error.log", "w");
	FILE *out = fopen("output.log", "w");

	#if defined(_MSC_VER)
		_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
	#endif

	if (err != NULL) _dup2(_fileno(err), _fileno(stderr));
	if (out != NULL) _dup2(_fileno(out), _fileno(stdout));
	FreeConsole();
#endif
#ifdef TOS
	(void)Cconws(window_caption);
	(void)Cconws("\r\nrevision:   ");
	(void)Cconws(g_opendune_revision);
	(void)Cconws("\r\nbuild date: ");
	(void)Cconws(g_opendune_build_date);
	(void)Cconws("\r\n");
	/* open log files and set buffering mode */
	g_errlog = fopen("error.log", "w");
	if(g_errlog != NULL) setvbuf(g_errlog, NULL, _IONBF, 0);
#ifdef _DEBUG
	g_outlog = fopen("output.log", "w");
	if(g_outlog != NULL) setvbuf(g_outlog, NULL, _IOLBF, 0);
#endif
	if(atexit(exit_handler) != 0) {
		Error("atexit() failed\n");
	}
#endif
	CrashLog_Init();

	VARIABLE_NOT_USED(argc);
	VARIABLE_NOT_USED(argv);

	/* Load opendune.ini file */
	Load_IniFile();

	if (!File_Init()) {
		exit(1);
	}

	/* Loading config from dune.cfg */
	if (!Config_Read("dune.cfg", &g_config)) {
		Config_Default(&g_config);
		commit_dune_cfg = true;
	}
	/* reading config from opendune.ini which prevail over dune.cfg */
	SetLanguage_From_IniFile(&g_config);

	/* Writing config to dune.cfg */
	if (commit_dune_cfg && !Config_Write("dune.cfg", &g_config)) {
		Error("Error writing to dune.cfg file.\n");
		exit(1);
	}

	Input_Init();

	Drivers_All_Init();

	scaling_factor = IniFile_GetInteger("scalefactor", 2);
	if (IniFile_GetString("scalefilter", NULL, filter_text, sizeof(filter_text)) != NULL) {
		if (strcasecmp(filter_text, "nearest") == 0) {
			scale_filter = FILTER_NEAREST_NEIGHBOR;
		} else if (strcasecmp(filter_text, "scale2x") == 0) {
			scale_filter = FILTER_SCALE2X;
		} else if (strcasecmp(filter_text, "hqx") == 0) {
			scale_filter = FILTER_HQX;
		} else {
			Error("unrecognized scalefilter value '%s'\n", filter_text);
		}
	}

	if (!OpenDune_Init(scaling_factor, scale_filter)) exit(1);

	g_mouseDisabled = 0;

	GameLoop_Main();

	printf("%s\n", String_Get_ByIndex(STR_THANK_YOU_FOR_PLAYING_DUNE_II));

	PrepareEnd();
	Free_IniFile();
	exit(0);
}
Пример #10
0
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();
	}
}
Пример #11
0
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();
	}
}