From 035fa16fc32bfec6ae2454f90c46a716ece34246 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Sun, 27 Apr 2014 23:46:18 +0200 Subject: [PATCH 01/17] Crude start of a decompiled update_climate() --- src/addresses.h | 1 + src/climate.c | 64 ++++++++++++++++++++++++++++++++ src/climate.h | 1 + src/game.c | 4 +- src/window_game_bottom_toolbar.c | 2 +- 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index d042c530d9..b62115f3d1 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -168,6 +168,7 @@ #define RCT2_ADDRESS_CURRENT_WEATHER 0x013CA74A #define RCT2_ADDRESS_NEXT_WEATHER 0x013CA74B #define RCT2_ADDRESS_CURRENT_TEMPERATURE 0x013CA74C +#define RCT2_ADDRESS_CLIMATE_UPDATE_TIMER 0x013CA748 #define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754 diff --git a/src/climate.c b/src/climate.c index 71ae908eda..fc3f3af706 100644 --- a/src/climate.c +++ b/src/climate.c @@ -20,6 +20,7 @@ #include "addresses.h" #include "date.h" +#include "gfx.h" #include "rct2.h" int climate_celcius_to_fahrenheit(int celcius) @@ -48,3 +49,66 @@ void climate_reset(int climate) RCT2_GLOBAL(0x013CA752, sint8) = (ecx >> 8) & 0xFF; RCT2_CALLPROC_X(0x6C461C, 0, 0, 0, 0, 0, 0, 0); } + + +/** + * + * rct2: 0x006C46B1 + **/ +void update_climate() +{ + uint8 screen_flags = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8); + if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate + return; + + if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)) { + + if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) == 960) + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + + RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)--; + + } else if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32) & 0x7F)) { + sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8); + sint8 target_temperature = RCT2_GLOBAL(0x013CA74D, sint8); + + if (temperature == target_temperature) { + if (RCT2_GLOBAL(0x013CA750, sint8) == RCT2_GLOBAL(0x013CA751, sint8)) { + + RCT2_GLOBAL(0x013CA74E, sint8) = RCT2_GLOBAL(0x013CA74F, sint8); + + if (RCT2_GLOBAL(0x013CA752, sint8) == RCT2_GLOBAL(0x013CA753, sint8)) { + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); + RCT2_CALLPROC(0x006C461C); + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + } + else { + if (RCT2_GLOBAL(0x013CA753, sint8) == 3) + RCT2_GLOBAL(0x013CA752, sint8) = 3; + else { + sint8 next = RCT2_GLOBAL(0x013CA752, sint8) + 1; + + if (RCT2_GLOBAL(0x013CA752, sint8) > RCT2_GLOBAL(0x013CA753, sint8)) + next = RCT2_GLOBAL(0x013CA752, sint8) - 1; + RCT2_GLOBAL(0x013CA752, sint8) = next; + } + } + } else { + sint8 next = RCT2_GLOBAL(0x013CA750, sint8) + 1; + + if (RCT2_GLOBAL(0x013CA750, sint8) > RCT2_GLOBAL(0x013CA751, sint8)) + next = RCT2_GLOBAL(0x013CA750, sint8) - 1; + RCT2_GLOBAL(0x013CA750, sint8) = next; + gfx_invalidate_screen(); + } + + } else { + sint8 newtemp = temperature + 1; + if (temperature > target_temperature) + newtemp = temperature - 1; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8) = newtemp; + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + } + } +} \ No newline at end of file diff --git a/src/climate.h b/src/climate.h index 7325bfd8b1..183bd0f08c 100644 --- a/src/climate.h +++ b/src/climate.h @@ -30,5 +30,6 @@ enum { int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); +void update_climate(); #endif diff --git a/src/game.c b/src/game.c index 7c94a2fb76..2aa8dcc08e 100644 --- a/src/game.c +++ b/src/game.c @@ -20,6 +20,7 @@ #include "addresses.h" #include "audio.h" +#include "climate.h" #include "config.h" #include "rct2.h" #include "game.h" @@ -136,7 +137,8 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x0068B089); RCT2_CALLPROC_EBPSAFE(0x006C44B1); // update_objective - RCT2_CALLPROC_EBPSAFE(0x006C46B1); // update_climate + //RCT2_CALLPROC_EBPSAFE(0x006C46B1); // update_climate + update_climate(); RCT2_CALLPROC_EBPSAFE(0x006646E1); RCT2_CALLPROC_EBPSAFE(0x006A876D); peep_update_all(); diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 9723e30a65..4530c8c68e 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -484,7 +484,7 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, // Next weather if (((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) * 2] != ((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) * 2]) { - if (RCT2_GLOBAL(0x013CA748, sint16) < 960) { + if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) < 960) { gfx_draw_sprite(dpi, SPR_NEXT_WEATHER, x + 27, y + 5); gfx_draw_sprite(dpi, ((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) * 2], x + 40, y); } From b557f5bf1c2c174578707a93fa4b9c20ed942c18 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 01:05:00 +0200 Subject: [PATCH 02/17] Identified more climate related values. --- src/addresses.h | 4 ++++ src/climate.c | 36 +++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index b62115f3d1..a01560b914 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -169,6 +169,10 @@ #define RCT2_ADDRESS_NEXT_WEATHER 0x013CA74B #define RCT2_ADDRESS_CURRENT_TEMPERATURE 0x013CA74C #define RCT2_ADDRESS_CLIMATE_UPDATE_TIMER 0x013CA748 +#define RCT2_ADDRESS_CURRENT_WEATHER_EFFECT 0x013CA74E +#define RCT2_ADDRESS_NEXT_WEATHER_EFFECT 0x013CA74F +#define RCT2_ADDRESS_CURRENT_WEATHER_GLOOM 0x013CA750 +#define RCT2_ADDRESS_NEXT_WEATHER_GLOOM 0x013CA751 #define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754 diff --git a/src/climate.c b/src/climate.c index fc3f3af706..71c83f0d42 100644 --- a/src/climate.c +++ b/src/climate.c @@ -44,15 +44,15 @@ void climate_reset(int climate) RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = eax & 0xFF; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8) = ebx & 0xFF; - RCT2_GLOBAL(0x013CA74E, sint8) = (ebx >> 8) & 0xFF; - RCT2_GLOBAL(0x013CA750, sint8) = ecx & 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = (ebx >> 8) & 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8) = ecx & 0xFF; RCT2_GLOBAL(0x013CA752, sint8) = (ecx >> 8) & 0xFF; RCT2_CALLPROC_X(0x6C461C, 0, 0, 0, 0, 0, 0, 0); } /** - * + * Weather & climate update iteration. * rct2: 0x006C46B1 **/ void update_climate() @@ -61,26 +61,28 @@ void update_climate() if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate return; + sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8); + sint8 target_temperature = RCT2_GLOBAL(0x013CA74D, sint8); + sint8 cur_gloom = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8); + sint8 next_gloom = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8); + if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) == 960) - RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)--; } else if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32) & 0x7F)) { - sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8); - sint8 target_temperature = RCT2_GLOBAL(0x013CA74D, sint8); - + if (temperature == target_temperature) { - if (RCT2_GLOBAL(0x013CA750, sint8) == RCT2_GLOBAL(0x013CA751, sint8)) { - - RCT2_GLOBAL(0x013CA74E, sint8) = RCT2_GLOBAL(0x013CA74F, sint8); + if (cur_gloom == next_gloom) { + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8); if (RCT2_GLOBAL(0x013CA752, sint8) == RCT2_GLOBAL(0x013CA753, sint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); - RCT2_CALLPROC(0x006C461C); - RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + RCT2_CALLPROC(0x006C461C); // determine_future_weather() + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } else { if (RCT2_GLOBAL(0x013CA753, sint8) == 3) @@ -94,11 +96,11 @@ void update_climate() } } } else { - sint8 next = RCT2_GLOBAL(0x013CA750, sint8) + 1; + sint8 next_gloom_step = cur_gloom + 1; + if (cur_gloom > next_gloom) + next_gloom_step = cur_gloom - 1; - if (RCT2_GLOBAL(0x013CA750, sint8) > RCT2_GLOBAL(0x013CA751, sint8)) - next = RCT2_GLOBAL(0x013CA750, sint8) - 1; - RCT2_GLOBAL(0x013CA750, sint8) = next; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8) = next_gloom_step; gfx_invalidate_screen(); } @@ -108,7 +110,7 @@ void update_climate() newtemp = temperature - 1; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8) = newtemp; - RCT2_GLOBAL(0x009A9804, uint32) |= 8; // XXX climate dirty flag? + RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } } } \ No newline at end of file From b3c279d9b5312eaa5af6dfb9e18ad97e437a3a29 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 02:24:57 +0200 Subject: [PATCH 03/17] Implement determining future weather. --- src/addresses.h | 1 + src/climate.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index a01560b914..11453b0f75 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -168,6 +168,7 @@ #define RCT2_ADDRESS_CURRENT_WEATHER 0x013CA74A #define RCT2_ADDRESS_NEXT_WEATHER 0x013CA74B #define RCT2_ADDRESS_CURRENT_TEMPERATURE 0x013CA74C +#define RCT2_ADDRESS_NEXT_TEMPERATURE 0x013CA74D #define RCT2_ADDRESS_CLIMATE_UPDATE_TIMER 0x013CA748 #define RCT2_ADDRESS_CURRENT_WEATHER_EFFECT 0x013CA74E #define RCT2_ADDRESS_NEXT_WEATHER_EFFECT 0x013CA74F diff --git a/src/climate.c b/src/climate.c index 71c83f0d42..d6c5b4ceca 100644 --- a/src/climate.c +++ b/src/climate.c @@ -23,6 +23,8 @@ #include "gfx.h" #include "rct2.h" +void determine_future_weather(); + int climate_celcius_to_fahrenheit(int celcius) { return (celcius * 29) / 16 + 32; @@ -58,14 +60,15 @@ void climate_reset(int climate) void update_climate() { uint8 screen_flags = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8); - if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate - return; - sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8); - sint8 target_temperature = RCT2_GLOBAL(0x013CA74D, sint8); + sint8 target_temperature = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8); sint8 cur_gloom = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8); sint8 next_gloom = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8); + if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate + return; + // 0x013CA752 and 0x013CA753 are possibly for rain particles. Can't be sure as rain rendering seems broken atm for me. + if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) == 960) @@ -81,7 +84,8 @@ void update_climate() if (RCT2_GLOBAL(0x013CA752, sint8) == RCT2_GLOBAL(0x013CA753, sint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); - RCT2_CALLPROC(0x006C461C); // determine_future_weather() + //RCT2_CALLPROC(0x006C461C); // determine_future_weather() + determine_future_weather(); RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } else { @@ -113,4 +117,28 @@ void update_climate() RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } } +} + + +/** +* Calculates future weather development +* rct2: 0x006C461C +**/ +void determine_future_weather() +{ + sint8 climate = RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8); + uint8** climate_table = ((uint8***)0x00993998)[climate]; + sint8 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; + uint8* month_table = climate_table[month]; + + sint8 next_weather = month_table[ 2 + (uint8)((rand() * month_table[1]) >> 8) ]; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; + + sint8* weather_table = (sint8*)0x00993C94; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table[0] + weather_table[next_weather * 8]; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather * 8 + 1]; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather * 8 + 2]; + RCT2_GLOBAL(0x013CA753, sint8) = weather_table[next_weather * 8 + 3]; + + RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } \ No newline at end of file From 039241cde40587f58a37bc5dfda95b5f4183e3c5 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 17:07:13 +0200 Subject: [PATCH 04/17] Moved the weather table into our code. Introduced the weather table struct used for future weather calculation. Added a bit more explanation on how future weather is calculated. --- src/climate.c | 29 +++++++++++++++++++++++------ src/climate.h | 8 ++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/climate.c b/src/climate.c index d6c5b4ceca..d1d6cd4198 100644 --- a/src/climate.c +++ b/src/climate.c @@ -19,10 +19,21 @@ *****************************************************************************/ #include "addresses.h" +#include "climate.h" #include "date.h" #include "gfx.h" #include "rct2.h" +const sint8 weather_table[48] = { + 10, 0, 0, 0, 0x96, 0x5a, 0, 0, // Sunny + 5, 0, 0, 0, 0x97, 0x5A, 0, 0, // Partially cloudy + 0, 0, 0, 0, 0x98, 0x5A, 0, 0, // Cloudy + -2, 1, 1, 1, 0x99, 0x5A, 0, 0, // Rain + -4, 1, 2, 2, 0x9A, 0x5A, 0, 0, // Heavy rain + 2, 2, 2, 2, 0x9B, 0x5A, 0, 0 // Thunderstorm +}; + + void determine_future_weather(); int climate_celcius_to_fahrenheit(int celcius) @@ -121,21 +132,27 @@ void update_climate() /** -* Calculates future weather development +* Calculates future weather development. +* RCT2 implements this as discrete probability distributions dependant on month and climate +* for next_weather. The other weather parameters are then looked up depending only on the +* next weather. +* * rct2: 0x006C461C **/ void determine_future_weather() { sint8 climate = RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8); - uint8** climate_table = ((uint8***)0x00993998)[climate]; + rct_weather_table** climate_data = ((rct_weather_table***)0x00993998)[climate]; sint8 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; - uint8* month_table = climate_table[month]; + // don't do this at home. Temporary measure until we rewrite the tables. + rct_weather_table* month_table = climate_data[month]; - sint8 next_weather = month_table[ 2 + (uint8)((rand() * month_table[1]) >> 8) ]; + // generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly + sint8 next_weather = month_table->distribution[ ((rand() & 0xFF) * month_table->distribution_size) >> 8 ]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; - sint8* weather_table = (sint8*)0x00993C94; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table[0] + weather_table[next_weather * 8]; + //sint8* weather_table = (sint8*)0x00993C94; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table->base_temperature + weather_table[next_weather * 8]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather * 8 + 1]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather * 8 + 2]; RCT2_GLOBAL(0x013CA753, sint8) = weather_table[next_weather * 8 + 3]; diff --git a/src/climate.h b/src/climate.h index 183bd0f08c..704c39f8ed 100644 --- a/src/climate.h +++ b/src/climate.h @@ -18,6 +18,8 @@ * along with this program. If not, see . *****************************************************************************/ +#include "rct2.h" + #ifndef _CLIMATE_H_ #define _CLIMATE_H_ @@ -28,6 +30,12 @@ enum { CLIMATE_COLD }; +typedef struct { + sint8 base_temperature; + sint8 distribution_size; + sint8 distribution[24]; +} rct_weather_table; + int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); void update_climate(); From 573929fee9de8a938a919d405db6f884767df7b8 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 19:59:40 +0200 Subject: [PATCH 05/17] Identified full weather data table. Restructured weather data properly and made window_game_bottom_toolbar use our table. Used determine_future_weather in climate_reset. --- src/addresses.h | 2 + src/climate.c | 69 +++++++++++++++++--------------- src/climate.h | 10 +++++ src/game.c | 1 - src/window_game_bottom_toolbar.c | 6 +-- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 11453b0f75..c59bb061a4 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -174,6 +174,8 @@ #define RCT2_ADDRESS_NEXT_WEATHER_EFFECT 0x013CA74F #define RCT2_ADDRESS_CURRENT_WEATHER_GLOOM 0x013CA750 #define RCT2_ADDRESS_NEXT_WEATHER_GLOOM 0x013CA751 +#define RCT2_ADDRESS_CURRENT_RAIN_LEVEL 0x013CA752 +#define RCT2_ADDRESS_NEXT_RAIN_LEVEL 0x013CA753 #define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754 diff --git a/src/climate.c b/src/climate.c index d1d6cd4198..75e483f3a2 100644 --- a/src/climate.c +++ b/src/climate.c @@ -24,18 +24,22 @@ #include "gfx.h" #include "rct2.h" -const sint8 weather_table[48] = { - 10, 0, 0, 0, 0x96, 0x5a, 0, 0, // Sunny - 5, 0, 0, 0, 0x97, 0x5A, 0, 0, // Partially cloudy - 0, 0, 0, 0, 0x98, 0x5A, 0, 0, // Cloudy - -2, 1, 1, 1, 0x99, 0x5A, 0, 0, // Rain - -4, 1, 2, 2, 0x9A, 0x5A, 0, 0, // Heavy rain - 2, 2, 2, 2, 0x9B, 0x5A, 0, 0 // Thunderstorm -}; - void determine_future_weather(); + +// rct2: 0x00993C94 +// There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented +const rct_weather weather_table[6] = { + { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny + { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy + { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy + { .temp_delta = -2, .effect_level = 1, .gloom_level = 1, .rain_level = 1, .sprite_id = 0x5A99 }, // Rain + { .temp_delta = -4, .effect_level = 1, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9A }, // Heavy Rain + { .temp_delta = 2, .effect_level = 2, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9B }, // Thunderstorm +}; + + int climate_celcius_to_fahrenheit(int celcius) { return (celcius * 29) / 16 + 32; @@ -59,26 +63,29 @@ void climate_reset(int climate) RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = (ebx >> 8) & 0xFF; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8) = ecx & 0xFF; - RCT2_GLOBAL(0x013CA752, sint8) = (ecx >> 8) & 0xFF; - RCT2_CALLPROC_X(0x6C461C, 0, 0, 0, 0, 0, 0, 0); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8) = (ecx >> 8) & 0xFF; + determine_future_weather(); } /** * Weather & climate update iteration. + * Gradually changes the weather parameters towards their determined next values. * rct2: 0x006C46B1 **/ void update_climate() { uint8 screen_flags = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8); - sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8); - sint8 target_temperature = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8); - sint8 cur_gloom = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8); - sint8 next_gloom = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8); + sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8), + target_temperature = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8), + cur_gloom = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8), + next_gloom = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8), + cur_rain = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8), + next_rain = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8); + if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate return; - // 0x013CA752 and 0x013CA753 are possibly for rain particles. Can't be sure as rain rendering seems broken atm for me. if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16)) { @@ -93,21 +100,19 @@ void update_climate() if (cur_gloom == next_gloom) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8); - if (RCT2_GLOBAL(0x013CA752, sint8) == RCT2_GLOBAL(0x013CA753, sint8)) { + if (cur_rain == next_rain) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); - //RCT2_CALLPROC(0x006C461C); // determine_future_weather() determine_future_weather(); RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } else { - if (RCT2_GLOBAL(0x013CA753, sint8) == 3) - RCT2_GLOBAL(0x013CA752, sint8) = 3; + if (next_rain == 3) + cur_rain = 3; else { - sint8 next = RCT2_GLOBAL(0x013CA752, sint8) + 1; - - if (RCT2_GLOBAL(0x013CA752, sint8) > RCT2_GLOBAL(0x013CA753, sint8)) - next = RCT2_GLOBAL(0x013CA752, sint8) - 1; - RCT2_GLOBAL(0x013CA752, sint8) = next; + sint8 next_rain_step = cur_rain + 1; + if (cur_rain > next_rain) + next_rain_step = cur_rain - 1; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8) = next_rain_step; } } } else { @@ -151,11 +156,11 @@ void determine_future_weather() sint8 next_weather = month_table->distribution[ ((rand() & 0xFF) * month_table->distribution_size) >> 8 ]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; - //sint8* weather_table = (sint8*)0x00993C94; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table->base_temperature + weather_table[next_weather * 8]; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather * 8 + 1]; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather * 8 + 2]; - RCT2_GLOBAL(0x013CA753, sint8) = weather_table[next_weather * 8 + 3]; - + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table->base_temperature + weather_table[next_weather].temp_delta; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather].effect_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather].gloom_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_table[next_weather].rain_level; + + RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; -} \ No newline at end of file +} diff --git a/src/climate.h b/src/climate.h index 704c39f8ed..2a40e867ca 100644 --- a/src/climate.h +++ b/src/climate.h @@ -36,6 +36,16 @@ typedef struct { sint8 distribution[24]; } rct_weather_table; +typedef struct { + sint8 temp_delta; + sint8 effect_level; + sint8 gloom_level; + sint8 rain_level; + uint32 sprite_id; +} rct_weather; + +extern const rct_weather weather_table[6]; + int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); void update_climate(); diff --git a/src/game.c b/src/game.c index c264d293ce..fddce0fb54 100644 --- a/src/game.c +++ b/src/game.c @@ -137,7 +137,6 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x0068B089); RCT2_CALLPROC_EBPSAFE(0x006C44B1); // update_objective - //RCT2_CALLPROC_EBPSAFE(0x006C46B1); // update_climate update_climate(); RCT2_CALLPROC_EBPSAFE(0x006646E1); RCT2_CALLPROC_EBPSAFE(0x006A876D); diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 4530c8c68e..5bd1cd50ee 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -480,13 +480,13 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, x += 30; // Current weather - gfx_draw_sprite(dpi, ((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) * 2], x, y); + gfx_draw_sprite(dpi, weather_table[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); // Next weather - if (((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) * 2] != ((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) * 2]) { + if (weather_table[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != weather_table[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) < 960) { gfx_draw_sprite(dpi, SPR_NEXT_WEATHER, x + 27, y + 5); - gfx_draw_sprite(dpi, ((int*)0x00993C98)[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) * 2], x + 40, y); + gfx_draw_sprite(dpi, weather_table[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); } } } From 22bcc5d2012de5c5f47348e8abc27ec7e37c8b79 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 20:14:50 +0200 Subject: [PATCH 06/17] Removed redundance in climate_reset --- src/climate.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/climate.c b/src/climate.c index 75e483f3a2..0dba3f00b0 100644 --- a/src/climate.c +++ b/src/climate.c @@ -31,7 +31,7 @@ void determine_future_weather(); // rct2: 0x00993C94 // There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented const rct_weather weather_table[6] = { - { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny + { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy { .temp_delta = -2, .effect_level = 1, .gloom_level = 1, .rain_level = 1, .sprite_id = 0x5A99 }, // Rain @@ -46,24 +46,12 @@ int climate_celcius_to_fahrenheit(int celcius) } /** - * + * Set climate and determine start weather. * rct2: 0x006C45ED */ void climate_reset(int climate) { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8) = climate; - - eax = 1; - RCT2_CALLFUNC_X(0x006C4672, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = eax & 0xFF; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8) = ebx & 0xFF; - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = (ebx >> 8) & 0xFF; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8) = ecx & 0xFF; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8) = (ecx >> 8) & 0xFF; determine_future_weather(); } @@ -160,7 +148,6 @@ void determine_future_weather() RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather].effect_level; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather].gloom_level; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_table[next_weather].rain_level; - - + RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } From b7ae1c7266a4255787983ac7c0e6330d525e967f Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 20:39:10 +0200 Subject: [PATCH 07/17] Slight climate refactoring --- src/climate.c | 16 ++++++++-------- src/climate.h | 4 ++-- src/window_game_bottom_toolbar.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/climate.c b/src/climate.c index 0dba3f00b0..63ce668a95 100644 --- a/src/climate.c +++ b/src/climate.c @@ -30,7 +30,7 @@ void determine_future_weather(); // rct2: 0x00993C94 // There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented -const rct_weather weather_table[6] = { +const rct_weather weather_data[6] = { { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy @@ -135,19 +135,19 @@ void update_climate() void determine_future_weather() { sint8 climate = RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8); - rct_weather_table** climate_data = ((rct_weather_table***)0x00993998)[climate]; + rct_weather_transition** climate_table = ((rct_weather_transition***)0x00993998)[climate]; sint8 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; // don't do this at home. Temporary measure until we rewrite the tables. - rct_weather_table* month_table = climate_data[month]; + rct_weather_transition* transition = climate_table[month]; // generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly - sint8 next_weather = month_table->distribution[ ((rand() & 0xFF) * month_table->distribution_size) >> 8 ]; + sint8 next_weather = transition->distribution[ ((rand() & 0xFF) * transition->distribution_size) >> 8 ]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = month_table->base_temperature + weather_table[next_weather].temp_delta; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_table[next_weather].effect_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_table[next_weather].gloom_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_table[next_weather].rain_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition->base_temperature + weather_data[next_weather].temp_delta; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_data[next_weather].effect_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_data[next_weather].gloom_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_data[next_weather].rain_level; RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } diff --git a/src/climate.h b/src/climate.h index 2a40e867ca..9d28ba297e 100644 --- a/src/climate.h +++ b/src/climate.h @@ -34,7 +34,7 @@ typedef struct { sint8 base_temperature; sint8 distribution_size; sint8 distribution[24]; -} rct_weather_table; +} rct_weather_transition; typedef struct { sint8 temp_delta; @@ -44,7 +44,7 @@ typedef struct { uint32 sprite_id; } rct_weather; -extern const rct_weather weather_table[6]; +extern const rct_weather weather_data[6]; int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 5bd1cd50ee..e39e2ebac0 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -480,13 +480,13 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, x += 30; // Current weather - gfx_draw_sprite(dpi, weather_table[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); + gfx_draw_sprite(dpi, weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); // Next weather - if (weather_table[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != weather_table[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { + if (weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) < 960) { gfx_draw_sprite(dpi, SPR_NEXT_WEATHER, x + 27, y + 5); - gfx_draw_sprite(dpi, weather_table[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); + gfx_draw_sprite(dpi, weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); } } } From 6f756bb4587c8f21d7bcf62996d7187eb18a9dcc Mon Sep 17 00:00:00 2001 From: ZedThree Date: Mon, 28 Apr 2014 22:00:54 +0200 Subject: [PATCH 08/17] Replace variable addresses with named constants Done automatically with sed/unix --- src/game.c | 10 +++++----- src/gfx.c | 2 +- src/osinterface.c | 12 ++++++------ src/peep.c | 2 +- src/rct2.c | 4 ++-- src/scenario.c | 4 ++-- src/title.c | 2 +- src/window_clear_scenery.c | 4 ++-- src/window_dropdown.c | 2 +- src/window_game_bottom_toolbar.c | 8 ++++---- src/window_game_top_toolbar.c | 8 ++++---- src/window_land.c | 8 ++++---- src/window_main.c | 2 +- src/window_park.c | 4 ++-- src/window_water.c | 4 ++-- 15 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/game.c b/src/game.c index 7c94a2fb76..3aa242b296 100644 --- a/src/game.c +++ b/src/game.c @@ -128,7 +128,7 @@ void game_logic_update() { short stringId, _dx; - RCT2_GLOBAL(0x013628F4, sint32)++; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32)++; RCT2_GLOBAL(0x00F663AC, sint32)++; RCT2_GLOBAL(0x009DEA66, sint16)++; if (RCT2_GLOBAL(0x009DEA66, sint16) == 0) @@ -321,8 +321,8 @@ static void game_handle_input_mouse(int x, int y, int state) RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_DRAG; RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y; - RCT2_GLOBAL(0x009DE530, rct_windowclass) = w->classification; - RCT2_GLOBAL(0x009DE52E, rct_windownumber) = w->number; + RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = w->classification; + RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = w->number; RCT2_GLOBAL(0x009DE540, sint16) = 0; // hide cursor // RCT2_CALLPROC_X(0x00407045, 0, 0, 0, 0, 0, 0, 0); @@ -384,7 +384,7 @@ static void game_handle_input_mouse(int x, int y, int state) dx = x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16); dy = y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16); - w = window_find_by_id(RCT2_GLOBAL(0x009DE530, rct_windowclass), RCT2_GLOBAL(0x009DE52E, rct_windownumber)); + w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber)); if (state == 0) { rct_viewport *viewport = w->viewport; RCT2_GLOBAL(0x009DE540, sint16) += RCT2_GLOBAL(0x009DE588, sint16); @@ -908,7 +908,7 @@ void game_handle_keyboard_input() // Handle mouse scrolling if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0) - if (RCT2_GLOBAL(0x009AACBA, uint8) != 0) + if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) != 0) if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == 1) if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 3)) game_handle_edge_scroll(); diff --git a/src/gfx.c b/src/gfx.c index 8890e67b5d..7785422d87 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -239,7 +239,7 @@ void gfx_set_dirty_blocks(int left, int top, int right, int bottom) for (y = top; y <= bottom; y++) for (x = left; x <= right; x++) - screenDirtyBlocks[y * RCT2_GLOBAL(0x009ABDE8, sint32) + x] = 0xFF; + screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] = 0xFF; } /** diff --git a/src/osinterface.c b/src/osinterface.c index 594a398da2..7d11ff2ced 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -68,8 +68,8 @@ static void osinterface_create_window() RCT2_CALLPROC_EBPSAFE(0x0068352C); RCT2_CALLPROC_EBPSAFE(0x0068371D); - width = RCT2_GLOBAL(0x009AB4C2, sint16); - height = RCT2_GLOBAL(0x009AB4C4, sint16); + width = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, sint16); + height = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, sint16); width = 640; height = 480; @@ -136,10 +136,10 @@ static void osinterface_resize(int width, int height) RCT2_GLOBAL(0x009ABDF0, uint8) = 6; RCT2_GLOBAL(0x009ABDF1, uint8) = 3; RCT2_GLOBAL(0x009ABDF2, uint8) = 1; - RCT2_GLOBAL(0x009ABDE4, sint16) = 64; - RCT2_GLOBAL(0x009ABDE6, sint16) = 8; - RCT2_GLOBAL(0x009ABDE8, sint32) = (width >> 6) + 1; - RCT2_GLOBAL(0x009ABDEC, sint32) = (height >> 3) + 1; + RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16) = 64; + RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16) = 8; + RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) = (width >> 6) + 1; + RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32) = (height >> 3) + 1; RCT2_CALLPROC_EBPSAFE(0x0066B905); // resize_gui() gfx_invalidate_screen(); diff --git a/src/peep.c b/src/peep.c index e50fb7c80a..0a16060ca2 100644 --- a/src/peep.c +++ b/src/peep.c @@ -60,7 +60,7 @@ void peep_update_all() peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); sprite_index = peep->next; - if ((i & 0x7F) != (RCT2_GLOBAL(0x013628F4, uint32) & 0x7F)) { + if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) { RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, peep, 0, 0); } else { RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, peep, 0, 0); diff --git a/src/rct2.c b/src/rct2.c index 64fd70c1a9..df687dca0c 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -103,8 +103,8 @@ void rct2_init() RCT2_GLOBAL(0x00F663AC, int) = 0; RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*); get_system_time(); - RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(0x01424304, short); - RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(0x01424304, short); + RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); + RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); rct2_init_directories(); rct2_startup_checks(); config_reset_shortcut_keys(); diff --git a/src/scenario.c b/src/scenario.c index 61b9108483..6eee3c4849 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -424,7 +424,7 @@ void scenario_load_and_play(rct_scenario_basic *scenario) uint8 _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - mainWindow->viewport->zoom; mainWindow->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF; - *((char*)(&RCT2_GLOBAL(0x0141E9E0, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8; + *((char*)(&RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8; if (_cl != 0) { if (_cl < 0) { _cl = -_cl; @@ -451,7 +451,7 @@ void scenario_load_and_play(rct_scenario_basic *scenario) RCT2_CALLPROC_EBPSAFE(0x00684AC3); RCT2_CALLPROC_EBPSAFE(0x006DFEE4); news_item_init_queue(); - if (RCT2_ADDRESS(0x013580F8, uint8) != OBJECTIVE_NONE) + if (RCT2_ADDRESS(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) != OBJECTIVE_NONE) window_park_objective_open(); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, sint16) = calculate_park_rating(); diff --git a/src/title.c b/src/title.c index 6eb9fd77c7..5b447bca8a 100644 --- a/src/title.c +++ b/src/title.c @@ -172,7 +172,7 @@ static void title_update_showcase() { char _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - w->viewport->zoom; w->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF; - *((char*)(&RCT2_GLOBAL(0x0141E9E0, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8; + *((char*)(&RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8; if (_cl != 0) { if (_cl < 0) { _cl = -_cl; diff --git a/src/window_clear_scenery.c b/src/window_clear_scenery.c index 567a9358f8..061de23294 100644 --- a/src/window_clear_scenery.c +++ b/src/window_clear_scenery.c @@ -226,9 +226,9 @@ static int window_clear_scenery_should_close() { if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) return 1; - if (RCT2_GLOBAL(0x009DE544, rct_windowclass) != WC_TOP_TOOLBAR) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR) return 1; - if (RCT2_GLOBAL(0x009DE546, uint16) != 16) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != 16) return 1; return 0; } diff --git a/src/window_dropdown.c b/src/window_dropdown.c index 0aecd65450..9050dd6c64 100644 --- a/src/window_dropdown.c +++ b/src/window_dropdown.c @@ -108,7 +108,7 @@ void window_dropdown_show_text(int x, int y, int extray, uint8 colour, uint8 fla max_string_width = 0; for (i = 0; i < num_items; i++) { format_string(buffer, gDropdownItemsFormat[i], (void*)(&gDropdownItemsArgs[i])); - RCT2_GLOBAL(0x013CE950, sint16) = 224; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224; string_width = gfx_get_string_width(buffer); max_string_width = max(string_width, max_string_width); } diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 9723e30a65..c749c7d113 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -390,7 +390,7 @@ static void window_game_bottom_toolbar_draw_left_panel(rct_drawpixelinfo *dpi, r dpi, (*((int*)0x013CE952) < 0 ? 1391 : 1390), x, y - 3, - (RCT2_GLOBAL(0x009DE55C, rct_windowclass) == 2 && RCT2_GLOBAL(0x009DE560, sint32) == WIDX_MONEY ? 2 : w->colours[0] & 0x7F), + (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) == 2 && RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, sint32) == WIDX_MONEY ? 2 : w->colours[0] & 0x7F), (void*)0x013CE952 ); y += 7; @@ -401,7 +401,7 @@ static void window_game_bottom_toolbar_draw_left_panel(rct_drawpixelinfo *dpi, r dpi, STR_NUM_GUESTS + RCT2_GLOBAL(0x013573FE, uint8), x, y, - (RCT2_GLOBAL(0x009DE55C, rct_windowclass) == 2 && RCT2_GLOBAL(0x009DE560, sint32) == WIDX_GUESTS ? 2 : w->colours[0] & 0x7F), + (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) == 2 && RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, sint32) == WIDX_GUESTS ? 2 : w->colours[0] & 0x7F), (void*)0x01357844 ); @@ -426,7 +426,7 @@ static void window_game_bottom_toolbar_draw_park_rating(rct_drawpixelinfo *dpi, bar_width = (factor * 90) / 256; gfx_fill_rect_inset(dpi, x, y + 1, x + 93, y + 9, w->colours[1], 48); - if (!(colour & 0x80000000) || RCT2_GLOBAL(0x009DEA6E, uint8) != 0 || (RCT2_GLOBAL(0x013628F4, uint8) & 8)) { + if (!(colour & 0x80000000) || RCT2_GLOBAL(0x009DEA6E, uint8) != 0 || (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint8) & 8)) { if (bar_width > 2) gfx_fill_rect_inset(dpi, x + 2, y + 2, x + bar_width - 1, y + 8, colour & 0x7FFFFFFF, 0); } @@ -461,7 +461,7 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, 1845, x, y, - (RCT2_GLOBAL(0x009DE55C, rct_windowclass) == 2 && RCT2_GLOBAL(0x009DE560, sint32) == WIDX_DATE ? 2 : w->colours[0] & 0x7F), + (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) == 2 && RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, sint32) == WIDX_DATE ? 2 : w->colours[0] & 0x7F), (void*)0x013CE952 ); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 92a7d4e7b3..acd1ab0180 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -174,7 +174,7 @@ static void window_game_top_toolbar_mouseup() break; case WIDX_CLEAR_SCENERY: - if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(0x009DE544, uint8) == 1 && RCT2_GLOBAL(0x009DE546, uint16) == 16) { + if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) { RCT2_CALLPROC_EBPSAFE(0x006EE281); } else { show_gridlines(); @@ -185,7 +185,7 @@ static void window_game_top_toolbar_mouseup() } break; case WIDX_LAND: - if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(0x009DE544, uint8) == 1 && RCT2_GLOBAL(0x009DE546, uint16) == 7) { + if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) { RCT2_CALLPROC_EBPSAFE(0x006EE281); } else { show_gridlines(); @@ -196,7 +196,7 @@ static void window_game_top_toolbar_mouseup() } break; case WIDX_WATER: - if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(0x009DE544, uint8) == 1 && RCT2_GLOBAL(0x009DE546, uint16) == 8) { + if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) { RCT2_CALLPROC_EBPSAFE(0x006EE281); } else { show_gridlines(); @@ -378,7 +378,7 @@ static void window_game_top_toolbar_dropdown() RCT2_CALLPROC_EBPSAFE(0x006BAC5B); break; case 5: // screenshot - RCT2_GLOBAL(0x009DEA6D, sint8) = 10; + RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; break; case 7: // quit game RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 1, 0); diff --git a/src/window_land.c b/src/window_land.c index 46db92465c..0c196b46f1 100644 --- a/src/window_land.c +++ b/src/window_land.c @@ -137,8 +137,8 @@ void window_land_open() RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255; _selectedFloorTexture = 0; _selectedWallTexture = 0; - RCT2_GLOBAL(0x009E2E1C, sint32) = 0x80000000; - RCT2_GLOBAL(0x009E2E20, sint32) = 0x80000000; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, sint32) = 0x80000000; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, sint32) = 0x80000000; window->colours[0] = 24; window->colours[1] = 24; window->colours[2] = 24; @@ -405,9 +405,9 @@ static int window_land_should_close() { if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) return 1; - if (RCT2_GLOBAL(0x009DE544, rct_windowclass) != WC_TOP_TOOLBAR) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR) return 1; - if (RCT2_GLOBAL(0x009DE546, sint16) != 7) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, sint16) != 7) return 1; return 0; } diff --git a/src/window_main.c b/src/window_main.c index ba79333998..2c95d7cbc8 100644 --- a/src/window_main.c +++ b/src/window_main.c @@ -63,7 +63,7 @@ void window_main_open() or word ptr [edi+12h], 400h } - RCT2_GLOBAL(0x0141E9E0, sint32) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32) = 0; RCT2_GLOBAL(0x009E32B0, uint8) = 0; RCT2_GLOBAL(0x009E32B2, uint8) = 0; RCT2_GLOBAL(0x009E32B3, uint8) = 0; diff --git a/src/window_park.c b/src/window_park.c index 8480be7627..84550d2026 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -644,7 +644,7 @@ static void window_park_entrance_close() __asm mov w, esi if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) - if (w->classification == RCT2_GLOBAL(0x009DE544, rct_windowclass) && w->number == RCT2_GLOBAL(0x009DE542, rct_windownumber)) + if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) RCT2_CALLPROC_EBPSAFE(0x006EE281); } @@ -1617,7 +1617,7 @@ void window_park_objective_open() } if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) - if (window->classification == RCT2_GLOBAL(0x009DE544, rct_windowclass) && window->number == RCT2_GLOBAL(0x009DE542, rct_windownumber)) + if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) RCT2_CALLPROC_EBPSAFE(0x006EE281); window->viewport = NULL; diff --git a/src/window_water.c b/src/window_water.c index fa0a0c12c2..6b7eab58a5 100644 --- a/src/window_water.c +++ b/src/window_water.c @@ -232,9 +232,9 @@ static int window_water_should_close() { if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) return 1; - if (RCT2_GLOBAL(0x009DE544, rct_windowclass) != WC_TOP_TOOLBAR) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR) return 1; - if (RCT2_GLOBAL(0x009DE546, uint16) != 8) + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != 8) return 1; return 0; } From 6dff411f2d445277a59ea4e63278486d5d3cadab Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 28 Apr 2014 02:35:23 +0100 Subject: [PATCH 09/17] fix bugs in game_handle_input_mouse --- src/game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game.c b/src/game.c index 3aa242b296..3a34b542fa 100644 --- a/src/game.c +++ b/src/game.c @@ -309,7 +309,7 @@ static void game_handle_input_mouse(int x, int y, int state) window_close_by_id(5, 0); if (w != NULL) - window_bring_to_front(w); + w = window_bring_to_front(w); if (widgetIndex == -1) break; @@ -635,7 +635,7 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) if (w == NULL) return; - window_bring_to_front(w); + w = window_bring_to_front(w); if (widgetIndex == -1) return; @@ -684,7 +684,7 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_SCROLL_LEFT; RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex; RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass; - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windowclass) = windowNumber; + RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) = windowNumber; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y; From eba38c7bb97d324a27f116d3a40d912a256a7250 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 28 Apr 2014 02:35:37 +0100 Subject: [PATCH 10/17] add about window --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 + src/strings.h | 23 ++++ src/window.h | 3 + src/window_about.c | 199 ++++++++++++++++++++++++++++++ src/window_game_top_toolbar.c | 2 +- 6 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 src/window_about.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index f42dbdeb6d..6cff1ca042 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -78,6 +78,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 80c4dd0124..ae7245d7f1 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -251,6 +251,9 @@ Source Files + + Windows + diff --git a/src/strings.h b/src/strings.h index 3743e75d2a..583bc4738e 100644 --- a/src/strings.h +++ b/src/strings.h @@ -144,6 +144,24 @@ enum { STR_PAUSE_GAME_TIP = 833, STR_DISC_AND_GAME_OPTIONS_TIP = 834, + STR_ROLLERCOASTER_TYCOON_2 = 848, + STR_VERSION_X = 849, + STR_COPYRIGHT_CS = 850, + STR_DESIGNED_AND_PROGRAMMED_BY_CS = 851, + STR_GRAPHICS_BY_SF = 852, + STR_SOUND_AND_MUSIC_BY_AB = 853, + STR_ADDITIONAL_SOUNDS_RECORDED_BY_DE = 854, + STR_REPRESENTATION_BY_JL = 855, + STR_THANKS_TO = 856, + STR_THANKS_TO_PEOPLE = 857, + STR_CREDIT_SPARE_1 = 858, + STR_CREDIT_SPARE_2 = 859, + STR_CREDIT_SPARE_3 = 860, + STR_CREDIT_SPARE_4 = 861, + STR_CREDIT_SPARE_5 = 862, + STR_CREDIT_SPARE_6 = 863, + STR_CREDIT_SPARE_7 = 864, + STR_SCR_BMP = 890, STR_SCREENSHOT = 891, STR_SCREENSHOT_SAVED_AS = 892, @@ -354,6 +372,11 @@ enum { STR_TUTORIAL = 2856, STR_PRESS_KEY_OR_MOUSE_BUTTON_FOR_CONTROL = 2857, + STR_INFOGRAMES_INTERACTIVE_CREDITS = 2860, + STR_LICENSED_TO_INFOGRAMES_INTERACTIVE_INC = 2861, + STR_MUSIC_ACKNOWLEDGEMENTS_ELLIPSIS = 2862, + STR_MUSIC_ACKNOWLEDGEMENTS = 2863, + STR_LICENCE_AGREEMENT_NOTICE_1 = 2969, STR_LICENCE_AGREEMENT_NOTICE_2 = 2970, diff --git a/src/window.h b/src/window.h index 305ed237d4..41ec37d2e7 100644 --- a/src/window.h +++ b/src/window.h @@ -245,6 +245,8 @@ enum { WC_TOOLTIP = 5, WC_DROPDOWN = 6, WC_ABOUT = 8, + WC_MUSIC_CREDITS = 9, + WC_PUBLISHER_CREDITS = 10, WC_ERROR = 11, WC_RIDE = 12, WC_RIDE_CONSTRUCTION = 13, @@ -321,6 +323,7 @@ void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth, void window_main_open(); void window_game_top_toolbar_open(); void window_game_bottom_toolbar_open(); +void window_about_open(); void window_title_menu_open(); void window_title_exit_open(); void window_title_logo_open(); diff --git a/src/window_about.c b/src/window_about.c new file mode 100644 index 0000000000..c6657996f8 --- /dev/null +++ b/src/window_about.c @@ -0,0 +1,199 @@ +/***************************************************************************** + * 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 +#include "addresses.h" +#include "strings.h" +#include "sprites.h" +#include "widget.h" +#include "window.h" + +static enum WINDOW_ABOUT_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_MUSIC_CREDITS, + WIDX_PUBLISHER_CREDITS +}; + +static rct_widget window_about_widgets[] = { + { WWT_FRAME, 0, 0, 399, 0, 329, 0x0FFFFFFFF, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 398, 1, 14, STR_ROLLERCOASTER_TYCOON_2, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 387, 397, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_DROPDOWN_BUTTON, 1, 100, 299, 230, 241, STR_MUSIC_ACKNOWLEDGEMENTS_ELLIPSIS, STR_NONE }, // music credits button + { WWT_DROPDOWN_BUTTON, 1, 157, 356, 307, 318, STR_INFOGRAMES_INTERACTIVE_CREDITS, STR_NONE }, // infogrames credits button + { WIDGETS_END }, +}; + +static void window_about_emptysub() { } +static void window_about_mouseup(); +static void window_about_paint(); + +static uint32 window_about_events[] = { + window_about_emptysub, + window_about_mouseup, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_emptysub, + window_about_paint, + window_about_emptysub +}; + +/** + * + * rct2: 0x0066D2AC + */ +void window_about_open() +{ + int x, y; + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_ABOUT, 0); + if (window != NULL) + return; + + window = window_create( + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2 - 200, + max(28, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) / 2 - 165), + 400, + 330, + window_about_events, + WC_ABOUT, + 0 + ); + window->widgets = window_about_widgets; + window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_MUSIC_CREDITS) | (1 << WIDX_PUBLISHER_CREDITS); + + window_init_scroll_widgets(window); + window->colours[0] = 7; + window->colours[1] = 7; + window->colours[2] = 7; +} + +/** + * + * rct2: 0x0066D4D5 + */ +static void window_about_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_MUSIC_CREDITS: + RCT2_CALLPROC_EBPSAFE(0x0066D4EC); + break; + case WIDX_PUBLISHER_CREDITS: + RCT2_CALLPROC_EBPSAFE(0x0066D55B); + break; + } +} + +/** + * + * rct2: 0x0066D321 + */ +static void window_about_paint() +{ + int x, y; + rct_window *w; + rct_drawpixelinfo *dpi; + + __asm mov w, esi + __asm mov dpi, edi + + window_draw_widgets(w, dpi); + + x = w->x + 200; + y = w->y + 17; + + // Version + RCT2_GLOBAL(0x009C383C, uint8) = 49; + gfx_draw_string_centred(dpi, STR_VERSION_X, x, y, 0, 0x009E2D28); + + // Credits + RCT2_GLOBAL(0x009C383C, uint8) = 48; + y += 10; + gfx_draw_string_centred(dpi, STR_COPYRIGHT_CS, x, y, 0, 0x009E2D28); + y += 79; + gfx_draw_string_centred(dpi, STR_DESIGNED_AND_PROGRAMMED_BY_CS, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_GRAPHICS_BY_SF, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_SOUND_AND_MUSIC_BY_AB, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_ADDITIONAL_SOUNDS_RECORDED_BY_DE, x, y, 0, 0x009E2D28); + y += 13; + gfx_draw_string_centred(dpi, STR_REPRESENTATION_BY_JL, x, y, 0, 0x009E2D28); + y += 25; + gfx_draw_string_centred(dpi, STR_THANKS_TO, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_THANKS_TO_PEOPLE, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_1, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_2, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_3, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_4, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_5, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_6, x, y, 0, 0x009E2D28); + y += 10; + gfx_draw_string_centred(dpi, STR_CREDIT_SPARE_7, x, y, 0, 0x009E2D28); + + // Images + gfx_draw_sprite(dpi, SPR_CREDITS_CHRIS_SAWYER_SMALL, w->x + 92, w->y + 40); + gfx_draw_sprite(dpi, SPR_CREDITS_INFOGRAMES, w->x + 50, w->y + 247); + + // Licence + gfx_draw_string_left(dpi, STR_LICENSED_TO_INFOGRAMES_INTERACTIVE_INC, 0, 0, w->x + 157, w->y + 257); +} \ No newline at end of file diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index acd1ab0180..fdf6697dbb 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -372,7 +372,7 @@ static void window_game_top_toolbar_dropdown() } break; case 3: // about - RCT2_CALLPROC_EBPSAFE(0x0066D2AC); + window_about_open(); break; case 4: // options RCT2_CALLPROC_EBPSAFE(0x006BAC5B); From 4201ff06d21d12f57cd8a80e3322709a018ef753 Mon Sep 17 00:00:00 2001 From: Alexander Overvoorde Date: Mon, 28 Apr 2014 16:06:07 +0200 Subject: [PATCH 11/17] Add separate key buffer for shortcuts to fix misbehaving panning with keyboard --- src/game.c | 4 ++-- src/osinterface.c | 7 +++++++ src/osinterface.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/game.c b/src/game.c index 3a34b542fa..f64ce69e2d 100644 --- a/src/game.c +++ b/src/game.c @@ -850,8 +850,8 @@ int get_next_key() { int i; for (i = 0; i < 221; i++) { - if (gKeysState[i]) { - gKeysState[i] = 0; + if (gKeysPressed[i]) { + gKeysPressed[i] = 0; return i; } } diff --git a/src/osinterface.c b/src/osinterface.c index 7d11ff2ced..4299f7f5fb 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -31,6 +31,7 @@ typedef void(*update_palette_func)(char*, int, int); openrct2_cursor gCursorState; unsigned char* gKeysState; +unsigned char* gKeysPressed; unsigned int gLastKeyPressed; static void osinterface_create_window(); @@ -49,6 +50,9 @@ void osinterface_init() { osinterface_create_window(); + gKeysPressed = malloc(sizeof(unsigned char) * 256); + memset(gKeysPressed, 0, sizeof(unsigned char) * 256); + // RCT2_CALLPROC(0x00404584); // dinput_init() } @@ -253,6 +257,7 @@ void osinterface_process_messages() break; case SDL_KEYDOWN: gLastKeyPressed = e.key.keysym.sym; + gKeysPressed[e.key.keysym.scancode] = 1; break; default: break; @@ -278,6 +283,8 @@ static void osinterface_close_window() void osinterface_free() { + free(gKeysPressed); + osinterface_close_window(); SDL_Quit(); } diff --git a/src/osinterface.h b/src/osinterface.h index ee7e83505f..205d0170a0 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -38,6 +38,7 @@ typedef struct { extern openrct2_cursor gCursorState; extern unsigned char* gKeysState; +extern unsigned char* gKeysPressed; extern unsigned int gLastKeyPressed; void osinterface_init(); From 6f11cc90ff83187740d0e08e0c9f672a10ae4a92 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 28 Apr 2014 15:29:54 +0100 Subject: [PATCH 12/17] credit author in source code header --- src/osinterface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osinterface.c b/src/osinterface.c index 4299f7f5fb..2b2484f70c 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Alexander Overvoorde * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. From b5bb145f039a6b6ac60763698602f173467b7249 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 23:12:08 +0200 Subject: [PATCH 13/17] Move all the transition tables to our code. --- src/climate.c | 119 ++++++++++++++++++++++++++++++++++++++++++-------- src/climate.h | 1 + 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/climate.c b/src/climate.c index 63ce668a95..f96ef33d31 100644 --- a/src/climate.c +++ b/src/climate.c @@ -28,18 +28,6 @@ void determine_future_weather(); -// rct2: 0x00993C94 -// There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented -const rct_weather weather_data[6] = { - { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny - { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy - { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy - { .temp_delta = -2, .effect_level = 1, .gloom_level = 1, .rain_level = 1, .sprite_id = 0x5A99 }, // Rain - { .temp_delta = -4, .effect_level = 1, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9A }, // Heavy Rain - { .temp_delta = 2, .effect_level = 2, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9B }, // Thunderstorm -}; - - int climate_celcius_to_fahrenheit(int celcius) { return (celcius * 29) / 16 + 32; @@ -135,19 +123,116 @@ void update_climate() void determine_future_weather() { sint8 climate = RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8); - rct_weather_transition** climate_table = ((rct_weather_transition***)0x00993998)[climate]; + const rct_weather_transition* climate_table = climate_transitions[climate]; sint8 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; - // don't do this at home. Temporary measure until we rewrite the tables. - rct_weather_transition* transition = climate_table[month]; + rct_weather_transition transition = climate_table[month]; // generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly - sint8 next_weather = transition->distribution[ ((rand() & 0xFF) * transition->distribution_size) >> 8 ]; + sint8 next_weather = transition.distribution[ ((rand() & 0xFF) * transition.distribution_size) >> 8 ]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition->base_temperature + weather_data[next_weather].temp_delta; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition.base_temperature + weather_data[next_weather].temp_delta; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_data[next_weather].effect_level; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_data[next_weather].gloom_level; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_data[next_weather].rain_level; RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } + + + +#pragma region Climate/Weather data tables +// rct2: 0x00993C94 +// There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented +const rct_weather weather_data[6] = { + { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny + { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy + { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy + { .temp_delta = -2, .effect_level = 1, .gloom_level = 1, .rain_level = 1, .sprite_id = 0x5A99 }, // Rain + { .temp_delta = -4, .effect_level = 1, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9A }, // Heavy Rain + { .temp_delta = 2, .effect_level = 2, .gloom_level = 2, .rain_level = 2, .sprite_id = 0x5A9B }, // Thunderstorm +}; + + +// rct2: 00993998 +const rct_weather_transition cool_and_wet_climate_transitions[] = { + { .base_temperature = 8, .distribution_size = 18, + .distribution = { 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 0, 0, 0, 0, 0 } }, + { .base_temperature = 10, .distribution_size = 21, + .distribution = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 0, 0 } }, + { .base_temperature = 14, .distribution_size = 17, + .distribution = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 17, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 19, .distribution_size = 23, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4 } }, + { .base_temperature = 20, .distribution_size = 23, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 } }, + { .base_temperature = 16, .distribution_size = 19, + .distribution = { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0 } }, + { .base_temperature = 13, .distribution_size = 16, + .distribution = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0 } } +}; +const rct_weather_transition warm_climate_transitions[] = { + { .base_temperature = 12, .distribution_size = 21, + .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 4, 0, 0 } }, + { .base_temperature = 13, .distribution_size = 22, + .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 0 } }, + { .base_temperature = 16, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 19, .distribution_size = 18, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0 } }, + { .base_temperature = 21, .distribution_size = 22, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0 } }, + { .base_temperature = 22, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 5, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 19, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 16, .distribution_size = 17, + .distribution = { 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0 } } +}; +const rct_weather_transition hot_and_dry_climate_transitions[] = { + { .base_temperature = 12, .distribution_size = 15, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 14, .distribution_size = 12, + .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 16, .distribution_size = 11, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 19, .distribution_size = 9, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 21, .distribution_size = 13, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 22, .distribution_size = 11, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 21, .distribution_size = 12, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 16, .distribution_size = 13, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } +}; +const rct_weather_transition cold_climate_transitions[] = { + { .base_temperature = 4, .distribution_size = 18, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 4, 0, 0, 0, 0, 0 } }, + { .base_temperature = 5, .distribution_size = 21, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 0, 0 } }, + { .base_temperature = 7, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 9, .distribution_size = 17, + .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0 } }, + { .base_temperature = 10, .distribution_size = 23, + .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4 } }, + { .base_temperature = 11, .distribution_size = 23, + .distribution = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5 } }, + { .base_temperature = 9, .distribution_size = 19, + .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 0, 0, 0, 0 } }, + { .base_temperature = 6, .distribution_size = 16, + .distribution = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0 } } +}; + +const rct_weather_transition* climate_transitions[] = { + cool_and_wet_climate_transitions, + warm_climate_transitions, + hot_and_dry_climate_transitions, + cold_climate_transitions +}; + +#pragma endregion \ No newline at end of file diff --git a/src/climate.h b/src/climate.h index 9d28ba297e..b7a728305b 100644 --- a/src/climate.h +++ b/src/climate.h @@ -45,6 +45,7 @@ typedef struct { } rct_weather; extern const rct_weather weather_data[6]; +extern const rct_weather_transition* climate_transitions[4]; int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); From bda09d93d5e914ff0248e89baf04b15455195416 Mon Sep 17 00:00:00 2001 From: Matthias Lanzinger Date: Mon, 28 Apr 2014 23:19:18 +0200 Subject: [PATCH 14/17] Move include inside guard block. --- src/climate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/climate.h b/src/climate.h index b7a728305b..d50731677f 100644 --- a/src/climate.h +++ b/src/climate.h @@ -18,11 +18,11 @@ * along with this program. If not, see . *****************************************************************************/ -#include "rct2.h" - #ifndef _CLIMATE_H_ #define _CLIMATE_H_ +#include "rct2.h" + enum { CLIMATE_COOL_AND_WET, CLIMATE_WARM, From 1dcfdbe355b804011f5f36e28928cf8d92733288 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Apr 2014 12:18:50 +0100 Subject: [PATCH 15/17] refactor climate --- src/climate.c | 74 ++++++++++++++++++-------------- src/climate.h | 11 +---- src/game.c | 2 +- src/window_game_bottom_toolbar.c | 6 +-- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/climate.c b/src/climate.c index f96ef33d31..061ddd1bbb 100644 --- a/src/climate.c +++ b/src/climate.c @@ -24,8 +24,15 @@ #include "gfx.h" #include "rct2.h" +typedef struct { + sint8 base_temperature; + sint8 distribution_size; + sint8 distribution[24]; +} rct_weather_transition; -void determine_future_weather(); +static const rct_weather_transition* climate_transitions[4]; + +static void climate_determine_future_weather(); int climate_celcius_to_fahrenheit(int celcius) @@ -40,16 +47,17 @@ int climate_celcius_to_fahrenheit(int celcius) void climate_reset(int climate) { RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8) = climate; - determine_future_weather(); + climate_determine_future_weather(); } /** * Weather & climate update iteration. * Gradually changes the weather parameters towards their determined next values. + * * rct2: 0x006C46B1 - **/ -void update_climate() + */ +void climate_update() { uint8 screen_flags = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8); sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8), @@ -78,13 +86,12 @@ void update_climate() if (cur_rain == next_rain) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); - determine_future_weather(); + climate_determine_future_weather(); RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? - } - else { - if (next_rain == 3) + } else { + if (next_rain == 3) { cur_rain = 3; - else { + } else { sint8 next_rain_step = cur_rain + 1; if (cur_rain > next_rain) next_rain_step = cur_rain - 1; @@ -113,38 +120,39 @@ void update_climate() /** -* Calculates future weather development. -* RCT2 implements this as discrete probability distributions dependant on month and climate -* for next_weather. The other weather parameters are then looked up depending only on the -* next weather. -* -* rct2: 0x006C461C -**/ -void determine_future_weather() + * Calculates future weather development. + * RCT2 implements this as discrete probability distributions dependant on month and climate + * for next_weather. The other weather parameters are then looked up depending only on the + * next weather. + * + * rct2: 0x006C461C + */ +static void climate_determine_future_weather() { sint8 climate = RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, sint8); const rct_weather_transition* climate_table = climate_transitions[climate]; sint8 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; rct_weather_transition transition = climate_table[month]; - // generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly + // Generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly sint8 next_weather = transition.distribution[ ((rand() & 0xFF) * transition.distribution_size) >> 8 ]; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition.base_temperature + weather_data[next_weather].temp_delta; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = weather_data[next_weather].effect_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = weather_data[next_weather].gloom_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = weather_data[next_weather].rain_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition.base_temperature + climate_weather_data[next_weather].temp_delta; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = climate_weather_data[next_weather].effect_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = climate_weather_data[next_weather].gloom_level; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = climate_weather_data[next_weather].rain_level; RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } -#pragma region Climate/Weather data tables +#pragma region Climate / Weather data tables + // rct2: 0x00993C94 // There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented -const rct_weather weather_data[6] = { +const rct_weather climate_weather_data[6] = { { .temp_delta = 10, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A96 }, // Sunny { .temp_delta = 5, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A97 }, // Partially Cloudy { .temp_delta = 0, .effect_level = 0, .gloom_level = 0, .rain_level = 0, .sprite_id = 0x5A98 }, // Cloudy @@ -155,7 +163,7 @@ const rct_weather weather_data[6] = { // rct2: 00993998 -const rct_weather_transition cool_and_wet_climate_transitions[] = { +static const rct_weather_transition climate_cool_and_wet_transitions[] = { { .base_temperature = 8, .distribution_size = 18, .distribution = { 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 0, 0, 0, 0, 0 } }, { .base_temperature = 10, .distribution_size = 21, @@ -173,7 +181,7 @@ const rct_weather_transition cool_and_wet_climate_transitions[] = { { .base_temperature = 13, .distribution_size = 16, .distribution = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0 } } }; -const rct_weather_transition warm_climate_transitions[] = { +static const rct_weather_transition climate_warm_transitions[] = { { .base_temperature = 12, .distribution_size = 21, .distribution = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 4, 0, 0 } }, { .base_temperature = 13, .distribution_size = 22, @@ -191,7 +199,7 @@ const rct_weather_transition warm_climate_transitions[] = { { .base_temperature = 16, .distribution_size = 17, .distribution = { 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0 } } }; -const rct_weather_transition hot_and_dry_climate_transitions[] = { +static const rct_weather_transition climate_hot_and_dry_transitions[] = { { .base_temperature = 12, .distribution_size = 15, .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0 } }, { .base_temperature = 14, .distribution_size = 12, @@ -209,7 +217,7 @@ const rct_weather_transition hot_and_dry_climate_transitions[] = { { .base_temperature = 16, .distribution_size = 13, .distribution = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }; -const rct_weather_transition cold_climate_transitions[] = { +static const rct_weather_transition climate_cold_transitions[] = { { .base_temperature = 4, .distribution_size = 18, .distribution = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 4, 0, 0, 0, 0, 0 } }, { .base_temperature = 5, .distribution_size = 21, @@ -228,11 +236,11 @@ const rct_weather_transition cold_climate_transitions[] = { .distribution = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0 } } }; -const rct_weather_transition* climate_transitions[] = { - cool_and_wet_climate_transitions, - warm_climate_transitions, - hot_and_dry_climate_transitions, - cold_climate_transitions +static const rct_weather_transition* climate_transitions[] = { + climate_cool_and_wet_transitions, + climate_warm_transitions, + climate_hot_and_dry_transitions, + climate_cold_transitions }; #pragma endregion \ No newline at end of file diff --git a/src/climate.h b/src/climate.h index d50731677f..5d1bd23ab8 100644 --- a/src/climate.h +++ b/src/climate.h @@ -30,12 +30,6 @@ enum { CLIMATE_COLD }; -typedef struct { - sint8 base_temperature; - sint8 distribution_size; - sint8 distribution[24]; -} rct_weather_transition; - typedef struct { sint8 temp_delta; sint8 effect_level; @@ -44,11 +38,10 @@ typedef struct { uint32 sprite_id; } rct_weather; -extern const rct_weather weather_data[6]; -extern const rct_weather_transition* climate_transitions[4]; +extern const rct_weather climate_weather_data[6]; int climate_celcius_to_fahrenheit(int celcius); void climate_reset(int climate); -void update_climate(); +void climate_update(); #endif diff --git a/src/game.c b/src/game.c index f5400f288f..d5f909d3b1 100644 --- a/src/game.c +++ b/src/game.c @@ -137,7 +137,7 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x0068B089); RCT2_CALLPROC_EBPSAFE(0x006C44B1); // update_objective - update_climate(); + climate_update(); RCT2_CALLPROC_EBPSAFE(0x006646E1); RCT2_CALLPROC_EBPSAFE(0x006A876D); peep_update_all(); diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 58c7e399ce..7bc65b8654 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -480,13 +480,13 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, x += 30; // Current weather - gfx_draw_sprite(dpi, weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); + gfx_draw_sprite(dpi, climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); // Next weather - if (weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { + if (climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) < 960) { gfx_draw_sprite(dpi, SPR_NEXT_WEATHER, x + 27, y + 5); - gfx_draw_sprite(dpi, weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); + gfx_draw_sprite(dpi, climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); } } } From a325bcc8569c83cb0370d590aa6e9d224162d99f Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Apr 2014 12:35:37 +0100 Subject: [PATCH 16/17] define next climate variables, all refs rewritten --- src/climate.c | 28 +++++++++++++++++----------- src/climate.h | 1 + src/window_game_bottom_toolbar.c | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/climate.c b/src/climate.c index 061ddd1bbb..e56938f550 100644 --- a/src/climate.c +++ b/src/climate.c @@ -30,11 +30,17 @@ typedef struct { sint8 distribution[24]; } rct_weather_transition; +int gClimateNextWeather; + +static int _climateNextTemperature; +static int _climateNextWeatherEffect; +static int _climateNextWeatherGloom; +static int _climateNextRainLevel; + static const rct_weather_transition* climate_transitions[4]; static void climate_determine_future_weather(); - int climate_celcius_to_fahrenheit(int celcius) { return (celcius * 29) / 16 + 32; @@ -61,11 +67,11 @@ void climate_update() { uint8 screen_flags = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8); sint8 temperature = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TEMPERATURE, sint8), - target_temperature = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8), + target_temperature = _climateNextTemperature, cur_gloom = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8), - next_gloom = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8), + next_gloom = _climateNextWeatherGloom, cur_rain = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8), - next_rain = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8); + next_rain = _climateNextRainLevel; if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only normal play mode gets climate @@ -82,10 +88,10 @@ void climate_update() if (temperature == target_temperature) { if (cur_gloom == next_gloom) { - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = _climateNextWeatherEffect; if (cur_rain == next_rain) { - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = gClimateNextWeather; climate_determine_future_weather(); RCT2_GLOBAL(0x009A9804, uint32) |= 8; // climate dirty flag? } else { @@ -136,12 +142,12 @@ static void climate_determine_future_weather() // Generate a random variable with values 0 upto distribution_size-1 and chose weather from the distribution table accordingly sint8 next_weather = transition.distribution[ ((rand() & 0xFF) * transition.distribution_size) >> 8 ]; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8) = next_weather; + gClimateNextWeather = next_weather; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_TEMPERATURE, sint8) = transition.base_temperature + climate_weather_data[next_weather].temp_delta; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_EFFECT, sint8) = climate_weather_data[next_weather].effect_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER_GLOOM, sint8) = climate_weather_data[next_weather].gloom_level; - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RAIN_LEVEL, sint8) = climate_weather_data[next_weather].rain_level; + _climateNextTemperature = transition.base_temperature + climate_weather_data[next_weather].temp_delta; + _climateNextWeatherEffect = climate_weather_data[next_weather].effect_level; + _climateNextWeatherGloom = climate_weather_data[next_weather].gloom_level; + _climateNextRainLevel = climate_weather_data[next_weather].rain_level; RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } diff --git a/src/climate.h b/src/climate.h index 5d1bd23ab8..ac04df7eb8 100644 --- a/src/climate.h +++ b/src/climate.h @@ -38,6 +38,7 @@ typedef struct { uint32 sprite_id; } rct_weather; +extern int gClimateNextWeather; extern const rct_weather climate_weather_data[6]; int climate_celcius_to_fahrenheit(int celcius); diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 7bc65b8654..c161165956 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -483,10 +483,10 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, gfx_draw_sprite(dpi, climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id, x, y); // Next weather - if (climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id) { + if (climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8)].sprite_id != climate_weather_data[gClimateNextWeather].sprite_id) { if (RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) < 960) { gfx_draw_sprite(dpi, SPR_NEXT_WEATHER, x + 27, y + 5); - gfx_draw_sprite(dpi, climate_weather_data[RCT2_GLOBAL(RCT2_ADDRESS_NEXT_WEATHER, sint8)].sprite_id, x + 40, y); + gfx_draw_sprite(dpi, climate_weather_data[gClimateNextWeather].sprite_id, x + 40, y); } } } From 073057dbbe513d442f470c15895d52ab3dea7123 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Apr 2014 12:39:18 +0100 Subject: [PATCH 17/17] add author credit to source code header --- src/climate.c | 2 +- src/climate.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/climate.c b/src/climate.c index e56938f550..dd2275be2a 100644 --- a/src/climate.c +++ b/src/climate.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Matthias Lanzinger * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. diff --git a/src/climate.h b/src/climate.h index ac04df7eb8..2c035b86f7 100644 --- a/src/climate.h +++ b/src/climate.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Matthias Lanzinger * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2.