mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement window_track_place_toolupdate
This commit is contained in:
parent
2b9aa8a2b7
commit
f761306beb
|
@ -1088,3 +1088,27 @@ void viewport_set_visibility(uint8 mode)
|
|||
window_invalidate(window);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00685ADC
|
||||
* screenX: eax
|
||||
* screenY: ebx
|
||||
* flags: edx
|
||||
* x: ax
|
||||
* y: cx
|
||||
* z: bl
|
||||
* mapElement: edx
|
||||
*/
|
||||
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
ebx = y;
|
||||
edx = flags;
|
||||
RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
if (x != NULL) *x = *((uint8*)&eax);
|
||||
if (y != NULL) *y = *((uint8*)&ecx);
|
||||
if (z != NULL) *z = *((uint8*)&ebx);
|
||||
if (mapElement != NULL) *mapElement = (rct_map_element*)edx;
|
||||
}
|
|
@ -65,4 +65,6 @@ void show_construction_rights();
|
|||
void hide_construction_rights();
|
||||
void viewport_set_visibility(uint8 mode);
|
||||
|
||||
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -615,16 +615,7 @@ static void window_footpath_set_provisional_path_at_point(int x, int y)
|
|||
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 = (rct_map_element*)edx;
|
||||
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement);
|
||||
|
||||
if (z == 0) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~1;
|
||||
|
@ -697,17 +688,7 @@ static void window_footpath_place_path_at_point(int x, int y)
|
|||
|
||||
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 = (rct_map_element*)edx;
|
||||
|
||||
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement);
|
||||
if (z == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1153,11 +1153,11 @@ void window_peep_overview_tool_update(){
|
|||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
eax = x;
|
||||
int ebx = y;
|
||||
edx = 0;
|
||||
RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
if ((ebx & 0xFF) == 0) return;
|
||||
|
||||
int ebx;
|
||||
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &ebx, NULL);
|
||||
if (ebx == 0)
|
||||
return;
|
||||
|
||||
x--;
|
||||
y += 16;
|
||||
|
|
|
@ -18,13 +18,19 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "addresses.h"
|
||||
#include "game.h"
|
||||
#include "sprites.h"
|
||||
#include "string_ids.h"
|
||||
#include "viewport.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
|
||||
#define TRACK_MINI_PREVIEW_WIDTH 168
|
||||
#define TRACK_MINI_PREVIEW_HEIGHT 78
|
||||
#define TRACK_MINI_PREVIEW_SIZE (TRACK_MINI_PREVIEW_WIDTH * TRACK_MINI_PREVIEW_HEIGHT)
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
|
@ -87,6 +93,108 @@ static void* window_track_place_events[] = {
|
|||
window_track_place_emptysub
|
||||
};
|
||||
|
||||
static uint8 *_window_track_place_mini_preview;
|
||||
static sint16 _window_track_place_last_x;
|
||||
static sint16 _window_track_place_last_y;
|
||||
|
||||
static uint8 _window_track_place_last_was_valid;
|
||||
static sint16 _window_track_place_last_valid_x;
|
||||
static sint16 _window_track_place_last_valid_y;
|
||||
static sint16 _window_track_place_last_valid_z;
|
||||
static money32 _window_track_place_last_cost;
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D182E
|
||||
*/
|
||||
static void window_track_place_clear_mini_preview()
|
||||
{
|
||||
memset(_window_track_place_mini_preview, 220, TRACK_MINI_PREVIEW_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D1845
|
||||
*/
|
||||
static void window_track_place_draw_mini_preview()
|
||||
{
|
||||
RCT2_GLOBAL(0x00F44168, uint8*) = _window_track_place_mini_preview;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D1845);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068A15E
|
||||
*/
|
||||
static short sub_68A15E(int x, int y, short *ax, short *bx)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
ebx = y;
|
||||
RCT2_CALLFUNC_X(0x0068A15E, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
*ax = *((short*)&eax);
|
||||
*bx = *((short*)&ebx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seems to highlight the surface tiles to match the track layout at the given position but also returns some Z value.
|
||||
* rct2: 0x006D01B3
|
||||
*/
|
||||
static int sub_6D01B3(int bl, int x, int y, int z)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
ebx = bl;
|
||||
ecx = y;
|
||||
edx = z;
|
||||
esi = 0;
|
||||
edi = 0;
|
||||
ebp = 0;
|
||||
RCT2_CALLFUNC_X(0x006D01B3, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return *((short*)&ebx);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D017F
|
||||
*/
|
||||
static void window_track_place_clear_provisional()
|
||||
{
|
||||
if (_window_track_place_last_was_valid) {
|
||||
sub_6D01B3(
|
||||
(RCT2_GLOBAL(0x00F440EB, uint8) << 8) | 6,
|
||||
_window_track_place_last_valid_x,
|
||||
_window_track_place_last_valid_y,
|
||||
_window_track_place_last_valid_z
|
||||
);
|
||||
_window_track_place_last_was_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int sub_6D17C6(int x, int y)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
int z;
|
||||
|
||||
mapElement = map_get_surface_element_at(x >> 5, y >> 5);
|
||||
z = mapElement->base_height * 8;
|
||||
|
||||
// Increase Z above slope
|
||||
if (mapElement->properties.surface.slope & 0x0F) {
|
||||
z += 16;
|
||||
|
||||
// Increase Z above double slope
|
||||
if (mapElement->properties.surface.slope & 0x10)
|
||||
z += 16;
|
||||
}
|
||||
|
||||
// Increase Z above water
|
||||
if (mapElement->properties.surface.terrain & 0x1F)
|
||||
z = max(z, (mapElement->properties.surface.terrain & 0x1F) << 4);
|
||||
|
||||
return z + sub_6D01B3(3, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CFCA0
|
||||
|
@ -96,8 +204,9 @@ void window_track_place_open()
|
|||
rct_window *w;
|
||||
|
||||
window_close_construction_windows();
|
||||
RCT2_GLOBAL(0x00F44168, void*) = rct2_malloc(13104);
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D182E);
|
||||
|
||||
_window_track_place_mini_preview = malloc(TRACK_MINI_PREVIEW_SIZE);
|
||||
window_track_place_clear_mini_preview();
|
||||
|
||||
w = window_create(0, 29, 200, 124, (uint32*)window_track_place_events, WC_TRACK_DESIGN_PLACE, 0);
|
||||
w->widgets = window_track_place_widgets;
|
||||
|
@ -110,10 +219,10 @@ void window_track_place_open()
|
|||
RCT2_GLOBAL(0x009DE518, uint32) |= 6;
|
||||
window_push_others_right(w);
|
||||
show_gridlines();
|
||||
RCT2_GLOBAL(0x00F440D9, uint32) |= 0x80000000;
|
||||
RCT2_GLOBAL(0x00F440DD, uint16) = 0xFFFF;
|
||||
_window_track_place_last_cost = MONEY32_UNDEFINED;
|
||||
_window_track_place_last_x = 0xFFFF;
|
||||
RCT2_GLOBAL(0x00F440AE, uint8) = (-RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)) & 3;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D1845);
|
||||
window_track_place_draw_mini_preview();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,12 +231,12 @@ void window_track_place_open()
|
|||
*/
|
||||
static void window_track_place_close()
|
||||
{
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D017F);
|
||||
window_track_place_clear_provisional();
|
||||
viewport_set_visibility(0);
|
||||
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~6;
|
||||
hide_gridlines();
|
||||
rct2_free(RCT2_GLOBAL(0x00F44168, void*));
|
||||
free(_window_track_place_mini_preview);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,18 +255,18 @@ static void window_track_place_mouseup()
|
|||
window_close(w);
|
||||
break;
|
||||
case WIDX_ROTATE:
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D017F);
|
||||
window_track_place_clear_provisional();
|
||||
RCT2_GLOBAL(0x00F440AE, uint16) = (RCT2_GLOBAL(0x00F440AE, uint16) + 1) & 3;
|
||||
window_invalidate(w);
|
||||
RCT2_GLOBAL(0x00F440DD, uint16) = 0xFFFF;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D1845);
|
||||
_window_track_place_last_x = 0xFFFF;
|
||||
window_track_place_draw_mini_preview();
|
||||
break;
|
||||
case WIDX_MIRROR:
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D2436);
|
||||
RCT2_GLOBAL(0x00F440AE, uint16) = (-RCT2_GLOBAL(0x00F440AE, uint16)) & 3;
|
||||
window_invalidate(w);
|
||||
RCT2_GLOBAL(0x00F440DD, uint16) = 0xFFFF;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D1845);
|
||||
_window_track_place_last_x = 0xFFFF;
|
||||
window_track_place_draw_mini_preview();
|
||||
break;
|
||||
case WIDX_SELECT_DIFFERENT_DESIGN:
|
||||
window_close(w);
|
||||
|
@ -185,10 +294,67 @@ static void window_track_place_toolupdate()
|
|||
{
|
||||
rct_window *w;
|
||||
short widgetIndex, x, y;
|
||||
int i, z;
|
||||
money32 cost;
|
||||
|
||||
window_tool_get_registers(w, widgetIndex, x, y);
|
||||
|
||||
RCT2_CALLPROC_X(0x006CFF2D, x, y, 0, widgetIndex, (int)w, 0, 0);
|
||||
RCT2_CALLPROC_X(0x006CFF2D, x, y, 0, widgetIndex, (int)w, 0, 0); return;
|
||||
|
||||
// BUG: After placing layout, path tiles aren't connected, even though they were in the provisional appearance
|
||||
|
||||
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7;
|
||||
|
||||
// Get the tool map position
|
||||
sub_68A15E(x, y, &x, &y);
|
||||
if (x == (short)0x8000) {
|
||||
window_track_place_clear_provisional();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if tool map position has changed since last update
|
||||
if (x == _window_track_place_last_x && y == _window_track_place_last_y) {
|
||||
sub_6D01B3(0, x, y, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
cost = MONEY32_UNDEFINED;
|
||||
|
||||
// Get base Z position
|
||||
z = sub_6D17C6(x, y);
|
||||
if (RCT2_GLOBAL(0x009DEA6E, uint8) == 0) {
|
||||
window_track_place_clear_provisional();
|
||||
|
||||
// Try increasing Z until a feasible placement is found
|
||||
for (i = 0; i < 7; i++) {
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
|
||||
eax = x;
|
||||
ebx = 105;
|
||||
ecx = y;
|
||||
edi = z;
|
||||
cost = game_do_command_p(GAME_COMMAND_47, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
if (cost != MONEY32_UNDEFINED) {
|
||||
RCT2_GLOBAL(0x00F440EB, uint16) = *((short*)&edi);
|
||||
_window_track_place_last_valid_x = x;
|
||||
_window_track_place_last_valid_y = y;
|
||||
_window_track_place_last_valid_z = z;
|
||||
_window_track_place_last_was_valid = 1;
|
||||
break;
|
||||
}
|
||||
z += 8;
|
||||
}
|
||||
}
|
||||
|
||||
_window_track_place_last_x = x;
|
||||
_window_track_place_last_y = y;
|
||||
if (cost != _window_track_place_last_cost) {
|
||||
_window_track_place_last_cost = cost;
|
||||
widget_invalidate(WC_TRACK_DESIGN_PLACE, 0, WIDX_PRICE);
|
||||
}
|
||||
|
||||
sub_6D01B3(0, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -211,7 +377,7 @@ static void window_track_place_tooldown()
|
|||
*/
|
||||
static void window_track_place_toolabort()
|
||||
{
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D017F);
|
||||
window_track_place_clear_provisional();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,7 +386,7 @@ static void window_track_place_toolabort()
|
|||
*/
|
||||
static void window_track_place_unknown14()
|
||||
{
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D1845);
|
||||
window_track_place_draw_mini_preview();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,9 +408,9 @@ static void window_track_place_paint()
|
|||
if (clippedDpi != NULL) {
|
||||
subsituteElement = &g1Elements[0];
|
||||
tmpElement = *subsituteElement;
|
||||
subsituteElement->offset = RCT2_GLOBAL(0x00F44168, uint8*);
|
||||
subsituteElement->width = 168;
|
||||
subsituteElement->height = 78;
|
||||
subsituteElement->offset = _window_track_place_mini_preview;
|
||||
subsituteElement->width = TRACK_MINI_PREVIEW_WIDTH;
|
||||
subsituteElement->height = TRACK_MINI_PREVIEW_HEIGHT;
|
||||
subsituteElement->x_offset = 0;
|
||||
subsituteElement->y_offset = 0;
|
||||
subsituteElement->flags = 0;
|
||||
|
@ -252,10 +418,8 @@ static void window_track_place_paint()
|
|||
*subsituteElement = tmpElement;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F440D9, money32) == 0x80000000)
|
||||
return;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)
|
||||
return;
|
||||
|
||||
gfx_draw_string_centred(dpi, STR_COST_LABEL, w->x + 88, w->y + 94, 0, (money32*)0x00F440D9);
|
||||
// Price
|
||||
if (_window_track_place_last_cost != MONEY32_UNDEFINED)
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY))
|
||||
gfx_draw_string_centred(dpi, STR_COST_LABEL, w->x + 88, w->y + 94, 0, &_window_track_place_last_cost);
|
||||
}
|
Loading…
Reference in New Issue