From af5ef5e75d4adae33582ecfe13462687a7c16cf7 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:21:08 +0100 Subject: [PATCH] add game_load_or_quit function --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 + src/game.c | 211 +++++++++++++++++++++++++++++- src/game.h | 2 + src/strings.h | 15 +++ src/window.h | 2 + src/window_save_prompt.c | 192 +++++++++++++++++++++++++++ 7 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 src/window_save_prompt.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index f948462979..831470a580 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -88,6 +88,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 181b6cd8bd..3b8344d289 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -257,6 +257,9 @@ Source Files + + Windows + diff --git a/src/game.c b/src/game.c index b83169e0d8..ea88c3a7c2 100644 --- a/src/game.c +++ b/src/game.c @@ -29,6 +29,7 @@ #include "peep.h" #include "screenshot.h" #include "strings.h" +#include "title.h" #include "tutorial.h" #include "widget.h" #include "window.h" @@ -986,6 +987,8 @@ static int game_check_affordability(int cost) return ebp; } +static uint32 game_do_command_table[58]; + /** * * rct2: 0x006677F2 @@ -1004,9 +1007,6 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb original_edi = edi; original_ebp = ebp; - RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return ebx; - flags = ebx; RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF; @@ -1016,7 +1016,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb ebx &= ~1; // Primary command - RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); cost = ebx; if (cost != 0x80000000) { @@ -1039,7 +1039,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb } // Secondary command - RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); edx = ebx; if (edx != 0x80000000 && edx < cost) @@ -1075,4 +1075,203 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16)); return 0x80000000; -} \ No newline at end of file +} + +/** + * + * rct2: 0x0066DB5F + */ +static void game_load_or_quit() +{ + rct_window *w; + char input_bl, input_dl; + short input_di; + + __asm mov input_bl, bl + __asm mov input_dl, dl + __asm mov input_di, di + + if (!(input_bl & 1)) + return 0; + + switch (input_dl) { + case 0: + RCT2_GLOBAL(0x009A9802, uint16) = input_di; + window_save_prompt_open(); + break; + case 1: + window_close_by_id(WC_SAVE_PROMPT, 0); + break; + default: + game_load_or_quit_no_save_prompt(); + break; + } + + __asm mov ebx, 0 +} + +/** + * + * rct2: 0x00674F40 + */ +static int open_landscape_file_dialog() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x00674F40, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return eax; +} + +/** + * + * rct2: 0x00674EB6 + */ +static int open_load_game_dialog() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x00674EB6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return eax; +} + +/** + * + * rct2: 0x0066DC0F + */ +static void load_landscape() +{ + if (open_landscape_file_dialog() == 0) { + gfx_invalidate_screen(); + } else { + // string stuff + + RCT2_CALLPROC_EBPSAFE(0x006758C0); + if (1) { + gfx_invalidate_screen(); + // game_loop_iteration + } else { + RCT2_GLOBAL(0x009DEA66, uint16) = 0; + // game_loop_iteration + } + } +} + +/** + * + * rct2: 0x0066DBB7 + */ +static void load_game() +{ + if (open_load_game_dialog() == 0) { + gfx_invalidate_screen(); + } else { + // string stuff + + RCT2_CALLPROC_EBPSAFE(0x00675E1B); + if (1) { + gfx_invalidate_screen(); + // game_loop_iteration + } else { + RCT2_GLOBAL(0x009DEA66, uint16) = 0; + // game_loop_iteration + } + } +} + +/** + * + * rct2: 0x006E3879 + */ +static void rct2_exit() +{ + RCT2_CALLPROC_EBPSAFE(0x006E3879); +} + +/** + * + * rct2: 0x0066DB79 + */ +void game_load_or_quit_no_save_prompt() +{ + if (RCT2_GLOBAL(0x009A9802, uint16) < 1) { + game_do_command(0, 1, 0, 1, 5, 0, 0); + RCT2_CALLPROC_EBPSAFE(0x006EE281); // tool_cancel + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + load_landscape(); + else + load_game(); + } else if (RCT2_GLOBAL(0x009A9802, uint16) == 1) { + game_do_command(0, 1, 0, 1, 5, 0, 0); + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) { + RCT2_CALLPROC_EBPSAFE(0x0040705E); + RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 5); + } + title_load(); + // game_loop_iteration + } else { + rct2_exit(); + } +} + +#pragma region Game command function table + +static uint32 game_do_command_table[58] = { + 0x006B2FC5, + 0x0066397F, + 0x00667C15, + 0x006C511D, + 0x006C5B69, + 0x0066DB5F, // game_load_or_quit, + 0x006B3F0F, + 0x006B49D9, + 0x006B4EA6, + 0x006B52D4, + 0x006B578B, + 0x006B5559, + 0x006660A8, + 0x0066640B, + 0x006E0E01, + 0x006E08F4, + 0x006E650F, + 0x006A61DE, + 0x006A68AE, + 0x006A67C0, + 0x00663CCD, + 0x006B53E9, + 0x00698D6C, + 0x0068C542, + 0x0068C6D1, + 0x0068BC01, + 0x006E66A0, + 0x006E6878, + 0x006C5AE9, + 0x006BEFA1, + 0x006C09D1, + 0x006C0B83, + 0x006C0BB5, + 0x00669C6D, + 0x00669D4A, + 0x006649BD, + 0x006666E7, + 0x00666A63, + 0x006CD8CE, + 0x00669E30, + 0x00669E55, + 0x006E519A, + 0x006E5597, + 0x006B893C, + 0x006B8E1B, + 0x0069DFB3, + 0x00684A7F, + 0x006D13FE, + 0x0069E73C, + 0x006CDEE4, + 0x006B9E6D, + 0x006BA058, + 0x006E0F26, + 0x006E56B5, + 0x006B909A, + 0x006BA16A, + 0x006648E3, + 0x0068DF91 +}; + +#pragma endregion \ No newline at end of file diff --git a/src/game.h b/src/game.h index cca9afb469..23aaff9a33 100644 --- a/src/game.h +++ b/src/game.h @@ -27,4 +27,6 @@ void game_logic_update(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +void game_load_or_quit_no_save_prompt(); + #endif diff --git a/src/strings.h b/src/strings.h index 583bc4738e..f088c56212 100644 --- a/src/strings.h +++ b/src/strings.h @@ -162,6 +162,8 @@ enum { STR_CREDIT_SPARE_6 = 863, STR_CREDIT_SPARE_7 = 864, + STR_QUIT_SCENARIO_EDITOR = 887, + STR_SCR_BMP = 890, STR_SCREENSHOT = 891, STR_SCREENSHOT_SAVED_AS = 892, @@ -170,6 +172,19 @@ enum { STR_VIEW_OPTIONS_TIP = 937, STR_ADJUST_LAND_TIP = 938, + STR_SAVE_PROMPT_SAVE = 944, + STR_SAVE_PROMPT_DONT_SAVE = 945, + STR_SAVE_PROMPT_CANCEL = 946, + + STR_SAVE_BEFORE_LOADING = 947, + STR_SAVE_BEFORE_QUITTING = 948, + STR_SAVE_BEFORE_QUITTING_2 = 949, + + STR_LOAD_GAME = 950, + STR_QUIT_GAME = 951, + STR_QUIT_GAME_2 = 952, + STR_LOAD_LANDSCAPE = 953, + STR_CANCEL = 972, STR_OK = 973, diff --git a/src/window.h b/src/window.h index d74e7e98d7..cc424965b8 100644 --- a/src/window.h +++ b/src/window.h @@ -250,6 +250,7 @@ enum { WC_ERROR = 11, WC_RIDE = 12, WC_RIDE_CONSTRUCTION = 13, + WC_SAVE_PROMPT = 14, WC_RIDE_LIST = 15, WC_CONSTRUCT_RIDE = 16, WC_SCENERY = 18, @@ -324,6 +325,7 @@ void window_main_open(); void window_game_top_toolbar_open(); void window_game_bottom_toolbar_open(); void window_about_open(); +void window_save_prompt_open(); void window_title_menu_open(); void window_title_exit_open(); void window_title_logo_open(); diff --git a/src/window_save_prompt.c b/src/window_save_prompt.c new file mode 100644 index 0000000000..35c95a7797 --- /dev/null +++ b/src/window_save_prompt.c @@ -0,0 +1,192 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "game.h" +#include "rct2.h" +#include "strings.h" +#include "sprites.h" +#include "tutorial.h" +#include "widget.h" +#include "window.h" + +static enum WINDOW_SAVE_PROMPT_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_3, + WIDX_SAVE, + WIDX_DONT_SAVE, + WIDX_CANCEL +}; + +static rct_widget window_save_prompt_widgets[] = { + { WWT_FRAME, 0, 0, 259, 0, 49, -1, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 258, 1, 14, 0, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 247, 257, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_12, 0, 2, 257, 19, 30, 0, STR_NONE }, // + { WWT_DROPDOWN_BUTTON, 0, 8, 85, 35, 46, STR_SAVE_PROMPT_SAVE, STR_NONE }, // save + { WWT_DROPDOWN_BUTTON, 0, 91, 168, 35, 46, STR_SAVE_PROMPT_DONT_SAVE, STR_NONE }, // don't save + { WWT_DROPDOWN_BUTTON, 0, 174, 251, 35, 46, STR_SAVE_PROMPT_CANCEL, STR_NONE }, // cancel + { WIDGETS_END }, +}; + +static void window_save_prompt_emptysub() { } +static void window_save_prompt_close(); +static void window_save_prompt_mouseup(); +static void window_save_prompt_paint(); + +static uint32 window_save_prompt_events[] = { + window_save_prompt_close, + window_save_prompt_mouseup, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_paint, + window_save_prompt_emptysub +}; + +/** + * + * rct2: 0x0066DCBE + */ +void window_save_prompt_open() +{ + int stringId; + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_SAVE_PROMPT, 0); + if (window == NULL) { + window = window_create( + (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2) - 130, + max(28, (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) / 2) - 25), + 260, + 50, + window_save_prompt_events, + WC_SAVE_PROMPT, + 0 + ); + + window->widgets = window_save_prompt_widgets; + window->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_SAVE) | + (1 << WIDX_DONT_SAVE) | + (1 << WIDX_CANCEL); + window_init_scroll_widgets(window); + window->colours[0] = 154; + window->flags |= WF_TRANSPARENT; + + // Pause the game + RCT2_GLOBAL(0x009DEA6E, uint8) |= 2; + RCT2_CALLPROC_EBPSAFE(0x006BABB4); + window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0); + } + + stringId = RCT2_GLOBAL(0x009A9802, uint16) + STR_LOAD_GAME; + if (stringId == STR_LOAD_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + stringId = STR_LOAD_LANDSCAPE; + if (stringId == STR_QUIT_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + stringId = STR_QUIT_SCENARIO_EDITOR; + window_save_prompt_widgets[WIDX_TITLE].image = stringId; + window_save_prompt_widgets[WIDX_3].image = RCT2_GLOBAL(0x009A9802, uint16) + STR_SAVE_BEFORE_LOADING; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0D) { + game_load_or_quit_no_save_prompt(); + return; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) { + if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) { + RCT2_CALLPROC_EBPSAFE(0x0066EE54); + game_load_or_quit_no_save_prompt(); + return; + } else { + tutorial_stop(); + game_load_or_quit_no_save_prompt(); + return; + } + } + + if (RCT2_GLOBAL(0x009DEA66, uint16) < 3840) { + game_load_or_quit_no_save_prompt(); + return; + } +} + +/** + * + * rct2: 0x0066DF17 + */ +static void window_save_prompt_close() +{ + // Unpause the game + RCT2_GLOBAL(0x009DEA6E, uint8) &= ~2; + RCT2_CALLPROC_EBPSAFE(0x006BABD8); + window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0); +} + +/** + * + * rct2: 0x0066DDF2 + */ +static void window_save_prompt_mouseup() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + // TODO +} + +static void window_save_prompt_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + __asm mov w, esi + __asm mov dpi, edi + + window_draw_widgets(w, dpi); +} \ No newline at end of file