implement window_track_place_toolupdate

This commit is contained in:
IntelOrca 2014-10-01 02:03:36 +01:00
parent 2b9aa8a2b7
commit f761306beb
5 changed files with 221 additions and 50 deletions

View File

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

View File

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

View File

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

View File

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

View File

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