diff --git a/src/addresses.h b/src/addresses.h index efb780f9e5..bc1493a850 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -257,6 +257,7 @@ #define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7 #define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8 +#define RCT2_ADDRESS_MAP_MAXIMUM_X_Y 0x01358832 #define RCT2_ADDRESS_MAP_SIZE 0x01358834 #define RCT2_ADDRESS_PARK_SIZE 0x013580EA diff --git a/src/editor.c b/src/editor.c index ebccbb1e20..db3ead3c26 100644 --- a/src/editor.c +++ b/src/editor.c @@ -73,7 +73,7 @@ void editor_load() RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create mainWindow = window_get_main(); window_scroll_to_location(mainWindow, 2400, 2400, 112); - mainWindow->flags &= ~WF_3; + mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION; RCT2_CALLPROC_EBPSAFE(0x006837E3); gfx_invalidate_screen(); RCT2_GLOBAL(0x009DEA66, sint16) = 0; @@ -120,7 +120,7 @@ void trackdesigner_load() RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create mainWindow = window_get_main(); window_scroll_to_location(mainWindow, 2400, 2400, 112); - mainWindow->flags &= ~WF_3; + mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION; RCT2_CALLPROC_EBPSAFE(0x006837E3); gfx_invalidate_screen(); RCT2_GLOBAL(0x009DEA66, sint16) = 0; @@ -158,7 +158,7 @@ void trackmanager_load() RCT2_CALLPROC_EBPSAFE(0x0066EF38); // window_main_editor_create mainWindow = window_get_main(); window_scroll_to_location(mainWindow, 2400, 2400, 112); - mainWindow->flags &= ~WF_3; + mainWindow->flags &= ~WF_SCROLLING_TO_LOCATION; RCT2_CALLPROC_EBPSAFE(0x006837E3); gfx_invalidate_screen(); RCT2_GLOBAL(0x009DEA66, sint16) = 0; diff --git a/src/map.c b/src/map.c index 39fcdbef7d..c82fd6dc48 100644 --- a/src/map.c +++ b/src/map.c @@ -102,7 +102,7 @@ void map_init() RCT2_GLOBAL(0x013CE774, sint16) = 0; RCT2_GLOBAL(0x013CE776, sint16) = 0; RCT2_GLOBAL(0x01358830, sint16) = 4768; - RCT2_GLOBAL(0x01358832, sint16) = 5054; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) = 5054; RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16) = 150; RCT2_GLOBAL(0x01358836, sint16) = 4767; RCT2_GLOBAL(0x01359208, sint16) = 7; @@ -141,7 +141,7 @@ void map_update_tile_pointers() /** * Return the absolute height of an element, given its (x,y) coordinates - * + * * rct2: 0x00662783 */ int map_element_height(int x, int y) @@ -168,7 +168,7 @@ int map_element_height(int x, int y) // Remove the extra height bit slope &= 0xF; - uint8 quad, quad_extra; // which quadrant the element is in? + sint8 quad, quad_extra; // which quadrant the element is in? // quad_extra is for extra height tiles uint8 xl, yl; // coordinates across this tile @@ -198,7 +198,7 @@ int map_element_height(int x, int y) quad = TILE_SIZE - yl - xl; break; case 8: // NW corner up - quad = xl - yl; + quad = yl - xl; break; } // If the element is in the quadrant with the slope, raise its height @@ -210,7 +210,7 @@ int map_element_height(int x, int y) // One side up switch (slope) { case 3: // E side up - height += xl / 2; + height += xl / 2 + 1; break; case 6: // S side up height += (TILE_SIZE - yl) / 2; @@ -233,15 +233,15 @@ int map_element_height(int x, int y) break; case 11: // SW corner down quad_extra = xl + yl; - quad = xl + yl - TILE_SIZE; + quad = xl + yl - TILE_SIZE - 1; break; case 13: // SE corner down quad_extra = TILE_SIZE - xl + yl; - quad = xl - yl; + quad = yl - xl; break; case 14: // NE corner down quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl); - quad = TILE_SIZE - yl - xl; + quad = TILE_SIZE - yl - xl - 1; break; } @@ -255,7 +255,6 @@ int map_element_height(int x, int y) // so we move *down* the slope if (quad < 0) { height += quad / 2; - height += 0xFF00; } } diff --git a/src/map.h b/src/map.h index 069c0d52c9..8aa4e171fd 100644 --- a/src/map.h +++ b/src/map.h @@ -24,8 +24,8 @@ #include "rct2.h" typedef struct { - uint8 slope; - uint8 terrain; + uint8 slope; //4 + uint8 terrain; //5 uint8 grass_length; uint8 ownership; } rct_map_element_surface_properties; @@ -92,10 +92,10 @@ typedef union { * size: 0x08 */ typedef struct { - uint8 type; - uint8 flags; - uint8 base_height; - uint8 clearance_height; + uint8 type; //0 + uint8 flags; //1 + uint8 base_height; //2 + uint8 clearance_height; //3 rct_map_element_properties properties; } rct_map_element; @@ -177,6 +177,8 @@ enum { #define MAP_ELEMENT_WATER_HEIGHT_MASK 0x1F #define MAP_ELEMENT_SURFACE_TERRAIN_MASK 0xE0 +#define MAP_MINIMUM_X_Y -256 + #define MAX_MAP_ELEMENTS 196608 #define MAX_TILE_MAP_ELEMENT_POINTERS (256 * 256) diff --git a/src/viewport.c b/src/viewport.c index 8a00f235e4..b5de1c435e 100644 --- a/src/viewport.c +++ b/src/viewport.c @@ -18,9 +18,11 @@ * along with this program. If not, see . *****************************************************************************/ +#include #include "addresses.h" #include "config.h" #include "gfx.h" +#include "map.h" #include "string_ids.h" #include "sprite.h" #include "sprites.h" @@ -219,13 +221,166 @@ void viewport_update_pointers() *vp = NULL; } +void sub_689174(sint16* x, sint16* y, uint8 curr_rotation){ + //RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, &ecx, &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); + } + 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); + } + 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); + } + 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); + } + break; + } +} + /** * * rct2: 0x006E7A3A */ void viewport_update_position(rct_window *window) { - RCT2_CALLPROC_X(0x006E7A3A, 0, 0, 0, 0, (int)window, 0, 0); + //RCT2_CALLPROC_X(0x006E7A3A, 0, 0, 0, 0, (int)window, 0, 0); + + RCT2_CALLPROC_X(window->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)window, 0, 0); + + rct_viewport* viewport = window->viewport; + if (!viewport)return; + + if (window->viewport_target_sprite != -1){ + rct_sprite* sprite = &g_sprite_list[window->viewport_target_sprite]; + + int height = map_element_height(sprite->unknown.x, sprite->unknown.y) - 16; + int underground = sprite->unknown.z < height; + + RCT2_CALLPROC_X(0x6E7A15, sprite->unknown.x, sprite->unknown.y, sprite->unknown.z, underground, (int)window, (int)viewport, 0); + + int center_x, center_y; + center_2d_coordinates(sprite->unknown.x, sprite->unknown.y, sprite->unknown.z, ¢er_x, ¢er_y, window->viewport); + + RCT2_CALLPROC_X(0x6E7DE1, center_x, center_y, 0, 0, (int)window, (int)viewport, 0); + window_invalidate(window);//Added to force a redraw. + return; + } + + + sint16 x = viewport->view_width / 2 + window->saved_view_x; + sint16 y = viewport->view_height / 2 + window->saved_view_y; + + int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); + sub_689174(&x, &y, curr_rotation); + + RCT2_CALLPROC_X(0x006E7A15, x, y, 0, 0, (int)window, (int)viewport, 0); + + //Clamp to the map minimum value + int at_map_edge = 0; + if (x < MAP_MINIMUM_X_Y){ + x = MAP_MINIMUM_X_Y; + at_map_edge = 1; + } + if (y < MAP_MINIMUM_X_Y){ + y = MAP_MINIMUM_X_Y; + at_map_edge = 1; + } + + //Clamp to the map maximum value (scenario specific) + if (x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){ + x = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16); + at_map_edge = 1; + } + if (y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){ + y = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16); + at_map_edge = 1; + } + + if (at_map_edge) { + // The &0xFFFF is to prevent the sign extension messing the + // function up. + int z = map_element_height(x & 0xFFFF, y & 0xFFFF); + int _2d_x, _2d_y; + center_2d_coordinates(x, y, z, &_2d_x, &_2d_y, viewport); + + if (window->saved_view_x > 0){ + _2d_x = min(_2d_x, window->saved_view_x); + } + else{ + _2d_x = max(_2d_x, window->saved_view_x); + } + + if (window->saved_view_y > 0){ + _2d_y = min(_2d_y, window->saved_view_y); + } + else{ + _2d_y = max(_2d_y, window->saved_view_y); + } + + window->saved_view_x = _2d_x; + window->saved_view_y = _2d_y; + } + + x = window->saved_view_x; + y = window->saved_view_y; + if (window->flags & WF_SCROLLING_TO_LOCATION){ + // Moves the viewport if focusing in on an item + uint8 flags = 0; + x -= viewport->view_x; + if (x < 0){ + x = -x; + flags |= 1; + } + y -= viewport->view_y; + if (y < 0){ + y = -y; + flags |= 2; + } + x = (x + 7)/8; + y = (y + 7)/8; + + //If we are at the final zoom position + if (!x && !y){ + window->flags &= ~WF_SCROLLING_TO_LOCATION; + } + if (flags & 1){ + x = -x; + } + if (flags & 2){ + y = -y; + } + x += viewport->view_x; + y += viewport->view_y; + } + + RCT2_CALLPROC_X(0x6E7DE1, x, y, 0, 0, (int)window, (int)viewport, 0); } void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, int top, int right, int bottom); diff --git a/src/window.h b/src/window.h index bab8718775..7fbab578ca 100644 --- a/src/window.h +++ b/src/window.h @@ -260,7 +260,7 @@ typedef enum { WF_STICK_TO_BACK = (1 << 0), WF_STICK_TO_FRONT = (1 << 1), WF_2 = (1 << 2), - WF_3 = (1 << 3), + WF_SCROLLING_TO_LOCATION = (1 << 3), WF_TRANSPARENT = (1 << 4), WF_5 = (1 << 5), WF_RESIZABLE = (1 << 8), diff --git a/src/window_new_ride.c b/src/window_new_ride.c index 2d8eebdd10..1269f7d395 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -680,6 +680,7 @@ static void window_new_ride_scrollmouseover() return; item = window_new_ride_scroll_get_ride_list_item_at(w, x, y); + if (w->new_ride.highlighted_ride_id == *((sint16*)&item)) return; diff --git a/src/window_peep.c b/src/window_peep.c index f0bc914724..8c7ef1601a 100644 --- a/src/window_peep.c +++ b/src/window_peep.c @@ -521,10 +521,10 @@ void window_peep_viewport_init(rct_window* w){ void window_peep_overview_paint(){ rct_window *w; rct_drawpixelinfo *dpi; - rct_widget *labelWidget; + //rct_widget *labelWidget; window_paint_get_registers(w, dpi); - RCT2_CALLPROC_X(0x696887, 0, 0, 0, 0, w, dpi, 0); + RCT2_CALLPROC_X(0x696887, 0, 0, 0, 0, (int)w, (int)dpi, 0); return; window_draw_widgets(w, dpi);