From 95649ba942daf68955b7b690f0e51dc98521a569 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 1 May 2014 22:55:26 +0100 Subject: [PATCH 1/9] Added happy peeps cheat. Labeled Bathroom peep offset. --- src/peep.h | 3 +- src/window_cheats.c | 127 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 115 insertions(+), 15 deletions(-) diff --git a/src/peep.h b/src/peep.h index d167afc2fb..1d4b092350 100644 --- a/src/peep.h +++ b/src/peep.h @@ -80,7 +80,8 @@ typedef struct { uint8 var_03D; uint8 hunger; // 0x3E uint8 thirst; // 0x3F - uint8 pad_040[0x28]; + uint8 bathroom; // 0x40 + uint8 pad_041[0x27]; uint8 current_ride; // 0x68 uint8 pad_6a; // 0x6A Part of current_ride? uint8 current_train; // 0x6B diff --git a/src/window_cheats.c b/src/window_cheats.c index 8e09e207cc..60861bb94f 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -21,11 +21,14 @@ #include #include "addresses.h" #include "park.h" +#include "peep.h" #include "strings.h" +#include "sprite.h" #include "sprites.h" #include "widget.h" #include "window.h" + #define WW 200 #define WH 128 @@ -41,10 +44,11 @@ static enum WINDOW_CHEATS_WIDGET_IDX { WIDX_PAGE_BACKGROUND, WIDX_TAB_1, WIDX_TAB_2, - WIDX_HIGH_MONEY + WIDX_HIGH_MONEY, + WIDX_HAPPY_GUESTS }; -static rct_widget window_cheats_widgets[] = { +static rct_widget window_cheats_money_widgets[] = { { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535}, // panel / background { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP}, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP}, // close x button @@ -55,13 +59,30 @@ static rct_widget window_cheats_widgets[] = { { WIDGETS_END }, }; +static rct_widget window_cheats_guests_widgets[] = { + { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535 }, // panel / background + { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 + { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2375, 2375 }, // happy guests + { WIDGETS_END }, +}; + +static rct_widget *window_cheats_page_widgets[] = { + window_cheats_money_widgets, + window_cheats_guests_widgets +}; + static void window_cheats_emptysub() { } static void window_cheats_mouseup(); static void window_cheats_update(); static void window_cheats_invalidate(); static void window_cheats_paint(); +static void window_cheats_set_page(rct_window *w, int page); -static uint32 window_cheats_events[] = { +static uint32 window_cheats_money_events[] = { window_cheats_emptysub, window_cheats_mouseup, window_cheats_emptysub, @@ -92,6 +113,47 @@ static uint32 window_cheats_events[] = { window_cheats_emptysub }; +static uint32 window_cheats_guests_events[] = { + window_cheats_emptysub, + window_cheats_mouseup, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_update, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_invalidate, + window_cheats_paint, + window_cheats_emptysub +}; + +static uint32 *window_cheats_page_events[] = { + window_cheats_money_events, + window_cheats_guests_events, +}; + +static uint32 window_cheats_page_enabled_widgets[] = { + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY), + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY) //Change to WIDX_HAPPY_GUESTSs when enabled widgets is figured out. +}; + static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); void window_cheats_open() @@ -103,11 +165,10 @@ void window_cheats_open() if (window != NULL) return; - window = window_create(32, 32, WW, WH, window_cheats_events, WC_CHEATS, 0); - window->widgets = window_cheats_widgets; - window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY); + window = window_create(32, 32, WW, WH, window_cheats_money_events, WC_CHEATS, 0); + window->widgets = window_cheats_money_widgets; + window->enabled_widgets = window_cheats_page_enabled_widgets[0]; window_init_scroll_widgets(window); - window->page = WINDOW_CHEATS_PAGE_MONEY; window->colours[0] = 1; window->colours[1] = 19; @@ -122,16 +183,37 @@ static void window_cheats_mouseup() __asm mov widgetIndex, dx __asm mov w, esi + rct_peep* peep; + uint16 sprite_idx; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; + case WIDX_TAB_1: + case WIDX_TAB_2: + window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); + break; case WIDX_HIGH_MONEY: - i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); - + if (w->page == WINDOW_CHEATS_PAGE_MONEY){ + i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); + i += 100000; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); + } + else{ + for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); + if (peep->type != PEEP_TYPE_GUEST) + continue; + if (peep->var_2A != 0) + continue; + peep->happiness = 255; + } + } + window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); + break; + case WIDX_HAPPY_GUESTS: + //At present HAPPY_GUESTS does not activate window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; } @@ -144,7 +226,7 @@ static void window_cheats_update() __asm mov w, esi w->var_48E++; - widget_invalidate(w->classification, w->number, WIDX_TAB_1); + widget_invalidate(w->classification, w->number, WIDX_TAB_1+w->page); } static void window_cheats_invalidate() @@ -153,9 +235,14 @@ static void window_cheats_invalidate() rct_window *w; __asm mov w, esi - strcpy((char*)0x009BC677, "Cheats"); + rct_widget **widgets = window_cheats_page_widgets[w->page]; + if (w->widgets != widgets) { + w->widgets = widgets; + window_init_scroll_widgets(w); + } + // Set correct active tab for (i = 0; i < 7; i++) w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); @@ -190,7 +277,19 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) if (!(w->disabled_widgets & (1 << WIDX_TAB_2))) { sprite_idx = 5568; if (w->page == WINDOW_CHEATS_PAGE_GUESTS) - sprite_idx += w->var_48E / 4; + sprite_idx += (w->var_48E / 2) % 8; gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_2].left, w->y + w->widgets[WIDX_TAB_2].top); } } + +static void window_cheats_set_page(rct_window *w, int page) +{ + w->page = page; + + w->enabled_widgets = window_cheats_page_enabled_widgets[page]; + + w->event_handlers = window_cheats_page_events[page]; + w->widgets = window_cheats_page_widgets[page]; + + window_invalidate(w); +} \ No newline at end of file From 1efbb600b0c8b016a6e09b9bc368f06bbe7904bc Mon Sep 17 00:00:00 2001 From: RollingStar Date: Fri, 2 May 2014 00:12:44 -0400 Subject: [PATCH 2/9] Clarify "can" into "must". --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4671196629..266984bbaf 100644 --- a/readme.md +++ b/readme.md @@ -49,7 +49,7 @@ The aim is to decompile RollerCoaster Tycoon 2 fully into C so that it can remai 1. Checkout the repository. This can be done using [GitHub Windows](https://windows.github.com/) or [other tools](https://help.github.com/articles/which-remote-url-should-i-use). 2. Download [SDL2 development library for Visual C++]((http://www.libsdl.org/release/SDL2-devel-2.0.3-VC.zip)) and copy it to a new directory called "sdl" in the repository. This directory should contain "include". The path should be something like ```\GitHub\OpenRCT2\sdl\include\```. 3. Open the solution in the projects directory (**openrct2.vcxproj**) with Visual C++. -4. In *rct2.c*, ```GAME_PATH``` can be edited to reflect your RollerCoaster Tycoon 2 installation. Each slash needs to be marked twice, like this: ```C:\\Program Files (x86)\\GOGcom\\RollerCoaster Tycoon 2\\RollerCoaster Tycoon 2 Triple Thrill Pack```. Existing registry keys and the original RCT2 executable are not required. +4. In *rct2.c*, ```GAME_PATH``` **must** be edited to reflect your RollerCoaster Tycoon 2 installation. Each slash needs to be marked twice, like this: ```C:\\Program Files (x86)\\GOGcom\\RollerCoaster Tycoon 2\\RollerCoaster Tycoon 2 Triple Thrill Pack```. Existing registry keys and the original RCT2 executable are not required. 5. [Select the 'Release' configuration](http://msdn.microsoft.com/en-us/library/wx0123s5.aspx) and click Build -> Rebuild Solution. The dropdown menu to enable the 'release' configuration is towards the top of the VS Express window, near the "TEST" menu. 6. Start debugging. Press the "Local Windows Debugger" button with a green "play" icon next to it. If warned about *openrct2.exe* not having debug information, just continue. 7. If the game crashes, you may need to press the red, square button along the top of VS Express (for "stop") to stop the program. From 168df9171a0c1325f86c89e5809ff2df08c3746a Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 2 May 2014 06:59:12 +0100 Subject: [PATCH 3/9] Added seperate mouseup events so that happy cheat works. --- src/window_cheats.c | 68 ++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index 60861bb94f..80b741bc6b 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -45,7 +45,7 @@ static enum WINDOW_CHEATS_WIDGET_IDX { WIDX_TAB_1, WIDX_TAB_2, WIDX_HIGH_MONEY, - WIDX_HAPPY_GUESTS + WIDX_HAPPY_GUESTS = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page }; static rct_widget window_cheats_money_widgets[] = { @@ -66,7 +66,7 @@ static rct_widget window_cheats_guests_widgets[] = { { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2375, 2375 }, // happy guests + { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2376, 2376 }, // happy guests { WIDGETS_END }, }; @@ -76,7 +76,8 @@ static rct_widget *window_cheats_page_widgets[] = { }; static void window_cheats_emptysub() { } -static void window_cheats_mouseup(); +static void window_cheats_money_mouseup(); +static void window_cheats_guests_mouseup(); static void window_cheats_update(); static void window_cheats_invalidate(); static void window_cheats_paint(); @@ -84,7 +85,7 @@ static void window_cheats_set_page(rct_window *w, int page); static uint32 window_cheats_money_events[] = { window_cheats_emptysub, - window_cheats_mouseup, + window_cheats_money_mouseup, window_cheats_emptysub, window_cheats_emptysub, window_cheats_emptysub, @@ -115,7 +116,7 @@ static uint32 window_cheats_money_events[] = { static uint32 window_cheats_guests_events[] = { window_cheats_emptysub, - window_cheats_mouseup, + window_cheats_guests_mouseup, window_cheats_emptysub, window_cheats_emptysub, window_cheats_emptysub, @@ -151,7 +152,7 @@ static uint32 *window_cheats_page_events[] = { static uint32 window_cheats_page_enabled_widgets[] = { (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY), - (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY) //Change to WIDX_HAPPY_GUESTSs when enabled widgets is figured out. + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HAPPY_GUESTS) }; static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); @@ -175,7 +176,33 @@ void window_cheats_open() window->colours[2] = 19; } -static void window_cheats_mouseup() +static void window_cheats_money_mouseup() +{ + int i; + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); + break; + case WIDX_HIGH_MONEY: + i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); + i += 100000; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); + window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); + break; + } +} + +static void window_cheats_guests_mouseup() { int i; short widgetIndex; @@ -194,26 +221,15 @@ static void window_cheats_mouseup() case WIDX_TAB_2: window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; - case WIDX_HIGH_MONEY: - if (w->page == WINDOW_CHEATS_PAGE_MONEY){ - i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); - } - else{ - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - if (peep->type != PEEP_TYPE_GUEST) - continue; - if (peep->var_2A != 0) - continue; - peep->happiness = 255; - } - } - window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); - break; case WIDX_HAPPY_GUESTS: - //At present HAPPY_GUESTS does not activate + for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); + if (peep->type != PEEP_TYPE_GUEST) + continue; + if (peep->var_2A != 0) + continue; + peep->happiness = 255; + } window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; } From a3a8c1248f75a2b0634f217f12b77b38eda3bee5 Mon Sep 17 00:00:00 2001 From: Inseok Lee Date: Fri, 2 May 2014 21:32:44 +0900 Subject: [PATCH 4/9] Implement loading savefile from commandline argument. --- src/rct2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/rct2.c b/src/rct2.c index df687dca0c..e8f5ef2e92 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -191,6 +191,53 @@ void rct2_update() rct2_update_2(); } +void check_cmdline_arg() +{ + if(RCT2_GLOBAL(0x009AC310, uint32) == 0xFFFFFFFF) + return; + + char *arg = RCT2_GLOBAL(0x009AC310, char *); + char processed_arg[255]; + int len, i, j; + int quote = 0; + int last_period = 0; + + RCT2_GLOBAL(0x009AC310, uint32) = 0xFFFFFFFF; + len = strlen(arg); + + for(i = 0, j = 0; i < len; i ++) + { + if(arg[i] == '\"') + { + if(quote) + quote = 0; + else + quote = 1; + continue; + } + if(arg[i] == ' ' && !quote) + break; + if(arg[i] == '.') + last_period = i; + processed_arg[j ++] = arg[i]; + } + processed_arg[j ++] = 0; + + if(!stricmp(processed_arg + last_period, "sv6")) + { + strcpy(0x00141EF68, processed_arg); + RCT2_CALLPROC_EBPSAFE(0x00675E1B); //load_saved_game + } + else if(!stricmp(processed_arg + last_period, "sc6")) + { + //TODO: scenario install + } + else if(!stricmp(processed_arg + last_period, "td6") || !stricmp(processed_arg + last_period, "td4")) + { + //TODO: track design install + } +} + void rct2_update_2() { int tick, tick2; @@ -213,6 +260,7 @@ void rct2_update_2() // TODO: screenshot countdown process + check_cmdline_arg(); // Screens if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) intro_update(); From 8da8519b6f3e19078e6ed77d207f6ab04c984a2b Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Fri, 2 May 2014 21:07:20 +0100 Subject: [PATCH 5/9] Capping money in cheats --- src/window_cheats.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index 8e09e207cc..d04b70c2b4 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -28,6 +28,7 @@ #define WW 200 #define WH 128 +#define CHEATS_MONEY_INCREMENT 10000 enum { WINDOW_CHEATS_PAGE_MONEY, @@ -129,7 +130,13 @@ static void window_cheats_mouseup() break; case WIDX_HIGH_MONEY: i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; + + if (i < INT_MAX - CHEATS_MONEY_INCREMENT) { + i += CHEATS_MONEY_INCREMENT; + } + else { + i = INT_MAX; + } RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); From ca81c5e06d6281fbec485b85552de93931334307 Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Fri, 2 May 2014 21:07:48 +0100 Subject: [PATCH 6/9] Adding enum with peep states --- src/peep.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/peep.h b/src/peep.h index 62f8b75602..6f0af308d7 100644 --- a/src/peep.h +++ b/src/peep.h @@ -38,6 +38,32 @@ enum PEEP_THOUGHT_TYPE { PEEP_THOUGHT_TYPE_NONE = 255 }; +enum PEEP_STATE { + + PEEP_STATE_QUEUING_FRONT = 2, + PEEP_STATE_ON_RIDE = 3, + PEEP_STATE_LEAVING_RIDE = 4, + PEEP_STATE_WALKING = 5, + PEEP_STATE_QUEUING = 6, + PEEP_STATE_ENTERING_RIDE = 7, + PEEP_STATE_SITTING = 8, + PEEP_STATE_PICKED = 9, + PEEP_STATE_PATROLLING = 10, // Not sure + PEEP_STATE_MOPING = 11, + PEEP_STATE_SWEEPING = 12, + PEEP_STATE_ENTERING_PARK = 13, + PEEP_STATE_LEAVING_PARK = 14, + PEEP_STATE_ANSWERING = 15, + PEEP_STATE_FIXING = 16, + PEEP_STATE_BUYING = 17, + PEEP_STATE_WATCHING = 18, + PEEP_STATE_EMPTYING_BIN = 19, + + PEEP_STATE_WATERING = 21, + PEEP_STATE_HEADING_TO_INSPECTION = 22, + PEEP_STATE_INSPECTING = 23 +}; + typedef struct { uint8 type; uint8 item; From c87ec51c28672dc9cbd6c0959869fd3495e78b56 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 2 May 2014 21:54:19 +0100 Subject: [PATCH 7/9] Labelled some of the peep financial offsets. --- src/peep.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/peep.h b/src/peep.h index 13b4343346..7b061639d3 100644 --- a/src/peep.h +++ b/src/peep.h @@ -101,8 +101,17 @@ typedef struct { uint16 pad_C4; uint8 var_C6; uint8 pad_C7; - uint32 var_C8; - uint8 pad_CC[0x2A]; + uint32 var_C8; //Bit 11 tracking, Bit 8 leaving the park + uint8 var_CC; //Bit 0 mad, bit 1 Ice Cream + uint8 pad_CD[0x18]; + uint16 paid_to_enter; //0xE5 Number is /10 when displayed + uint16 paid_on_rides; //0xE7 Number is /10 when displayed + uint16 paid_on_food; //0xE9 Number is /10 when displayed + uint16 paid_on_souvenirs; //0xEB Number is /10 when displayed + uint8 no_of_food; //0xEC + uint8 no_of_drinks; //0xED + uint8 no_of_souvenirs; //0xEE + uint8 pad_EF[0x07]; uint8 balloon_colour; // 0xF6 uint8 umbrella_colour; // 0xF7 uint8 hat_colour; // 0xF8 From af5ef5e75d4adae33582ecfe13462687a7c16cf7 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:21:08 +0100 Subject: [PATCH 8/9] 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 From 9e3fedad59cbf1955a57e161d7c6ac016eb0a9a8 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:34:14 +0100 Subject: [PATCH 9/9] add more peep fields --- src/peep.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/peep.h b/src/peep.h index 92790af4c2..6bd275f025 100644 --- a/src/peep.h +++ b/src/peep.h @@ -120,27 +120,31 @@ typedef struct { uint8 current_train; // 0x6B uint8 current_car; // 0x6C uint8 current_seat; // 0x6D - uint8 pad_6E[0x2E]; + uint8 pad_6E[0x0E]; + uint8 rides_been_on[32]; // 0x7C uint32 id; // 0x9C - uint8 pad_A0[0x10]; + sint32 cash_in_pocket; // 0xA0 + sint32 cash_spent; // 0xA4 + uint8 pad_A8[8]; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 uint16 pad_C4; uint8 var_C6; uint8 pad_C7; - uint32 var_C8; //Bit 11 tracking, Bit 8 leaving the park - uint8 var_CC; //Bit 0 mad, bit 1 Ice Cream + uint32 var_C8; // Bit 11 tracking, Bit 8 leaving the park + uint8 var_CC; // Bit 0 mad, bit 1 Ice Cream uint8 pad_CD[0x18]; - uint16 paid_to_enter; //0xE5 Number is /10 when displayed - uint16 paid_on_rides; //0xE7 Number is /10 when displayed - uint16 paid_on_food; //0xE9 Number is /10 when displayed - uint16 paid_on_souvenirs; //0xEB Number is /10 when displayed - uint8 no_of_food; //0xEC - uint8 no_of_drinks; //0xED - uint8 no_of_souvenirs; //0xEE + uint16 paid_to_enter; // 0xE5 + uint16 paid_on_rides; // 0xE7 + uint16 paid_on_food; // 0xE9 + uint16 paid_on_souvenirs; // 0xEB + uint8 no_of_food; // 0xEC + uint8 no_of_drinks; // 0xED + uint8 no_of_souvenirs; // 0xEE uint8 pad_EF[0x07]; uint8 balloon_colour; // 0xF6 uint8 umbrella_colour; // 0xF7 uint8 hat_colour; // 0xF8 + uint8 favourite_ride; // 0xF9 } rct_peep; int peep_get_staff_count();