From 4a9dfcc849ada15e0f02afd146746fd8ef760c5d Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 8 Feb 2015 15:37:33 +0000 Subject: [PATCH] implement scenario_create_ducks --- src/game.c | 87 +++++++++++------------------------------ src/game.h | 2 +- src/scenario.c | 97 ++++++++++++++++++++++++++++++++++------------ src/world/park.c | 1 + src/world/sprite.c | 9 +++++ src/world/sprite.h | 1 + 6 files changed, 107 insertions(+), 90 deletions(-) diff --git a/src/game.c b/src/game.c index 7f379f2e3d..309ff41940 100644 --- a/src/game.c +++ b/src/game.c @@ -465,18 +465,9 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int * * * rct2: 0x00667C15 */ -void game_pause_toggle() +void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) { - char input_bl; - - #ifdef _MSC_VER - __asm mov input_bl, bl - #else - __asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) ); - #endif - - - if (input_bl & 1) { + if (*ebx & GAME_COMMAND_FLAG_APPLY) { RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) ^= 1; window_invalidate_by_class(WC_TOP_TOOLBAR); if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1) @@ -484,64 +475,30 @@ void game_pause_toggle() else unpause_sounds(); } - - #ifdef _MSC_VER - __asm mov ebx, 0 - #else - __asm__ ( "mov ebx, 0 " ); - #endif - + *ebx = 0; } /** * * rct2: 0x0066DB5F */ -static void game_load_or_quit() +static void game_load_or_quit(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) { - char input_bl, input_dl; - short input_di; - - #ifdef _MSC_VER - __asm mov input_bl, bl - #else - __asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) ); - #endif - - #ifdef _MSC_VER - __asm mov input_dl, dl - #else - __asm__ ( "mov %[input_dl], dl " : [input_dl] "+m" (input_dl) ); - #endif - - #ifdef _MSC_VER - __asm mov input_di, di - #else - __asm__ ( "mov %[input_di], di " : [input_di] "+m" (input_di) ); - #endif - - if (!(input_bl & 1)) - return; // 0; - - switch (input_dl) { - case 0: - RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = input_di; - window_save_prompt_open(); - break; - case 1: - window_close_by_class(WC_SAVE_PROMPT); - break; - default: - game_load_or_quit_no_save_prompt(); - break; + if (*ebx & GAME_COMMAND_FLAG_APPLY) { + switch (*edx & 0xFF) { + case 0: + RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = *edi & 0xFF; + window_save_prompt_open(); + break; + case 1: + window_close_by_class(WC_SAVE_PROMPT); + break; + default: + game_load_or_quit_no_save_prompt(); + break; + } } - -#ifdef _MSC_VER - __asm mov ebx, 0 -#else - __asm__ ( "mov ebx, 0 " ); -#endif - + *ebx = 0; } /** @@ -861,10 +818,10 @@ void game_load_or_quit_no_save_prompt() static uint32 game_do_command_table[58] = { 0x006B2FC5, 0x0066397F, - (uint32)game_pause_toggle, + 0, 0x006C511D, 0x006C5B69, - (uint32)game_load_or_quit, + 0, 0x006B3F0F, 0x006B49D9, 0x006B4EA6, @@ -924,10 +881,10 @@ void game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int static GAME_COMMAND_POINTER* new_game_command_table[58] = { game_command_emptysub, game_command_emptysub, + game_pause_toggle, game_command_emptysub, game_command_emptysub, - game_command_emptysub, - game_command_emptysub, + game_load_or_quit, game_command_emptysub, game_command_emptysub, game_command_emptysub, diff --git a/src/game.h b/src/game.h index cdde118d15..d748ac417f 100644 --- a/src/game.h +++ b/src/game.h @@ -106,7 +106,7 @@ void game_reduce_game_speed(); void game_load_or_quit_no_save_prompt(); int game_load_save(const char *path); -void game_pause_toggle(); +void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); char save_game(); void rct2_exit(); diff --git a/src/scenario.c b/src/scenario.c index b5ee0a98ef..cd1399c126 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -39,6 +39,8 @@ #include "world/park.h" #include "world/sprite.h" +static int scenario_create_ducks(); + /** * Loads only the basic information from a scenario. * rct2: 0x006761D6 @@ -596,21 +598,24 @@ void scenario_update() if ((current_days_in_month * next_month_tick) >> 16 != (current_days_in_month * month_tick) >> 16) { // daily checks - finance_update_daily_profit(); // daily profit update + finance_update_daily_profit(); RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); - RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging - if (objective_type == 10 || objective_type == 9 || objective_type == 8 || - objective_type == 6 || objective_type == 5) { + RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging + switch (objective_type) { + case OBJECTIVE_REPLAY_LOAN_AND_PARK_VALUE: + case OBJECTIVE_FINISH_5_ROLLERCOASTERS: + case OBJECTIVE_10_ROLLERCOASTERS_LENGTH: + case OBJECTIVE_GUESTS_AND_RATING: + case OBJECTIVE_10_ROLLERCOASTERS: scenario_objectives_check(); + break; } window_invalidate_by_class(WC_BOTTOM_TOOLBAR); } - - //if ( (unsigned int)((4 * current_day) & 0xFFFF) >= 0xFFEFu) { - if ( next_month_tick % 0x4000 == 0) { + if (next_month_tick % 0x4000 == 0) { // weekly checks finance_pay_wages(); finance_pay_research(); @@ -621,18 +626,9 @@ void scenario_update() ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { - for (int i = 0; i < 100; ++i) { - int carry; - RCT2_CALLPROC_EBPSAFE(0x006744A9); // clears carry flag on failure -.- - #ifdef _MSC_VER - __asm mov carry, 0; - __asm adc carry, 0; - #else - __asm__ ( "mov %[carry], 0; " : [carry] "+m" (carry) ); - __asm__ ( "adc %[carry], 0; " : [carry] "+m" (carry) ); - #endif - - if (!carry) + // 100 attempts at finding some water to create a few ducks at + for (int i = 0; i < 100; i++) { + if (scenario_create_ducks()) break; } } @@ -640,7 +636,6 @@ void scenario_update() park_calculate_size(); } - //if ( (unsigned int)((2 * current_day) & 0xFFFF) >= 0xFFF8) { if (next_month_tick % 0x8000 == 0) { // fortnightly finance_pay_ride_upkeep(); @@ -656,13 +651,67 @@ void scenario_update() scenario_entrance_fee_too_high_check(); award_update_all(); } - } /** -* -* rct2: 0x006E37D2 -*/ + * + * rct2: 0x006744A9 + */ +static int scenario_create_ducks() +{ + int i, j, r, c, x, y, waterZ, centreWaterZ, x2, y2; + + r = scenario_rand(); + x = ((r >> 16) & 0xFFFF) & 0x7F; + y = (r & 0xFFFF) & 0x7F; + x = (x + 64) * 32; + y = (y + 64) * 32; + + if (!map_is_location_in_park(x, y)) + return 0; + + centreWaterZ = (map_element_height(x, y) >> 16) & 0xFFFF; + if (centreWaterZ == 0) + return 0; + + // Check 7x7 area around centre tile + x2 = x - (32 * 3); + y2 = y - (32 * 3); + c = 0; + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + waterZ = (map_element_height(x2, y2) >> 16) & 0xFFFF; + if (waterZ == centreWaterZ) + c++; + + x2 += 32; + } + x2 -= 224; + y2 += 32; + } + + // Must be at least 25 water tiles of the same height in 7x7 area + if (c < 25) + return 0; + + // Set x, y to the centre of the tile + x += 16; + y += 16; + c = (scenario_rand() & 3) + 2; + for (i = 0; i < c; i++) { + r = scenario_rand(); + x2 = (r >> 16) & 0x7F; + y2 = (r & 0xFFFF) & 0x7F; + create_duck(x + x2 - 64, y + y2 - 64); + } + + return 1; +} + +/** + * + * rct2: 0x006E37D2 + */ unsigned int scenario_rand() { int eax = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32); diff --git a/src/world/park.c b/src/world/park.c index 5882d7ebb1..43d911d176 100644 --- a/src/world/park.c +++ b/src/world/park.c @@ -595,6 +595,7 @@ void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx, RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = (*edi & 0xFFFF); window_invalidate_by_class(WC_PARK_INFORMATION); } + *ebx = 0; } void park_set_open(int open) diff --git a/src/world/sprite.c b/src/world/sprite.c index ce952a6387..ac4b6a3a07 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -33,6 +33,15 @@ void create_balloon(int x, int y, int z, int colour) RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0); } +/** + * + * rct2: 0x0067440F + */ +void create_duck(int targetX, int targetY) +{ + RCT2_CALLPROC_X(0x0067440F, targetX, 0, targetY, 0, 0, 0, 0); +} + /* rct2: 0x006EC473 */ void invalidate_sprite(rct_sprite* sprite){ if (sprite->unknown.sprite_left == (sint16)0x8000) return; diff --git a/src/world/sprite.h b/src/world/sprite.h index 6cca19d844..a9d24991eb 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -97,6 +97,7 @@ typedef union { extern rct_sprite* g_sprite_list; void create_balloon(int x, int y, int z, int colour); +void create_duck(int targetX, int targetY); rct_sprite *create_sprite(uint8 bl); void reset_sprite_list(); void reset_0x69EBE4();