diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 1238b835ea..9530f3f191 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1,9 +1,9 @@ /***************************************************************************** * Copyright (c) 2014 Ted John * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * + * * This file is part of OpenRCT2. - * + * * OpenRCT2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -25,6 +25,8 @@ #include "../sprites.h" #include "../world/map.h" #include "../world/sprite.h" +#include "../world/banner.h" +#include "../world/scenery.h" #include "viewport.h" #include "window.h" @@ -106,7 +108,7 @@ void viewport_init_all() * z : cx * out_x : ax * out_y : bx - * Converts between 3d point of a sprite to 2d coordinates for centering on that sprite + * Converts between 3d point of a sprite to 2d coordinates for centering on that sprite */ void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_viewport* viewport){ int start_x = x; @@ -130,8 +132,8 @@ void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_view break; } - *out_x = x - viewport->view_width/2; - *out_y = y - viewport->view_height/2; + *out_x = x - viewport->view_width / 2; + *out_y = y - viewport->view_height / 2; } /** @@ -205,7 +207,7 @@ void viewport_create(rct_window *w, int x, int y, int width, int height, int zoo } /** - * + * * rct2: 0x006EE510 */ void viewport_update_pointers() @@ -408,7 +410,7 @@ void sub_6E7DE1(sint16 x, sint16 y, rct_window* w, rct_viewport* viewport){ } if (viewport->width <= 0){ - memcpy( viewport, &view_copy,sizeof(rct_viewport)); + memcpy(viewport, &view_copy, sizeof(rct_viewport)); return; } @@ -458,7 +460,7 @@ void viewport_set_underground_flag(int underground, rct_window* window, rct_view } /** - * + * * rct2: 0x006E7A3A */ void viewport_update_position(rct_window *window) @@ -494,7 +496,7 @@ void viewport_update_position(rct_window *window) int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); sub_689174(&x, &y, &z, curr_rotation); - + viewport_set_underground_flag(0, window, viewport); //RCT2_CALLPROC_X(0x006E7A15, x, y, z, 0, (int)window, (int)viewport, 0); @@ -525,7 +527,7 @@ void viewport_update_position(rct_window *window) 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); } @@ -559,8 +561,8 @@ void viewport_update_position(rct_window *window) y = -y; flags |= 2; } - x = (x + 7)/8; - y = (y + 7)/8; + x = (x + 7) / 8; + y = (y + 7) / 8; //If we are at the final zoom position if (!x && !y){ @@ -581,7 +583,7 @@ void viewport_update_position(rct_window *window) } /** - * + * * rct2: 0x00685C02 * ax: left * bx: top @@ -594,8 +596,8 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i { if (right <= viewport->x) return; if (bottom <= viewport->y) return; - if (left >= viewport->x + viewport->width )return; - if (top >= viewport->y + viewport->height )return; + if (left >= viewport->x + viewport->width)return; + if (top >= viewport->y + viewport->height)return; int l = left, t = top, r = right, b = bottom; @@ -621,8 +623,8 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i top += 384; } //Paint - viewport_paint(viewport, dpi, left, top, right, bottom); - + viewport_paint(viewport, dpi, left, top, right, bottom); + #ifdef DEBUG_SHOW_DIRTY_BOX if (viewport != g_viewport_list){ gfx_fill_rect_inset(dpi, l, t, r-1, b-1, 0x2, 0x30); @@ -632,7 +634,7 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i } /** -* +* * rct2: 0x0068615B * ebp: ebp */ @@ -735,7 +737,7 @@ void sub_688485(){ if (!(ps->var_1A & 1)) gfx_draw_sprite(dpi, image_id, x, y, ps->var_04); else - RCT2_CALLPROC_X(0x00681DE2, 0, image_id, x, y, 0, (int)dpi, ps->var_04); + RCT2_CALLPROC_X(0x00681DE2, 0, image_id, x, y, 0, (int)dpi, ps->var_04); if (ps->var_20 != 0){ ps = ps->var_20; @@ -786,7 +788,7 @@ void sub_0x6736FC(rct_litter* litter, int ebx, int edx){ RCT2_GLOBAL(0x9DEA54, uint16) = 0xFFFC; RCT2_GLOBAL(0x9DEA56, uint16) = edx + 2; - switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION,uint32)){ + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ case 0: //0x686806 break; @@ -812,19 +814,19 @@ void sub_0x69E8B0(uint32 eax, uint32 ecx){ rct_drawpixelinfo* dpi; - if (RCT2_GLOBAL(0x9DEA6F,uint8) & 1) return; - - dpi = RCT2_GLOBAL(0x140E9A8,rct_drawpixelinfo*); - + if (RCT2_GLOBAL(0x9DEA6F, uint8) & 1) return; + + dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_VIEWPORT_FLAGS, uint16) & 0x4000)return; - + if (dpi->zoom_level > 2) return; - + if (eax > 0x2000)return; if (ecx > 0x2000)return; - + //push eax, ecx - eax = (eax&0x1FE0)<<3 | (ecx>>5); + eax = (eax & 0x1FE0) << 3 | (ecx >> 5); int sprite_idx = RCT2_ADDRESS(0xF1EF60, uint16)[eax]; if (sprite_idx == SPRITE_INDEX_NULL) return; @@ -871,6 +873,344 @@ void sub_0x69E8B0(uint32 eax, uint32 ecx){ //return; } +/*rct2: 0x006C42D9*/ +int sub_6C42D9(rct_string_id string_id, int scroll, int ebp) +{ + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + if (dpi->zoom_level != 0) return 0x626; + RCT2_GLOBAL(0x9D7A80, uint32_t)++; + uint32_t edx = 0xFFFFFFFF; + for (int i = 0; i < 0x20; i++) + { + uint8_t* unknown_pointer = RCT2_ADDRESS(0x9C3840, uint8_t) + 0xA12 * i; + if (edx >= *((uint32_t*)(unknown_pointer + 0x0E))) + { + edx = *((uint32_t*)(unknown_pointer + 0x0E)); + RCT2_GLOBAL(0x9D7A84, uint32_t) = i; + RCT2_GLOBAL(0x9D7A88, uint32_t) = (uint32_t)unknown_pointer; + } + if (*((rct_string_id*)unknown_pointer) == string_id && + *((uint32_t*)(unknown_pointer + 0x02)) == RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32_t) && + *((uint32_t*)(unknown_pointer + 0x06)) == RCT2_GLOBAL(0x13CE956, uint32_t) && + *((uint16_t*)(unknown_pointer + 0x0A)) == scroll && + *((uint16_t*)(unknown_pointer + 0x0C)) == ebp) + { + *((uint32_t*)(unknown_pointer + 0x0E)) = RCT2_GLOBAL(0x9D7A80, uint32_t); + return i + 0x606; + } + } + uint8_t* unknown_pointer = RCT2_GLOBAL(0x9D7A88, uint8_t*); + *((rct_string_id*)unknown_pointer) = string_id; + *((uint32_t*)(unknown_pointer + 0x02)) = RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32_t); + *((uint32_t*)(unknown_pointer + 0x06)) = RCT2_GLOBAL(0x13CE956, uint32_t); + *((uint16_t*)(unknown_pointer + 0x0A)) = scroll; + *((uint16_t*)(unknown_pointer + 0x0C)) = ebp; + *((uint32_t*)(unknown_pointer + 0x0E)) = RCT2_GLOBAL(0x9D7A80, uint32_t); + unknown_pointer += 0x12; + memset(unknown_pointer, 0, 0x280 * 4); + format_string(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS); + int al = RCT2_GLOBAL(0x13CE959, uint8_t); + int edi = al & 0x7F; + int offs = 0; + if (al >= 0x80) offs = 2; + RCT2_GLOBAL(0x9D7A8C, uint8_t) = RCT2_ADDRESS(0x0141FC47, uint8_t)[offs + edi * 8]; + int16_t* unk = RCT2_ADDRESS(0x992FB8, uint16_t*)[ebp]; + uint8_t* format_result = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8_t); + while (true) + { + al = *format_result; + format_result++; + if (al == 0) + { + format_result = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + continue; + } + if (al <= FORMAT_COLOUR_CODE_END && al >= FORMAT_COLOUR_CODE_START) + { + al -= FORMAT_COLOUR_CODE_START; + RCT2_GLOBAL(0x9D7A8C, uint8_t) = RCT2_ADDRESS(RCT2_GLOBAL(0x9FF048, uint32_t), uint8_t)[al * 4]; + continue; + } + if (al < 0x20) continue; + al -= 0x20; + int edx = RCT2_ADDRESS(0x141EBA8, uint8_t)[al]; + uint8_t* unk2 = &(RCT2_ADDRESS(0xF4393C, uint8)[al * 8]); + while (true) + { + if (scroll != 0) + { + scroll--; + unk2++; + edx--; + if (edx == 0) break; + } + else + { + int16_t eax = *unk; + if (eax == -1) return RCT2_GLOBAL(0x9D7A84, uint32_t) + 0x606; + if (eax > -1) + { + uint8_t* dst = &unknown_pointer[eax]; + int ah = *unk2; + int al = RCT2_GLOBAL(0x9D7A8C, uint8_t); + while (true) + { + if (ah & 1) *dst = al; + ah >>= 1; + dst += 0x40; + if (ah == 0) break; + } + } + unk2++; + unk++; + edx--; + if (edx == 0) break; + } + } + } +} + +/* rct2: 0x006B9CC4 */ +void viewport_banner_paint_setup(uint32_t direction, int edx, rct_map_element* map_element) +{ + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + RCT2_GLOBAL(0x9DE570, uint8_t) = 0xC; + if (dpi->zoom_level > 1 || RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) return; + edx -= 16; + rct_scenery_entry* banner_scenery = g_bannerSceneryEntries[gBanners[map_element->properties.banner.index].type]; + direction += map_element->properties.banner.position; + direction &= 3; + RCT2_GLOBAL(0x9DEA56, uint16_t) = edx + 2; + RCT2_GLOBAL(0x9DEA52, uint32_t) = RCT2_ADDRESS(0x98D884, uint32_t)[direction * 2]; + int ebx = (direction << 1) + banner_scenery->image; + ebx += (gBanners[map_element->properties.banner.index].colour << 19) | 0x20000000; + if (map_element->flags & 0x10)//if being placed (ghost appearance) + { + RCT2_GLOBAL(0x9DE570, uint8_t) = 0; + ebx &= 0x7FFFF; + ebx |= RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8_t)]; + } + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x1500, ebx, 0, edx, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + RCT2_GLOBAL(0x9DEA52, uint32_t) = RCT2_ADDRESS(0x98D888, uint32_t)[direction * 2]; + ebx++; + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x1500, ebx, 0, edx, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + direction ^= 2; + direction--; + if (direction >= 2 || (map_element->flags & 0x10)) return; + int ebp = banner_scenery->banner.var_06; + ebp += direction; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32_t) = 0; + RCT2_GLOBAL(0x13CE956, uint32_t) = 0; + rct_string_id string_id = 0xBA5;//no entry + if (!(gBanners[map_element->properties.banner.index].flags & BANNER_FLAG_NO_ENTRY)) + { + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16_t) = gBanners[map_element->properties.banner.index].string_idx; + string_id = 0x6C3; + } + format_string(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16_t) = 0x1C0; + uint16_t string_width = gfx_get_string_width(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char)); + uint16_t scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32_t) >> 1) % string_width; + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x1500, sub_6C42D9(string_id, scroll, ebp), 0, edx + 22, 1, 1, 0); +} + +/*rct2: 0x0068B35F*/ +void sub_68B35F(int ax, int cx) +{ + if (ax < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16_t) && + cx < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16_t) && + ax >= 32 && cx >= 32) + { + RCT2_GLOBAL(0x141E9B4, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9B8, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9BC, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9C0, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9C4, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9C8, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9CC, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9D0, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9D4, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9D8, uint32_t) = 0xFFFF; + RCT2_GLOBAL(0x141E9DC, uint32_t) = 0xFFFF; + //loc_68B3FB: Another function jumps to here. We need to split this! + RCT2_GLOBAL(0x141F56A, uint16_t) = 0; + RCT2_GLOBAL(0x9E3138, uint8_t) = 0xFF; + RCT2_GLOBAL(0x9E30B6, uint8_t) = 0xFF; + RCT2_GLOBAL(0x9E323C, uint8_t) = 0xFF; + RCT2_GLOBAL(0x9DE56A, uint16_t) = ax; + RCT2_GLOBAL(0x9DE56E, uint16_t) = cx; + RCT2_GLOBAL(0x9DE574, uint16_t) = ax; + RCT2_GLOBAL(0x9DE576, uint16_t) = cx; + int dx = cx; + int esi = dx; + esi <<= 8; + esi |= ax; + esi >>= 3; + int ax_tmp = ax; + int cx_tmp = cx; + rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(esi / 4); + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) + { + case 0: + dx = ax + cx; + break; + case 1: + ax += 32; + dx = cx - ax; + break; + case 2: + ax += 32; + cx += 32; + dx = -(ax + cx); + break; + case 3: + cx += 32; + dx = ax - cx; + break; + } + dx /= 2; + if ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16_t) & 4) && + RCT2_GLOBAL(0x9DE56A, uint16_t) == RCT2_GLOBAL(0x9DEA48, uint16_t) && + RCT2_GLOBAL(0x9DE56E, uint16_t) == RCT2_GLOBAL(0x9DEA4A, uint16_t)) + { + + int ebx = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t); + RCT2_GLOBAL(0x9DE568, uint16_t) = ax; + RCT2_GLOBAL(0x9DE56C, uint16_t) = cx; + int dl = RCT2_GLOBAL(0x009DEA4E, uint8_t) & 3; + ebx += dl; + ebx &= 3; + dl = RCT2_GLOBAL(0x009DEA4E, uint8_t) & 0xFC; + ebx += dl; + ebx += 0x20900C27; + int d = RCT2_GLOBAL(0x009DEA4C, uint16_t); + RCT2_GLOBAL(0x9DE570, uint8_t) = 0; + RCT2_GLOBAL(0x9DEA52, uint16_t) = 0; + RCT2_GLOBAL(0x9DEA54, uint16_t) = 0; + RCT2_GLOBAL(0x9DEA56, uint16_t) = d + 18; + RCT2_CALLPROC_X( + (int)RCT2_ADDRESS(0x0098197C, uint32_t*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0xFF00, ebx, cx & 0xFF00, d, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + } + int bx = dx + 52; + if (bx > dpi->y) + { + rct_map_element* element = map_element;//push map_element + bx = element->clearance_height; + if (!map_element_is_last_for_tile(element)) + { + while (true) + { + element++; + bx = max(bx, element->clearance_height); + if (map_element_is_last_for_tile(element)) break; + } + } + if (map_element_get_type(element) == MAP_ELEMENT_TYPE_SURFACE && + (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) != 0) + { + bx = (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 1; + } + bx <<= 3; + dx -= bx; + dx -= 32; + element = map_element;//pop map_element + dx -= dpi->height; + if (dx < dpi->y) + { + RCT2_GLOBAL(0x9DE568, uint16_t) = ax; + RCT2_GLOBAL(0x9DE56C, uint16_t) = cx; + RCT2_GLOBAL(0x9DE57C, uint16_t) = 0; + while (true) + { + int direction = (map_element->type + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) & MAP_ELEMENT_DIRECTION_MASK; + dx = map_element->base_height * 8; + uint32_t dword_9DE574 = RCT2_GLOBAL(0x9DE574, uint32_t); + RCT2_GLOBAL(0x9DE578, rct_map_element*) = map_element; + //setup the painting of for example: the underground, signs, rides, scenery, etc. + switch (map_element_get_type(map_element)) + { + case MAP_ELEMENT_TYPE_SURFACE: + RCT2_CALLPROC_X(0x66062C, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_PATH: + RCT2_CALLPROC_X(0x6A3590, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_TRACK: + RCT2_CALLPROC_X(0x6C4794, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_SCENERY: + RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_ENTRANCE: + RCT2_CALLPROC_X(0x664FD4, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_FENCE: + RCT2_CALLPROC_X(0x6E44B0, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: + RCT2_CALLPROC_X(0x6B7F0C, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_BANNER: + //there are still some small localisation glitches, + //because the old function still gets called sometimes + //viewport_banner_paint_setup(direction, dx, map_element); + //Until that is solved, use the original function instead + RCT2_CALLPROC_X(0x6B9CC4, 0, 0, direction, dx, (int)map_element, 0, 0); + break; + default: + break; + } + RCT2_GLOBAL(0x9DE574, uint32_t) = dword_9DE574; + int stop = map_element_is_last_for_tile(map_element); + map_element++; + if (stop) break; + } + } + } + } + else + { + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + int dx; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) + { + case 0: + dx = ax + cx; + break; + case 1: + ax += 32; + dx = cx - ax; + break; + case 2: + ax += 32; + cx += 32; + dx = -(ax + cx); + break; + case 3: + cx += 32; + dx = ax - cx; + break; + } + dx /= 2; + dx -= 16; + int bx = dx + 32; + if (bx <= dpi->y) return; + dx -= 20; + dx -= dpi->height; + if (dx >= dpi->y) return; + RCT2_GLOBAL(0x9DE568, uint16_t) = ax; + RCT2_GLOBAL(0x9DE56C, uint16_t) = cx; + RCT2_GLOBAL(0x9DE570, uint8_t) = 0; + RCT2_CALLPROC_X((int)RCT2_ADDRESS(0x98196C, uint32_t*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0xFF00, 3123, cx & 0xFF00, 16, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + } +} + /** * * rct2: 0x0068B6C2 @@ -896,13 +1236,13 @@ void sub_0x68B6C2(){ dx += 2128; dx >>= 5; for (int i = dx; i > 0; --i){ - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); cx += 0x20; ax -= 0x20; sub_0x69E8B0(ax, cx); ax += 0x20; - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax += 0x20; cx -= 0x20; @@ -917,7 +1257,7 @@ void sub_0x68B6C2(){ bx &= 0xFFE0; ax &= 0xFFE0; bx >>= 1; - cx = ax; + cx = ax; ax = -ax; ax -= bx; cx -= bx; @@ -928,13 +1268,13 @@ void sub_0x68B6C2(){ dx += 0x860; dx >>= 5; for (int i = dx; i > 0; i--){ - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax -= 0x20; cx -= 0x20; sub_0x69E8B0(ax, cx); cx += 0x20; - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax += 0x20; cx += 0x20; @@ -959,13 +1299,13 @@ void sub_0x68B6C2(){ dx += 0x860; dx >>= 5; for (int i = dx; i > 0; i--){ - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax += 0x20; cx -= 0x20; sub_0x69E8B0(ax, cx); ax -= 0x20; - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax -= 0x20; cx += 0x20; @@ -991,13 +1331,13 @@ void sub_0x68B6C2(){ dx += 0x860; dx >>= 5; for (int i = dx; i > 0; i--){ - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax += 0x20; cx += 0x20; sub_0x69E8B0(ax, cx); cx -= 0x20; - RCT2_CALLPROC_X(0x68B35F, ax, 0, cx, 0, 0, 0, 0); + sub_68B35F(ax, cx); sub_0x69E8B0(ax, cx); ax -= 0x20; cx -= 0x20; @@ -1110,13 +1450,13 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in gfx_fill_rect(dpi2, dpi2->x, dpi2->y, dpi2->width + dpi2->x - 1, dpi2->height + dpi2->y - 1, weather_colour); } RCT2_CALLPROC_EBPSAFE(0x6860C3); //string related - } + } //RCT2_CALLPROC_X(0x00685CBF, left, top, 0, right, (int)viewport, (int)dpi, bottom); } /** - * + * * rct2: 0x0068958D */ void screen_pos_to_map_pos(short *x, short *y) @@ -1130,7 +1470,7 @@ void screen_pos_to_map_pos(short *x, short *y) } /** - * + * * rct2: 0x00664689 */ void show_gridlines() @@ -1149,7 +1489,7 @@ void show_gridlines() } /** - * + * * rct2: 0x006646B4 */ void hide_gridlines() @@ -1168,7 +1508,7 @@ void hide_gridlines() } /** - * + * * rct2: 0x00664E8E */ void show_land_rights() @@ -1187,7 +1527,7 @@ void show_land_rights() } /** - * + * * rct2: 0x00664EB9 */ void hide_land_rights() @@ -1206,7 +1546,7 @@ void hide_land_rights() } /** - * + * * rct2: 0x00664EDD */ void show_construction_rights() @@ -1225,7 +1565,7 @@ void show_construction_rights() } /** - * + * * rct2: 0x00664F08 */ void hide_construction_rights() @@ -1244,48 +1584,48 @@ void hide_construction_rights() } /** - * + * * rct2: 0x006CB70A */ void viewport_set_visibility(uint8 mode) { - rct_window* window = window_get_main(); + rct_window* window = window_get_main(); - if(window != NULL) { - rct_viewport* edi = window->viewport; - uint32 invalidate = 0; + if (window != NULL) { + rct_viewport* edi = window->viewport; + uint32 invalidate = 0; - switch(mode) { - case 0: { //Set all these flags to 0, and invalidate if any were active - uint16 mask = VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_SEETHROUGH_RIDES | - VIEWPORT_FLAG_SEETHROUGH_SCENERY | VIEWPORT_FLAG_INVISIBLE_SUPPORTS | - VIEWPORT_FLAG_LAND_HEIGHTS | VIEWPORT_FLAG_TRACK_HEIGHTS | - VIEWPORT_FLAG_PATH_HEIGHTS | VIEWPORT_FLAG_INVISIBLE_PEEPS | - VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL; + switch (mode) { + case 0: { //Set all these flags to 0, and invalidate if any were active + uint16 mask = VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_SEETHROUGH_RIDES | + VIEWPORT_FLAG_SEETHROUGH_SCENERY | VIEWPORT_FLAG_INVISIBLE_SUPPORTS | + VIEWPORT_FLAG_LAND_HEIGHTS | VIEWPORT_FLAG_TRACK_HEIGHTS | + VIEWPORT_FLAG_PATH_HEIGHTS | VIEWPORT_FLAG_INVISIBLE_PEEPS | + VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL; - invalidate += edi->flags & mask; - edi->flags &= ~mask; - break; - } - case 1: //6CB79D - case 4: //6CB7C4 - //Set underground on, invalidate if it was off - invalidate += !(edi->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE); - edi->flags |= VIEWPORT_FLAG_UNDERGROUND_INSIDE; - break; - case 2: //6CB7EB - //Set track heights on, invalidate if off - invalidate += !(edi->flags & VIEWPORT_FLAG_TRACK_HEIGHTS); - edi->flags |= VIEWPORT_FLAG_TRACK_HEIGHTS; - break; - case 3: //6CB7B1 - case 5: //6CB7D8 - //Set underground off, invalidate if it was on - invalidate += edi->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE; - edi->flags &= ~((uint16)VIEWPORT_FLAG_UNDERGROUND_INSIDE); - break; - } - if (invalidate != 0) + invalidate += edi->flags & mask; + edi->flags &= ~mask; + break; + } + case 1: //6CB79D + case 4: //6CB7C4 + //Set underground on, invalidate if it was off + invalidate += !(edi->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE); + edi->flags |= VIEWPORT_FLAG_UNDERGROUND_INSIDE; + break; + case 2: //6CB7EB + //Set track heights on, invalidate if off + invalidate += !(edi->flags & VIEWPORT_FLAG_TRACK_HEIGHTS); + edi->flags |= VIEWPORT_FLAG_TRACK_HEIGHTS; + break; + case 3: //6CB7B1 + case 5: //6CB7D8 + //Set underground off, invalidate if it was on + invalidate += edi->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE; + edi->flags &= ~((uint16)VIEWPORT_FLAG_UNDERGROUND_INSIDE); + break; + } + if (invalidate != 0) window_invalidate(window); } } @@ -1303,13 +1643,43 @@ 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) { - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = screenX; - ebx = screenY; - edx = flags; - RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if (x != NULL) *x = *((uint16*)&eax); - if (y != NULL) *y = *((uint16*)&ecx); - if (z != NULL) *z = *((uint8*)&ebx); - if (mapElement != NULL) *mapElement = (rct_map_element*)edx; + RCT2_GLOBAL(0x9AC154, uint16_t) = flags & 0xFFFF; + RCT2_GLOBAL(0x9AC148, uint8_t) = 0; + rct_window* window = window_find_from_point(screenX, screenY); + if (window != NULL && window->viewport != NULL) + { + rct_viewport* viewport = window->viewport; + RCT2_GLOBAL(0x9AC138 + 4, int16_t) = screenX; + RCT2_GLOBAL(0x9AC138 + 6, int16_t) = screenY; + screenX -= (int)viewport->x; + screenY -= (int)viewport->y; + if (screenX >= 0 && screenX < (int)viewport->width && screenY >= 0 && screenY < (int)viewport->height) + { + screenX <<= viewport->zoom; + screenY <<= viewport->zoom; + screenX += (int)viewport->view_x; + screenY += (int)viewport->view_y; + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_ZOOM, uint16_t) = viewport->zoom; + screenX &= (0xFFFF << viewport->zoom) & 0xFFFF; + screenY &= (0xFFFF << viewport->zoom) & 0xFFFF; + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, int16_t) = screenX; + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, int16_t) = screenY; + rct_drawpixelinfo* dpi = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_DPI, rct_drawpixelinfo); + dpi->y = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, int16_t); + dpi->height = 1; + dpi->zoom_level = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_ZOOM, uint16_t); + dpi->x = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, int16_t); + dpi->width = 1; + RCT2_GLOBAL(0xEE7880, uint32_t) = 0xF1A4CC; + RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*) = dpi; + sub_0x68615B(0xEE788C); + sub_0x68B6C2(); + RCT2_CALLPROC_X(0x688217, 0, 0, 0, 0, 0, 0, 0); + RCT2_CALLPROC_X(0x68862C, 0, 0, 0, 0, 0, 0, 0); + } + } + if (z != NULL) *z = RCT2_GLOBAL(0x9AC148, uint8_t); + if (x != NULL) *x = (int)RCT2_GLOBAL(0x9AC14C, int16_t); + if (y != NULL) *y = (int)RCT2_GLOBAL(0x9AC14E, int16_t); + if (mapElement != NULL) *mapElement = RCT2_GLOBAL(0x9AC150, rct_map_element*); } \ No newline at end of file diff --git a/src/windows/ride.c b/src/windows/ride.c index ff84a7e466..b52e27c9a6 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -3541,17 +3541,20 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y) newColourScheme = (uint8)(*((uint16*)&w->var_494)); + int z; + + get_map_coordinates_from_pos(x, y, -5, &x, &y, &z, &mapElement); // Get map coordinates from point - int eax, ebx, ecx, edx, esi, edi, ebp; + /*int eax, ebx, ecx, edx, esi, edi, ebp; eax = x; ebx = y; edx = -5; RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); x = eax & 0xFFFF; y = ecx & 0xFFFF; - mapElement = (rct_map_element*)edx; + mapElement = (rct_map_element*)edx;*/ - if ((ebx & 0xFF) != 3) + if ((/*ebx*/z & 0xFF) != 3) return; if (mapElement->properties.track.ride_index != w->number) return;