1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Merge branch 'master' into jvlomax-settings

This commit is contained in:
Jørn Lomax
2014-05-03 13:54:30 +02:00
36 changed files with 2087 additions and 127 deletions

View File

@@ -87,7 +87,9 @@
<ClCompile Include="..\src\window_dropdown.c" />
<ClCompile Include="..\src\window_land.c" />
<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" />

View File

@@ -257,6 +257,12 @@
<ClCompile Include="..\lodepng\lodepng.c">
<Filter>Source Files</Filter>
</ClCompile>
<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">

View File

@@ -98,12 +98,20 @@
#define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542
#define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544
#define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545
#define RCT2_ADDRESS_TOOL_WIDGETINDEX 0x009DE546
#define RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS 0x009DE55C
#define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E
#define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560
#define RCT2_ADDRESS_MAP_SELECTION_FLAGS 0x009DE58A
#define RCT2_ADDRESS_MAP_SELECTION_A_X 0x009DE58C
#define RCT2_ADDRESS_MAP_SELECTION_B_X 0x009DE58E
#define RCT2_ADDRESS_MAP_SELECTION_A_Y 0x009DE590
#define RCT2_ADDRESS_MAP_SELECTION_B_Y 0x009DE592
#define RCT2_ADDRESS_MAP_SELECTION_TYPE 0x009DE594
#define RCT2_ADDRESS_SCREEN_FLAGS 0x009DEA68
#define RCT2_ADDRESS_SCREENSHOT_COUNTDOWN 0x009DEA6D
#define RCT2_ADDRESS_PLACE_OBJECT_MODIFIER 0x009DEA70
@@ -133,7 +141,7 @@
#define RCT2_ADDRESS_SPRITES_START_LITTER 0x013573C4
#define RCT2_ADDRESS_CURRENT_LOAN 0x013573E0
#define RCT2_ADDRESS_GAME_FLAGS 0x013573E4
#define RCT2_ADDRESS_PARK_FLAGS 0x013573E4
#define RCT2_ADDRESS_PARK_ENTRANCE_FEE 0x013573E8
#define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844
#define RCT2_ADDRESS_MONTHLY_RIDE_INCOME 0x01357894
@@ -155,6 +163,7 @@
#define RCT2_ADDRESS_MAP_SIZE 0x01358834
#define RCT2_ADDRESS_SCENARIO_NAME 0x0135920A
#define RCT2_ADDRESS_SCENARIO_DETAILS 0x0135924A
#define RCT2_ADDRESS_PARK_ENTRANCE_X 0x01359350
@@ -188,6 +197,7 @@
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT 0x0141E9AC
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE 0x0141E9AE
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE
#define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0
#define RCT2_ADDRESS_SCENARIO_NAME 0x0141F5B8

View File

@@ -58,7 +58,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x006BD39C);
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR;
RCT2_GLOBAL(0x0141F570, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= 16;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= 16;
RCT2_CALLPROC_EBPSAFE(0x006ACA58);
RCT2_GLOBAL(0x0141F571, uint8) = 4;
viewport_init_all();

View File

@@ -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,257 @@ 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: 0x00667C15
*/
static void game_pause_toggle()
{
rct_window *w;
char input_bl, input_dl;
short input_di;
__asm mov input_bl, bl
if (input_bl & 1) {
RCT2_GLOBAL(0x009DEA6E, uint32) ^= 1;
window_invalidate_by_id(WC_TOP_TOOLBAR, 0);
if (RCT2_GLOBAL(0x009DEA6E, uint32) & 1)
RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds
else
RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds
}
__asm mov ebx, 0
}
/**
*
* 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()
{
format_string(0x0141ED68, STR_LOAD_LANDSCAPE_DIALOG_TITLE, 0);
strcpy(0x0141EF68, RCT2_ADDRESS_LANDSCAPES_PATH);
format_string(0x0141EE68, STR_RCT2_LANDSCAPE_FILE, 0);
RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds
osinterface_open_common_file_dialog(1, 0x0141ED68, 0x0141EF68, "*.SV6;*.SV4;*.SC6", 0x0141EE68);
RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds
// window_proc
}
/**
*
* rct2: 0x00674EB6
*/
static int open_load_game_dialog()
{
format_string(0x0141ED68, STR_LOAD_GAME_DIALOG_TITLE, 0);
strcpy(0x0141EF68, RCT2_ADDRESS_SAVED_GAMES_PATH);
format_string(0x0141EE68, STR_RCT2_SAVED_GAME, 0);
RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds
osinterface_open_common_file_dialog(1, 0x0141ED68, 0x0141EF68, "*.SV6", 0x0141EE68);
RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds
// window_proc
}
/**
*
* rct2: 0x0066DC0F
*/
static void load_landscape()
{
if (open_landscape_file_dialog() == 0) {
gfx_invalidate_screen();
} else {
// Set default filename
char *esi = 0x0141EF67;
while (1) {
esi++;
if (*esi == '.')
break;
if (*esi != 0)
continue;
strcpy(esi, ".SC6");
break;
}
strcpy(0x009ABB37, 0x0141EF68);
RCT2_CALLPROC_EBPSAFE(0x006758C0); // landscape_load
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 {
// Set default filename
char *esi = 0x0141EF67;
while (1) {
esi++;
if (*esi == '.')
break;
if (*esi != 0)
continue;
strcpy(esi, ".SV6");
break;
}
strcpy(0x009ABB37, 0x0141EF68);
RCT2_CALLPROC_EBPSAFE(0x00675E1B); // game_load
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);
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,
game_pause_toggle,
0x006C511D,
0x006C5B69,
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

View File

@@ -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

View File

@@ -27,6 +27,10 @@
#include "strings.h"
#include "window.h"
// HACK These were originally passed back through registers
int gLastDrawStringX;
int gLastDrawStringY;
uint8 _screenDirtyBlocks[5120];
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows);
@@ -486,5 +490,17 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co
*/
void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y)
{
RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, format, dpi, 0);
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = colour;
ebx = 0;
ecx = x;
edx = y;
esi = format;
edi = dpi;
ebp = 0;
RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
gLastDrawStringX = ecx;
gLastDrawStringY = edx;
}

View File

@@ -46,6 +46,9 @@ typedef struct {
sint16 unused; // 0x0E
} rct_g1_element;
extern int gLastDrawStringX;
extern int gLastDrawStringY;
void gfx_load_g1();
void gfx_clear(rct_drawpixelinfo *dpi, int colour);

135
src/map.c
View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* Copyright (c) 2014 Ted John, Peter Hill
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
@@ -123,34 +123,147 @@ void map_update_tile_pointers()
}
/**
*
* Return the absolute height of an element, given its (x,y) coordinates
*
* rct2: 0x00662783
* UNFINISHED
*/
int sub_662783(int x, int y)
int map_element_height(int x, int y)
{
int i;
rct_map_element *mapElement;
// Off the map
if (x >= 8192 || y >= 8192)
return 16;
x &= 0xFFFFFFE0;
y &= 0xFFFFFFE0;
// Find the tile the element is on
int x_tile = x & 0xFFFFFFE0;
int y_tile = y & 0xFFFFFFE0;
i = ((y * 256) + x) / 8;
i = ((y_tile * 256) + x_tile) / 32;
mapElement = TILE_MAP_ELEMENT_POINTER(i);
while (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
mapElement++;
}
uint32 result =
uint32 height =
((mapElement->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 20) |
(mapElement->base_height << 3);
uint32 ebx = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK) & ~0x16;
// slope logic
uint32 slope = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK);
uint8 extra_height = (slope & 0x10) >> 4; // 0x10 is the 5th bit - sets slope to double height
// Remove the extra height bit
slope &= 0xF;
return result;
uint8 quad, quad_extra; // which quadrant the element is in?
// quad_extra is for extra height tiles
uint8 xl, yl; // coordinates across this tile
uint8 TILE_SIZE = 31;
xl = x & 0x1f;
yl = y & 0x1f;
// Slope logic:
// Each of the four bits in slope represents that corner being raised
// slope == 15 (all four bits) is not used and slope == 0 is flat
// If the extra_height bit is set, then the slope goes up two z-levels
// We arbitrarily take the SW corner to be closest to the viewer
// One corner up
if ((slope == 1) || (slope == 2) || (slope == 4) || (slope == 8)) {
switch (slope) {
case 1: // NE corner up
quad = xl + yl - TILE_SIZE;
break;
case 2: // SE corner up
quad = xl - yl;
break;
case 4: // SW corner up
quad = TILE_SIZE - yl - xl;
break;
case 8: // NW corner up
quad = xl - yl;
break;
}
// If the element is in the quadrant with the slope, raise its height
if (quad > 0) {
height += quad / 2;
}
}
// One side up
switch (slope) {
case 3: // E side up
height += xl / 2;
break;
case 6: // S side up
height += (TILE_SIZE - yl) / 2;
break;
case 9: // N side up
height += yl / 2;
height++;
break;
case 12: // W side up
height += (TILE_SIZE - xl) / 2;
break;
}
// One corner down
if ((slope == 7) || (slope == 11) || (slope == 13) || (slope == 14)) {
switch (slope) {
case 7: // NW corner down
quad_extra = xl + TILE_SIZE - yl;
quad = xl - yl;
break;
case 11: // SW corner down
quad_extra = xl + yl;
quad = xl + yl - TILE_SIZE;
break;
case 13: // SE corner down
quad_extra = TILE_SIZE - xl + yl;
quad = xl - yl;
break;
case 14: // NE corner down
quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl);
quad = TILE_SIZE - yl - xl;
break;
}
if (extra_height) {
height += quad_extra / 2;
height++;
return height;
}
// This tile is essentially at the next height level
height += 0x10;
// so we move *down* the slope
if (quad < 0) {
height += quad / 2;
height += 0xFF00;
}
}
// Valleys
if ((slope == 5) || (slope == 10)) {
switch (slope) {
case 5: // NW-SE valley
if (xl + yl <= TILE_SIZE + 1) {
return height;
}
quad = TILE_SIZE - xl - yl;
break;
case 10: // NE-SW valley
quad = xl - yl;
break;
}
if (quad > 0) {
height += quad / 2;
}
}
return height;
}

View File

@@ -184,5 +184,6 @@ enum {
void map_init();
void map_update_tile_pointers();
int map_element_height(int x, int y);
#endif

View File

@@ -184,17 +184,9 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int *
*x = SPRITE_LOCATION_NULL;
break;
}
{
uint32 eax, ebx, ecx, edx, esi, edi, ebp;
eax = (ride->var_050 & 0xFF) * 32 + 16;
ecx = (ride->var_050 >> 8) * 32 + 16;
RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (edx & 0xFFFF0000)
edx >>= 16;
*x = eax;
*y = ecx;
*z = edx;
}
*x = (ride->var_050 & 0xFF) * 32 + 16;
*y = (ride->var_050 >> 8) * 32 + 16;
*z = map_element_height(*x, *y);
break;
case NEWS_ITEM_PEEP_ON_RIDE:
peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]);
@@ -233,16 +225,10 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int *
*z = peep->z;
break;
case NEWS_ITEM_BLANK:
{
uint32 eax, ebx, ecx, edx, esi, edi, ebp;
eax = subject;
ecx = subject >> 16;
RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*x = eax;
*y = ecx;
*z = edx;
}
break;
*x = subject;
*y = subject >> 16;
*z = map_element_height(*x, *y);
break;
default:
*x = SPRITE_LOCATION_NULL;
break;

View File

@@ -22,6 +22,7 @@
#define _NEWS_ITEM_H_
#include "rct2.h"
#include "map.h"
enum {
NEWS_ITEM_NULL,

View File

@@ -19,6 +19,7 @@
*****************************************************************************/
#include <stdio.h>
#include <windows.h>
#include <SDL.h>
#include <SDL_syswm.h>
@@ -288,3 +289,63 @@ void osinterface_free()
osinterface_close_window();
SDL_Quit();
}
/**
*
* rct2: 0x004080EA
*/
int osinterface_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName)
{
char initialDirectory[MAX_PATH], *dotAddress, *slashAddress;
OPENFILENAME openFileName;
BOOL result;
int tmp;
// Get directory path from given filename
strcpy(initialDirectory, filename);
dotAddress = strrchr(filename, '.');
if (dotAddress != NULL) {
slashAddress = strrchr(filename, '\\');
if (slashAddress < dotAddress)
*(slashAddress + 1) = 0;
}
// Clear filename
*filename = 0;
// Set open file name options
memset(&openFileName, 0, sizeof(OPENFILENAME));
openFileName.lStructSize = sizeof(OPENFILENAME);
openFileName.hwndOwner = RCT2_GLOBAL(0x009E2D70, HWND);
openFileName.lpstrFile = filename;
openFileName.nMaxFile = MAX_PATH;
openFileName.lpstrInitialDir = initialDirectory;
openFileName.lpstrTitle = title;
// Copy filter name
strcpy(0x01423800, filterName);
// Copy filter pattern
strcpy(0x01423800 + strlen(filterName) + 1, filterPattern);
*((char*)(0x01423800 + strlen(filterName) + 1 + strlen(filterPattern) + 1)) = 0;
openFileName.lpstrFilter = 0x01423800;
//
tmp = RCT2_GLOBAL(0x009E2C74, uint32);
if (RCT2_GLOBAL(0x009E2BB8, uint32) == 2 && RCT2_GLOBAL(0x009E1AF8, uint32) == 1)
RCT2_GLOBAL(0x009E2C74, uint32) = 1;
// Open dialog
if (type == 0) {
openFileName.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
result = GetSaveFileName(&openFileName);
} else if (type == 1) {
openFileName.Flags = OFN_EXPLORER | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
result = GetOpenFileName(&openFileName);
}
//
RCT2_GLOBAL(0x009E2C74, uint32) = tmp;
return result;
}

View File

@@ -46,4 +46,6 @@ void osinterface_process_messages();
void osinterface_draw();
void osinterface_free();
int osinterface_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName);
#endif

View File

@@ -28,7 +28,7 @@
int park_is_open()
{
return (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_PARK_OPEN) != 0;
return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0;
}
/**
@@ -86,7 +86,7 @@ int calculate_park_rating()
int result;
result = 1150;
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x4000)
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x4000)
result = 1050;
// Guests

View File

@@ -51,6 +51,22 @@ enum {
PARK_AWARD_BEST_GENTLE_RIDES,
};
enum {
PARK_FLAGS_PARK_OPEN = (1 << 0),
PARK_FLAGS_FORBID_LANDSCAPE_CHANGES = (1 << 2),
PARK_FLAGS_FORBID_TREE_REMOVAL = (1 << 3),
PARK_FLAGS_SHOW_REAL_GUEST_NAMES = (1 << 4),
PARK_FLAGS_FORBID_HIGH_CONSTRUCTION = (1 << 5), // below tree height
PARK_FLAGS_PREF_LESS_INTENSE_RIDES = (1 << 6),
PARK_FLAGS_FORBID_MARKETING_CAMPAIGN = (1 << 7),
PARK_FLAGS_PREF_MORE_INTENSE_RIDES = (1 << 11),
PARK_FLAGS_DIFFICULT_GUEST_GENERATION = (1 << 12),
PARK_FLAGS_PARK_FREE_ENTRY = (1 << 13),
PARK_FLAGS_DIFFICULT_PARK_RATING = (1 << 14),
PARK_FLAGS_NO_MONEY = (1 << 17),
PARK_FLAGS_18 = (1 << 18)
};
int park_is_open();
void park_init();
int park_calculate_size();

View File

@@ -8,12 +8,12 @@
* 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/>.
*****************************************************************************/
@@ -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;
@@ -65,7 +91,9 @@ typedef struct {
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
uint8 pad_14[0x0E];
uint8 pad_14[0x09];
uint8 direction; // 0x1D
uint32 pad_1E;
uint16 name_string_idx; // 0x22
uint16 next_x; // 0x24
uint16 next_y; // 0x26
@@ -76,35 +104,49 @@ typedef struct {
uint8 sprite_type; // 0x2D
uint8 type; // 0x2E
uint8 staff_type; // 0x2F
uint8 var_30;
uint8 var_31;
uint8 tshirt_colour; // 0x30
uint8 trousers_colour; // 0x31
uint8 pad_32[0x06];
uint8 energy; // 0x38
uint8 var_39;
uint8 energy_growth_rate; // 0x39
uint8 happiness; // 0x3A
uint8 var_03B;
uint8 happiness_growth_rate; // 0x3B
uint8 nausea; // 0x3C
uint8 var_03D;
uint8 nausea_growth_rate; // 0x3D
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_69;
uint8 current_train; // 0x6A
uint8 current_car; // 0x6B
uint8 current_seat; // 0x6C
uint8 pad_6D[0x0F];
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 25 Ice Cream, Bit 24 mad, Bit 3 tracking, Bit 0 leaving the park
uint8 var_CC;
uint8 pad_CD[0x17];
uint16 paid_to_enter; // 0xE4
uint16 paid_on_rides; // 0xE6
uint16 paid_on_food; // 0xE8
uint16 paid_on_souvenirs; // 0xEA
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();

View File

@@ -194,6 +194,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;
@@ -216,6 +263,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();

View File

@@ -120,14 +120,6 @@ enum {
};
enum {
GAME_FLAGS_PARK_OPEN = (1 << 0),
GAME_FLAGS_BELOW_TREE_HEIGHT_ONLY = (1 << 5),
GAME_FLAGS_NO_MONEY = (1 << 11),
GAME_FLAGS_PARK_FREE_ENTRY = (1 << 13),
GAME_FLAGS_18 = (1 << 18)
};
void rct2_endupdate();
char *get_file_path(int pathId);
void get_system_info();

View File

@@ -446,9 +446,9 @@ void scenario_load_and_play(rct_scenario_basic *scenario)
RCT2_GLOBAL(0x00F663B0, sint32) = RCT2_GLOBAL(0x009AA0F0, sint32);
RCT2_GLOBAL(0x00F663B4, sint32) = RCT2_GLOBAL(0x009AA0F4, sint32);
RCT2_GLOBAL(0x009DEB7C, sint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) &= 0xFFFFF7FF;
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) & 0x20000)
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) |= 0x800;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) &= 0xFFFFF7FF;
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) & 0x20000)
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) |= 0x800;
RCT2_CALLPROC_EBPSAFE(0x00684AC3);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
news_item_init_queue();
@@ -479,11 +479,13 @@ void scenario_load_and_play(rct_scenario_basic *scenario)
//
format_string(0x0141ED68, RCT2_GLOBAL(ebp + 0, uint16), 0);
strcpy_s(0x0135920A, 32, 0x0141ED68);
strncpy(RCT2_ADDRESS_SCENARIO_NAME, 0x0141ED68, 31);
((char*)RCT2_ADDRESS_SCENARIO_NAME)[31] = '\0';
// Set scenario details
format_string(0x0141ED68, RCT2_GLOBAL(ebp + 4, uint16), 0);
strcpy_s(RCT2_ADDRESS_SCENARIO_DETAILS, 256, 0x0141ED68);
strncpy(RCT2_ADDRESS_SCENARIO_DETAILS, 0x0141ED68, 255);
((char*)RCT2_ADDRESS_SCENARIO_DETAILS)[255] = '\0';
}
// Set the last saved game path
@@ -512,12 +514,12 @@ void scenario_load_and_play(rct_scenario_basic *scenario)
RCT2_GLOBAL(0x00135882E, uint16) = 0;
// Open park with free entry when there is no money
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_PARK_OPEN;
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_OPEN;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) = 0;
}
RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_18;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_18;
RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related)

View File

@@ -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,
@@ -190,12 +205,31 @@ enum {
STR_LOCATE_SUBJECT_TIP = 1027,
STR_LOAD_GAME_DIALOG_TITLE = 1036,
STR_LOAD_LANDSCAPE_DIALOG_TITLE = 1037,
STR_RCT2_SAVED_GAME = 1043,
STR_RCT2_LANDSCAPE_FILE = 1045,
STR_RIDES_IN_PARK_TIP = 1053,
STR_PLACE_SCENERY_TIP = 1159,
STR_ADJUST_WATER_TIP = 1160,
STR_BUILD_FOOTPATH_TIP = 1173,
STR_CANT_BUILD_FOOTPATH_HERE = 1176,
STR_CANT_REMOVE_FOOTPATH_FROM_HERE = 1177,
STR_FOOTPATHS = 1181,
STR_TYPE = 1182,
STR_DIRECTION = 1183,
STR_SLOPE = 1184,
STR_DIRECTION_TIP = 1185,
STR_SLOPE_DOWN_TIP = 1186,
STR_LEVEL_TIP = 1187,
STR_SLOPE_UP_TIP = 1188,
STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP = 1189,
STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP = 1190,
STR_CLOSED = 1194,
STR_TEST_RUN = 1195,
@@ -212,10 +246,19 @@ enum {
STR_NUMERIC_UP = 1218,
STR_NUMERIC_DOWN = 1219,
STR_BUILD_THIS = 1407,
STR_COST_LABEL = 1408,
STR_QUEUE_LINE_PATH_TIP = 1423,
STR_FOOTPATH_TIP = 1424,
STR_FREE = 1430,
STR_GUESTS = 1463,
STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655,
STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP = 1656,
STR_GUESTS_TIP = 1693,
STR_STAFF_TIP = 1694,
@@ -227,6 +270,9 @@ enum {
STR_PARK_CLOSED = 1721,
STR_PARK_OPEN = 1722,
STR_CANT_OPEN_PARK = 1723,
STR_CANT_CLOSE_PARK = 1724,
STR_INDIVIDUAL_GUESTS_TIP = 1752,
STR_SUMMARISED_GUESTS_TIP = 1753,
STR_ADMISSION_PRICE = 1756,

View File

@@ -152,7 +152,7 @@ static void title_update_showcase()
{
rct_window* w;
uint8 script_opcode, script_operand;
short x, y;
short x, y, z;
int i, _edx;
if (_scriptWaitCounter <= 0) {
@@ -201,18 +201,12 @@ static void title_update_showcase()
case TITLE_SCRIPT_LOCATION:
x = (*_currentScript++) * 32 + 16;
y = (*_currentScript++) * 32 + 16;
// Set location
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ecx = y;
RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
_edx = edx;
z = map_element_height(x, y);
// Update viewport
w = window_get_main();
if (w != NULL) {
window_scroll_to_location(w, x, y, _edx);
window_scroll_to_location(w, x, y, z);
w->flags &= ~0x08;
viewport_update_position(w);
}

View File

@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <memory.h>
#include <stdlib.h>
#include "addresses.h"
#include "sprites.h"
@@ -33,6 +34,8 @@ static void widget_text_button(rct_drawpixelinfo *dpi, rct_window *w, int widget
static void widget_text_unknown(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_text(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
@@ -94,6 +97,10 @@ void widget_scroll_update_thumbs(rct_window *w, int widget_index)
}
}
/**
*
* rct2: 0x006EB2A8
*/
void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
{
switch (w->widgets[widgetIndex].type) {
@@ -134,7 +141,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
break;
case WWT_18:
break;
case WWT_19:
case WWT_GROUPBOX:
widget_groupbox_draw(dpi, w, widgetIndex);
break;
case WWT_CAPTION:
widget_caption_draw(dpi, w, widgetIndex);
@@ -500,6 +508,99 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
widget_text(dpi, w, widgetIndex);
}
/**
*
* rct2: 0x006EC1A6
*/
static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
{
rct_widget* widget;
int l, t, r, b, press;
uint8 colour;
// Get the widget
widget = &w->widgets[widgetIndex];
// Resolve the absolute ltrb
l = w->x + widget->left + 5;
t = w->y + widget->top;
r = w->x + widget->right;
b = w->y + widget->bottom;
// Get the colour
colour = w->colours[widget->colour];
press = 0;
if (widget_is_pressed(w, widgetIndex) || widget_is_active_tool(w, widgetIndex))
press |= 0x20;
gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
// TODO
gfx_fill_rect(dpi, l, t, r, b, colour);
}
/**
*
* rct2: 0x006EB535
*/
static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
{
rct_widget* widget;
int l, t, r, b, textRight;
uint8 colour;
// Get the widget
widget = &w->widgets[widgetIndex];
// Resolve the absolute ltrb
l = w->x + widget->left + 5;
t = w->y + widget->top;
r = w->x + widget->right;
b = w->y + widget->bottom;
textRight = l;
// Text
if (widget->image != (uint32)-1) {
colour = w->colours[widget->colour] & 0x7F;
if (colour & 1)
colour |= 0x40;
gfx_draw_string_left(dpi, widget->image, 0x013CE952, colour, l, t);
textRight = gLastDrawStringX + 1;
}
// Border
// Resolve the absolute ltrb
l = w->x + widget->left;
t = w->y + widget->top + 4;
r = w->x + widget->right;
b = w->y + widget->bottom;
// Get the colour
colour = w->colours[widget->colour] & 0x7F;
// Border left of text
gfx_fill_rect(dpi, l, t, l + 4, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
gfx_fill_rect(dpi, l + 1, t + 1, l + 4, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
// Border right of text
gfx_fill_rect(dpi, textRight, t, r - 1, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
gfx_fill_rect(dpi, textRight, t + 1, r - 2, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
// Border right
gfx_fill_rect(dpi, r - 1, t + 1, r - 1, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
gfx_fill_rect(dpi, r, t, r, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
// Border bottom
gfx_fill_rect(dpi, l, b - 1, r - 2, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
gfx_fill_rect(dpi, l, b, r - 1, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
// Border left
gfx_fill_rect(dpi, l, t + 1, l, b - 2, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
gfx_fill_rect(dpi, l + 1, t + 2, l + 1, b - 2, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
}
/**
*
* rct2: 0x006EB2F9
@@ -734,6 +835,10 @@ static void widget_vscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, i
gfx_draw_string(dpi, (char*)0x009DED69, 0, l + 1, b - 8);
}
/**
*
* rct2: 0x006EB951
*/
static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
{
int l, t, r, b, colour, image;
@@ -760,7 +865,26 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
if (widget_is_pressed(w, widgetIndex) || widget_is_active_tool(w, widgetIndex))
image++;
if (!widget_is_disabled(w, widgetIndex)) {
if (widget_is_disabled(w, widgetIndex)) {
// Draw greyed out (light border bottom right shadow)
colour = w->colours[widget->colour];
colour = RCT2_ADDRESS(0x00141FC4A, uint8)[(colour & 0x7F) * 8] & 0xFF;
RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74;
memset(0x009DED74, colour, 256);
RCT2_GLOBAL(0x009DED74, uint8) = 0;
RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000;
image &= 0x7FFFF;
RCT2_CALLPROC_X(0x0067A46E, 0, image, l + 1, t + 1, 0, dpi, 0);
// Draw greyed out (dark)
colour = w->colours[widget->colour];
colour = RCT2_ADDRESS(0x00141FC48, uint8)[(colour & 0x7F) * 8] & 0xFF;
RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74;
memset(0x009DED74, colour, 256);
RCT2_GLOBAL(0x009DED74, uint8) = 0;
RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000;
RCT2_CALLPROC_X(0x0067A46E, 0, image, l, t, 0, dpi, 0);
} else {
if (image & 0x80000000) {
// ?
}
@@ -771,8 +895,6 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
image |= colour << 19;
gfx_draw_sprite(dpi, image, l, t);
} else {
// ?
}
}

View File

@@ -43,7 +43,7 @@ typedef enum {
WWT_DROPDOWN = 16,
WWT_VIEWPORT = 17,
WWT_18,
WWT_19,
WWT_GROUPBOX = 19,
WWT_CAPTION = 20,
WWT_CLOSEBOX = 21,
WWT_SCROLL = 22,

View File

@@ -1105,3 +1105,70 @@ void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth,
window_invalidate(w);
}
}
/**
*
* rct2: 0x006EE212
*
* @param tool (al)
* @param widgetIndex (dx)
* @param w (esi)
*/
int tool_set(rct_window *w, int widgetIndex, int tool)
{
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) {
if (
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
widgetIndex == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16)
) {
tool_cancel();
return 1;
}
}
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 3);
RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = tool;
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) = w->classification;
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) = w->number;
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) = widgetIndex;
return 0;
}
/**
*
* rct2: 0x006EE281
*/
void tool_cancel()
{
rct_window *w;
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) {
RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 3);
//
RCT2_CALLPROC_EBPSAFE(0x0068AAE1);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
// Reset map selection
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) = 0;
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, sint16) >= 0) {
// Invalidate tool widget
widget_invalidate(
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber),
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16)
);
// Abort tool event
w = window_find_by_id(
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
);
if (w != NULL)
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_ABORT], 0, 0, 0, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), w, 0, 0);
}
}
}

View File

@@ -22,6 +22,7 @@
#define _WINDOW_H_
#include "gfx.h"
#include "park.h"
#include "rct2.h"
struct rct_window;
@@ -250,6 +251,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,
@@ -319,11 +321,16 @@ void window_move_position(rct_window *w, int dx, int dy);
void window_resize(rct_window *w, int dw, int dh);
void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth, int maxHeight);
int tool_set(rct_window *w, int widgetIndex, int tool);
void tool_cancel();
// Open window functions
void window_main_open();
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();

View File

@@ -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 / 3) % 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);
}

View File

@@ -116,7 +116,7 @@ static void window_clear_scenery_close()
{
// If the tool wasn't changed, turn tool off
if (!window_clear_scenery_should_close())
RCT2_CALLPROC_EBPSAFE(0x006EE281);
tool_cancel();
}
/**

854
src/window_footpath.c Normal file
View File

@@ -0,0 +1,854 @@
/*****************************************************************************
* 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 <string.h>
#include "addresses.h"
#include "audio.h"
#include "game.h"
#include "map.h"
#include "strings.h"
#include "sprites.h"
#include "viewport.h"
#include "widget.h"
#include "window.h"
#include "window_dropdown.h"
enum {
PATH_CONSTRUCTION_MODE_LAND,
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL,
PATH_CONSTRUCTION_MODE_2
};
typedef struct {
uint16 pad_00;
uint32 image; // 0x02
uint32 pad_06;
uint8 pad_0A;
uint8 flags; // 0x0B
} rct_path_type;
static enum WINDOW_FOOTPATH_WIDGET_IDX {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_TYPE_GROUP,
WIDX_FOOTPATH_TYPE,
WIDX_QUEUELINE_TYPE,
WIDX_DIRECTION_GROUP,
WIDX_DIRECTION_NW,
WIDX_DIRECTION_NE,
WIDX_DIRECTION_SW,
WIDX_DIRECTION_SE,
WIDX_SLOPE_GROUP,
WIDX_SLOPEDOWN,
WIDX_LEVEL,
WIDX_SLOPEUP,
WIDX_CONSTRUCT,
WIDX_REMOVE,
WIDX_MODE_GROUP,
WIDX_CONSTRUCT_ON_LAND,
WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL,
};
static rct_widget window_footpath_widgets[] = {
{ WWT_FRAME, 0, 0, 105, 0, 380, 0x0FFFFFFFF, STR_NONE },
{ WWT_CAPTION, 0, 1, 104, 1, 14, STR_FOOTPATHS, STR_WINDOW_TITLE_TIP },
{ WWT_CLOSEBOX, 0, 93, 103, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
// Type group
{ WWT_GROUPBOX, 0, 3, 102, 17, 71, STR_TYPE, STR_NONE },
{ WWT_FLATBTN, 1, 6, 52, 30, 65, 0xFFFFFFFF, STR_FOOTPATH_TIP },
{ WWT_FLATBTN, 1, 53, 99, 30, 65, 0xFFFFFFFF, STR_QUEUE_LINE_PATH_TIP },
// Direction group
{ WWT_GROUPBOX, 0, 3, 102, 75, 151, STR_DIRECTION, STR_NONE },
{ WWT_FLATBTN, 1, 53, 97, 87, 115, 5635, STR_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 53, 97, 116, 144, 5636, STR_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 8, 52, 116, 144, 5637, STR_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 8, 52, 87, 115, 5638, STR_DIRECTION_TIP },
// Slope group
{ WWT_GROUPBOX, 0, 3, 102, 155, 195, STR_SLOPE, STR_NONE },
{ WWT_FLATBTN, 1, 17, 40, 167, 190, 5145, STR_SLOPE_DOWN_TIP },
{ WWT_FLATBTN, 1, 41, 64, 167, 190, 5146, STR_LEVEL_TIP },
{ WWT_FLATBTN, 1, 65, 88, 167, 190, 5147, STR_SLOPE_UP_TIP },
{ WWT_FLATBTN, 1, 8, 97, 202, 291, 0xFFFFFFFF, STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP },
{ WWT_FLATBTN, 1, 30, 75, 295, 318, 5162, STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP },
// Mode group
{ WWT_GROUPBOX, 0, 3, 102, 321, 374, 0xFFFFFFFF, STR_NONE },
{ WWT_FLATBTN, 1, 13, 48, 332, 367, 5639, STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP },
{ WWT_FLATBTN, 1, 57, 92, 332, 367, 5640, STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP },
{ WIDGETS_END },
};
static void window_footpath_emptysub() { }
static void window_footpath_close();
static void window_footpath_mouseup();
static void window_footpath_mousedown();
static void window_footpath_dropdown();
static void window_footpath_update();
static void window_footpath_toolupdate();
static void window_footpath_tooldown();
static void window_footpath_tooldrag();
static void window_footpath_toolup();
static void window_footpath_invalidate();
static void window_footpath_paint();
static uint32 window_footpath_events[] = {
window_footpath_close,
window_footpath_mouseup,
window_footpath_emptysub,
window_footpath_mousedown,
window_footpath_dropdown,
window_footpath_emptysub,
window_footpath_update,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_toolupdate,
window_footpath_tooldown,
window_footpath_tooldrag,
window_footpath_toolup,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_emptysub,
window_footpath_invalidate,
window_footpath_paint,
window_footpath_emptysub
};
sint32 _window_footpath_cost;
static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues);
static void window_footpath_set_provisional_path_at_point(int x, int y);
static int window_footpath_set_provisional_path(int type, int x, int y, int z, int slope);
static void window_footpath_place_path_at_point(int x, int y);
static void window_footpath_construct();
static void window_footpath_remove();
/**
*
* rct2: 0x006A7C43
*/
void window_footpath_open()
{
rct_window* window;
// Check if window is already open
window = window_bring_to_front_by_id(WC_FOOTPATH, 0);
if (window != NULL)
return;
window = window_create(
0,
29,
106,
381,
window_footpath_events,
WC_FOOTPATH,
0
);
window->widgets = window_footpath_widgets;
window->enabled_widgets =
(1 << WIDX_CLOSE) |
(1 << WIDX_FOOTPATH_TYPE) |
(1 << WIDX_QUEUELINE_TYPE) |
(1 << WIDX_DIRECTION_NW) |
(1 << WIDX_DIRECTION_NE) |
(1 << WIDX_DIRECTION_SW) |
(1 << WIDX_DIRECTION_SE) |
(1 << WIDX_SLOPEDOWN) |
(1 << WIDX_LEVEL) |
(1 << WIDX_SLOPEUP) |
(1 << WIDX_CONSTRUCT) |
(1 << WIDX_REMOVE) |
(1 << WIDX_CONSTRUCT_ON_LAND) |
(1 << WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL);
window_init_scroll_widgets(window);
RCT2_CALLPROC_EBPSAFE(0x006EE65A);
show_gridlines();
window->colours[0] = 24;
window->colours[1] = 24;
window->colours[2] = 24;
tool_cancel();
RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_LAND;
tool_set(window, WIDX_CONSTRUCT_ON_LAND, 17);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(0x00F3EF9F, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
}
/**
*
* rct2: 0x006A852F
*/
static void window_footpath_close()
{
rct_window *w;
__asm mov w, esi
RCT2_CALLPROC_EBPSAFE(0x006A7831);
RCT2_CALLPROC_X(0x006CB70A, 0, 0, 0, 0, 0, 0, 0);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
RCT2_GLOBAL(0x009DE58A, uint16) &= ~2;
window_invalidate_by_id(WC_TOP_TOOLBAR, 0);
hide_gridlines();
}
/**
*
* rct2: 0x006A7E92
*/
static void window_footpath_mouseup()
{
short widgetIndex;
rct_window *w;
__asm mov widgetIndex, dx
__asm mov w, esi
switch (widgetIndex) {
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_CONSTRUCT:
window_footpath_construct();
break;
case WIDX_REMOVE:
window_footpath_remove();
break;
case WIDX_CONSTRUCT_ON_LAND:
if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND)
break;
_window_footpath_cost = 0x80000000;
tool_cancel();
RCT2_CALLPROC_EBPSAFE(0x006A7831);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
RCT2_GLOBAL(0x009DE58A, uint16) &= ~2;
RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_LAND;
tool_set(w, WIDX_CONSTRUCT_ON_LAND, 17);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(0x00F3EF9F, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
break;
case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL:
if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
break;
_window_footpath_cost = 0x80000000;
RCT2_CALLPROC_EBPSAFE(0x006EE281);
RCT2_CALLPROC_EBPSAFE(0x006A7831);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
RCT2_GLOBAL(0x009DE58A, uint16) &= ~2;
RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL;
tool_set(w, WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, 12);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(0x00F3EF9F, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
break;
}
}
/**
*
* rct2: 0x006A7EC5
*/
static void window_footpath_mousedown()
{
short widgetIndex;
rct_window *w;
rct_widget *widget;
__asm mov widgetIndex, dx
__asm mov w, esi
__asm mov widget, edi
switch (widgetIndex) {
case WIDX_FOOTPATH_TYPE:
window_footpath_show_footpath_types_dialog(w, widget, 0);
break;
case WIDX_QUEUELINE_TYPE:
window_footpath_show_footpath_types_dialog(w, widget, 1);
break;
case WIDX_DIRECTION_NW:
RCT2_CALLPROC_X(0x006A8111, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_DIRECTION_NE:
RCT2_CALLPROC_X(0x006A8135, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_DIRECTION_SW:
RCT2_CALLPROC_X(0x006A815C, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_DIRECTION_SE:
RCT2_CALLPROC_X(0x006A8183, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_SLOPEDOWN:
RCT2_CALLPROC_X(0x006A81AA, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_LEVEL:
RCT2_CALLPROC_X(0x006A81C5, 0, 0, 0, 0, w, 0, 0);
break;
case WIDX_SLOPEUP:
RCT2_CALLPROC_X(0x006A81E0, 0, 0, 0, 0, w, 0, 0);
break;
}
}
/**
*
* rct2: 0x006A7F18
*/
static void window_footpath_dropdown()
{
int i, j, pathId;
short dropdownIndex;
short widgetIndex;
rct_window *w;
rct_path_type *pathType;
__asm mov dropdownIndex, ax
__asm mov widgetIndex, dx
__asm mov w, esi
if (widgetIndex == WIDX_FOOTPATH_TYPE)
RCT2_GLOBAL(0x00F3EFA2, uint8) = 0;
else if (widgetIndex == WIDX_QUEUELINE_TYPE)
RCT2_GLOBAL(0x00F3EFA2, uint8) = 1;
else
return;
// Get path id
pathId = dropdownIndex;
if (pathId == -1) {
pathId = RCT2_GLOBAL(0x00F3EFA0, sint16);
} else {
int flags = 4;
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
flags = 0;
j = 0;
for (i = 0; i < 16; i++) {
pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[i];
if (pathType == (rct_path_type*)-1)
continue;
if (pathType->flags & flags)
continue;
if (j == pathId)
break;
j++;
}
pathId = i;
}
// Set selected path id
RCT2_GLOBAL(0x00F3EFA0, sint16) = pathId;
RCT2_CALLPROC_EBPSAFE(0x006A7831);
_window_footpath_cost = 0x80000000;
window_invalidate(w);
}
/**
*
* rct2: 0x006A8032
*/
static void window_footpath_toolupdate()
{
int x, y, z;
short widgetIndex;
rct_window *w;
rct_map_element *mapElement;
__asm mov x, eax
__asm mov y, ebx
__asm mov widgetIndex, dx
__asm mov w, esi
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
window_footpath_set_provisional_path_at_point(x, y);
} else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) {
RCT2_CALLPROC_X(0x006A8388, 0, 0, 0, 0, w, 0, 0);
}
}
/**
*
* rct2: 0x006A8047
*/
static void window_footpath_tooldown()
{
int x, y, z;
short widgetIndex;
rct_window *w;
rct_map_element *mapElement;
__asm mov x, eax
__asm mov y, ebx
__asm mov widgetIndex, dx
__asm mov w, esi
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
window_footpath_place_path_at_point(x, y);
} else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) {
RCT2_CALLPROC_X(0x006A840F, x, y, 0, 0, w, 0, 0);
}
}
/**
*
* rct2: 0x006A8067
*/
static void window_footpath_tooldrag()
{
int x, y;
short widgetIndex;
rct_window *w;
__asm mov x, eax
__asm mov y, ebx
__asm mov widgetIndex, dx
__asm mov w, esi
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
RCT2_CALLPROC_X(0x006A82C5, x, y, 0, 0, w, 0, 0);
}
}
/**
*
* rct2: 0x006A8066
*/
static void window_footpath_toolup()
{
int x, y;
short widgetIndex;
rct_window *w;
__asm mov x, eax
__asm mov y, ebx
__asm mov widgetIndex, dx
__asm mov w, esi
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
RCT2_CALLPROC_X(0x006A8380, x, y, 0, 0, w, 0, 0);
}
}
/**
*
* rct2: 0x006A84BB
*/
static void window_footpath_update()
{
rct_window *w;
__asm mov w, esi
// Invalidate construct button
widget_invalidate(WC_FOOTPATH, 0, WIDX_CONSTRUCT);
RCT2_CALLPROC_EBPSAFE(0x006A7760);
// Check tool
if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND) {
if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)))
window_close(w);
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH)
window_close(w);
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_ON_LAND)
window_close(w);
} else if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)))
window_close(w);
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH)
window_close(w);
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
window_close(w);
}
}
/**
*
* rct2: 0x006A7D1C
*/
static void window_footpath_invalidate()
{
int selectedPath;
rct_path_type *pathType;
rct_window *w;
__asm mov w, esi
// Press / unpress footpath and queue type buttons
w->pressed_widgets &= ~(1 << WIDX_FOOTPATH_TYPE);
w->pressed_widgets &= ~(1 << WIDX_QUEUELINE_TYPE);
w->pressed_widgets |= RCT2_GLOBAL(0x00F3EFA2, uint8) == 0 ?
(1 << WIDX_FOOTPATH_TYPE) :
(1 << WIDX_QUEUELINE_TYPE);
// Enable / disable construct button
window_footpath_widgets[WIDX_CONSTRUCT].type = RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND ? WWT_EMPTY : WWT_IMGBTN;
// Set footpath and queue type button images
selectedPath = RCT2_GLOBAL(0x00F3EFA0, uint16);
pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[selectedPath];
int pathImage = 71 + pathType->image;
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = pathImage + 1;
window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_FLATBTN;
// Disable queue in if in editor
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_EMPTY;
}
/**
*
* rct2: 0x006A7D8B
*/
static void window_footpath_paint()
{
int x, y, image, selectedPath;
rct_path_type *pathType;
rct_window *w;
rct_drawpixelinfo *dpi;
__asm mov w, esi
__asm mov dpi, edi
window_draw_widgets(w, dpi);
if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT))) {
// Get construction image
image = (RCT2_GLOBAL(0x00F3EF90, uint8) + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) % 4;
if (RCT2_GLOBAL(0x00F3EF91, uint8) == 2)
image += 4;
else if (RCT2_GLOBAL(0x00F3EF91, uint8) == 6)
image += 8;
image = RCT2_ADDRESS(0x0098D7E0, uint8)[image];
selectedPath = RCT2_GLOBAL(0x00F3EFA0, uint16);
pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[selectedPath];
image += pathType->image;
if (RCT2_GLOBAL(0x00F3EFA2, uint8) != 0)
image += 51;
// Draw construction image
x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 60;
gfx_draw_sprite(dpi, image, x, y);
// Draw build this... label
x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 23;
gfx_draw_string_centred(dpi, STR_BUILD_THIS, x, y, 0, 0);
}
// Draw cost
x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12;
if (_window_footpath_cost != 0x80000000)
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY))
gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, 0, &_window_footpath_cost);
}
/**
*
* rct2: 0x006A7F88
*/
static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues)
{
int i, flags, numPathTypes, image;
rct_path_type *pathType;
numPathTypes = 0;
flags = 4;
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
flags = 0;
for (i = 0; i < 16; i++) {
pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[i];
if (pathType == (rct_path_type*)-1)
continue;
if (pathType->flags & flags)
continue;
image = pathType->image + 71;
if (showQueues)
image++;
gDropdownItemsFormat[numPathTypes] = -1;
gDropdownItemsArgs[numPathTypes] = image;
numPathTypes++;
}
window_dropdown_show_image(
w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1,
w->colours[1],
0,
numPathTypes,
47,
36,
gAppropriateImageDropdownItemsPerRow[numPathTypes]
);
}
/**
*
* rct2: 0x006A81FB
*/
static void window_footpath_set_provisional_path_at_point(int x, int y)
{
int z, slope, pathType;
rct_map_element *mapElement;
RCT2_CALLPROC_EBPSAFE(0x0068AAE1);
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~4;
// Get map coordinates from point
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
edx = -34;
RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
x = eax & 0xFFFF;
z = ebx & 0xFF;
y = ecx & 0xFFFF;
mapElement = edx;
if (z == 0) {
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~1;
RCT2_CALLPROC_EBPSAFE(0x006A7831);
} else {
// Check for change
if ((RCT2_GLOBAL(0x00F3EF92, uint8) & 2) && RCT2_GLOBAL(0x00F3EF94, uint16) == x && RCT2_GLOBAL(0x00F3EF96, uint16) == y && RCT2_GLOBAL(0x00F3EF98, uint8) == mapElement->base_height)
return;
// Set map selection
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y;
RCT2_CALLPROC_EBPSAFE(0x006A7831);
// Set provisional path
slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F];
if (z == 6)
slope = mapElement->properties.surface.slope & 7;
pathType = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8);
_window_footpath_cost = window_footpath_set_provisional_path(pathType, x, y, mapElement->base_height, slope);
// window_invalidate_by_id(eax, ebx);
}
}
/**
*
* rct2: 0x006A76FF
*/
static int window_footpath_set_provisional_path(int type, int x, int y, int z, int slope)
{
int cost;
int eax, ebx, ecx, edx, esi, edi, ebp;
RCT2_CALLPROC_EBPSAFE(0x006A77FF);
// Try and show provisional path
cost = game_do_command(x, (slope << 8) | 121, y, (type << 8) | z, 17, 0, 0);
if (cost != 0x80000000) {
RCT2_GLOBAL(0x00F3EF94, uint16) = x;
RCT2_GLOBAL(0x00F3EF96, uint16) = y;
RCT2_GLOBAL(0x00F3EF98, uint8) = z & 0xFF;
RCT2_GLOBAL(0x00F3EF92, uint8) |= 2;
eax = 3;
if (RCT2_GLOBAL(0x00F3EFA4, uint8) & 2)
eax = 1;
RCT2_CALLPROC_X(0x006CB70A, eax, 0, 0, 0, 0, 0, 0);
}
return cost;
}
/**
*
* rct2: 0x006A82C5
*/
static void window_footpath_place_path_at_point(int x, int y)
{
int z, presentType, selectedType, cost;
rct_map_element *mapElement;
if (RCT2_GLOBAL(0x00F3EF9F, uint8) != 0)
return;
RCT2_CALLPROC_EBPSAFE(0x006A7831);
// Get map coordinates from point
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
edx = -34;
RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
x = eax & 0xFFFF;
z = ebx & 0xFF;
y = ecx & 0xFFFF;
mapElement = edx;
if (z == 0)
return;
// Set path
presentType = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.path.type & 0x1F];
if (z == 6)
presentType = mapElement->properties.path.type & 7;
z = mapElement->base_height;
selectedType = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8);
// Prepare error text
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_BUILD_FOOTPATH_HERE;
// Try and place path
cost = game_do_command(x, (presentType << 8) | 1, y, (selectedType << 8) | z, 17, 0, 0);
if (cost == 0x80000000) {
RCT2_GLOBAL(0x00F3EF9F, uint8) = 1;
} else if (RCT2_GLOBAL(0x00F3EFD9, uint32) != 0) {
// bp = 0x009DEA62
// dx = 0x009DEA60
// cx = 0x009DEA5E
sound_play_panned(6, 0x8001);
}
}
/**
*
* rct2: 0x006A79B7
*/
static void window_footpath_construct()
{
RCT2_CALLPROC_EBPSAFE(0x006A79B7);
}
/**
*
* rct2: 0x006A7863
*/
static void window_footpath_remove()
{
int x, y, z, lastTile;
rct_map_element *mapElement;
// RCT2_CALLPROC_EBPSAFE(0x006A7863);
_window_footpath_cost = 0x80000000;
RCT2_CALLPROC_EBPSAFE(0x006A7831);
x = RCT2_GLOBAL(0x00F3EF8A, uint16) / 32;
y = RCT2_GLOBAL(0x00F3EF8C, uint16) / 32;
int dl = (RCT2_GLOBAL(0x00F3EF8E, uint16) >> 3) & 0xFF;
int dh = dl - 2;
if (x >= 256 || y >= 256)
goto loc_6A79B0;
mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
if (mapElement->base_height == dl) {
if (mapElement->properties.path.type & 4)
if (((mapElement->properties.path.type & 3) ^ 2) != RCT2_GLOBAL(0x00F3EF90, uint8))
continue;
goto loc_6A78EF;
} else if (mapElement->base_height == dh) {
if (!(mapElement->properties.path.type & 4))
if ((mapElement->properties.path.type & 3) == RCT2_GLOBAL(0x00F3EF90, uint8))
continue;
goto loc_6A78EF;
}
}
lastTile = (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE) != 0;
mapElement++;
} while (!lastTile);
goto loc_6A79B0;
loc_6A78EF:
dl = mapElement->base_height;
int pathType = mapElement->properties.path.type;
if (pathType & 4) {
pathType &= 3;
pathType ^= 2;
if (pathType == RCT2_GLOBAL(0x00F3EF90, uint8))
dl += 2;
}
// Find a connected edge
int edge = RCT2_GLOBAL(0x00F3EF90, uint8) ^ 2;
if (!(mapElement->properties.path.edges & (1 << edge))) {
edge = (edge + 1) % 4;
if (!(mapElement->properties.path.edges & (1 << edge))) {
edge = (edge + 2) % 4;
if (!(mapElement->properties.path.edges & (1 << edge))) {
edge = (edge - 1) % 4;
if (!(mapElement->properties.path.edges & (1 << edge)))
edge ^= 2;
}
}
}
// Remove path
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_REMOVE_FOOTPATH_FROM_HERE;
game_do_command(RCT2_GLOBAL(0x00F3EF8A, uint16), 1, RCT2_GLOBAL(0x00F3EF8C, uint16), mapElement->base_height, 19, 0, 0);
// Move selection
edge ^= 2;
x = RCT2_GLOBAL(0x00F3EF8A, uint16) - RCT2_GLOBAL(0x00993CCC + (edge * 4), sint16);
y = RCT2_GLOBAL(0x00F3EF8C, uint16) - RCT2_GLOBAL(0x00993CCE + (edge * 4), sint16);
RCT2_GLOBAL(0x00F3EF8A, uint16) = x;
RCT2_GLOBAL(0x00F3EF8C, uint16) = y;
RCT2_GLOBAL(0x00F3EF8E, uint16) = dl << 3;
RCT2_GLOBAL(0x00F3EF90, uint8) = edge;
RCT2_GLOBAL(0x00F3EF9E, uint8) = 255;
loc_6A79B0:
RCT2_CALLPROC_EBPSAFE(0x006A855C);
}

View File

@@ -159,7 +159,7 @@ static void window_game_bottom_toolbar_mouseup()
switch (widgetIndex) {
case WIDX_LEFT_OUTSET:
case WIDX_MONEY:
if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x800))
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800))
RCT2_CALLPROC_EBPSAFE(0x0069DDF1);
break;
case WIDX_GUESTS:
@@ -302,7 +302,7 @@ static void window_game_bottom_toolbar_invalidate()
}
// Hide money if there is no money
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x800) {
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800) {
window_game_bottom_toolbar_widgets[WIDX_MONEY].type = WWT_EMPTY;
window_game_bottom_toolbar_widgets[WIDX_GUESTS].top = 1;
window_game_bottom_toolbar_widgets[WIDX_GUESTS].bottom = 17;

View File

@@ -176,10 +176,10 @@ static void window_game_top_toolbar_mouseup()
case WIDX_CLEAR_SCENERY:
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);
tool_cancel();
} else {
show_gridlines();
RCT2_CALLPROC_X(0x006EE212, 12, 0, 0, WIDX_CLEAR_SCENERY, w, 0, 0);
tool_set(w, WIDX_CLEAR_SCENERY, 12);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2;
window_clear_scenery_open();
@@ -187,10 +187,10 @@ static void window_game_top_toolbar_mouseup()
break;
case WIDX_LAND:
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);
tool_cancel();
} else {
show_gridlines();
RCT2_CALLPROC_X(0x006EE212, 18, 0, 0, WIDX_LAND, w, 0, 0);
tool_set(w, WIDX_LAND, 18);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
window_land_open();
@@ -198,26 +198,26 @@ static void window_game_top_toolbar_mouseup()
break;
case WIDX_WATER:
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);
tool_cancel();
} else {
show_gridlines();
RCT2_CALLPROC_X(0x006EE212, 19, 0, 0, WIDX_WATER, w, 0, 0);
tool_set(w, WIDX_WATER, 19);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
window_water_open();
}
break;
case WIDX_SCENERY:
RCT2_CALLPROC_X(0x006EE212, 0, 0, 0, WIDX_SCENERY, w, 0, 0);
tool_set(w, WIDX_SCENERY, 0);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_CALLPROC_EBPSAFE(0x006E0FEF);
break;
case WIDX_PATH:
if (window_find_by_id(20, 0) == NULL) {
RCT2_CALLPROC_EBPSAFE(0x00006A7C43);
if (window_find_by_id(WC_FOOTPATH, 0) == NULL) {
window_footpath_open();
} else {
RCT2_CALLPROC_EBPSAFE(0x006EE281);
window_close_by_id(0x80 | 20, 0);
tool_cancel();
window_close_by_id(0x80 | WC_FOOTPATH, 0);
}
break;
case WIDX_CONSTRUCT_RIDE:
@@ -346,7 +346,7 @@ static void window_game_top_toolbar_dropdown()
game_do_command(0, 1, 0, 0, 5, 0, 0);
break;
case 1: // save game
RCT2_CALLPROC_EBPSAFE(0x006EE281);
tool_cancel();
{
int eax, ebx, ecx, edx, esi, edi, ebp;
RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);

View File

@@ -152,7 +152,7 @@ static void window_land_close()
{
// If the tool wasn't changed, turn tool off
if (!window_land_should_close())
RCT2_CALLPROC_EBPSAFE(0x006EE281);
tool_cancel();
}
/**
@@ -391,7 +391,7 @@ static void window_land_paint()
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) != 255)
price += numTiles * 100;
if (price != 0 && !(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)) {
if (price != 0 && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) {
RCT2_GLOBAL(0x013CE952, sint32) = price;
gfx_draw_string_centred(dpi, 986, x, y, 0, 0x013CE952);
}

View File

@@ -935,7 +935,7 @@ static void window_park_entrance_invalidate()
}
// Only allow closing of park and purchase of land when there is money
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) {
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) {
window_park_entrance_widgets[WIDX_OPEN_OR_CLOSE].type = WWT_EMPTY;
window_park_entrance_widgets[WIDX_BUY_LAND_RIGHTS].type = WWT_EMPTY;
window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_EMPTY;
@@ -1417,7 +1417,7 @@ static void window_park_price_invalidate()
RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x013573D4, uint16);
RCT2_GLOBAL(0x013CE952 + 2, uint32) = RCT2_GLOBAL(0x013573D8, uint32);
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_PARK_FREE_ENTRY) {
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY) {
window_park_price_widgets[WIDX_PRICE].type = WWT_12;
window_park_price_widgets[WIDX_INCREASE_PRICE].type = WWT_EMPTY;
window_park_price_widgets[WIDX_DECREASE_PRICE].type = WWT_EMPTY;
@@ -1711,7 +1711,7 @@ static void window_park_objective_invalidate()
*((short*)0x013CE954) = RCT2_GLOBAL(0x013573D8, uint32);
//
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x02)
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x02)
window_park_objective_widgets[WIDX_ENTER_NAME].type = WWT_DROPDOWN_BUTTON;
else
window_park_objective_widgets[WIDX_ENTER_NAME].type = WWT_EMPTY;

View File

@@ -255,7 +255,7 @@ static void window_ride_list_mousedown()
numItems = 9;
if (w->page != PAGE_RIDES)
numItems -= 5;
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)
numItems--;
for (i = 0; i < numItems; i++) {

192
src/window_save_prompt.c Normal file
View 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);
}

View File

@@ -117,7 +117,7 @@ static void window_water_close()
{
// If the tool wasn't changed, turn tool off
if (!window_water_should_close())
RCT2_CALLPROC_EBPSAFE(0x006EE281);
tool_cancel();
}
/**