Merge pull request #891 from Gericom/develop

Implemented some viewport drawing functions
This commit is contained in:
Ted John 2015-03-17 17:07:37 +00:00
commit d862ff73a7
2 changed files with 465 additions and 92 deletions

View File

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

View File

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