1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 19:13:07 +01:00

Refactored common code into viewport_coord_to_map_coord

This commit is contained in:
Timmy Weerwag
2015-04-03 21:11:03 +02:00
parent 8e11c6528d
commit b20efdada8
4 changed files with 70 additions and 101 deletions

View File

@@ -223,74 +223,37 @@ void viewport_update_pointers()
*vp = NULL;
}
void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){
/**
* edx is assumed to be (and always is) the current rotation, so it is not needed as parameter.
* rct2: 0x00689174
*/
void sub_689174(sint16* x, sint16* y, sint16 *z)
{
//RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, (int*)&z, &curr_rotation, (int*)&window, (int*)&viewport, &ebp);
sint16 start_x = *x;
sint16 start_y = *y;
sint16 height = 0;
switch (curr_rotation){
case 0:
for (int i = 0; i < 6; ++i){
*x = start_y - start_x / 2 + height;
*y = start_y + start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = start_y - start_x / 2;
*y = start_y + start_x / 2;
}
rct_xy16 pos;
for (int i = 0; i < 6; i++) {
pos = viewport_coord_to_map_coord(start_x, start_y, height);
height = map_element_height((0xFFFF) & pos.x, (0xFFFF) & pos.y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
sint16 max = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16);
if (pos.x > max && pos.y > max) {
int x_corr[] = { -1, 1, 1, -1 };
int y_corr[] = { -1, -1, 1, 1 };
uint32 rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
pos.x += x_corr[rotation] * height;
pos.y += y_corr[rotation] * height;
}
break;
case 1:
for (int i = 0; i < 6; ++i){
*x = -start_y - start_x / 2 - height;
*y = start_y - start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = -start_y - start_x / 2;
*y = start_y - start_x / 2;
}
}
break;
case 2:
for (int i = 0; i < 6; ++i){
*x = -start_y + start_x / 2 - height;
*y = -start_y - start_x / 2 - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = -start_y + start_x / 2;
*y = -start_y - start_x / 2;
}
}
break;
case 3:
for (int i = 0; i < 6; ++i){
*x = start_x / 2 + start_y + height;
*y = start_x / 2 - start_y - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = start_y + start_x / 2;
*y = -start_y + start_x / 2;
}
}
break;
}
*x = pos.x;
*y = pos.y;
*z = height;
}
@@ -494,8 +457,7 @@ void viewport_update_position(rct_window *window)
sint16 y = viewport->view_height / 2 + window->saved_view_y;
sint16 z;
int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
sub_689174(&x, &y, &z, curr_rotation);
sub_689174(&x, &y, &z);
viewport_set_underground_flag(0, window, viewport);
//RCT2_CALLPROC_X(0x006E7A15, x, y, z, 0, (int)window, (int)viewport, 0);
@@ -1505,6 +1467,38 @@ void screen_pos_to_map_pos(short *x, short *y)
*y = ebx & 0xFFFF;
}
rct_xy16 screen_coord_to_viewport_coord(rct_viewport *viewport, uint16 x, uint16 y)
{
rct_xy16 ret;
ret.x = ((x - viewport->x) << viewport->zoom) + viewport->view_x;
ret.y = ((y - viewport->y) << viewport->zoom) + viewport->view_y;
return ret;
}
rct_xy16 viewport_coord_to_map_coord(int x, int y, int z)
{
rct_xy16 ret;
switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) {
case 0:
ret.x = -x / 2 + y + z;
ret.y = x / 2 + y + z;
break;
case 1:
ret.x = -x / 2 - y - z;
ret.y = -x / 2 + y + z;
break;
case 2:
ret.x = x / 2 - y - z;
ret.y = -x / 2 - y - z;
break;
case 3:
ret.x = x / 2 + y + z;
ret.y = x / 2 - y - z;
break;
}
return ret;
}
/**
*
* rct2: 0x00664689

View File

@@ -82,8 +82,10 @@ void viewport_update_position(rct_window *window);
void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, int top, int right, int bottom);
void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, int top, int right, int bottom);
void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation);
void sub_689174(sint16* x, sint16* y, sint16 *z);
rct_xy16 screen_coord_to_viewport_coord(rct_viewport *viewport, uint16 x, uint16 y);
rct_xy16 viewport_coord_to_map_coord(int x, int y, int z);
void screen_pos_to_map_pos(short *x, short *y);
void show_gridlines();

View File

@@ -1156,8 +1156,6 @@ void window_rotate_camera(rct_window *w)
sint16 y = (viewport->height >> 1) + viewport->y;
sint16 z;
uint8 rot = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
int ecx, edx, esi, edi = (int)viewport, ebp;
//has something to do with checking if middle of the viewport is obstructed
RCT2_CALLFUNC_X(0x00688972, (int*)&x, (int*)&y, &ecx, &edx, &esi, &edi, &ebp);
@@ -1169,12 +1167,12 @@ void window_rotate_camera(rct_window *w)
x = (viewport->view_width >> 1) + viewport->view_x;
y = (viewport->view_height >> 1) + viewport->view_y;
sub_689174(&x, &y, &z, rot);
sub_689174(&x, &y, &z);
} else {
z = map_element_height(x, y);
}
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) = (rot + 1) % 4;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) % 4;
int new_x, new_y;
center_2d_coordinates(x, y, z, &new_x, &new_y, viewport);

View File

@@ -474,28 +474,6 @@ void footpath_provisional_update()
footpath_provisional_remove();
}
void sub_689726_helper(int x, int y, int z, int *out_x, int *out_y)
{
switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) {
case 0:
*out_x = -x / 2 + y + z;
*out_y = x / 2 + y + z;
break;
case 1:
*out_x = -x / 2 - y - z;
*out_y = -x / 2 + y + z;
break;
case 2:
*out_x = x / 2 - y - z;
*out_y = -x / 2 - y - z;
break;
case 3:
*out_x = x / 2 + y + z;
*out_y = x / 2 - y - z;
break;
}
}
/**
* Determines the location of the footpath at which we point with the cursor. If no footpath is underneath the cursor,
* then return the location of the ground tile. Besides the location it also computes the direction of the yellow arrow
@@ -543,26 +521,23 @@ void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y,
*x += 16;
*y += 16;
int start_x, start_y;
start_x = ((screenX - viewport->x) << viewport->zoom) + viewport->view_x;
start_y = ((screenY - viewport->y) << viewport->zoom) + viewport->view_y;
int out_x = *x, out_y = *y;
rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);
rct_xy16 map_pos = { *x, *y };
for (int i = 0; i < 5; i++) {
if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 6) {
z = map_element_height(out_x, out_y);
z = map_element_height(map_pos.x, map_pos.y);
} else {
z = RCT2_GLOBAL(0x00F1AD3C, uint16);
}
sub_689726_helper(start_x, start_y, z, &out_x, &out_y);
out_x = clamp(RCT2_GLOBAL(0x00F1AD34, uint16), out_x, RCT2_GLOBAL(0x00F1AD38, uint16));
out_y = clamp(RCT2_GLOBAL(0x00F1AD36, uint16), out_y, RCT2_GLOBAL(0x00F1AD3A, uint16));
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, uint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, uint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, uint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, uint16));
}
// Determine to which edge the cursor is closest
uint32 myDirection;
int mod_x = out_x & 0x1F, mod_y = out_y & 0x1F;
int mod_x = map_pos.x & 0x1F, mod_y = map_pos.y & 0x1F;
if (mod_x < mod_y) {
if (mod_x + mod_y < 32) {
myDirection = 0;
@@ -577,8 +552,8 @@ void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y,
}
}
if (x != NULL) *x = out_x & ~0x1F;
if (y != NULL) *y = out_y & ~0x1F;
if (x != NULL) *x = map_pos.x & ~0x1F;
if (y != NULL) *y = map_pos.y & ~0x1F;
if (direction != NULL) *direction = myDirection;
if (mapElement != NULL) *mapElement = myMapElement;
// We should get the rct_map_element from 0x00F1AD30 here, but we set it earlier to our myMapElement anyway.