mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c355d27459
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
@ -188,6 +196,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
|
||||
|
|
265
src/game.c
265
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,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
|
|
@ -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
|
||||
|
|
18
src/gfx.c
18
src/gfx.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
135
src/map.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -184,5 +184,6 @@ enum {
|
|||
|
||||
void map_init();
|
||||
void map_update_tile_pointers();
|
||||
int map_element_height(int x, int y);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _NEWS_ITEM_H_
|
||||
|
||||
#include "rct2.h"
|
||||
#include "map.h"
|
||||
|
||||
enum {
|
||||
NEWS_ITEM_NULL,
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
47
src/peep.h
47
src/peep.h
|
@ -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/>.
|
||||
*****************************************************************************/
|
||||
|
@ -91,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
|
||||
|
@ -102,36 +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 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();
|
||||
|
|
|
@ -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,
|
||||
|
|
12
src/title.c
12
src/title.c
|
@ -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);
|
||||
}
|
||||
|
|
130
src/widget.c
130
src/widget.c
|
@ -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 {
|
||||
// ?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
67
src/window.c
67
src/window.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
@ -319,11 +320,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();
|
||||
|
|
|
@ -300,7 +300,7 @@ 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 / 2) % 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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_GAME_FLAGS, uint32) & GAME_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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue