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

Added remaining scenery functions

This commit is contained in:
Duncan Frost
2015-04-21 18:19:11 +01:00
parent 59c594fcf6
commit b3be906270
4 changed files with 262 additions and 76 deletions

View File

@@ -105,5 +105,6 @@ int viewport_interaction_left_click(int x, int y);
int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info *info);
int viewport_interaction_right_over(int x, int y);
int viewport_interaction_right_click(int x, int y);
void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement);
#endif

View File

@@ -557,4 +557,73 @@ static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDist
}
return closestPeep;
}
/**
*
* rct2: 0x0068A15E
*/
void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement)
{
int my_x, my_y, z;
rct_map_element *myMapElement;
rct_viewport *viewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, &my_x, &my_y, &z, &myMapElement, &viewport);
if (z == 0) {
*x = 0x8000;
return;
}
RCT2_GLOBAL(0x00F1AD3E, uint8) = z;
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
if (z == 4) {
// myMapElement appears to be water
z = myMapElement->properties.surface.terrain;
z = (z & MAP_ELEMENT_WATER_HEIGHT_MASK) << 4;
}
RCT2_GLOBAL(0x00F1AD3C, uint16) = z;
RCT2_GLOBAL(0x00F1AD34, sint16) = my_x;
RCT2_GLOBAL(0x00F1AD36, sint16) = my_y;
RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31;
RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31;
rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);
rct_xy16 map_pos = { my_x + 16, my_y + 16 };
for (int i = 0; i < 5; i++) {
if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 4) {
z = map_element_height(map_pos.x, map_pos.y);
} else {
z = RCT2_GLOBAL(0x00F1AD3C, uint16);
}
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16));
}
// Determine to which edge the cursor is closest
int myDirection;
int mod_x = map_pos.x & 0x1F;
int mod_y = map_pos.y & 0x1F;
if (mod_x < mod_y) {
if (mod_x + mod_y < 32) {
myDirection = 0;
} else {
myDirection = 1;
}
} else {
if (mod_x + mod_y < 32) {
myDirection = 3;
} else {
myDirection = 2;
}
}
*x = map_pos.x & ~0x1F;
*y = map_pos.y & ~0x1F;
if (direction != NULL) *direction = myDirection;
if (mapElement != NULL) *mapElement = myMapElement;
}

View File

@@ -752,6 +752,26 @@ void sub_68964B(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y, ui
*cl = ecx;
}
void sub_689692(sint16 x, sint16 y, sint16* grid_x, sint16* grid_y, uint8* cl){
int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0;
RCT2_CALLFUNC_X(0x00689692, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*grid_x = eax;
*grid_y = ebx;
*cl = ecx;
}
void sub_6896DC(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y, uint8* cl){
int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = z;
RCT2_CALLFUNC_X(0x006896DC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*grid_x = eax;
*grid_y = ebx;
*cl = ecx;
}
void sub_6894D4(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y){
int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = z;
@@ -905,7 +925,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin
if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){
rotation = scenario_rand() & 0xFF;
}
rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
rotation &= 0x3;
@@ -915,7 +935,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin
*parameter_3 = rotation | (window_scenery_secondary_colour << 16);
return;
}
// If CTRL not pressed
if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){
uint16 flags = 0xFFF6;
@@ -989,26 +1009,191 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin
*parameter_1 = (selected_scenery & 0xFF) << 8;
*parameter_2 = 0 | (window_scenery_primary_colour << 8);
*parameter_3 = rotation | (window_scenery_secondary_colour << 16);
return;
break;
}
case 1:
{
// Path bits
// 6e23dd
uint16 flags = 0xFF9F;
int interaction_type = 0;
rct_map_element* map_element;
get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL);
if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE)
{
*grid_x = 0x8000;
return;
}
*parameter_1 = 0 | map_element->properties.path.type & 0x7;
*parameter_2 = map_element->base_height | ((map_element->properties.path.type >> 4) << 8);
if (map_element->type & 1){
*parameter_2 |= 0x8000;
}
*parameter_3 = (selected_scenery & 0xFF) + 1;
break;
}
case 2:
{
// Walls
// 6e2415
uint8 cl;
// If CTRL not pressed
if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){
sub_689692(x, y, grid_x, grid_y, &cl);
if (*grid_x == 0x8000)
return;
RCT2_GLOBAL(0x00F64ED4, sint16) = 0;
// If SHIFT pressed
if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){
rct_map_element* map_element = map_get_surface_element_at(*grid_x / 32, *grid_y / 32);
if (map_element == NULL){
*grid_x = 0x8000;
return;
}
sint16 z = (map_element->base_height * 8) & 0xFFF0;
z += RCT2_GLOBAL(0x00F64ED2, sint16);
if (z < 16){
z = 16;
}
RCT2_GLOBAL(0x00F64ED4, sint16) = z;
}
}
else{
sint16 z = RCT2_GLOBAL(0x00F64ECC, sint16);
sub_6896DC(x, y, z, grid_x, grid_y, &cl);
// If SHIFT pressed
if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){
z += RCT2_GLOBAL(0x00F64ED2, sint16);
}
if (z < 16){
z = 16;
}
RCT2_GLOBAL(0x00F64ED4, sint16) = z;
}
if (*grid_x == 0x8000)
return;
RCT2_GLOBAL(0x00F64F15, uint8) = window_scenery_secondary_colour;
RCT2_GLOBAL(0x00F64F16, uint8) = window_scenery_tertiary_colour;
// Also places it in lower but think thats for clobering
*parameter_1 = (selected_scenery & 0xFF) << 8;
*parameter_2 = cl | (window_scenery_primary_colour << 8);
*parameter_3 = 0;
break;
}
case 3:
{
// Large scenery
// 6e22a4
// If CTRL not pressed
if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){
sub_68A15E(x, y, grid_x, grid_y, NULL, NULL);
if (*grid_x == 0x8000)
return;
RCT2_GLOBAL(0x00F64ED4, sint16) = 0;
// If SHIFT pressed
if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){
rct_map_element* map_element = map_get_surface_element_at(*grid_x / 32, *grid_y / 32);
if (map_element == NULL){
*grid_x = 0x8000;
return;
}
sint16 z = (map_element->base_height * 8) & 0xFFF0;
z += RCT2_GLOBAL(0x00F64ED2, sint16);
if (z < 16){
z = 16;
}
RCT2_GLOBAL(0x00F64ED4, sint16) = z;
}
}
else{
sint16 z = RCT2_GLOBAL(0x00F64ECC, sint16);
sub_6894D4(x, y, z, grid_x, grid_y);
// If SHIFT pressed
if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){
z += RCT2_GLOBAL(0x00F64ED2, sint16);
}
if (z < 16){
z = 16;
}
RCT2_GLOBAL(0x00F64ED4, sint16) = z;
}
if (*grid_x == 0x8000)
return;
*grid_x &= 0xFFE0;
*grid_y &= 0xFFE0;
uint8 rotation = window_scenery_rotation;
rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
rotation &= 0x3;
*parameter_1 = (rotation << 8);
*parameter_2 = window_scenery_primary_colour | (window_scenery_secondary_colour << 8);
*parameter_3 = selected_scenery & 0xFF;
break;
}
case 4:
{
// Banner
// 6e2385
uint16 flags = 0xFF9F;
int interaction_type = 0;
rct_map_element* map_element;
get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL);
if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE)
{
*grid_x = 0x8000;
return;
}
uint8 rotation = window_scenery_rotation;
rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
rotation &= 0x3;
sint16 z = map_element->base_height;
if (map_element->properties.path.type & (1 << 2)){
if (rotation != ((map_element->properties.path.type & 3) ^ 2)){
z += 2;
}
}
z /= 2;
// Also places it in lower but think thats for clobering
*parameter_1 = (selected_scenery & 0xFF) << 8;
*parameter_2 = z | (rotation << 8);
*parameter_3 = window_scenery_primary_colour;
break;
}
}
}
/**

View File

@@ -300,75 +300,6 @@ static void window_track_place_draw_mini_preview()
}
}
/**
*
* rct2: 0x0068A15E
*/
static void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement)
{
int my_x, my_y, z;
rct_map_element *myMapElement;
rct_viewport *viewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, &my_x, &my_y, &z, &myMapElement, &viewport);
if (z == 0) {
*x = 0x8000;
return;
}
RCT2_GLOBAL(0x00F1AD3E, uint8) = z;
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
if (z == 4) {
// myMapElement appears to be water
z = myMapElement->properties.surface.terrain;
z = (z & MAP_ELEMENT_WATER_HEIGHT_MASK) << 4;
}
RCT2_GLOBAL(0x00F1AD3C, uint16) = z;
RCT2_GLOBAL(0x00F1AD34, sint16) = my_x;
RCT2_GLOBAL(0x00F1AD36, sint16) = my_y;
RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31;
RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31;
rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);
rct_xy16 map_pos = { my_x + 16, my_y + 16 };
for (int i = 0; i < 5; i++) {
if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 4) {
z = map_element_height(map_pos.x, map_pos.y);
} else {
z = RCT2_GLOBAL(0x00F1AD3C, uint16);
}
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16));
}
// Determine to which edge the cursor is closest
int myDirection;
int mod_x = map_pos.x & 0x1F;
int mod_y = map_pos.y & 0x1F;
if (mod_x < mod_y) {
if (mod_x + mod_y < 32) {
myDirection = 0;
} else {
myDirection = 1;
}
} else {
if (mod_x + mod_y < 32) {
myDirection = 3;
} else {
myDirection = 2;
}
}
*x = map_pos.x & ~0x1F;
*y = map_pos.y & ~0x1F;
if (direction != NULL) *direction = myDirection;
if (mapElement != NULL) *mapElement = myMapElement;
}
/**
*
* rct2: 0x006D017F