From b58766aa3fb634e2dca2ecae014c05ccd6f66e6a Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 13 May 2016 21:36:07 +0100 Subject: [PATCH] clean up the logo and make it scalable - fixes #1776: graphical glitches on intro - fixes #708: screen turns white when resizing intro --- src/addresses.h | 4 +- src/interface/screenshot.c | 3 +- src/intro.c | 253 +++++++++++++++++------------------- src/intro.h | 17 +++ src/openrct2.c | 5 +- src/rct2.c | 9 +- src/windows/title_exit.c | 3 +- src/windows/title_options.c | 3 +- 8 files changed, 152 insertions(+), 145 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 114bea065f..8eb3d9ea62 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -81,8 +81,6 @@ #define RCT2_ADDRESS_VIEWPORT_ZOOM 0x009AC126 -#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 - // 0 = none, 255 = load file, 254 = anything else #define RCT2_ADDRESS_ERROR_TYPE 0x009AC31B #define RCT2_ADDRESS_ERROR_STRING_ID 0x009AC31C @@ -545,6 +543,8 @@ #define RCT2_ADDRESS_RAIN_PATTERN 0x009AC010 #define RCT2_ADDRESS_LIGHTNING_ACTIVE 0x009AC068 +#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 + #define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542 #define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544 #define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545 diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 19788601d1..e3e3c8ca5f 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -20,6 +20,7 @@ #include "../drawing/drawing.h" #include "../game.h" #include "../image_io.h" +#include "../intro.h" #include "../localisation/localisation.h" #include "../openrct2.h" #include "../platform/platform.h" @@ -301,7 +302,7 @@ int cmdline_for_screenshot(const char **argv, int argc) if (openrct2_initialise()) { rct2_open_file(inputPath); - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; + gIntroState = INTRO_STATE_NONE; gScreenFlags = SCREEN_FLAGS_PLAYING; int mapSize = gMapSize; diff --git a/src/intro.c b/src/intro.c index 07b8a02418..a60b9d5d0c 100644 --- a/src/intro.c +++ b/src/intro.c @@ -23,102 +23,99 @@ #include "platform/platform.h" #include "sprites.h" +#define BACKROUND_COLOUR_DARK 10 +#define BACKROUND_COLOUR_LOGO 245 +#define BORDER_COLOUR_PUBLISHER 129 + +#define PALETTE_G1_IDX_DEVELOPER 23217 +#define PALETTE_G1_IDX_LOGO 23224 + +uint8 gIntroState; + +// Used mainly for timing but also for Y coordinate and fading. +static int _introStateCounter; + +static void *_soundChannel = NULL; +static bool _chainLiftFinished; + static void screen_intro_process_mouse_input(); static void screen_intro_process_keyboard_input(); static void screen_intro_skip_part(); - -static int _tick_counter; ///< Used mainly for timing but also for Y coordinate and fading. -static void *_soundChannel = NULL; +static void screen_intro_draw_logo(); // rct2: 0x0068E966 void intro_update() { rct_drawpixelinfo *screenDPI = &gScreenDPI; int screenWidth = gScreenWidth; - uint8 (*part) = RCT2_ADDRESS(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8); screen_intro_process_mouse_input(); screen_intro_process_keyboard_input(); - RCT2_GLOBAL(0x009E2C78, int) = 1; - switch ((*part)) { - // Cases 8 and 9 were used for the disclaimer text. There might be some residual occurences. - case 8: - case 9: - (*part) = 1; - case 1: - // Clear the screen - gfx_clear(screenDPI, 10); + switch (gIntroState) { + case INTRO_STATE_DISCLAIMER_1: + case INTRO_STATE_DISCLAIMER_2: + // Originally used for the disclaimer text + gIntroState = INTRO_STATE_PUBLISHER_BEGIN; + case INTRO_STATE_PUBLISHER_BEGIN: + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); // Set the Y for the Infogrammes logo - _tick_counter = -580; + _introStateCounter = -580; - // Chain lift sound + // Play the chain lift sound _soundChannel = Mixer_Play_Effect(SOUND_LIFT_7, MIXER_LOOP_INFINITE, SDL_MIX_MAXVOLUME, 0.5f, 1, true); - - // Move to next part - (*part)++; + _chainLiftFinished = false; + gIntroState++; break; - case 2: - // Move the Infogrammes logo down by 5 pixels - _tick_counter += 5; + case INTRO_STATE_PUBLISHER_SCROLL: + // Move the Infogrammes logo down + _introStateCounter += 5; - // Clear the screen - gfx_clear(screenDPI, 10); + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); // Draw a white rectangle for the logo background (gives a bit of white margin) gfx_fill_rect(screenDPI, - (screenWidth / 2) - 320 + 50, _tick_counter + 50, - (screenWidth / 2) - 320 + 50 + 540, _tick_counter + 50 + 425, - 129); + (screenWidth / 2) - 320 + 50, _introStateCounter + 50, + (screenWidth / 2) - 320 + 50 + 540, _introStateCounter + 50 + 425, + BORDER_COLOUR_PUBLISHER); - // Draw the logo - gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_00, (screenWidth / 2) - 320 + 69, _tick_counter + 69, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_10, (screenWidth / 2) - 320 + 319, _tick_counter + 69, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_01, (screenWidth / 2) - 320 + 69, _tick_counter + 319, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_11, (screenWidth / 2) - 320 + 319, _tick_counter + 319, 0); + // Draw Infogrames logo + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_00, (screenWidth / 2) - 320 + 69, _introStateCounter + 69, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_10, (screenWidth / 2) - 320 + 319, _introStateCounter + 69, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_01, (screenWidth / 2) - 320 + 69, _introStateCounter + 319, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_11, (screenWidth / 2) - 320 + 319, _introStateCounter + 319, 0); - // Check if logo is off the screen .ish - if (_tick_counter > 520) { - // Clear the screen - gfx_clear(screenDPI, 10); - - _tick_counter = -116; - - // Move to the next part - (*part)++; + // Check if logo is off the screen...ish + if (_introStateCounter > gScreenHeight - 120) { + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); + _introStateCounter = -116; + gIntroState++; } break; - case 3: - // - _tick_counter += 5; - - // Clear the screen - gfx_clear(screenDPI, 10); - - // Set some palette thing - gfx_transpose_palette(23217, 255); + case INTRO_STATE_DEVELOPER_BEGIN: + _introStateCounter += 5; + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); + gfx_transpose_palette(PALETTE_G1_IDX_DEVELOPER, 255); // Set the Y for the Chris Sawyer logo - _tick_counter = -116; + _introStateCounter = -116; - // Move to the next part - (*part)++; + gIntroState++; break; - case 4: - // Chris Sawyer logo - _tick_counter += 5; - - // Clear the screen - gfx_clear(screenDPI, 10); + case INTRO_STATE_DEVELOPER_SCROLL: + _introStateCounter += 5; + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); // Draw Chris Sawyer logo - gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_00, (screenWidth / 2) - 320 + 70, _tick_counter, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_10, (screenWidth / 2) - 320 + 320, _tick_counter, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_00, (screenWidth / 2) - 320 + 70, _introStateCounter, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_10, (screenWidth / 2) - 320 + 320, _introStateCounter, 0); + + // Check if logo is almost scrolled to the bottom + if (!_chainLiftFinished && _introStateCounter >= gScreenHeight + 40 - 421) { + _chainLiftFinished = true; - // Check if logo is at 259 pixels - if (_tick_counter == 259) { // Stop the chain lift sound if (_soundChannel != NULL) { Mixer_Stop_Channel(_soundChannel); @@ -129,21 +126,11 @@ void intro_update() _soundChannel = Mixer_Play_Effect(SOUND_TRACK_FRICTION_3, MIXER_LOOP_INFINITE, SDL_MIX_MAXVOLUME, 0.25f, 0.75, true); } - // Check if logo is off the screen .ish - if (_tick_counter >= 680) { - // Clear the screen - gfx_clear(screenDPI, 245); + // Check if logo is off the screen...ish + if (_introStateCounter >= gScreenHeight + 40) { + gfx_transpose_palette(PALETTE_G1_IDX_LOGO, 0); - // Draw RollerCoaster Tycoon 2 logo - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_00, (screenWidth / 2) - 320 + 0, 0, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_10, (screenWidth / 2) - 320 + 220, 0, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_20, (screenWidth / 2) - 320 + 440, 0, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_01, (screenWidth / 2) - 320 + 0, 240, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_11, (screenWidth / 2) - 320 + 220, 240, 0); - gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_21, (screenWidth / 2) - 320 + 440, 240, 0); - - // Set palette thing - gfx_transpose_palette(23224, 0); + screen_intro_draw_logo(); // Stop the track friction sound if (_soundChannel != NULL) { @@ -154,60 +141,47 @@ void intro_update() // Play long peep scream sound _soundChannel = Mixer_Play_Effect(SOUND_SCREAM_1, MIXER_LOOP_NONE, SDL_MIX_MAXVOLUME, 0.5f, 1, true); - // Move to the next part - (*part)++; - - // Set the current fade to 0 - _tick_counter = 0; + gIntroState++; + _introStateCounter = 0; } break; - case 5: + case INTRO_STATE_LOGO_FADE_IN: // Fade in, add 4 / 256 to fading - _tick_counter += 0x000400; - if (_tick_counter <= 0x00FF00) { - // Set palette thing - gfx_transpose_palette(23224, (_tick_counter >> 8) & 0xFF); - } - else { - // Set palette thing - gfx_transpose_palette(23224, 255); - - // Move to next part - (*part)++; - - // Set the fade to 0 - _tick_counter = 0; + _introStateCounter += 0x400; + if (_introStateCounter <= 0xFF00) { + gfx_transpose_palette(PALETTE_G1_IDX_LOGO, (_introStateCounter >> 8) & 0xFF); + } else { + gfx_transpose_palette(PALETTE_G1_IDX_LOGO, 255); + gIntroState++; + _introStateCounter = 0; } + screen_intro_draw_logo(); break; - case 6: + case INTRO_STATE_LOGO_WAIT: // Wait 80 game ticks - _tick_counter++; - if (_tick_counter >= 80) { + _introStateCounter++; + if (_introStateCounter >= 80) { // Set fading to 256 - _tick_counter = 0x00FF00; + _introStateCounter = 0xFF00; - // Move to next part - (*part)++; + gIntroState++; } + screen_intro_draw_logo(); break; - case 7: + case INTRO_STATE_LOGO_FADE_OUT: // Fade out, subtract 4 / 256 from fading - _tick_counter -= 0x000400; - if (_tick_counter >= 0) { + _introStateCounter -= 0x400; + if (_introStateCounter >= 0) { // Do palette thing - gfx_transpose_palette(23224, (_tick_counter >> 8) & 0xFF); - } - else { - // Do palette thing - gfx_transpose_palette(23224, 0); - - // Finish the intro sequence - (*part) = 254; + gfx_transpose_palette(PALETTE_G1_IDX_LOGO, (_introStateCounter >> 8) & 0xFF); + } else { + gfx_transpose_palette(PALETTE_G1_IDX_LOGO, 0); + gIntroState = INTRO_STATE_CLEAR; } + screen_intro_draw_logo(); break; - case 254: - // Clear the screen - gfx_clear(screenDPI, 10); + case INTRO_STATE_CLEAR: + gfx_clear(screenDPI, BACKROUND_COLOUR_DARK); // Stop any playing sound if (_soundChannel != NULL) { @@ -216,17 +190,12 @@ void intro_update() } // Move to next part - (*part)++; - _tick_counter = 0; + gIntroState++; + _introStateCounter = 0; break; - case 255: - // Finish the intro sequence - (*part) = 0; - - // Change palette + case INTRO_STATE_FINISH: + gIntroState = INTRO_STATE_NONE; load_palette(); - - RCT2_GLOBAL(0x009E2C78, sint32) = 0; gfx_invalidate_screen(); break; } @@ -234,8 +203,9 @@ void intro_update() static void screen_intro_process_mouse_input() { - if (gCursorState.any == CURSOR_PRESSED) + if (gCursorState.any == CURSOR_PRESSED) { screen_intro_skip_part(); + } } /** @@ -244,22 +214,37 @@ static void screen_intro_process_mouse_input() */ static void screen_intro_process_keyboard_input() { - if (gLastKeyPressed != 0) + if (gLastKeyPressed != 0) { screen_intro_skip_part(); + } } static void screen_intro_skip_part() { - uint8 (*part) = RCT2_ADDRESS(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8); - - switch ((*part)) { - case 0: + switch (gIntroState) { + case INTRO_STATE_NONE: break; - case 9: - (*part) = 1; + case INTRO_STATE_DISCLAIMER_2: + gIntroState = INTRO_STATE_PUBLISHER_BEGIN; break; default: - (*part) = 254; + gIntroState = INTRO_STATE_CLEAR; break; } } + +static void screen_intro_draw_logo() +{ + rct_drawpixelinfo *screenDPI = &gScreenDPI; + sint32 screenWidth = gScreenWidth; + sint32 imageWidth = 640; + sint32 imageX = (screenWidth - imageWidth) / 2; + + gfx_clear(screenDPI, BACKROUND_COLOUR_LOGO); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_00, imageX + 0, 0, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_10, imageX + 220, 0, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_20, imageX + 440, 0, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_01, imageX + 0, 240, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_11, imageX + 220, 240, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_21, imageX + 440, 240, 0); +} diff --git a/src/intro.h b/src/intro.h index 8a33721f80..6a129f151e 100644 --- a/src/intro.h +++ b/src/intro.h @@ -17,6 +17,23 @@ #ifndef _INTRO_H_ #define _INTRO_H_ +enum INTRO_STATE { + INTRO_STATE_NONE, + INTRO_STATE_PUBLISHER_BEGIN, + INTRO_STATE_PUBLISHER_SCROLL, + INTRO_STATE_DEVELOPER_BEGIN, + INTRO_STATE_DEVELOPER_SCROLL, + INTRO_STATE_LOGO_FADE_IN, + INTRO_STATE_LOGO_WAIT, + INTRO_STATE_LOGO_FADE_OUT, + INTRO_STATE_DISCLAIMER_1, + INTRO_STATE_DISCLAIMER_2, + INTRO_STATE_CLEAR = 254, + INTRO_STATE_FINISH = 255, +}; + +extern uint8 gIntroState; + void intro_update(); #endif diff --git a/src/openrct2.c b/src/openrct2.c index 40c946e26a..5c900b3da9 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -25,6 +25,7 @@ #include "interface/themes.h" #include "interface/window.h" #include "interface/viewport.h" +#include "intro.h" #include "localisation/localisation.h" #include "network/http.h" #include "network/network.h" @@ -264,13 +265,13 @@ bool openrct2_initialise() void openrct2_launch() { if (openrct2_initialise()) { - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; + gIntroState = INTRO_STATE_NONE; if((gOpenRCT2StartupAction == STARTUP_ACTION_TITLE) && gConfigGeneral.play_intro) gOpenRCT2StartupAction = STARTUP_ACTION_INTRO; switch (gOpenRCT2StartupAction) { case STARTUP_ACTION_INTRO: - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 1; + gIntroState = INTRO_STATE_PUBLISHER_BEGIN; break; case STARTUP_ACTION_TITLE: gScreenFlags = SCREEN_FLAGS_TITLE_DEMO; diff --git a/src/rct2.c b/src/rct2.c index 1226749fc3..5b42526e05 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -276,7 +276,7 @@ int rct2_startup_checks() void rct2_draw() { - if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) { + if (gIntroState != INTRO_STATE_NONE) { return; } @@ -454,12 +454,13 @@ void rct2_update() // check_cmdline_arg(); // Screens - if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) + if (gIntroState != INTRO_STATE_NONE) { intro_update(); - else if ((gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !gOpenRCT2Headless) + } else if ((gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !gOpenRCT2Headless) { title_update(); - else + } else { game_update(); + } //stop_completed_sounds(); // removes other sounds that are no longer playing in directsound diff --git a/src/windows/title_exit.c b/src/windows/title_exit.c index 900885f29f..91a27f34d2 100644 --- a/src/windows/title_exit.c +++ b/src/windows/title_exit.c @@ -22,6 +22,7 @@ #include "../interface/widget.h" #include "../interface/window.h" #include "../interface/themes.h" +#include "../intro.h" static rct_widget window_title_exit_widgets[] = { { WWT_IMGBTN, 2, 0, 39, 0, 63, SPR_MENU_EXIT, STR_EXIT }, @@ -89,7 +90,7 @@ void window_title_exit_open() */ static void window_title_exit_mouseup(rct_window *w, int widgetIndex) { - if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) + if (gIntroState != INTRO_STATE_NONE) return; if (widgetIndex == 0) diff --git a/src/windows/title_options.c b/src/windows/title_options.c index c459182f6f..f2f0dd7b81 100644 --- a/src/windows/title_options.c +++ b/src/windows/title_options.c @@ -17,6 +17,7 @@ #include "../addresses.h" #include "../config.h" #include "../game.h" +#include "../intro.h" #include "../localisation/localisation.h" #include "../interface/widget.h" #include "../interface/window.h" @@ -83,7 +84,7 @@ void window_title_options_open() static void window_title_options_mouseup(rct_window *w, int widgetIndex) { - if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) + if (gIntroState != INTRO_STATE_NONE) return; if (widgetIndex == 0)