예제 #1
0
/**
 * The Intro.
 */
void GameLoop_GameIntroAnimation(void)
{
	GUI_ChangeSelectionType(SELECTIONTYPE_INTRO);

	Gameloop_Logos();

	if (Input_Keyboard_NextKey() == 0 || !g_canSkipIntro) {
		const HouseAnimation_Animation   *animation   = g_table_houseAnimation_animation[HOUSEANIMATION_INTRO];
		const HouseAnimation_Subtitle    *subtitle    = g_table_houseAnimation_subtitle[HOUSEANIMATION_INTRO];
		const HouseAnimation_SoundEffect *soundEffect = g_table_houseAnimation_soundEffect[HOUSEANIMATION_INTRO];

		Music_Play(0x1B);

		/* 0x4A = 74 = Intro feedback base index */
		GameLoop_PrepareAnimation(subtitle, 0x4A, soundEffect);

		GameLoop_PlayAnimation(animation);

		Driver_Music_FadeOut();

		GameLoop_FinishAnimation();
	}

	GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT);
}
예제 #2
0
파일: security.c 프로젝트: gnaghi/OpenDUNE
/**
 * 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;
}
예제 #3
0
/**
 * Logos at begin of intro.
 */
static void Gameloop_Logos(void)
{
	Screen oldScreenID;
	void *wsa;
	uint16 frame;

	oldScreenID = GFX_Screen_SetActive(SCREEN_0);

	GFX_SetPalette(g_palette2);
	GFX_ClearScreen();

	File_ReadBlockFile("WESTWOOD.PAL", g_palette_998A, 256 * 3);

	frame = 0;
	wsa = WSA_LoadFile("WESTWOOD.WSA", GFX_Screen_Get_ByIndex(SCREEN_1), GFX_Screen_GetSize_ByIndex(SCREEN_1) + GFX_Screen_GetSize_ByIndex(SCREEN_2) + GFX_Screen_GetSize_ByIndex(SCREEN_3), true);
	WSA_DisplayFrame(wsa, frame++, 0, 0, SCREEN_0);

	GUI_SetPaletteAnimated(g_palette_998A, 60);

	Music_Play(0x24);

	g_timerTimeout = 360;

	while (WSA_DisplayFrame(wsa, frame++, 0, 0, SCREEN_0)) Timer_Sleep(6);
	
	WSA_Unload(wsa);

	if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit;
	Voice_LoadVoices(0xFFFF);

	for (; g_timerTimeout != 0; sleepIdle()) {
		if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit;
	}

	GUI_SetPaletteAnimated(g_palette2, 60);

	while (Driver_Music_IsPlaying()) sleepIdle();

	GUI_SetPaletteAnimated(g_palette2, 60);

	GFX_ClearScreen();

	Sprites_LoadImage(String_GenerateFilename("AND"), SCREEN_1, g_palette_998A);

	GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0);

	GUI_SetPaletteAnimated(g_palette_998A, 30);

	for (g_timerTimeout = 60; g_timerTimeout != 0; sleepIdle()) {
		if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit;
	}

	GUI_SetPaletteAnimated(g_palette2, 30);

	GUI_ClearScreen(SCREEN_0);

	Sprites_LoadImage("VIRGIN.CPS", SCREEN_1, g_palette_998A);

	GUI_Screen_Copy(0, 0, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT, SCREEN_1, SCREEN_0);

	GUI_SetPaletteAnimated(g_palette_998A, 30);

	for (g_timerTimeout = 180; g_timerTimeout != 0; sleepIdle()) {
		if (Input_Keyboard_NextKey() != 0 && g_canSkipIntro) goto logos_exit;
	}

logos_exit:
	GUI_SetPaletteAnimated(g_palette2, 30);

	GUI_ClearScreen(SCREEN_0);

	GFX_Screen_SetActive(oldScreenID);
}
예제 #4
0
/**
 * Shows the game credits.
 */
static void GameLoop_GameCredits(void)
{
	static const uint8 colours[] = {0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0};

	uint16 i;
	uint8 *memory;

	GUI_Mouse_Hide_Safe();

	Widget_SetCurrentWidget(20);

	Sprites_LoadImage("BIGPLAN.CPS", SCREEN_1, g_palette_998A);

	GUI_ClearScreen(SCREEN_0);

	GUI_Screen_Copy(g_curWidgetXBase, g_curWidgetYBase, g_curWidgetXBase, g_curWidgetYBase, g_curWidgetWidth, g_curWidgetHeight, SCREEN_1, SCREEN_0);

	GUI_SetPaletteAnimated(g_palette_998A, 60);

	Music_Play(0);

	GameLoop_Uninit();

	Music_Play(33);

	memory = GFX_Screen_Get_ByIndex(SCREEN_2);

	for (i = 0; i < 256; i++) {
		uint8 loc06;
		uint8 loc04;

		memory[i] = i & 0xFF;

		loc06 = i / 16;
		loc04 = i % 16;

		if (loc06 == 9 && loc04 <= 6) {
			memory[i] = (g_playerHouseID * 16) + loc04 + 144;
		}
	}

	Sprites_LoadImage("MAPPLAN.CPS", SCREEN_1, g_palette_998A);

	GUI_Palette_RemapScreen(g_curWidgetXBase << 3, g_curWidgetYBase, g_curWidgetWidth << 3, g_curWidgetHeight, SCREEN_1, memory);

	GUI_Screen_FadeIn2(g_curWidgetXBase << 3, g_curWidgetYBase, g_curWidgetWidth << 3, g_curWidgetHeight, SCREEN_1, SCREEN_0, 1, false);

	GameCredits_LoadPalette();

	GUI_Mouse_Hide_Safe();

	GUI_InitColors(colours, 0, lengthof(colours) - 1);

	g_fontCharOffset = -1;

	GFX_SetPalette(g_palette1);

	for (;; sleepIdle()) {
		File_ReadBlockFile(String_GenerateFilename("CREDITS"), s_buffer_1832, GFX_Screen_GetSize_ByIndex(SCREEN_3));

		GameCredits_Play(s_buffer_1832, 20, SCREEN_1, SCREEN_2, 6);

		if (Input_Keyboard_NextKey() != 0) break;

		Music_Play(33);
	}

	GUI_SetPaletteAnimated(g_palette2, 60);

	Driver_Music_FadeOut();

	GFX_ClearScreen();
}
예제 #5
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);
}
예제 #6
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();
	}
}
예제 #7
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();
	}
}