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. diff --git a/src/peep.h b/src/peep.h index f78b5d1f43..13b4343346 100644 --- a/src/peep.h +++ b/src/peep.h @@ -87,7 +87,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/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(); diff --git a/src/window_cheats.c b/src/window_cheats.c index 8e09e207cc..80b741bc6b 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 = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page }; -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,15 +59,33 @@ 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, 2376, 2376 }, // 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_money_mouseup(); +static void window_cheats_guests_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_money_mouseup, window_cheats_emptysub, window_cheats_emptysub, window_cheats_emptysub, @@ -92,6 +114,47 @@ static uint32 window_cheats_events[] = { window_cheats_emptysub }; +static uint32 window_cheats_guests_events[] = { + window_cheats_emptysub, + window_cheats_guests_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_HAPPY_GUESTS) +}; + static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); void window_cheats_open() @@ -103,18 +166,17 @@ 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; window->colours[2] = 19; } -static void window_cheats_mouseup() +static void window_cheats_money_mouseup() { int i; short widgetIndex; @@ -127,11 +189,47 @@ static void window_cheats_mouseup() 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; + rct_window *w; + + __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_HAPPY_GUESTS: + 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; } @@ -144,7 +242,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 +251,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 +293,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