diff --git a/src/climate.c b/src/climate.c index 37bae75fda..ca0c832038 100644 --- a/src/climate.c +++ b/src/climate.c @@ -283,9 +283,11 @@ static void climate_update_thunder() _thunderStereoEcho = 1; } } else { - _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; - int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16; - climate_play_thunder(0, _thunderSoundId, 0, pan); + if (_thunderStatus[0] == THUNDER_STATUS_NULL){ + _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; + int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16; + climate_play_thunder(0, _thunderSoundId, 0, pan); + } } } diff --git a/src/editor.c b/src/editor.c index f9f2a43c70..d70af6bea9 100644 --- a/src/editor.c +++ b/src/editor.c @@ -32,6 +32,7 @@ #include "viewport.h" #include "finance.h" #include "audio.h" +#include "sprite.h" #include "string_ids.h" static void set_all_land_owned(); @@ -53,7 +54,7 @@ void editor_load() RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); // sprites_init + reset_sprite_list(); ride_init_all(); window_guest_list_init_vars_a(); sub_6BD3A4(); @@ -102,7 +103,7 @@ void trackdesigner_load() RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); // reset_sprites + reset_sprite_list(); ride_init_all(); window_guest_list_init_vars_a(); sub_6BD3A4(); @@ -140,7 +141,7 @@ void trackmanager_load() RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); // reset_sprites + reset_sprite_list(); ride_init_all(); window_guest_list_init_vars_a(); sub_6BD3A4(); diff --git a/src/game.c b/src/game.c index a5327e18c8..5da9973f5d 100644 --- a/src/game.c +++ b/src/game.c @@ -32,6 +32,7 @@ #include "sawyercoding.h" #include "scenario.h" #include "screenshot.h" +#include "sprite.h" #include "string_ids.h" #include "title.h" #include "tutorial.h" @@ -1581,7 +1582,7 @@ int game_load_save() // The rest is the same as in scenario load and play RCT2_CALLPROC_EBPSAFE(0x006A9FC0); map_update_tile_pointers(); - RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; viewport_init_all(); game_create_windows(); @@ -1607,7 +1608,7 @@ int game_load_save() mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1; window_invalidate(mainWindow); - RCT2_CALLPROC_EBPSAFE(0x0069E9A7); + sub_0x0069E9A7(); RCT2_CALLPROC_EBPSAFE(0x006DFEE4); window_new_ride_init_vars(); RCT2_GLOBAL(0x009DEB7C, uint16) = 0; @@ -1619,6 +1620,20 @@ int game_load_save() return 1; } +/* + * + * rct2: 0x0069E9A7 + */ +void sub_0x0069E9A7(){ + //RCT2_CALLPROC_EBPSAFE(0x0069E9A7); + //return; + for (rct_sprite* spr = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; ++spr){ + if (spr->unknown.sprite_identifier != 0xFF){ + RCT2_CALLPROC_X(0x0069E9D3, spr->unknown.x, 0, spr->unknown.y, spr->unknown.z, (int)spr, 0, 0); + } + } +} + /** * * rct2: 0x0066DBB7 diff --git a/src/game.h b/src/game.h index 4b1bd42d4c..47d7f51ceb 100644 --- a/src/game.h +++ b/src/game.h @@ -24,6 +24,7 @@ void game_create_windows(); void game_update(); void game_logic_update(); +void sub_0x0069E9A7(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); diff --git a/src/gfx.h b/src/gfx.h index d2e3eeb433..f82ae27d02 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -70,6 +70,7 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour); void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si); void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y); +void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y); void gfx_transpose_palette(int pal, unsigned char product); diff --git a/src/peep.c b/src/peep.c index 7042c04c5d..437bc56c3f 100644 --- a/src/peep.c +++ b/src/peep.c @@ -103,7 +103,7 @@ static void peep_update(rct_peep *peep) peep->thoughts[i].var_2++; ebp--; } - } else if (peep->thoughts[i].var_2 >= 0) { + } else if (peep->thoughts[i].var_2 > 1) { if (++peep->thoughts[i].var_3 > 255) { if (++peep->thoughts[i].var_3 >= 28) { peep->var_45 |= 1; diff --git a/src/peep.h b/src/peep.h index 74dfd3f6b8..2ddc702b7d 100644 --- a/src/peep.h +++ b/src/peep.h @@ -200,7 +200,7 @@ enum PEEP_STATE { PEEP_STATE_SITTING = 8, PEEP_STATE_PICKED = 9, PEEP_STATE_PATROLLING = 10, // Not sure - PEEP_STATE_MOPING = 11, + PEEP_STATE_MOWING = 11, PEEP_STATE_SWEEPING = 12, PEEP_STATE_ENTERING_PARK = 13, PEEP_STATE_LEAVING_PARK = 14, @@ -316,10 +316,10 @@ typedef struct { uint8 pad_01; uint16 pad_02; uint16 next; // 0x04 - uint16 pad_06; + uint16 previous; // 0x06 uint8 var_08; uint8 pad_09; - sint16 var_0A; + uint16 sprite_index; // 0x0A uint16 var_0C; sint16 x; // 0x0E sint16 y; // 0x10 diff --git a/src/rct2.c b/src/rct2.c index d532be976f..559fced6bf 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -33,6 +33,7 @@ #include "climate.h" #include "config.h" #include "date.h" +#include "editor.h" #include "game.h" #include "gfx.h" #include "intro.h" @@ -47,6 +48,7 @@ #include "title.h" #include "track.h" #include "viewport.h" +#include "sprite.h" typedef struct tm tm_t; @@ -167,10 +169,10 @@ void rct2_init() get_local_time(); reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); //Sprite list reset/load + reset_sprite_list(); ride_init_all(); window_guest_list_init_vars_a(); - RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep? + sub_6BD3A4();// RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep? map_init(); park_init(); RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows() diff --git a/src/scenario.c b/src/scenario.c index 6dc29fa1bf..d9aedb7fc4 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -154,7 +154,7 @@ void scenario_load(const char *path) RCT2_CALLPROC_EBPSAFE(0x006A9FC0); map_update_tile_pointers(); - RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); return; } @@ -214,7 +214,7 @@ void scenario_load_and_play(const rct_scenario_basic *scenario) mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1; window_invalidate(mainWindow); - RCT2_CALLPROC_EBPSAFE(0x0069E9A7); + sub_0x0069E9A7();// RCT2_CALLPROC_EBPSAFE(0x0069E9A7); window_new_ride_init_vars(); // Set the scenario pseduo-random seeds diff --git a/src/sprite.c b/src/sprite.c index 37157e98b6..b947a81f72 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -19,6 +19,7 @@ *****************************************************************************/ #include "addresses.h" +#include #include "sprite.h" /** @@ -28,4 +29,77 @@ void create_balloon(int x, int y, int z, int colour) { RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0); +} + +/* + * + * rct2: 0x0069EB13 + */ +void reset_sprite_list(){ + RCT2_GLOBAL(0x1388698, uint16) = 0; + memset((rct_sprite*)RCT2_ADDRESS_SPRITE_LIST, 0, sizeof(rct_sprite)* 0x2710); + + for (int i = 0; i < 6; ++i){ + RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[i] = -1; + RCT2_ADDRESS(0x13573C8, uint16)[i] = 0; + } + + rct_sprite* previous_spr = (rct_sprite*)SPRITE_INDEX_NULL; + + rct_sprite* spr = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); + for (int i = 0; i < 0x2710; ++i){ + spr->unknown.sprite_identifier = 0xFF; + spr->unknown.sprite_index = i; + spr->unknown.next = SPRITE_INDEX_NULL; + spr->unknown.var_08 = 0; + + if (previous_spr != (rct_sprite*)SPRITE_INDEX_NULL){ + spr->unknown.previous = previous_spr->unknown.sprite_index; + previous_spr->unknown.next = i; + } + else{ + spr->unknown.previous = SPRITE_INDEX_NULL; + RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16) = i; + } + previous_spr = spr; + spr++; + } + + RCT2_GLOBAL(0x13573C8, uint16) = 0x2710; + + //RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + reset_0x69EBE4(); +} + +/* + * + * rct: 0x0069EBE4 + * This function looks as though it sets some sort of order for sprites. + * Sprites can share thier position if this is the case. + */ +void reset_0x69EBE4(){ + //RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + //return; + memset((uint16*)0xF1EF60, -1, 0x10001*2); + + rct_sprite* spr = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); + for (; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; spr++){ + + if (spr->unknown.sprite_identifier != 0xFF){ + uint32 edi = spr->unknown.x; + if ((uint16)(spr->unknown.x) == SPRITE_LOCATION_NULL){ + edi = 0x10000; + } + else{ + int ecx = spr->unknown.y; + ecx >>= 5; + edi &= 0x1FE0; + edi <<= 3; + edi |= ecx; + } + uint16 ax = RCT2_ADDRESS(0xF1EF60,uint16)[edi]; + RCT2_ADDRESS(0xF1EF60,uint16)[edi] = spr->unknown.sprite_index; + spr->unknown.var_02 = ax; + } + } } \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index 3edb1d5e6f..d2c36b6371 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -32,9 +32,13 @@ typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01; - uint16 pad_02; + uint16 var_02; uint16 next; // 0x04 - uint8 pad_06[0x08]; + uint16 previous; // 0x06 + uint8 var_08; + uint8 pad_09; + uint16 sprite_index; // 0x0A + uint8 pad_0C[2]; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 @@ -43,7 +47,11 @@ typedef struct { typedef struct { uint32 pad_00; uint16 next; // 0x04 - uint8 pad_06[0x1E]; + uint16 previous; // 0x06 + uint8 var_08; + uint8 pad_09; + uint16 sprite_index; // 0x0A + uint8 pad_0B[0x19]; uint32 var_24; } rct_litter; @@ -60,5 +68,7 @@ typedef union { } rct_sprite; void create_balloon(int x, int y, int z, int colour); +void reset_sprite_list(); +void reset_0x69EBE4(); #endif diff --git a/src/string_ids.h b/src/string_ids.h index 83d86b7926..a13bbe7d2d 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -299,9 +299,29 @@ enum { STR_FOOTPATH_TIP = 1424, STR_FREE = 1430, - + STR_WALKING = 1431, + STR_HEADING_FOR = 1432, + STR_QUEUING_FOR = 1433, + STR_DROWNING = 1434, + STR_ON_RIDE = 1435, + STR_IN_RIDE = 1436, + STR_AT_RIDE = 1437, + STR_SITTING = 1438, + STR_SELECT_LOCATION = 1439, + STR_MOWING_GRASS = 1440, + STR_SWEEPING_FOOTPATH = 1441, + STR_EMPTYING_LITTER_BIN = 1442, + STR_WATERING_GARDENS = 1443, + STR_WATCHING_RIDE = 1444, + STR_WATCHING_CONSTRUCTION_OF = 1445, + STR_LOOKING_AT_SCENERY = 1446, + STR_LEAVING_PARK = 1447, + STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED = 1448, + STR_GUESTS = 1463, - + + STR_THOUGHT_START = 1480, + STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655, STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP = 1656, @@ -326,6 +346,11 @@ enum { STR_OFF = 1775, STR_ON = 1776, STR_MUSIC = 1777, + + STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL = 1792, + STR_HEADING_TO_RIDE_FOR_INSPECTION = 1793, + STR_FIXING_RIDE = 1794, + STR_ANSWERING_RADIO_CALL = 1795, STR_ACTIONS = 1814, STR_THOUGHTS = STR_ACTIONS + 1, @@ -357,7 +382,9 @@ enum { STR_GUESTS_FAVOURITE_PLURAL_LABEL = 1843, STR_RIDE_LIST_INFORMATION_TYPE_TIP = 1844, STR_NUM_GUESTS = 1846, - + + STR_INSPECTING_RIDE = 1886, + STR_BUILD_RIDE_TIP = 1895, STR_START_NEW_GAME_TIP = 1921, @@ -374,6 +401,11 @@ enum { STR_MARKETING = 1953, STR_RESEARCH_FUNDING = 1954, + STR_ITEM_START = 1988, + STR_ITEM_SINGULAR_START = 2044, + STR_ITEM2_START = 2090, + STR_ITEM2_SINGULAR_START = 2134, + STR_CELSIUS_VALUE = 2216, STR_FAHRENHEIT_VALUE = 2217, diff --git a/src/title.c b/src/title.c index fccce376a4..06a451667e 100644 --- a/src/title.c +++ b/src/title.c @@ -23,6 +23,7 @@ #include #include "addresses.h" #include "config.h" +#include "climate.h" #include "date.h" #include "game.h" #include "gfx.h" @@ -33,6 +34,7 @@ #include "rct2.h" #include "ride.h" #include "scenario.h" +#include "sprite.h" #include "string_ids.h" #include "viewport.h" #include "editor.h" @@ -95,20 +97,20 @@ void title_load() reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); + reset_sprite_list(); ride_init_all(); window_guest_list_init_vars_a(); - RCT2_CALLPROC_EBPSAFE(0x006BD3A4); + sub_6BD3A4(); // RCT2_CALLPROC_EBPSAFE(0x006BD3A4); map_init(); park_init(); date_reset(); - RCT2_CALLPROC_X(0x006C45ED, 0, 0, 0, 0, 0, 0, 0); + climate_reset(CLIMATE_COOL_AND_WET); RCT2_CALLPROC_EBPSAFE(0x006DFEE4); window_new_ride_init_vars(); window_guest_list_init_vars_b(); window_staff_init_vars(); - RCT2_CALLPROC_EBPSAFE(0x0068AFFD); - RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + map_update_tile_pointers(); //RCT2_CALLPROC_EBPSAFE(0x0068AFFD); + reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); viewport_init_all(); news_item_init_queue(); title_create_windows(); @@ -191,7 +193,7 @@ static void title_update_showcase() } window_invalidate(w); - RCT2_CALLPROC_EBPSAFE(0x0069E9A7); + sub_0x0069E9A7();// RCT2_CALLPROC_EBPSAFE(0x0069E9A7); window_new_ride_init_vars(); RCT2_CALLPROC_EBPSAFE(0x00684AC3); RCT2_CALLPROC_EBPSAFE(0x006DFEE4); diff --git a/src/vehicle.h b/src/vehicle.h index 3bddf738fc..9451bdb8c8 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -27,7 +27,11 @@ typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01[0x03]; uint16 next; // 0x04 - uint8 pad_06[0x08]; + uint16 previous; // 0x06 + uint8 var_08; + uint8 pad_09; + uint16 sprite_index; // 0x0A + uint8 pad_0C[2]; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 diff --git a/src/widget.c b/src/widget.c index f686f1bd26..d69b239cba 100644 --- a/src/widget.c +++ b/src/widget.c @@ -22,6 +22,7 @@ #include #include #include "addresses.h" +#include "gfx.h" #include "sprites.h" #include "widget.h" #include "window.h" @@ -914,21 +915,23 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI // Draw greyed out (light border bottom right shadow) colour = w->colours[widget->colour]; colour = RCT2_ADDRESS(0x00141FC4A, uint8)[(colour & 0x7F) * 8] & 0xFF; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74; - memset((void*)0x009DED74, colour, 256); - RCT2_GLOBAL(0x009DED74, uint8) = 0; + + uint8 palette[256]; + memset(palette, colour, 256); + palette[0] = 0; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; image &= 0x7FFFF; - RCT2_CALLPROC_X(0x0067A46E, 0, image, l + 1, t + 1, 0, (int)dpi, 0); + gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l + 1, t + 1, palette, NULL); // Draw greyed out (dark) colour = w->colours[widget->colour]; colour = RCT2_ADDRESS(0x00141FC48, uint8)[(colour & 0x7F) * 8] & 0xFF; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74; - memset((void*)0x009DED74, colour, 256); - RCT2_GLOBAL(0x009DED74, uint8) = 0; + memset(palette, colour, 256); + palette[0] = 0; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - RCT2_CALLPROC_X(0x0067A46E, 0, image, l, t, 0, (int)dpi, 0); + gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l, t, palette, NULL); } else { if (image & 0x80000000) { // ? diff --git a/src/window.c b/src/window.c index adc300a31c..541601a529 100644 --- a/src/window.c +++ b/src/window.c @@ -336,9 +336,8 @@ static void window_all_wheel_input() rct_window *window_create(int x, int y, int width, int height, uint32 *event_handlers, rct_windowclass cls, uint16 flags) { rct_window *w; - // Check if there are any window slots left - if (RCT2_NEW_WINDOW == &(RCT2_FIRST_WINDOW[12])) { + if (RCT2_NEW_WINDOW >= &(RCT2_FIRST_WINDOW[11])) { // Close least recently used window for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++) if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT | WF_9))) diff --git a/src/window_cheats.c b/src/window_cheats.c index 3c90ca597a..f95eb299f2 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -48,6 +48,7 @@ enum WINDOW_CHEATS_WIDGET_IDX { WIDX_TAB_1, WIDX_TAB_2, WIDX_HIGH_MONEY, + WIDX_PARK_ENTRANCE_FEE, WIDX_HAPPY_GUESTS = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page }; @@ -58,7 +59,8 @@ static rct_widget window_cheats_money_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, 67, 83, STR_VERY_HIGH, STR_VERY_HIGH}, // high money + { WWT_CLOSEBOX, 1, 4, 74, 67, 83, STR_VERY_HIGH, STR_VERY_HIGH}, // high money + { WWT_CLOSEBOX, 1, 4, 74, 107, 123, STR_FREE, STR_FREE}, //Park Entrance Fee Toggle { WIDGETS_END }, }; @@ -154,7 +156,7 @@ static void* 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) | (1 << WIDX_PARK_ENTRANCE_FEE), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HAPPY_GUESTS) }; @@ -218,6 +220,12 @@ static void window_cheats_money_mouseup() RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; + case WIDX_PARK_ENTRANCE_FEE: + RCT2_GLOBAL(0x13573E5, uint32) ^= 0x020; + if (!(RCT2_GLOBAL(0x13573E5, uint32) & 0x020) ) w->widgets[widgetIndex].image = 2010; + else w->widgets[widgetIndex].image = STR_FREE; + window_invalidate_by_id(0x40 | WC_PARK_INFORMATION, 0); + break; } } @@ -324,6 +332,10 @@ static void window_cheats_paint() sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases your money by 1,000."); // Draw shadow gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50); + + sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Toggle between Free and Paid Entry"); + // Draw shadow + gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 90); } else if (w->page == WINDOW_CHEATS_PAGE_GUESTS){ char buffer[256]; diff --git a/src/window_dropdown.c b/src/window_dropdown.c index 4b552e7d80..f9b609d453 100644 --- a/src/window_dropdown.c +++ b/src/window_dropdown.c @@ -53,6 +53,7 @@ int _dropdown_highlighted_index; uint16 gDropdownItemsFormat[64]; sint64 gDropdownItemsArgs[64]; +// Replaces 0x009DED38 uint32 gDropdownItemsChecked; static void window_dropdown_emptysub() { } diff --git a/src/window_guest_list.c b/src/window_guest_list.c index 14fe8d13a7..bea5fa5863 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -19,12 +19,14 @@ *****************************************************************************/ #include +#include #include "addresses.h" #include "game.h" #include "peep.h" #include "string_ids.h" #include "sprite.h" #include "sprites.h" +#include "ride.h" #include "widget.h" #include "window.h" #include "window_dropdown.h" @@ -132,7 +134,9 @@ static int window_guest_list_is_peep_in_filter(rct_peep* peep); static void window_guest_list_find_groups(); static int get_guest_face_sprite_small(rct_peep *peep); static int get_guest_face_sprite_large(rct_peep *peep); - +static void get_arguments_from_peep(rct_peep *peep, uint32 *argument_1, uint32* argument_2); +void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2); +void get_arguments_from_action(rct_peep* peep, uint32* argument_1, uint32* argument_2); /** * * rct2: 0x006992E3 @@ -277,11 +281,16 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge gDropdownItemsFormat[i] = 1142; gDropdownItemsArgs[i] = STR_PAGE_1 + i; } - RCT2_GLOBAL(0x009DED38, uint32) |= (1 << _window_guest_list_selected_view); + gDropdownItemsChecked = (1 << _window_guest_list_selected_view); break; case WIDX_INFO_TYPE_DROPDOWN_BUTTON: widget = &w->widgets[widgetIndex - 1]; + for (i = 0; i < 2; i++) { + gDropdownItemsFormat[i] = 1142; + gDropdownItemsArgs[i] = STR_ACTIONS + i; + } + window_dropdown_show_text_custom_width( w->x + widget->left, w->y + widget->top, @@ -292,11 +301,7 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge widget->right - widget->left - 3 ); - for (i = 0; i < 2; i++) { - gDropdownItemsFormat[i] = 1142; - gDropdownItemsArgs[i] = STR_ACTIONS + i; - } - RCT2_GLOBAL(0x009DED38, uint32) |= (1 << _window_guest_list_selected_view); + gDropdownItemsChecked = (1 << _window_guest_list_selected_view); break; } } @@ -653,6 +658,7 @@ static void window_guest_list_scrollpaint() rct_drawpixelinfo *dpi; rct_peep *peep; rct_peep_thought *thought; + uint32 argument_1, argument_2; #ifdef _MSC_VER __asm mov w, esi @@ -715,14 +721,11 @@ static void window_guest_list_scrollpaint() gfx_draw_sprite(dpi, 5129, 112, y); // Action - eax = peep->var_0A; - RCT2_CALLFUNC_X(0x00698B0D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - ebx &= 0xFFFF; - ecx &= 0xFFFF; - RCT2_GLOBAL(0x013CE952, uint16) = ebx; - RCT2_GLOBAL(0x013CE952 + 2, uint16) = ecx; - RCT2_GLOBAL(0x013CE952 + 4, uint32) = edx; + get_arguments_from_action(peep, &argument_1, &argument_2); + + RCT2_GLOBAL(0x013CE952, uint32) = argument_1; + RCT2_GLOBAL(0x013CE952 + 4, uint32) = argument_2; gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 133, y - 1, 314); break; case VIEW_THOUGHTS: @@ -735,15 +738,11 @@ static void window_guest_list_scrollpaint() continue; if (thought->var_2 > 5) break; + + get_arguments_from_thought(peep->thoughts[j], &argument_1, &argument_2); - ebx = thought->type; - eax = thought->item; - RCT2_CALLFUNC_X(0x00698342, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - ebx &= 0xFFFF; - - RCT2_GLOBAL(0x013CE952, uint16) = ebx; - RCT2_GLOBAL(0x013CE952 + 2, uint32) = *((uint32*)esi); - RCT2_GLOBAL(0x013CE952 + 6, uint16) = *((uint16*)(esi + 4)); + RCT2_GLOBAL(0x013CE952, uint32) = argument_1; + RCT2_GLOBAL(0x013CE952 + 4, uint32) = argument_2; gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 118, y - 1, 329); break; } @@ -777,11 +776,10 @@ static void window_guest_list_scrollpaint() // Draw guest faces numGuests = _window_guest_list_groups_num_guests[i]; for (j = 0; j < 56 && j < numGuests; j++) - gfx_draw_sprite(dpi, _window_guest_list_groups_guest_faces[numGuests * 56 + j] + 5486, j * 8, y + 9); + gfx_draw_sprite(dpi, _window_guest_list_groups_guest_faces[i * 56 + j] + 5486, j * 8, y + 9); // Draw action - RCT2_GLOBAL(0x013CE952, uint16) = _window_guest_list_groups_argument_1[i] & 0xFFFF; - RCT2_GLOBAL(0x013CE952 + 2, uint16) = _window_guest_list_groups_argument_1[i] >> 16; + RCT2_GLOBAL(0x013CE952, uint32) = _window_guest_list_groups_argument_1[i]; RCT2_GLOBAL(0x013CE952 + 4, uint32) = _window_guest_list_groups_argument_2[i]; RCT2_GLOBAL(0x013CE952 + 10, uint32) = numGuests; gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 0, y - 1, 414); @@ -796,68 +794,226 @@ static void window_guest_list_scrollpaint() } } + /** - * + * returns 0 for in filter and 1 for not in filter * rct2: 0x0069B865 */ static int window_guest_list_is_peep_in_filter(rct_peep* peep) { - int eax, ebx, ecx, edx, esi, edi, ebp; char temp; temp = _window_guest_list_selected_view; _window_guest_list_selected_view = _window_guest_list_selected_filter; - - esi = (int)peep; - RCT2_CALLFUNC_X(0x0069B7EA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - ebx &= 0xFFFF; + int argument1, argument2; + get_arguments_from_peep(peep, &argument1, &argument2); _window_guest_list_selected_view = temp; - eax = (RCT2_GLOBAL(0x013CE952, uint16) << 16) | ebx; if (((RCT2_GLOBAL(0x00F1EDF6, uint32) >> 16) & 0xFFFF) == 0xFFFF && _window_guest_list_selected_filter == 1) - eax |= 0xFFFF; + argument1 |= 0xFFFF; - if (eax == RCT2_GLOBAL(0x00F1EDF6, uint32) && RCT2_GLOBAL(0x013CE954, uint32) == RCT2_GLOBAL(0x00F1EDFA, uint32)) + if (argument1 == RCT2_GLOBAL(0x00F1EDF6, uint32) && argument2 == RCT2_GLOBAL(0x00F1EDFA, uint32)) return 0; return 1; } -static int sub_69B7EA(rct_peep *peep, int *outEAX) -{ - int eax, ebx, ecx, edx, esi, edi, ebp; +/** + * rct2: 0x00698342 + * thought.item (eax) + * thought.type (ebx) + * argument_1 (esi & ebx) + * argument_2 (esi+2) + */ +void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2){ + int esi = 0x9AC86C; + if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 1){ + rct_ride* ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST,rct_ride)[thought.item]); + esi = &(ride->var_04A); + } + else if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 2){ + if (thought.item < 0x20){ + RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM_START; + } + else{ + RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM2_START; + } + } + else if ((RCT2_ADDRESS(0x981DB1, uint16)[thought.type] & 0xFF) & 4){ + if (thought.item < 0x20){ + RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM_SINGULAR_START; + } + else + { + RCT2_GLOBAL(0x9AC86C, uint16) = thought.item + STR_ITEM2_SINGULAR_START; + } + } + else{ + esi = 0x9AC864; //No thought? + } + *argument_1 = ((thought.type + STR_THOUGHT_START) & 0xFFFF) | (*((uint16*)esi) << 16); + *argument_2 = *((uint32*)(esi+2)); //Always 0 apart from on rides? +} + +/** +* rct2: 0x00698B0D +* peep.sprite_index (eax) +* thought.type (ebx) +* argument_1 (ecx & ebx) +* argument_2 (edx) +*/ +void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argument_2){ + rct_ride ride; + + switch (peep->state){ + case 0: + *argument_1 = peep->var_71 == 0xB ? STR_DROWNING : STR_WALKING; + *argument_2 = 0; + break; + case 1: + *argument_1 = STR_WALKING; + *argument_2 = 0; + break; + case PEEP_STATE_ON_RIDE: + case PEEP_STATE_LEAVING_RIDE: + case PEEP_STATE_ENTERING_RIDE: + *argument_1 = STR_ON_RIDE; + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride.type*8, uint32)& 0x400000){ + *argument_1 = STR_IN_RIDE; + } + *argument_1 |= (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_BUYING: + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_AT_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_WALKING: + case 0x14: + if (peep->var_C5 != 0xFF){ + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->var_C5]; + *argument_1 = STR_HEADING_FOR | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + } + else{ + *argument_1 = peep->flags & 1 ? STR_LEAVING_PARK : STR_WALKING; + *argument_2 = 0; + } + break; + case PEEP_STATE_QUEUING_FRONT: + case PEEP_STATE_QUEUING: + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_QUEUING_FOR | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_SITTING: + *argument_1 = STR_SITTING; + *argument_2 = 0; + break; + case PEEP_STATE_WATCHING: + if (peep->current_ride != 0xFF){ + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + if (peep->current_seat & 0x1) + *argument_1 = STR_WATCHING_CONSTRUCTION_OF | (ride.var_04A << 16); + else + *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); + } + else{ + *argument_1 = peep->current_seat & 0x1 ? STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED : STR_LOOKING_AT_SCENERY; + *argument_2 = 0; + } + break; + case PEEP_STATE_PICKED: + *argument_1 = STR_SELECT_LOCATION; + *argument_2 = 0; + break; + case PEEP_STATE_PATROLLING: + case PEEP_STATE_ENTERING_PARK: + case PEEP_STATE_LEAVING_PARK: + *argument_1 = STR_WALKING; + *argument_2 = 0; + break; + case PEEP_STATE_MOWING: + *argument_1 = STR_MOWING_GRASS; + *argument_2 = 0; + break; + case PEEP_STATE_SWEEPING: + *argument_1 = STR_SWEEPING_FOOTPATH; + *argument_2 = 0; + break; + case PEEP_STATE_WATERING: + *argument_1 = STR_WATERING_GARDENS; + *argument_2 = 0; + break; + case PEEP_STATE_EMPTYING_BIN: + *argument_1 = STR_EMPTYING_LITTER_BIN; + *argument_2 = 0; + break; + case PEEP_STATE_ANSWERING: + if (peep->pad_2C == 0){ + *argument_1 = STR_WALKING; + *argument_2 = 0; + } + else if (peep->pad_2C == 1){ + *argument_1 = STR_ANSWERING_RADIO_CALL; + *argument_2 = 0; + } + else{ + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + } + break; + case PEEP_STATE_FIXING: + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_FIXING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_HEADING_TO_INSPECTION: + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_HEADING_TO_RIDE_FOR_INSPECTION | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_INSPECTING: + ride = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]; + *argument_1 = STR_INSPECTING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + } + +} + + +/** + * rct2:0x0069B7EA + * Calculates a hash value (arguments) for comparing peep actions/thoughts + * peep (esi) + * argument_1 (0x013CE952) + * argument_2 (0x013CE954) + */ +static void get_arguments_from_peep(rct_peep *peep, uint32 *argument_1, uint32* argument_2) +{ switch (_window_guest_list_selected_view) { case VIEW_ACTIONS: - eax = peep->var_0A; - RCT2_CALLFUNC_X(0x00698B0D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - RCT2_GLOBAL(0x013CE952, uint16) = ecx & 0xFFFF; - RCT2_GLOBAL(0x013CE952 + 2, uint32) = edx; - - *outEAX = eax; - return ebx & 0xFFFF; + get_arguments_from_action(peep, argument_1, argument_2); + break; case VIEW_THOUGHTS: if (peep->thoughts[0].var_2 <= 5) { - eax = peep->thoughts[0].item; - ebx = peep->thoughts[0].type; if (peep->thoughts[0].type != PEEP_THOUGHT_TYPE_NONE) { - RCT2_CALLFUNC_X(0x00698342, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - RCT2_GLOBAL(0x013CE952, uint16) = *((uint16*)esi); - RCT2_GLOBAL(0x013CE952 + 2, uint32) = *((uint32*)(esi + 2)); - - *outEAX = eax; - return ebx & 0xFFFF; + get_arguments_from_thought(peep->thoughts[0], argument_1, argument_2); + break; } } - - RCT2_GLOBAL(0x013CE952, uint16) = 0; - RCT2_GLOBAL(0x013CE952 + 2, uint32) = 0; - - *outEAX = 0; - return 0; + default: + *argument_1 = 0; + *argument_2 = 0; } - - return 0; + return; } /** @@ -894,16 +1050,15 @@ static void window_guest_list_find_groups() if (groupIndex >= 240) break; - int ax = peep->var_0A; + int ax = peep->sprite_index; _window_guest_list_num_groups++; _window_guest_list_groups_num_guests[groupIndex] = 1; peep->var_0C &= ~(1 << 8); - int bx = sub_69B7EA(peep, &eax); - eax = (RCT2_GLOBAL(0x013CE952, uint16) << 16) | bx; - RCT2_GLOBAL(0x00F1EDF6, uint32) = eax; - _window_guest_list_groups_argument_1[groupIndex] = eax; - RCT2_GLOBAL(0x00F1EDFA, uint32) = RCT2_GLOBAL(0x013CE952 + 2, uint32); - _window_guest_list_groups_argument_2[groupIndex] = RCT2_GLOBAL(0x013CE952 + 2, uint32); + + get_arguments_from_peep( peep, &_window_guest_list_groups_argument_1[groupIndex], &_window_guest_list_groups_argument_2[groupIndex]); + RCT2_GLOBAL(0x00F1EDF6, uint32) = _window_guest_list_groups_argument_1[groupIndex]; + RCT2_GLOBAL(0x00F1EDFA, uint32) = _window_guest_list_groups_argument_2[groupIndex]; + RCT2_ADDRESS(0x00F1AF26, uint8)[groupIndex] = groupIndex; faceIndex = groupIndex * 56; _window_guest_list_groups_guest_faces[faceIndex++] = get_guest_face_sprite_small(peep) - 5486; @@ -913,10 +1068,10 @@ static void window_guest_list_find_groups() if (peep2->var_2A != 0 || !(peep2->var_0C & (1 << 8))) continue; + int argument1, argument2; // Get and check if in same group - // BUG this doesn't work! - bx = sub_69B7EA(peep2, &eax); - if (bx != RCT2_GLOBAL(0x00F1EDF6, uint32) || (eax & 0xFFFF) != RCT2_GLOBAL(0x013CE952, uint16) || eax != RCT2_GLOBAL(0x013CE952 + 2, uint32)) + get_arguments_from_peep(peep2, &argument1, &argument2); + if (argument1 != _window_guest_list_groups_argument_1[groupIndex] || argument2 != _window_guest_list_groups_argument_2[groupIndex] ) continue; // Assign guest @@ -924,7 +1079,7 @@ static void window_guest_list_find_groups() peep2->var_0C &= ~(1 << 8); // Add face sprite, cap at 56 though - if (_window_guest_list_groups_num_guests[groupIndex] < 56) + if (_window_guest_list_groups_num_guests[groupIndex] >= 56) continue; _window_guest_list_groups_guest_faces[faceIndex++] = get_guest_face_sprite_small(peep2) - 5486; } @@ -934,38 +1089,44 @@ static void window_guest_list_find_groups() continue; } - ax = _window_guest_list_groups_num_guests[groupIndex]; - int edi = 0; - + int curr_num_guests = _window_guest_list_groups_num_guests[groupIndex]; + int swap_position = 0; + //This section places the groups in size order. while (1) { - if (edi >= groupIndex) + if (swap_position >= groupIndex) goto nextPeep; - if (ax > _window_guest_list_groups_num_guests[edi]) + if (curr_num_guests > _window_guest_list_groups_num_guests[swap_position]) break; - edi++; + swap_position++; } - int ecx = _window_guest_list_groups_argument_1[groupIndex]; - int edx = _window_guest_list_groups_argument_2[groupIndex]; + int argument_1 = _window_guest_list_groups_argument_1[groupIndex]; + int argument_2 = _window_guest_list_groups_argument_2[groupIndex]; int bl = RCT2_ADDRESS(0x00F1AF26, uint8)[groupIndex]; int temp; do { - temp = ax; - ax = _window_guest_list_groups_num_guests[edi]; - _window_guest_list_groups_num_guests[edi] = temp; + temp = curr_num_guests; + curr_num_guests = _window_guest_list_groups_num_guests[swap_position]; + _window_guest_list_groups_num_guests[swap_position] = temp; - temp = ecx; - ecx = _window_guest_list_groups_argument_1[edi]; - _window_guest_list_groups_argument_1[edi] = temp; + temp = argument_1; + argument_1 = _window_guest_list_groups_argument_1[swap_position]; + _window_guest_list_groups_argument_1[swap_position] = temp; - temp = edx; - edx = _window_guest_list_groups_argument_2[edi]; - _window_guest_list_groups_argument_2[edi] = temp; + temp = argument_2; + argument_2 = _window_guest_list_groups_argument_2[swap_position]; + _window_guest_list_groups_argument_2[swap_position] = temp; - RCT2_ADDRESS(0x00F1AF26, uint8)[edi] = bl; - bl = RCT2_ADDRESS(0x00F1AF26, uint8)[edi]; - } while (++edi <= groupIndex); + uint8 temp_faces[56]; + memcpy(temp_faces, &(_window_guest_list_groups_guest_faces[groupIndex*56]), 56); + memcpy(&(_window_guest_list_groups_guest_faces[groupIndex * 56]), &(_window_guest_list_groups_guest_faces[swap_position * 56]), 56); + memcpy(&(_window_guest_list_groups_guest_faces[swap_position * 56]), temp_faces, 56); + + temp = RCT2_ADDRESS(0x00F1AF26, uint8)[swap_position]; + RCT2_ADDRESS(0x00F1AF26, uint8)[swap_position] = bl; + bl = temp; + } while (++swap_position <= groupIndex); nextPeep: ; @@ -980,10 +1141,10 @@ static int get_guest_face_sprite_small(rct_peep *peep) { int sprite; sprite = SPR_PEEP_SMALL_FACE_ANGRY; - + if (peep->var_F3) return sprite; sprite = SPR_PEEP_SMALL_FACE_VERY_VERY_SICK; - + if (peep->nausea > 200) return sprite; sprite--; //VERY_SICK