mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Merge branch 'master' into path-window
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
<ClCompile Include="..\src\window_park.c" />
|
||||
<ClCompile Include="..\src\window_footpath.c" />
|
||||
<ClCompile Include="..\src\window_ride_list.c" />
|
||||
<ClCompile Include="..\src\window_save_prompt.c" />
|
||||
<ClCompile Include="..\src\window_title_exit.c" />
|
||||
<ClCompile Include="..\src\window_title_logo.c" />
|
||||
<ClCompile Include="..\src\window_main.c" />
|
||||
|
||||
@@ -260,6 +260,9 @@
|
||||
<ClCompile Include="..\src\window_footpath.c">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\window_save_prompt.c">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\openrct2.exe">
|
||||
|
||||
@@ -49,7 +49,7 @@ The aim is to decompile RollerCoaster Tycoon 2 fully into C so that it can remai
|
||||
1. Checkout the repository. This can be done using [GitHub Windows](https://windows.github.com/) or [other tools](https://help.github.com/articles/which-remote-url-should-i-use).
|
||||
2. Download [SDL2 development library for Visual C++]((http://www.libsdl.org/release/SDL2-devel-2.0.3-VC.zip)) and copy it to a new directory called "sdl" in the repository. This directory should contain "include". The path should be something like ```\GitHub\OpenRCT2\sdl\include\```.
|
||||
3. Open the solution in the projects directory (**openrct2.vcxproj**) with Visual C++.
|
||||
4. In *rct2.c*, ```GAME_PATH``` can be edited to reflect your RollerCoaster Tycoon 2 installation. Each slash needs to be marked twice, like this: ```C:\\Program Files (x86)\\GOGcom\\RollerCoaster Tycoon 2\\RollerCoaster Tycoon 2 Triple Thrill Pack```. Existing registry keys and the original RCT2 executable are not required.
|
||||
4. In *rct2.c*, ```GAME_PATH``` **must** be edited to reflect your RollerCoaster Tycoon 2 installation. Each slash needs to be marked twice, like this: ```C:\\Program Files (x86)\\GOGcom\\RollerCoaster Tycoon 2\\RollerCoaster Tycoon 2 Triple Thrill Pack```. Existing registry keys and the original RCT2 executable are not required.
|
||||
5. [Select the 'Release' configuration](http://msdn.microsoft.com/en-us/library/wx0123s5.aspx) and click Build -> Rebuild Solution. The dropdown menu to enable the 'release' configuration is towards the top of the VS Express window, near the "TEST" menu.
|
||||
6. Start debugging. Press the "Local Windows Debugger" button with a green "play" icon next to it. If warned about *openrct2.exe* not having debug information, just continue.
|
||||
7. If the game crashes, you may need to press the red, square button along the top of VS Express (for "stop") to stop the program.
|
||||
|
||||
211
src/game.c
211
src/game.c
@@ -29,6 +29,7 @@
|
||||
#include "peep.h"
|
||||
#include "screenshot.h"
|
||||
#include "strings.h"
|
||||
#include "title.h"
|
||||
#include "tutorial.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
@@ -986,6 +987,8 @@ static int game_check_affordability(int cost)
|
||||
return ebp;
|
||||
}
|
||||
|
||||
static uint32 game_do_command_table[58];
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006677F2
|
||||
@@ -1004,9 +1007,6 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb
|
||||
original_edi = edi;
|
||||
original_ebp = ebp;
|
||||
|
||||
RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return ebx;
|
||||
|
||||
flags = ebx;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF;
|
||||
|
||||
@@ -1016,7 +1016,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb
|
||||
ebx &= ~1;
|
||||
|
||||
// Primary command
|
||||
RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
cost = ebx;
|
||||
|
||||
if (cost != 0x80000000) {
|
||||
@@ -1039,7 +1039,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb
|
||||
}
|
||||
|
||||
// Secondary command
|
||||
RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
edx = ebx;
|
||||
|
||||
if (edx != 0x80000000 && edx < cost)
|
||||
@@ -1075,4 +1075,203 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb
|
||||
window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16));
|
||||
|
||||
return 0x80000000;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DB5F
|
||||
*/
|
||||
static void game_load_or_quit()
|
||||
{
|
||||
rct_window *w;
|
||||
char input_bl, input_dl;
|
||||
short input_di;
|
||||
|
||||
__asm mov input_bl, bl
|
||||
__asm mov input_dl, dl
|
||||
__asm mov input_di, di
|
||||
|
||||
if (!(input_bl & 1))
|
||||
return 0;
|
||||
|
||||
switch (input_dl) {
|
||||
case 0:
|
||||
RCT2_GLOBAL(0x009A9802, uint16) = input_di;
|
||||
window_save_prompt_open();
|
||||
break;
|
||||
case 1:
|
||||
window_close_by_id(WC_SAVE_PROMPT, 0);
|
||||
break;
|
||||
default:
|
||||
game_load_or_quit_no_save_prompt();
|
||||
break;
|
||||
}
|
||||
|
||||
__asm mov ebx, 0
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00674F40
|
||||
*/
|
||||
static int open_landscape_file_dialog()
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
RCT2_CALLFUNC_X(0x00674F40, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return eax;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00674EB6
|
||||
*/
|
||||
static int open_load_game_dialog()
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
RCT2_CALLFUNC_X(0x00674EB6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return eax;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DC0F
|
||||
*/
|
||||
static void load_landscape()
|
||||
{
|
||||
if (open_landscape_file_dialog() == 0) {
|
||||
gfx_invalidate_screen();
|
||||
} else {
|
||||
// string stuff
|
||||
|
||||
RCT2_CALLPROC_EBPSAFE(0x006758C0);
|
||||
if (1) {
|
||||
gfx_invalidate_screen();
|
||||
// game_loop_iteration
|
||||
} else {
|
||||
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
|
||||
// game_loop_iteration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DBB7
|
||||
*/
|
||||
static void load_game()
|
||||
{
|
||||
if (open_load_game_dialog() == 0) {
|
||||
gfx_invalidate_screen();
|
||||
} else {
|
||||
// string stuff
|
||||
|
||||
RCT2_CALLPROC_EBPSAFE(0x00675E1B);
|
||||
if (1) {
|
||||
gfx_invalidate_screen();
|
||||
// game_loop_iteration
|
||||
} else {
|
||||
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
|
||||
// game_loop_iteration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006E3879
|
||||
*/
|
||||
static void rct2_exit()
|
||||
{
|
||||
RCT2_CALLPROC_EBPSAFE(0x006E3879);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DB79
|
||||
*/
|
||||
void game_load_or_quit_no_save_prompt()
|
||||
{
|
||||
if (RCT2_GLOBAL(0x009A9802, uint16) < 1) {
|
||||
game_do_command(0, 1, 0, 1, 5, 0, 0);
|
||||
RCT2_CALLPROC_EBPSAFE(0x006EE281); // tool_cancel
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
|
||||
load_landscape();
|
||||
else
|
||||
load_game();
|
||||
} else if (RCT2_GLOBAL(0x009A9802, uint16) == 1) {
|
||||
game_do_command(0, 1, 0, 1, 5, 0, 0);
|
||||
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) {
|
||||
RCT2_CALLPROC_EBPSAFE(0x0040705E);
|
||||
RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 5);
|
||||
}
|
||||
title_load();
|
||||
// game_loop_iteration
|
||||
} else {
|
||||
rct2_exit();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region Game command function table
|
||||
|
||||
static uint32 game_do_command_table[58] = {
|
||||
0x006B2FC5,
|
||||
0x0066397F,
|
||||
0x00667C15,
|
||||
0x006C511D,
|
||||
0x006C5B69,
|
||||
0x0066DB5F, // game_load_or_quit,
|
||||
0x006B3F0F,
|
||||
0x006B49D9,
|
||||
0x006B4EA6,
|
||||
0x006B52D4,
|
||||
0x006B578B,
|
||||
0x006B5559,
|
||||
0x006660A8,
|
||||
0x0066640B,
|
||||
0x006E0E01,
|
||||
0x006E08F4,
|
||||
0x006E650F,
|
||||
0x006A61DE,
|
||||
0x006A68AE,
|
||||
0x006A67C0,
|
||||
0x00663CCD,
|
||||
0x006B53E9,
|
||||
0x00698D6C,
|
||||
0x0068C542,
|
||||
0x0068C6D1,
|
||||
0x0068BC01,
|
||||
0x006E66A0,
|
||||
0x006E6878,
|
||||
0x006C5AE9,
|
||||
0x006BEFA1,
|
||||
0x006C09D1,
|
||||
0x006C0B83,
|
||||
0x006C0BB5,
|
||||
0x00669C6D,
|
||||
0x00669D4A,
|
||||
0x006649BD,
|
||||
0x006666E7,
|
||||
0x00666A63,
|
||||
0x006CD8CE,
|
||||
0x00669E30,
|
||||
0x00669E55,
|
||||
0x006E519A,
|
||||
0x006E5597,
|
||||
0x006B893C,
|
||||
0x006B8E1B,
|
||||
0x0069DFB3,
|
||||
0x00684A7F,
|
||||
0x006D13FE,
|
||||
0x0069E73C,
|
||||
0x006CDEE4,
|
||||
0x006B9E6D,
|
||||
0x006BA058,
|
||||
0x006E0F26,
|
||||
0x006E56B5,
|
||||
0x006B909A,
|
||||
0x006BA16A,
|
||||
0x006648E3,
|
||||
0x0068DF91
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
@@ -27,4 +27,6 @@ void game_logic_update();
|
||||
|
||||
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);
|
||||
|
||||
void game_load_or_quit_no_save_prompt();
|
||||
|
||||
#endif
|
||||
|
||||
50
src/peep.h
50
src/peep.h
@@ -45,6 +45,32 @@ enum PEEP_THOUGHT_TYPE {
|
||||
PEEP_THOUGHT_TYPE_NONE = 255
|
||||
};
|
||||
|
||||
enum PEEP_STATE {
|
||||
|
||||
PEEP_STATE_QUEUING_FRONT = 2,
|
||||
PEEP_STATE_ON_RIDE = 3,
|
||||
PEEP_STATE_LEAVING_RIDE = 4,
|
||||
PEEP_STATE_WALKING = 5,
|
||||
PEEP_STATE_QUEUING = 6,
|
||||
PEEP_STATE_ENTERING_RIDE = 7,
|
||||
PEEP_STATE_SITTING = 8,
|
||||
PEEP_STATE_PICKED = 9,
|
||||
PEEP_STATE_PATROLLING = 10, // Not sure
|
||||
PEEP_STATE_MOPING = 11,
|
||||
PEEP_STATE_SWEEPING = 12,
|
||||
PEEP_STATE_ENTERING_PARK = 13,
|
||||
PEEP_STATE_LEAVING_PARK = 14,
|
||||
PEEP_STATE_ANSWERING = 15,
|
||||
PEEP_STATE_FIXING = 16,
|
||||
PEEP_STATE_BUYING = 17,
|
||||
PEEP_STATE_WATCHING = 18,
|
||||
PEEP_STATE_EMPTYING_BIN = 19,
|
||||
|
||||
PEEP_STATE_WATERING = 21,
|
||||
PEEP_STATE_HEADING_TO_INSPECTION = 22,
|
||||
PEEP_STATE_INSPECTING = 23
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8 type;
|
||||
uint8 item;
|
||||
@@ -87,24 +113,38 @@ typedef struct {
|
||||
uint8 var_03D;
|
||||
uint8 hunger; // 0x3E
|
||||
uint8 thirst; // 0x3F
|
||||
uint8 pad_040[0x28];
|
||||
uint8 bathroom; // 0x40
|
||||
uint8 pad_041[0x27];
|
||||
uint8 current_ride; // 0x68
|
||||
uint8 pad_6A; // 0x6A Part of current_ride?
|
||||
uint8 current_train; // 0x6B
|
||||
uint8 current_car; // 0x6C
|
||||
uint8 current_seat; // 0x6D
|
||||
uint8 pad_6E[0x2E];
|
||||
uint8 pad_6E[0x0E];
|
||||
uint8 rides_been_on[32]; // 0x7C
|
||||
uint32 id; // 0x9C
|
||||
uint8 pad_A0[0x10];
|
||||
sint32 cash_in_pocket; // 0xA0
|
||||
sint32 cash_spent; // 0xA4
|
||||
uint8 pad_A8[8];
|
||||
rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0
|
||||
uint16 pad_C4;
|
||||
uint8 var_C6;
|
||||
uint8 pad_C7;
|
||||
uint32 var_C8;
|
||||
uint8 pad_CC[0x2A];
|
||||
uint32 var_C8; // Bit 11 tracking, Bit 8 leaving the park
|
||||
uint8 var_CC; // Bit 0 mad, bit 1 Ice Cream
|
||||
uint8 pad_CD[0x18];
|
||||
uint16 paid_to_enter; // 0xE5
|
||||
uint16 paid_on_rides; // 0xE7
|
||||
uint16 paid_on_food; // 0xE9
|
||||
uint16 paid_on_souvenirs; // 0xEB
|
||||
uint8 no_of_food; // 0xEC
|
||||
uint8 no_of_drinks; // 0xED
|
||||
uint8 no_of_souvenirs; // 0xEE
|
||||
uint8 pad_EF[0x07];
|
||||
uint8 balloon_colour; // 0xF6
|
||||
uint8 umbrella_colour; // 0xF7
|
||||
uint8 hat_colour; // 0xF8
|
||||
uint8 favourite_ride; // 0xF9
|
||||
} rct_peep;
|
||||
|
||||
int peep_get_staff_count();
|
||||
|
||||
48
src/rct2.c
48
src/rct2.c
@@ -191,6 +191,53 @@ void rct2_update()
|
||||
rct2_update_2();
|
||||
}
|
||||
|
||||
void check_cmdline_arg()
|
||||
{
|
||||
if(RCT2_GLOBAL(0x009AC310, uint32) == 0xFFFFFFFF)
|
||||
return;
|
||||
|
||||
char *arg = RCT2_GLOBAL(0x009AC310, char *);
|
||||
char processed_arg[255];
|
||||
int len, i, j;
|
||||
int quote = 0;
|
||||
int last_period = 0;
|
||||
|
||||
RCT2_GLOBAL(0x009AC310, uint32) = 0xFFFFFFFF;
|
||||
len = strlen(arg);
|
||||
|
||||
for(i = 0, j = 0; i < len; i ++)
|
||||
{
|
||||
if(arg[i] == '\"')
|
||||
{
|
||||
if(quote)
|
||||
quote = 0;
|
||||
else
|
||||
quote = 1;
|
||||
continue;
|
||||
}
|
||||
if(arg[i] == ' ' && !quote)
|
||||
break;
|
||||
if(arg[i] == '.')
|
||||
last_period = i;
|
||||
processed_arg[j ++] = arg[i];
|
||||
}
|
||||
processed_arg[j ++] = 0;
|
||||
|
||||
if(!stricmp(processed_arg + last_period, "sv6"))
|
||||
{
|
||||
strcpy(0x00141EF68, processed_arg);
|
||||
RCT2_CALLPROC_EBPSAFE(0x00675E1B); //load_saved_game
|
||||
}
|
||||
else if(!stricmp(processed_arg + last_period, "sc6"))
|
||||
{
|
||||
//TODO: scenario install
|
||||
}
|
||||
else if(!stricmp(processed_arg + last_period, "td6") || !stricmp(processed_arg + last_period, "td4"))
|
||||
{
|
||||
//TODO: track design install
|
||||
}
|
||||
}
|
||||
|
||||
void rct2_update_2()
|
||||
{
|
||||
int tick, tick2;
|
||||
@@ -213,6 +260,7 @@ void rct2_update_2()
|
||||
|
||||
// TODO: screenshot countdown process
|
||||
|
||||
check_cmdline_arg();
|
||||
// Screens
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0)
|
||||
intro_update();
|
||||
|
||||
@@ -162,6 +162,8 @@ enum {
|
||||
STR_CREDIT_SPARE_6 = 863,
|
||||
STR_CREDIT_SPARE_7 = 864,
|
||||
|
||||
STR_QUIT_SCENARIO_EDITOR = 887,
|
||||
|
||||
STR_SCR_BMP = 890,
|
||||
STR_SCREENSHOT = 891,
|
||||
STR_SCREENSHOT_SAVED_AS = 892,
|
||||
@@ -170,6 +172,19 @@ enum {
|
||||
STR_VIEW_OPTIONS_TIP = 937,
|
||||
STR_ADJUST_LAND_TIP = 938,
|
||||
|
||||
STR_SAVE_PROMPT_SAVE = 944,
|
||||
STR_SAVE_PROMPT_DONT_SAVE = 945,
|
||||
STR_SAVE_PROMPT_CANCEL = 946,
|
||||
|
||||
STR_SAVE_BEFORE_LOADING = 947,
|
||||
STR_SAVE_BEFORE_QUITTING = 948,
|
||||
STR_SAVE_BEFORE_QUITTING_2 = 949,
|
||||
|
||||
STR_LOAD_GAME = 950,
|
||||
STR_QUIT_GAME = 951,
|
||||
STR_QUIT_GAME_2 = 952,
|
||||
STR_LOAD_LANDSCAPE = 953,
|
||||
|
||||
STR_CANCEL = 972,
|
||||
STR_OK = 973,
|
||||
|
||||
|
||||
@@ -250,6 +250,7 @@ enum {
|
||||
WC_ERROR = 11,
|
||||
WC_RIDE = 12,
|
||||
WC_RIDE_CONSTRUCTION = 13,
|
||||
WC_SAVE_PROMPT = 14,
|
||||
WC_RIDE_LIST = 15,
|
||||
WC_CONSTRUCT_RIDE = 16,
|
||||
WC_SCENERY = 18,
|
||||
@@ -328,6 +329,7 @@ void window_game_top_toolbar_open();
|
||||
void window_game_bottom_toolbar_open();
|
||||
void window_about_open();
|
||||
void window_footpath_open();
|
||||
void window_save_prompt_open();
|
||||
void window_title_menu_open();
|
||||
void window_title_exit_open();
|
||||
void window_title_logo_open();
|
||||
|
||||
@@ -21,13 +21,17 @@
|
||||
#include <string.h>
|
||||
#include "addresses.h"
|
||||
#include "park.h"
|
||||
#include "peep.h"
|
||||
#include "strings.h"
|
||||
#include "sprite.h"
|
||||
#include "sprites.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
|
||||
|
||||
#define WW 200
|
||||
#define WH 128
|
||||
#define CHEATS_MONEY_INCREMENT 10000
|
||||
|
||||
enum {
|
||||
WINDOW_CHEATS_PAGE_MONEY,
|
||||
@@ -41,10 +45,11 @@ static enum WINDOW_CHEATS_WIDGET_IDX {
|
||||
WIDX_PAGE_BACKGROUND,
|
||||
WIDX_TAB_1,
|
||||
WIDX_TAB_2,
|
||||
WIDX_HIGH_MONEY
|
||||
WIDX_HIGH_MONEY,
|
||||
WIDX_HAPPY_GUESTS = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page
|
||||
};
|
||||
|
||||
static rct_widget window_cheats_widgets[] = {
|
||||
static rct_widget window_cheats_money_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535}, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP}, // title bar
|
||||
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP}, // close x button
|
||||
@@ -55,15 +60,33 @@ static rct_widget window_cheats_widgets[] = {
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static rct_widget window_cheats_guests_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535 }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1
|
||||
{ WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2
|
||||
{ WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2376, 2376 }, // happy guests
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static rct_widget *window_cheats_page_widgets[] = {
|
||||
window_cheats_money_widgets,
|
||||
window_cheats_guests_widgets
|
||||
};
|
||||
|
||||
static void window_cheats_emptysub() { }
|
||||
static void window_cheats_mouseup();
|
||||
static void window_cheats_money_mouseup();
|
||||
static void window_cheats_guests_mouseup();
|
||||
static void window_cheats_update();
|
||||
static void window_cheats_invalidate();
|
||||
static void window_cheats_paint();
|
||||
static void window_cheats_set_page(rct_window *w, int page);
|
||||
|
||||
static uint32 window_cheats_events[] = {
|
||||
static uint32 window_cheats_money_events[] = {
|
||||
window_cheats_emptysub,
|
||||
window_cheats_mouseup,
|
||||
window_cheats_money_mouseup,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
@@ -92,6 +115,47 @@ static uint32 window_cheats_events[] = {
|
||||
window_cheats_emptysub
|
||||
};
|
||||
|
||||
static uint32 window_cheats_guests_events[] = {
|
||||
window_cheats_emptysub,
|
||||
window_cheats_guests_mouseup,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_update,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_emptysub,
|
||||
window_cheats_invalidate,
|
||||
window_cheats_paint,
|
||||
window_cheats_emptysub
|
||||
};
|
||||
|
||||
static uint32 *window_cheats_page_events[] = {
|
||||
window_cheats_money_events,
|
||||
window_cheats_guests_events,
|
||||
};
|
||||
|
||||
static uint32 window_cheats_page_enabled_widgets[] = {
|
||||
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY),
|
||||
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HAPPY_GUESTS)
|
||||
};
|
||||
|
||||
static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
|
||||
void window_cheats_open()
|
||||
@@ -103,18 +167,17 @@ void window_cheats_open()
|
||||
if (window != NULL)
|
||||
return;
|
||||
|
||||
window = window_create(32, 32, WW, WH, window_cheats_events, WC_CHEATS, 0);
|
||||
window->widgets = window_cheats_widgets;
|
||||
window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY);
|
||||
window = window_create(32, 32, WW, WH, window_cheats_money_events, WC_CHEATS, 0);
|
||||
window->widgets = window_cheats_money_widgets;
|
||||
window->enabled_widgets = window_cheats_page_enabled_widgets[0];
|
||||
window_init_scroll_widgets(window);
|
||||
|
||||
window->page = WINDOW_CHEATS_PAGE_MONEY;
|
||||
window->colours[0] = 1;
|
||||
window->colours[1] = 19;
|
||||
window->colours[2] = 19;
|
||||
}
|
||||
|
||||
static void window_cheats_mouseup()
|
||||
static void window_cheats_money_mouseup()
|
||||
{
|
||||
int i;
|
||||
short widgetIndex;
|
||||
@@ -127,11 +190,53 @@ static void window_cheats_mouseup()
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_TAB_1:
|
||||
case WIDX_TAB_2:
|
||||
window_cheats_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_HIGH_MONEY:
|
||||
i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32));
|
||||
i += 100000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i);
|
||||
|
||||
if (i < INT_MAX - CHEATS_MONEY_INCREMENT) {
|
||||
i += CHEATS_MONEY_INCREMENT;
|
||||
}
|
||||
else {
|
||||
i = INT_MAX;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i);
|
||||
window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_cheats_guests_mouseup()
|
||||
{
|
||||
int i;
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
__asm mov widgetIndex, dx
|
||||
__asm mov w, esi
|
||||
rct_peep* peep;
|
||||
uint16 sprite_idx;
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_TAB_1:
|
||||
case WIDX_TAB_2:
|
||||
window_cheats_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_HAPPY_GUESTS:
|
||||
for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) {
|
||||
peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep);
|
||||
if (peep->type != PEEP_TYPE_GUEST)
|
||||
continue;
|
||||
if (peep->var_2A != 0)
|
||||
continue;
|
||||
peep->happiness = 255;
|
||||
}
|
||||
window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0);
|
||||
break;
|
||||
}
|
||||
@@ -144,7 +249,7 @@ static void window_cheats_update()
|
||||
__asm mov w, esi
|
||||
|
||||
w->var_48E++;
|
||||
widget_invalidate(w->classification, w->number, WIDX_TAB_1);
|
||||
widget_invalidate(w->classification, w->number, WIDX_TAB_1+w->page);
|
||||
}
|
||||
|
||||
static void window_cheats_invalidate()
|
||||
@@ -153,9 +258,14 @@ static void window_cheats_invalidate()
|
||||
rct_window *w;
|
||||
|
||||
__asm mov w, esi
|
||||
|
||||
strcpy((char*)0x009BC677, "Cheats");
|
||||
|
||||
rct_widget **widgets = window_cheats_page_widgets[w->page];
|
||||
if (w->widgets != widgets) {
|
||||
w->widgets = widgets;
|
||||
window_init_scroll_widgets(w);
|
||||
}
|
||||
|
||||
// Set correct active tab
|
||||
for (i = 0; i < 7; i++)
|
||||
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
||||
@@ -190,7 +300,19 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
if (!(w->disabled_widgets & (1 << WIDX_TAB_2))) {
|
||||
sprite_idx = 5568;
|
||||
if (w->page == WINDOW_CHEATS_PAGE_GUESTS)
|
||||
sprite_idx += w->var_48E / 4;
|
||||
sprite_idx += (w->var_48E / 2) % 8;
|
||||
gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_2].left, w->y + w->widgets[WIDX_TAB_2].top);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_cheats_set_page(rct_window *w, int page)
|
||||
{
|
||||
w->page = page;
|
||||
|
||||
w->enabled_widgets = window_cheats_page_enabled_widgets[page];
|
||||
|
||||
w->event_handlers = window_cheats_page_events[page];
|
||||
w->widgets = window_cheats_page_widgets[page];
|
||||
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
192
src/window_save_prompt.c
Normal file
192
src/window_save_prompt.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "addresses.h"
|
||||
#include "game.h"
|
||||
#include "rct2.h"
|
||||
#include "strings.h"
|
||||
#include "sprites.h"
|
||||
#include "tutorial.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
|
||||
static enum WINDOW_SAVE_PROMPT_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_3,
|
||||
WIDX_SAVE,
|
||||
WIDX_DONT_SAVE,
|
||||
WIDX_CANCEL
|
||||
};
|
||||
|
||||
static rct_widget window_save_prompt_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 259, 0, 49, -1, STR_NONE }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, 258, 1, 14, 0, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, 247, 257, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_12, 0, 2, 257, 19, 30, 0, STR_NONE }, //
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 8, 85, 35, 46, STR_SAVE_PROMPT_SAVE, STR_NONE }, // save
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 91, 168, 35, 46, STR_SAVE_PROMPT_DONT_SAVE, STR_NONE }, // don't save
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 174, 251, 35, 46, STR_SAVE_PROMPT_CANCEL, STR_NONE }, // cancel
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static void window_save_prompt_emptysub() { }
|
||||
static void window_save_prompt_close();
|
||||
static void window_save_prompt_mouseup();
|
||||
static void window_save_prompt_paint();
|
||||
|
||||
static uint32 window_save_prompt_events[] = {
|
||||
window_save_prompt_close,
|
||||
window_save_prompt_mouseup,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_emptysub,
|
||||
window_save_prompt_paint,
|
||||
window_save_prompt_emptysub
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DCBE
|
||||
*/
|
||||
void window_save_prompt_open()
|
||||
{
|
||||
int stringId;
|
||||
rct_window* window;
|
||||
|
||||
// Check if window is already open
|
||||
window = window_bring_to_front_by_id(WC_SAVE_PROMPT, 0);
|
||||
if (window == NULL) {
|
||||
window = window_create(
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2) - 130,
|
||||
max(28, (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) / 2) - 25),
|
||||
260,
|
||||
50,
|
||||
window_save_prompt_events,
|
||||
WC_SAVE_PROMPT,
|
||||
0
|
||||
);
|
||||
|
||||
window->widgets = window_save_prompt_widgets;
|
||||
window->enabled_widgets =
|
||||
(1 << WIDX_CLOSE) |
|
||||
(1 << WIDX_SAVE) |
|
||||
(1 << WIDX_DONT_SAVE) |
|
||||
(1 << WIDX_CANCEL);
|
||||
window_init_scroll_widgets(window);
|
||||
window->colours[0] = 154;
|
||||
window->flags |= WF_TRANSPARENT;
|
||||
|
||||
// Pause the game
|
||||
RCT2_GLOBAL(0x009DEA6E, uint8) |= 2;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006BABB4);
|
||||
window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0);
|
||||
}
|
||||
|
||||
stringId = RCT2_GLOBAL(0x009A9802, uint16) + STR_LOAD_GAME;
|
||||
if (stringId == STR_LOAD_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
|
||||
stringId = STR_LOAD_LANDSCAPE;
|
||||
if (stringId == STR_QUIT_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
|
||||
stringId = STR_QUIT_SCENARIO_EDITOR;
|
||||
window_save_prompt_widgets[WIDX_TITLE].image = stringId;
|
||||
window_save_prompt_widgets[WIDX_3].image = RCT2_GLOBAL(0x009A9802, uint16) + STR_SAVE_BEFORE_LOADING;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0D) {
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) {
|
||||
RCT2_CALLPROC_EBPSAFE(0x0066EE54);
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
} else {
|
||||
tutorial_stop();
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x009DEA66, uint16) < 3840) {
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DF17
|
||||
*/
|
||||
static void window_save_prompt_close()
|
||||
{
|
||||
// Unpause the game
|
||||
RCT2_GLOBAL(0x009DEA6E, uint8) &= ~2;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006BABD8);
|
||||
window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DDF2
|
||||
*/
|
||||
static void window_save_prompt_mouseup()
|
||||
{
|
||||
short widgetIndex;
|
||||
rct_window *w;
|
||||
|
||||
__asm mov widgetIndex, dx
|
||||
__asm mov w, esi
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void window_save_prompt_paint()
|
||||
{
|
||||
rct_window *w;
|
||||
rct_drawpixelinfo *dpi;
|
||||
|
||||
__asm mov w, esi
|
||||
__asm mov dpi, edi
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
}
|
||||
Reference in New Issue
Block a user