From 00dcd4fba840a814784cb4bc3a268abadf28ebb8 Mon Sep 17 00:00:00 2001 From: Gericom Date: Fri, 27 Feb 2015 10:37:17 +0100 Subject: [PATCH 1/2] Implemented window_construction_paint Still contains some bug related to drawing the current track piece --- src/windows/ride_construction.c | 182 ++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 8 deletions(-) diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index fdded5c766..4c8261d196 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -8,12 +8,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - + * You should have received a copy of the GNU General Public License * along with this program. If not, see . *****************************************************************************/ @@ -22,6 +22,8 @@ #include "../interface/window.h" #include "../interface/viewport.h" #include "../game.h" +#include "../ride/track.h" +#include "../drawing/drawing.h" /* move to ride.c */ void sub_6b2fa9(rct_windownumber number){ @@ -47,8 +49,11 @@ enum { void window_construction_emptysub(){} void window_construction_close(); void window_construction_mouseup(); +void window_construction_paint(); void window_construction_maze_close(); +void window_construction_maze_invalidate(); +void window_construction_maze_paint(); // 0x993F6C static void* window_construction_maze_events[] = { @@ -77,8 +82,8 @@ static void* window_construction_maze_events[] = { window_construction_emptysub, window_construction_emptysub, window_construction_emptysub, - (void*)0x6CD435, - (void*)0x6CD45B, + window_construction_maze_invalidate, + window_construction_maze_paint, window_construction_emptysub }; @@ -110,12 +115,12 @@ static void* window_construction_events[] = { window_construction_emptysub, window_construction_emptysub, (void*)0x6C6AD5, - (void*)0x6C6B86, + window_construction_paint,//(void*)0x6C6B86, window_construction_emptysub }; /** - * + * * rct2: 0x006CB481 */ rct_window *window_construction_open() @@ -177,7 +182,7 @@ rct_window *window_construction_open() RCT2_GLOBAL(0xF440CE, uint8) = 30; } - RCT2_GLOBAL(0xF440A0,uint16) = RCT2_ADDRESS(0x0097CC68, uint8)[ride->type * 2] | 0x100; + RCT2_GLOBAL(0xF440A0, uint16) = RCT2_ADDRESS(0x0097CC68, uint8)[ride->type * 2] | 0x100; RCT2_GLOBAL(0x00F440B2, uint8) = 0; RCT2_GLOBAL(0x00F440B3, uint8) = 0; RCT2_GLOBAL(0x00F440B4, uint8) = 0; @@ -240,7 +245,7 @@ void window_construction_maze_close(){ RCT2_GLOBAL(0x9DE58A, uint16) &= 0xFFFD; hide_gridlines(); - + uint8 ride_id = RCT2_GLOBAL(0xF440A7, uint8); rct_ride* ride = GET_RIDE(ride_id); @@ -325,3 +330,164 @@ void window_construction_mouseup_demolish(rct_window* w){ //6c9BFE } +void window_construction_maze_invalidate() +{ + int ride_idx = RCT2_GLOBAL(0x00F440A7, uint8); + RCT2_GLOBAL(0x13CE958, uint32_t) = RCT2_GLOBAL(0x1362944 + ride_idx * 0x260, uint32_t); + RCT2_GLOBAL(0x13CE956, uint16_t) = RCT2_GLOBAL(0x1362942 + ride_idx * 0x260, uint16_t); +} + +//0x6C6B86 +void window_construction_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + window_paint_get_registers(w, dpi); + //RCT2_CALLPROC_X(0x6C6B86, 0, 0, 0, 0, w, dpi, 0); + //return; + window_draw_widgets(w, dpi); + if (RCT2_GLOBAL(0x9D7C00, uint8_t) == 0) return; + uint32_t eax = 0, esi = (uint32_t)w, ebp = 0;//nothing + uint32_t ebx = 0, ecx = 0, edx = 0, edi = (uint32_t)dpi;//returns + if (RCT2_CALLFUNC_X(0x6CA2DF, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp) &0x100) return; + RCT2_GLOBAL(0xF44133, uint8_t) = edx & 0xFF; + RCT2_GLOBAL(0xF44134, uint8_t) = (ebx >> 8) & 0xFF; + RCT2_GLOBAL(0xF44135, uint8_t) = (edx >> 8) & 0xFF; + edx >>= 16; + RCT2_GLOBAL(0xF44136, int16_t) = edx; + eax = RCT2_GLOBAL(0xF44133, uint8_t); + eax *= 0x260; + eax = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_LIST + eax, uint8_t); + eax = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + eax * 8, uint32_t); + RCT2_GLOBAL(0xF44064, uint32_t) = eax; + rct_drawpixelinfo* clip_dpi = clip_drawpixelinfo( + dpi, + w->x + RCT2_GLOBAL(0x9D7C02, int16_t) + 1, + RCT2_GLOBAL(0x9D7C04, int16_t) - RCT2_GLOBAL(0x9D7C02, int16_t) - 1, + w->y + RCT2_GLOBAL(0x9D7C06, int16_t) + 1, + RCT2_GLOBAL(0x9D7C08, int16_t) - RCT2_GLOBAL(0x9D7C06, int16_t) - 1); + if (clip_dpi != NULL) + { + short bp = RCT2_GLOBAL(0x9D7C04, int16_t) - RCT2_GLOBAL(0x9D7C02, int16_t) - 1; + short si = RCT2_GLOBAL(0x9D7C08, int16_t) - RCT2_GLOBAL(0x9D7C06, int16_t) - 1; + rct_preview_track *trackBlock; + ecx = RCT2_GLOBAL(0xF44135, uint8_t); + if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) + { + trackBlock = RCT2_GLOBAL(0x994A38 + ecx * 4, rct_preview_track*); + } + else trackBlock = RCT2_GLOBAL(0x994638 + ecx * 4, rct_preview_track*); + while (true) + { + if (trackBlock[1].var_00 == 0xFF) break; + trackBlock++; + } + //TODO: change these names + short ax = trackBlock->x; + short dx = ((uint16_t*)&trackBlock->pad_05)[0]; + short cx = trackBlock->y; + if (trackBlock->unk_09 & 2) ax = cx = 0; + short tmp; + switch (RCT2_GLOBAL(0xF44134, uint8_t) & 3) + { + case 1: + tmp = ax; + ax = cx; + cx = -tmp; + break; + case 2: + ax = -ax; + cx = -cx; + break; + case 3: + tmp = ax; + ax = -cx; + cx = tmp; + break; + case 0: + break; + } + //this is actually case 0, but the other cases all jump to it + ax /= 2; + cx /= 2; + ax += 4112; + cx += 4112; + dx += 1024; + ebx = RCT2_GLOBAL(0xF44135, uint8_t); + short bx; + if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) + bx = RCT2_GLOBAL(0x9984A2 + ebx * 8, uint8_t); + else bx = RCT2_GLOBAL(0x997CA2 + ebx * 8, uint8_t); + dx -= bx; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) + { + case 0: + bx = ax; + ax = -ax; + ax += cx; + cx += bx; + cx /= 2; + cx -= dx; + break; + case 1: + ax = -ax; + bx = ax; + ax -= cx; + cx += bx; + cx /= 2; + cx -= dx; + break; + case 2: + bx = ax; + ax -= cx; + cx = -cx; + cx -= bx; + cx /= 2; + cx -= dx; + break; + case 3: + bx = ax; + ax += cx; + cx = -cx; + cx += bx; + cx /= 2; + cx -= dx; + break; + } + bp >>= 1; + si >>= 1; + si += 16; + ax -= bp; + cx -= si; + clip_dpi->x += ax; + clip_dpi->y += cx; + RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*) = clip_dpi; + uint32_t d = RCT2_GLOBAL(0xF44136, int16_t) << 16; + d |= RCT2_GLOBAL(0xF44133, uint8_t); + d |= RCT2_GLOBAL(0xF44135, uint8_t) << 8; + RCT2_CALLPROC_X(0x6CBCE2, 0x1000, (((uint16_t)bx) & 0xFF) | (RCT2_GLOBAL(0xF44134, uint8_t) << 8), 0x1000, d, si, 0x400, bp); + } + short cx = (RCT2_GLOBAL(0x9D7C02, int16_t) + RCT2_GLOBAL(0x9D7C04, int16_t)) / 2 + w->x; + short dx = RCT2_GLOBAL(0x9D7C08, int16_t) + w->y - 23; + if (RCT2_GLOBAL(0xF440A6, uint8_t) != 4) + { + gfx_draw_string_centred(dpi, 1407, cx, dx, 0, w); + } + dx += 11; + if (RCT2_GLOBAL(0xF44070, uint32_t) != 0x80000000) + { + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800)) + { + gfx_draw_string_centred(dpi, 1408, cx, dx, 0, (void*)0xF44070); + } + } +} + +//0x006CD45B +void window_construction_maze_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + window_paint_get_registers(w, dpi); + window_draw_widgets(w, dpi); +} \ No newline at end of file From a64e89ec666030cda6ae62d912eb1b0e41a65bde Mon Sep 17 00:00:00 2001 From: Gericom Date: Fri, 27 Feb 2015 12:49:22 +0100 Subject: [PATCH 2/2] Refactoring window_construction_paint, fixed bugs --- src/drawing/drawing.h | 3 +- src/drawing/sprite.c | 2 +- src/openrct2.c | 4 +- src/ride/track.h | 9 +- src/windows/ride_construction.c | 141 ++++++++++++-------------------- 5 files changed, 60 insertions(+), 99 deletions(-) diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index bd593ff621..61b335ac9c 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -31,8 +31,7 @@ typedef struct { short width; // 0x08 short height; // 0x0A short pitch; // 0x0C note: this is actually (pitch - width) - uint8 zoom_level; // 0x0E - char var_0F; // 0x0F + uint16 zoom_level; // 0x0E } rct_drawpixelinfo; // Size: 0x10 diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 698d3ab42e..007afbbd18 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -80,7 +80,7 @@ int gfx_load_g1() * rct2: 0x0067A690 */ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ - uint8 zoom_level = dest_dpi->zoom_level; + uint16 zoom_level = dest_dpi->zoom_level; uint8 zoom_amount = 1 << zoom_level; //Requires use of palette? if (image_type & IMAGE_TYPE_USE_PALETTE){ diff --git a/src/openrct2.c b/src/openrct2.c index 7bbc3727fe..eaf2076791 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -131,10 +131,10 @@ void openrct2_launch() config_save_default(); // TODO add configuration option to allow multiple instances - if (!platform_lock_single_instance()) { + /*if (!platform_lock_single_instance()) { fprintf(stderr, "OpenRCT2 is already running.\n"); return; - } + }*/ get_system_info(); audio_init(); diff --git a/src/ride/track.h b/src/ride/track.h index d3b94066a6..fca8678206 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -40,11 +40,12 @@ typedef struct { */ typedef struct { uint8 var_00; - sint16 x; - sint16 y; - uint8 pad_05[3]; + sint16 x; // 0x01 + sint16 y; // 0x03 + uint16 z; + uint8 pad_07; uint8 var_08; - uint8 unk_09; + uint8 var_09; } rct_preview_track; /** diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index 4c8261d196..33c1ee1b02 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -343,144 +343,105 @@ void window_construction_paint() rct_window *w; rct_drawpixelinfo *dpi; window_paint_get_registers(w, dpi); - //RCT2_CALLPROC_X(0x6C6B86, 0, 0, 0, 0, w, dpi, 0); - //return; window_draw_widgets(w, dpi); if (RCT2_GLOBAL(0x9D7C00, uint8_t) == 0) return; uint32_t eax = 0, esi = (uint32_t)w, ebp = 0;//nothing uint32_t ebx = 0, ecx = 0, edx = 0, edi = (uint32_t)dpi;//returns - if (RCT2_CALLFUNC_X(0x6CA2DF, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp) &0x100) return; + if (RCT2_CALLFUNC_X(0x6CA2DF, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp) & 0x100) return; RCT2_GLOBAL(0xF44133, uint8_t) = edx & 0xFF; RCT2_GLOBAL(0xF44134, uint8_t) = (ebx >> 8) & 0xFF; RCT2_GLOBAL(0xF44135, uint8_t) = (edx >> 8) & 0xFF; edx >>= 16; RCT2_GLOBAL(0xF44136, int16_t) = edx; - eax = RCT2_GLOBAL(0xF44133, uint8_t); - eax *= 0x260; - eax = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_LIST + eax, uint8_t); - eax = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + eax * 8, uint32_t); - RCT2_GLOBAL(0xF44064, uint32_t) = eax; + rct_ride* ride = GET_RIDE(RCT2_GLOBAL(0xF44133, uint8)); + RCT2_GLOBAL(0xF44064, uint32_t) = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32_t); + // 0x009D7C04 is a widget address remember to change when widget implemented + short width = RCT2_GLOBAL(0x9D7C04, int16_t) - RCT2_GLOBAL(0x9D7C02, int16_t) - 1; + short height = RCT2_GLOBAL(0x9D7C08, int16_t) - RCT2_GLOBAL(0x9D7C06, int16_t) - 1; rct_drawpixelinfo* clip_dpi = clip_drawpixelinfo( dpi, + // 0x009D7C02 is a widget address remember to change when widget implemented w->x + RCT2_GLOBAL(0x9D7C02, int16_t) + 1, - RCT2_GLOBAL(0x9D7C04, int16_t) - RCT2_GLOBAL(0x9D7C02, int16_t) - 1, + width, w->y + RCT2_GLOBAL(0x9D7C06, int16_t) + 1, - RCT2_GLOBAL(0x9D7C08, int16_t) - RCT2_GLOBAL(0x9D7C06, int16_t) - 1); + height); if (clip_dpi != NULL) { - short bp = RCT2_GLOBAL(0x9D7C04, int16_t) - RCT2_GLOBAL(0x9D7C02, int16_t) - 1; - short si = RCT2_GLOBAL(0x9D7C08, int16_t) - RCT2_GLOBAL(0x9D7C06, int16_t) - 1; rct_preview_track *trackBlock; ecx = RCT2_GLOBAL(0xF44135, uint8_t); - if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) - { - trackBlock = RCT2_GLOBAL(0x994A38 + ecx * 4, rct_preview_track*); - } - else trackBlock = RCT2_GLOBAL(0x994638 + ecx * 4, rct_preview_track*); - while (true) - { - if (trackBlock[1].var_00 == 0xFF) break; - trackBlock++; - } - //TODO: change these names - short ax = trackBlock->x; - short dx = ((uint16_t*)&trackBlock->pad_05)[0]; - short cx = trackBlock->y; - if (trackBlock->unk_09 & 2) ax = cx = 0; + if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) trackBlock = RCT2_ADDRESS(0x994A38, rct_preview_track*)[ecx];//RCT2_GLOBAL(0x994A38 + ecx * 4, rct_preview_track*); + else trackBlock = RCT2_ADDRESS(0x994638, rct_preview_track*)[ecx];//RCT2_GLOBAL(0x994638 + ecx * 4, rct_preview_track*); + while ((trackBlock + 1)->var_00 != 0xFF) trackBlock++; + short x = trackBlock->x; + short z = trackBlock->z; + short y = trackBlock->y; + if (trackBlock->var_09 & 2) x = y = 0; short tmp; switch (RCT2_GLOBAL(0xF44134, uint8_t) & 3) { case 1: - tmp = ax; - ax = cx; - cx = -tmp; + tmp = x; + x = y; + y = -tmp; break; case 2: - ax = -ax; - cx = -cx; + x = -x; + y = -y; break; case 3: - tmp = ax; - ax = -cx; - cx = tmp; + tmp = x; + x = -y; + y = tmp; break; case 0: break; } //this is actually case 0, but the other cases all jump to it - ax /= 2; - cx /= 2; - ax += 4112; - cx += 4112; - dx += 1024; + x /= 2; + y /= 2; + x += 4112; + y += 4112; + z += 1024; ebx = RCT2_GLOBAL(0xF44135, uint8_t); short bx; - if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) - bx = RCT2_GLOBAL(0x9984A2 + ebx * 8, uint8_t); + if (RCT2_GLOBAL(0xF44064, uint32_t) & 0x80000) bx = RCT2_GLOBAL(0x9984A2 + ebx * 8, uint8_t); else bx = RCT2_GLOBAL(0x997CA2 + ebx * 8, uint8_t); - dx -= bx; + z -= bx; + int start_x = x; switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) { case 0: - bx = ax; - ax = -ax; - ax += cx; - cx += bx; - cx /= 2; - cx -= dx; + x = y - x; + y = (y + start_x) / 2 - z; break; case 1: - ax = -ax; - bx = ax; - ax -= cx; - cx += bx; - cx /= 2; - cx -= dx; + x = -x - y; + y = (y - start_x) / 2 - z; break; case 2: - bx = ax; - ax -= cx; - cx = -cx; - cx -= bx; - cx /= 2; - cx -= dx; + x -= y; + y = (-y - start_x) / 2 - z; break; case 3: - bx = ax; - ax += cx; - cx = -cx; - cx += bx; - cx /= 2; - cx -= dx; + x += y; + y = (-y + start_x) / 2 - z; break; } - bp >>= 1; - si >>= 1; - si += 16; - ax -= bp; - cx -= si; - clip_dpi->x += ax; - clip_dpi->y += cx; + clip_dpi->x += x - width / 2; + clip_dpi->y += y - height / 2 - 16; RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*) = clip_dpi; uint32_t d = RCT2_GLOBAL(0xF44136, int16_t) << 16; - d |= RCT2_GLOBAL(0xF44133, uint8_t); + d |= RCT2_GLOBAL(0xF44133, uint8_t);// Ride id d |= RCT2_GLOBAL(0xF44135, uint8_t) << 8; - RCT2_CALLPROC_X(0x6CBCE2, 0x1000, (((uint16_t)bx) & 0xFF) | (RCT2_GLOBAL(0xF44134, uint8_t) << 8), 0x1000, d, si, 0x400, bp); - } - short cx = (RCT2_GLOBAL(0x9D7C02, int16_t) + RCT2_GLOBAL(0x9D7C04, int16_t)) / 2 + w->x; - short dx = RCT2_GLOBAL(0x9D7C08, int16_t) + w->y - 23; - if (RCT2_GLOBAL(0xF440A6, uint8_t) != 4) - { - gfx_draw_string_centred(dpi, 1407, cx, dx, 0, w); - } - dx += 11; - if (RCT2_GLOBAL(0xF44070, uint32_t) != 0x80000000) - { - if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800)) - { - gfx_draw_string_centred(dpi, 1408, cx, dx, 0, (void*)0xF44070); - } + RCT2_CALLPROC_X(0x6CBCE2, 0x1000, (((uint16_t)bx) & 0xFF) | (RCT2_GLOBAL(0xF44134, uint8_t) << 8), 0x1000, d, width, 0x400, height); + rct2_free(clip_dpi); } + short string_x = (RCT2_GLOBAL(0x9D7C02, int16_t) + RCT2_GLOBAL(0x9D7C04, int16_t)) / 2 + w->x; + short string_y = RCT2_GLOBAL(0x9D7C08, int16_t) + w->y - 23; + if (RCT2_GLOBAL(0xF440A6, uint8_t) != 4) gfx_draw_string_centred(dpi, 1407, string_x, string_y, 0, w); + string_y += 11; + if (RCT2_GLOBAL(0xF44070, uint32_t) != 0x80000000 && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800)) + gfx_draw_string_centred(dpi, 1408, string_x, string_y, 0, (void*)0xF44070); } //0x006CD45B