From 9958ffc0f714e070ad8f6adb39ad01e23c7c0cd4 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 12:24:27 +0100 Subject: [PATCH 01/14] Started refactor of viewport drawing Renabled banner paint setup --- src/addresses.h | 5 + src/drawing/string.c | 2 +- src/interface/viewport.c | 170 +++++++++++++++++++--------------- src/localisation/string_ids.h | 3 + src/world/map.c | 1 + 5 files changed, 106 insertions(+), 75 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 5b0b4d5cf3..b9dfaebbca 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -304,6 +304,11 @@ #define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908 +// Each character is painted onto a drawing surface +// any coloured pixels are marked in this bitmap +// 8 x 8 in size. +#define RCT2_ADDRESS_CHARACTER_BITMAP 0x00F4393C + #define RCT2_ADDRESS_TRACK_PREVIEW_ROTATION 0x00F440AE #define RCT2_ADDRESS_TRACK_PREVIEW_X_MIN 0x00F440F9 diff --git a/src/drawing/string.c b/src/drawing/string.c index 2de4468b78..d0c575f963 100644 --- a/src/drawing/string.c +++ b/src/drawing/string.c @@ -69,7 +69,7 @@ void gfx_load_character_widths(){ val |= 0x80; } } - RCT2_ADDRESS(0xF4393C, uint8)[i * 8 + x] = val; + RCT2_ADDRESS(RCT2_ADDRESS_CHARACTER_BITMAP, uint8)[i * 8 + x] = val; } } diff --git a/src/interface/viewport.c b/src/interface/viewport.c index eaa10bc927..f80b548f75 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -872,32 +872,34 @@ void sub_0x69E8B0(uint16 eax, uint16 ecx){ } /*rct2: 0x006C42D9*/ -int sub_6C42D9(rct_string_id string_id, int scroll, int ebp) +int sub_6C42D9(rct_string_id string_id, uint16 scroll, uint16 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; + + RCT2_GLOBAL(0x9D7A80, uint32)++; + uint32 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))) + uint8_t* unknown_pointer = RCT2_ADDRESS(0x9C3840, uint8) + 0xA12 * i; + if (edx >= *((uint32*)(unknown_pointer + 0x0E))) { - edx = *((uint32_t*)(unknown_pointer + 0x0E)); - RCT2_GLOBAL(0x9D7A84, uint32_t) = i; - RCT2_GLOBAL(0x9D7A88, uint32_t) = (uint32_t)unknown_pointer; + edx = *((uint32*)(unknown_pointer + 0x0E)); + RCT2_GLOBAL(0x9D7A84, uint32) = i; + RCT2_GLOBAL(0x9D7A88, uint32) = (uint32)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*)(unknown_pointer + 0x02)) == RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) && + *((uint32*)(unknown_pointer + 0x06)) == RCT2_GLOBAL(0x13CE956, uint32) && + *((uint16*)(unknown_pointer + 0x0A)) == scroll && + *((uint16*)(unknown_pointer + 0x0C)) == ebp) { - *((uint32_t*)(unknown_pointer + 0x0E)) = RCT2_GLOBAL(0x9D7A80, uint32_t); + *((uint32*)(unknown_pointer + 0x0E)) = RCT2_GLOBAL(0x9D7A80, uint32); return i + 0x606; } } - uint8_t* unknown_pointer = RCT2_GLOBAL(0x9D7A88, uint8_t*); + uint8* unknown_pointer = RCT2_GLOBAL(0x9D7A88, uint8*); *((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); @@ -907,112 +909,132 @@ int sub_6C42D9(rct_string_id string_id, int scroll, int ebp) 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; + uint8 character = RCT2_GLOBAL(0x13CE959, uint8); + int edi = character & 0x7F; int offs = 0; - if (al >= 0x80) offs = 2; - RCT2_GLOBAL(0x9D7A8C, uint8_t) = RCT2_ADDRESS(0x0141FC47, uint8_t)[offs + edi * 8]; + if (character >= 0x80) offs = 2; + + uint8 character_colour = RCT2_ADDRESS(0x0141FC47, uint8)[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; + character = *format_result; format_result++; - if (al == 0) + if (character == 0) { format_result = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); continue; } - if (al <= FORMAT_COLOUR_CODE_END && al >= FORMAT_COLOUR_CODE_START) + if (character <= FORMAT_COLOUR_CODE_END && character >= 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]; + character -= FORMAT_COLOUR_CODE_START; + character_colour = RCT2_GLOBAL(0x9FF048, uint8*)[character * 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 (character < 0x20) continue; + character -= 0x20; + + uint8 character_width = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH + 0x1C0, uint8)[character]; + uint8* character_bitmap = &(RCT2_ADDRESS(RCT2_ADDRESS_CHARACTER_BITMAP, uint8)[character * 8]); + for (; character_width != 0;character_width--,character_bitmap++) { + // Skip any none displayed columns if (scroll != 0) { scroll--; - unk2++; - edx--; - if (edx == 0) break; + continue; } - else + + int16_t eax = *unk; + if (eax == -1) return RCT2_GLOBAL(0x9D7A84, uint32_t) + 0x606; + if (eax > -1) { - 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 = *character_bitmap; + while (true) { - 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; - } + if (ah & 1) *dst = character_colour; + ah >>= 1; + dst += 0x40; + if (ah == 0) break; } - unk2++; - unk++; - edx--; - if (edx == 0) break; } + unk++; + } } } /* rct2: 0x006B9CC4 */ -void viewport_banner_paint_setup(uint32_t direction, int edx, rct_map_element* map_element) +void viewport_banner_paint_setup(uint8 direction, int height, 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; + + height -= 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(0x9DEA56, uint16_t) = height + 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) + + uint32 base_id = (direction << 1) + banner_scenery->image; + uint32 image_id = base_id; + + if (map_element->flags & MAP_ELEMENT_FLAG_GHOST)//if being placed { RCT2_GLOBAL(0x9DE570, uint8_t) = 0; - ebx &= 0x7FFFF; - ebx |= RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8_t)]; + image_id |= 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)); + else{ + image_id |= + (gBanners[map_element->properties.banner.index].colour << 19) | + 0x20000000; + } + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + RCT2_GLOBAL(0x9DEA52, uint32) = RCT2_ADDRESS(0x98D888, uint32)[direction * 2]; + + image_id++; + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + // Opposite direction direction ^= 2; direction--; - if (direction >= 2 || (map_element->flags & 0x10)) return; + // If text not showing / ghost + if (direction >= 2 || (map_element->flags & MAP_ELEMENT_FLAG_GHOST)) return; + int ebp = banner_scenery->banner.var_06; ebp += direction; - RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32_t) = 0; + + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0; RCT2_GLOBAL(0x13CE956, uint32_t) = 0; - rct_string_id string_id = 0xBA5;//no entry + + rct_string_id string_id = STR_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; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = gBanners[map_element->properties.banner.index].string_idx; + string_id = STR_BANNER_TEXT; } 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_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0x1C0; + + uint16 string_width = gfx_get_string_width(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char)); + uint16 scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) / 2) % 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); + 0x1500, sub_6C42D9(string_id, scroll, ebp), 0, height + 22, 1, 1, 0); } /*rct2: 0x0068B35F*/ @@ -1157,9 +1179,9 @@ void sub_68B35F(int ax, int cx) 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); + 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); + //RCT2_CALLPROC_X(0x6B9CC4, 0, 0, direction, dx, (int)map_element, 0, 0); break; default: // This is a little hack for taking care of undefined map_elements diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 91ed513dc1..6b01892cd7 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -518,6 +518,8 @@ enum { STR_CANT_OPEN_PARK = 1723, STR_CANT_CLOSE_PARK = 1724, + STR_BANNER_TEXT = 1731, + STR_NUMBER_OF_LAPS = 1734, STR_NUMBER_OF_LAPS_TIP = 1735, @@ -1146,6 +1148,7 @@ enum { STR_MUSIC_ACKNOWLEDGEMENTS = 2863, STR_TOO_MANY_BANNERS_IN_GAME = 2980, + STR_NO_ENTRY = 2981, STR_CHANGE_BANNER_TEXT_TIP = 2986, STR_SET_AS_NO_ENTRY_BANNER_TIP = 2987, diff --git a/src/world/map.c b/src/world/map.c index 6bf07b1f08..09e4170305 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -904,6 +904,7 @@ void game_command_set_scenery_colour(int* eax, int* ebx, int* ecx, int* edx, int return; } } + if((*ebx & 0x40) && !(map_element->flags & MAP_ELEMENT_FLAG_GHOST)){ *ebx = 0; return; From 55d3b67cfe3e8a2f9b508ee4c991c4a2476a3e6b Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 21:21:35 +0100 Subject: [PATCH 02/14] Refactor of scrolling_text_setup --- src/addresses.h | 8 +++ src/interface/viewport.c | 136 +++++++++++++++++++++++---------------- src/world/scenery.h | 2 +- 3 files changed, 90 insertions(+), 56 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index b9dfaebbca..48520d6404 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -55,6 +55,10 @@ #define RCT2_ADDRESS_EASTEREGG_NAMES 0x00988C20 +// An array of pointers to the start of a way to +// translate between scroll positions for drawing +#define RCT2_ADDRESS_SCROLLING_MODE_POSITIONS 0x00992FB8 + #define RCT2_ADDRESS_RIDE_PROPERTIES 0x00997C9D #define RCT2_ADDRESS_LAND_TOOL_SIZE 0x009A9800 #define RCT2_ADDRESS_SAVE_PROMPT_MODE 0x009A9802 @@ -158,6 +162,10 @@ #define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288 +#define RCT2_ADDRESS_DRAW_SCROLL_LIST 0x009C3840 + +#define RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID 0x009D7A80 + #define RCT2_ADDRESS_INPUT_FLAGS 0x009DE518 #define RCT2_ADDRESS_CURENT_CURSOR 0x009DE51C #define RCT2_ADDRESS_INPUT_STATE 0x009DE51D diff --git a/src/interface/viewport.c b/src/interface/viewport.c index f80b548f75..0e715a5cfb 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -871,68 +871,99 @@ void sub_0x69E8B0(uint16 eax, uint16 ecx){ } } +/* size: 0xA12 */ +typedef struct{ + rct_string_id string_id; // 0x00 + uint32 string_args_0; // 0x02 + uint32 string_args_1; // 0x06 + uint16 position; // 0x0A + uint16 mode; // 0x0C + uint32 id; // 0x0E + uint8 bitmap[64 * 8 * 5];// 0x12 +}rct_draw_scroll_text; + /*rct2: 0x006C42D9*/ -int sub_6C42D9(rct_string_id string_id, uint16 scroll, uint16 ebp) +int scrolling_text_setup(rct_string_id string_id, uint16 scroll, uint16 scrolling_mode) { rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); if (dpi->zoom_level != 0) return 0x626; - RCT2_GLOBAL(0x9D7A80, uint32)++; - uint32 edx = 0xFFFFFFFF; - for (int i = 0; i < 0x20; i++) + RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32)++; + + uint32 oldest_id = 0xFFFFFFFF; + uint8 scroll_index = 0xFF; + rct_draw_scroll_text* oldest_scroll = NULL; + + // Find the oldest scroll for use as the newest + for (int i = 0; i < 32; i++) { - uint8_t* unknown_pointer = RCT2_ADDRESS(0x9C3840, uint8) + 0xA12 * i; - if (edx >= *((uint32*)(unknown_pointer + 0x0E))) - { - edx = *((uint32*)(unknown_pointer + 0x0E)); - RCT2_GLOBAL(0x9D7A84, uint32) = i; - RCT2_GLOBAL(0x9D7A88, uint32) = (uint32)unknown_pointer; + rct_draw_scroll_text* scroll_text = &RCT2_ADDRESS(RCT2_ADDRESS_DRAW_SCROLL_LIST, rct_draw_scroll_text)[i]; + if (oldest_id >= scroll_text->id){ + oldest_id = scroll_text->id; + scroll_index = i; + oldest_scroll = scroll_text; } - if (*((rct_string_id*)unknown_pointer) == string_id && - *((uint32*)(unknown_pointer + 0x02)) == RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) && - *((uint32*)(unknown_pointer + 0x06)) == RCT2_GLOBAL(0x13CE956, uint32) && - *((uint16*)(unknown_pointer + 0x0A)) == scroll && - *((uint16*)(unknown_pointer + 0x0C)) == ebp) - { - *((uint32*)(unknown_pointer + 0x0E)) = RCT2_GLOBAL(0x9D7A80, uint32); + + // If exact match return the matching index + if (scroll_text->string_id == string_id && + scroll_text->string_args_0 == RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) && + scroll_text->string_args_1 == RCT2_GLOBAL(0x13CE956, uint32) && + scroll_text->position == scroll && + scroll_text->mode == scrolling_mode){ + + scroll_text->id = RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32); return i + 0x606; } } - uint8* unknown_pointer = RCT2_GLOBAL(0x9D7A88, uint8*); - *((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); + + // Setup scrolling text + + rct_draw_scroll_text* scroll_text = oldest_scroll; + scroll_text->string_id = string_id; + scroll_text->string_args_0 = RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32); + scroll_text->string_args_1 = RCT2_GLOBAL(0x13CE956, uint32); + scroll_text->position = scroll; + scroll_text->mode = scrolling_mode; + scroll_text->id = RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32_t); + + uint8* scroll_pixel_pointer = scroll_text->bitmap; + memset(scroll_pixel_pointer, 0, 320 * 8); + + // Convert string id back into a string for processing + uint8 scroll_string[MAX_PATH]; + format_string(scroll_string, string_id, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS); + + // Setup character colour from ??? uint8 character = RCT2_GLOBAL(0x13CE959, uint8); int edi = character & 0x7F; int offs = 0; if (character >= 0x80) offs = 2; - uint8 character_colour = RCT2_ADDRESS(0x0141FC47, uint8)[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); + + sint16* scrolling_mode_positions = RCT2_ADDRESS(RCT2_ADDRESS_SCROLLING_MODE_POSITIONS, uint16_t*)[scrolling_mode]; + uint8* format_result = scroll_string; while (true) { - character = *format_result; - format_result++; - if (character == 0) - { - format_result = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + character = *format_result++; + + // If at the end of the string loop back to the start + if (character == 0){ + format_result = scroll_string; continue; } - if (character <= FORMAT_COLOUR_CODE_END && character >= FORMAT_COLOUR_CODE_START) - { + + // Set any change in colour + if (character <= FORMAT_COLOUR_CODE_END && character >= FORMAT_COLOUR_CODE_START){ character -= FORMAT_COLOUR_CODE_START; character_colour = RCT2_GLOBAL(0x9FF048, uint8*)[character * 4]; continue; } + + // If another type of control character ignore if (character < 0x20) continue; + + // Convert to an indexable character character -= 0x20; uint8 character_width = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH + 0x1C0, uint8)[character]; @@ -940,28 +971,23 @@ int sub_6C42D9(rct_string_id string_id, uint16 scroll, uint16 ebp) for (; character_width != 0;character_width--,character_bitmap++) { // Skip any none displayed columns - if (scroll != 0) - { + if (scroll != 0){ scroll--; continue; } - int16_t eax = *unk; - if (eax == -1) return RCT2_GLOBAL(0x9D7A84, uint32_t) + 0x606; - if (eax > -1) + sint16 scroll_position = *scrolling_mode_positions; + if (scroll_position == -1) return scroll_index + 0x606; + if (scroll_position > -1) { - uint8_t* dst = &unknown_pointer[eax]; - int ah = *character_bitmap; - while (true) - { - if (ah & 1) *dst = character_colour; - ah >>= 1; - dst += 0x40; - if (ah == 0) break; + uint8* dst = &scroll_pixel_pointer[scroll_position]; + for (uint8 char_bitmap = *character_bitmap; char_bitmap != 0; char_bitmap >>= 1){ + if (char_bitmap & 1) *dst = character_colour; + // Jump to next row + dst += 64; } } - unk++; - + scrolling_mode_positions++; } } } @@ -1014,8 +1040,8 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m // If text not showing / ghost if (direction >= 2 || (map_element->flags & MAP_ELEMENT_FLAG_GHOST)) return; - int ebp = banner_scenery->banner.var_06; - ebp += direction; + uint16 scrollingMode = banner_scenery->banner.scrolling_mode; + scrollingMode += direction; RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0; RCT2_GLOBAL(0x13CE956, uint32_t) = 0; @@ -1034,7 +1060,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m uint16 scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) / 2) % 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, height + 22, 1, 1, 0); + 0x1500, scrolling_text_setup(string_id, scroll, scrollingMode), 0, height + 22, 1, 1, 0); } /*rct2: 0x0068B35F*/ diff --git a/src/world/scenery.h b/src/world/scenery.h index c35704f13d..df208530a5 100644 --- a/src/world/scenery.h +++ b/src/world/scenery.h @@ -115,7 +115,7 @@ typedef struct { } rct_path_bit_scenery_entry; typedef struct { - uint8 var_06; + uint8 scrolling_mode; // 0x06 uint8 flags; // 0x07 sint16 price; // 0x08 uint8 scenery_tab_id; // 0x0A From c004d0e73f847f0cbf720c3ed308c6e66ed0b02d Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 21:52:33 +0100 Subject: [PATCH 03/14] Refactor viewport_paint_setup --- src/interface/viewport.c | 197 +++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 102 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 0e715a5cfb..44735dff83 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1267,25 +1267,26 @@ void sub_68B35F(int ax, int cx) * * rct2: 0x0068B6C2 */ -void sub_0x68B6C2(){ - rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); - sint16 ax, bx, cx, dx; - uint16 num_vertical_quadrants = 0; - rct_xy16 mapTile; +void viewport_paint_setup(){ + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + rct_xy16 mapTile = { + .x = dpi->x & 0xFFE0, + .y = (dpi->y - 16) & 0xFFE0 + }; + + sint16 half_x = mapTile.x / 2; + + uint16 num_vertical_quadrants = (dpi->height + 2128) / 32; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ case 0: - mapTile.x = dpi->x & 0xFFE0; - mapTile.y = (dpi->y - 16) & 0xFFE0; - - bx = mapTile.x / 2; - mapTile.x = mapTile.y - bx; - mapTile.y = mapTile.y + bx; + mapTile.x = mapTile.y - half_x; + mapTile.y = mapTile.y + half_x; mapTile.x &= 0xFFE0; mapTile.y &= 0xFFE0; - - num_vertical_quadrants = (dpi->height + 2128) / 32; - + for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ sub_68B35F(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); @@ -1309,98 +1310,90 @@ void sub_0x68B6C2(){ } break; case 1: - ax = dpi->y; - bx = dpi->x; - ax -= 0x10; - bx &= 0xFFE0; - ax &= 0xFFE0; - bx >>= 1; - cx = ax; - ax = -ax; - ax -= bx; - cx -= bx; - cx -= 0x10; - ax &= 0xFFE0; - cx &= 0xFFE0; - dx = dpi->height; - dx += 0x860; - dx >>= 5; - for (int i = dx; i > 0; i--){ - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax -= 0x20; - cx -= 0x20; - sub_0x69E8B0(ax, cx); - cx += 0x20; - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax += 0x20; - cx += 0x20; - sub_0x69E8B0(ax, cx); - ax -= 0x20; + mapTile.x = -mapTile.y - half_x; + mapTile.y = mapTile.y - half_x - 16; + + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; + mapTile.y -= 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.y += 32; + + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; + mapTile.y += 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; } break; case 2: - ax = dpi->y; - bx = dpi->x; - ax -= 0x10; - bx &= 0xFFE0; - ax &= 0xFFE0; - bx >>= 1; - ax = -ax; - cx = ax; - ax += bx; - cx -= bx; - ax &= 0xFFE0; - cx &= 0xFFE0; - dx = dpi->height; - dx += 0x860; - dx >>= 5; - for (int i = dx; i > 0; i--){ - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax += 0x20; - cx -= 0x20; - sub_0x69E8B0(ax, cx); - ax -= 0x20; - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax -= 0x20; - cx += 0x20; - sub_0x69E8B0(ax, cx); - cx -= 0x20; + mapTile.x = -mapTile.y + half_x; + mapTile.y = -mapTile.y - half_x; + + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; + mapTile.y -= 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; + + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; + mapTile.y += 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.y -= 32; } break; case 3: - ax = dpi->y; - bx = dpi->x; - ax -= 0x10; - bx &= 0xFFE0; - ax &= 0xFFE0; - bx >>= 1; - cx = ax; - ax += bx; - cx = -cx; - cx += bx; - cx -= 0x10; - ax &= 0xFFE0; - cx &= 0xFFE0; - dx = dpi->height; - dx += 0x860; - dx >>= 5; - for (int i = dx; i > 0; i--){ - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax += 0x20; - cx += 0x20; - sub_0x69E8B0(ax, cx); - cx -= 0x20; - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax -= 0x20; - cx -= 0x20; - sub_0x69E8B0(ax, cx); - ax += 0x20; + mapTile.x = mapTile.y + half_x; + mapTile.y = -mapTile.y + half_x - 16; + + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; + mapTile.y += 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.y -= 32; + + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; + mapTile.y -= 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; } break; } @@ -1622,7 +1615,7 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in RCT2_GLOBAL(0x140E9A8, uint32) = (int)dpi2; int ebp = 0, ebx = 0, esi = 0, ecx = 0; sub_0x68615B(0xEE788C); //Memory copy - sub_0x68B6C2(); + viewport_paint_setup(); sub_688217(); sub_688485(); @@ -2026,7 +2019,7 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x RCT2_GLOBAL(0xEE7880, uint32_t) = 0xF1A4CC; RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*) = dpi; sub_0x68615B(0xEE788C); - sub_0x68B6C2(); + viewport_paint_setup(); sub_688217(); sub_68862C(); } From 5ba52e3688a59bb4a8e7967a1bd8c2092ba3e82c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 31 May 2015 10:27:48 +0100 Subject: [PATCH 04/14] Refactor of map_element_paint_setup --- src/interface/viewport.c | 286 +++++++++++++++++++-------------------- 1 file changed, 139 insertions(+), 147 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 44735dff83..d4009c8049 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1064,12 +1064,14 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m } /*rct2: 0x0068B35F*/ -void sub_68B35F(int ax, int cx) +void map_element_paint_setup(int x, int y) { - 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) - { + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (x < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16_t) && + y < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16_t) && + x >= 32 && y >= 32){ + RCT2_GLOBAL(0x141E9B4, uint32_t) = 0xFFFF; RCT2_GLOBAL(0x141E9B8, uint32_t) = 0xFFFF; RCT2_GLOBAL(0x141E9BC, uint32_t) = 0xFFFF; @@ -1086,166 +1088,156 @@ void sub_68B35F(int ax, int cx) 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*); + RCT2_GLOBAL(0x9DE56A, uint16_t) = x; + RCT2_GLOBAL(0x9DE56E, uint16_t) = y; + RCT2_GLOBAL(0x9DE574, uint16_t) = x; + RCT2_GLOBAL(0x9DE576, uint16_t) = y; + + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + + int dx = 0; switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) { case 0: - dx = ax + cx; + dx = x + y; break; case 1: - ax += 32; - dx = cx - ax; + x += 32; + dx = y - x; break; case 2: - ax += 32; - cx += 32; - dx = -(ax + cx); + x += 32; + y += 32; + dx = -(x + y); break; case 3: - cx += 32; - dx = ax - cx; + y += 32; + dx = x - y; break; } dx /= 2; // Display little yellow arrow when building footpaths? - if ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16_t) & 4) && - RCT2_GLOBAL(0x9DE56A, uint16_t) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_X, uint16_t) && - RCT2_GLOBAL(0x9DE56E, uint16_t) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Y, uint16_t)) - { + if ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & 4) && + RCT2_GLOBAL(0x9DE56A, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_X, uint16) && + RCT2_GLOBAL(0x9DE56E, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Y, uint16)){ + uint8 arrowRotation = + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + + (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 3) & 3; + + uint32 imageId = + arrowRotation + + (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 0xFC) + + 0x20900C27; + + int arrowZ = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Z, uint16); + + RCT2_GLOBAL(0x9DE568, uint16) = x; + RCT2_GLOBAL(0x9DE56C, uint16) = y; + RCT2_GLOBAL(0x9DE570, uint8) = 0; + RCT2_GLOBAL(0x9DEA52, uint16) = 0; + RCT2_GLOBAL(0x9DEA54, uint16) = 0; + RCT2_GLOBAL(0x9DEA56, uint16) = arrowZ + 18; - 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(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8_t) & 3; - ebx += dl; - ebx &= 3; - dl = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8_t) & 0xFC; - ebx += dl; - ebx += 0x20900C27; - int d = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Z, 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)RCT2_ADDRESS(0x0098197C, uint32*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)], + 0xFF00, imageId, y & 0xFF00, arrowZ, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); } 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: - // This is a little hack for taking care of undefined map_elements - // 8cars MOM used a dirty version of this to skip drawing certain elements - if (map_element_is_last_for_tile(map_element)) - return; - map_element++; - break; - } - RCT2_GLOBAL(0x9DE574, uint32_t) = dword_9DE574; - int stop = map_element_is_last_for_tile(map_element); - map_element++; - if (stop) break; - } - } + + if (bx <= dpi->y) + return; + + rct_map_element* element = map_element;//push map_element + + sint16 max_height = 0; + do{ + max_height = max(max_height, element->clearance_height); + } while (!map_element_is_last_for_tile(element++)); + + element--; + + if (map_element_get_type(element) == MAP_ELEMENT_TYPE_SURFACE && + (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) != 0){ + max_height = (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 1; } + + max_height *= 8; + + dx -= max_height + 32; + + element = map_element;//pop map_element + dx -= dpi->height; + if (dx >= dpi->y) + return; + + RCT2_GLOBAL(0x9DE568, uint16_t) = x; + RCT2_GLOBAL(0x9DE56C, uint16_t) = y; + RCT2_GLOBAL(0x9DE57C, uint16_t) = 0; + do{ + int direction = (map_element->type + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) & MAP_ELEMENT_DIRECTION_MASK; + int height = 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, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_PATH: + RCT2_CALLPROC_X(0x6A3590, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_TRACK: + RCT2_CALLPROC_X(0x6C4794, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_SCENERY: + RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_ENTRANCE: + RCT2_CALLPROC_X(0x664FD4, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_FENCE: + RCT2_CALLPROC_X(0x6E44B0, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: + RCT2_CALLPROC_X(0x6B7F0C, 0, 0, direction, height, (int)map_element, 0, 0); + break; + case MAP_ELEMENT_TYPE_BANNER: + viewport_banner_paint_setup(direction, height, map_element); + break; + default: + // This is a little hack for taking care of undefined map_elements + // 8cars MOM used a dirty version of this to skip drawing certain elements + if (map_element_is_last_for_tile(map_element)) + return; + map_element++; + break; + } + RCT2_GLOBAL(0x9DE574, uint32_t) = dword_9DE574; + } while (!map_element_is_last_for_tile(map_element++)); + } - else - { - rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + else{ + int dx; switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) { case 0: - dx = ax + cx; + dx = x + y; break; case 1: - ax += 32; - dx = cx - ax; + x += 32; + dx = y - x; break; case 2: - ax += 32; - cx += 32; - dx = -(ax + cx); + x += 32; + y += 32; + dx = -(x + y); break; case 3: - cx += 32; - dx = ax - cx; + y += 32; + dx = x - y; break; } dx /= 2; @@ -1255,11 +1247,11 @@ void sub_68B35F(int ax, int cx) dx -= 20; dx -= dpi->height; if (dx >= dpi->y) return; - RCT2_GLOBAL(0x9DE568, uint16_t) = ax; - RCT2_GLOBAL(0x9DE56C, uint16_t) = cx; + RCT2_GLOBAL(0x9DE568, uint16_t) = x; + RCT2_GLOBAL(0x9DE56C, uint16_t) = y; 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)); + 0xFF00, 3123, y & 0xFF00, 16, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } } @@ -1288,7 +1280,7 @@ void viewport_paint_setup(){ mapTile.y &= 0xFFE0; for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x -= 32; @@ -1298,7 +1290,7 @@ void viewport_paint_setup(){ mapTile.x += 32; - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x += 32; @@ -1317,7 +1309,7 @@ void viewport_paint_setup(){ mapTile.y &= 0xFFE0; for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x -= 32; @@ -1327,7 +1319,7 @@ void viewport_paint_setup(){ mapTile.y += 32; - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x += 32; @@ -1346,7 +1338,7 @@ void viewport_paint_setup(){ mapTile.y &= 0xFFE0; for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x += 32; @@ -1356,7 +1348,7 @@ void viewport_paint_setup(){ mapTile.x -= 32; - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x -= 32; @@ -1375,7 +1367,7 @@ void viewport_paint_setup(){ mapTile.y &= 0xFFE0; for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x += 32; @@ -1385,7 +1377,7 @@ void viewport_paint_setup(){ mapTile.y -= 32; - sub_68B35F(mapTile.x, mapTile.y); + map_element_paint_setup(mapTile.x, mapTile.y); sub_0x69E8B0(mapTile.x, mapTile.y); mapTile.x -= 32; From b20513187c915a7fb1aa3a54ddcf5754708dcc2a Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 31 May 2015 10:54:01 +0100 Subject: [PATCH 05/14] Start viewport_entrance_paint_setup --- src/interface/viewport.c | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index d4009c8049..446fa9fa25 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -992,6 +992,51 @@ int scrolling_text_setup(rct_string_id string_id, uint16 scroll, uint16 scrollin } } +/* rct2: 0x00664FD4 */ +void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ + RCT2_GLOBAL(0x9DE570, uint8_t) = 0xB; + + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_VIEWPORT_FLAGS, uint16) & VIEWPORT_FLAG_PATH_HEIGHTS && + dpi->zoom_level == 0){ + uint32 ebx = + (map_element->properties.entrance.type << 4) | + (map_element->properties.entrance.index & 0xF); + + if (RCT2_ADDRESS(0x0097B974, uint8)[ebx] & 0xF){ + + int z = map_element->base_height * 8 + 3; + uint32 image_id = + z / 16 + + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS,sint16) + + 0x20101689; + + image_id -= RCT2_GLOBAL(0x01359208, sint16); + + RCT2_GLOBAL(0x009DEA52, uint16) = 31; + RCT2_GLOBAL(0x009DEA54, uint16) = 31; + RCT2_GLOBAL(0x009DEA56, sint16) = z; + RCT2_GLOBAL(0x009DEA56, uint16) += 64; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 16, image_id, 16, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + } + } + + switch (map_element->properties.entrance.type){ + case ENTRANCE_TYPE_RIDE_ENTRANCE: + //66508C + break; + case ENTRANCE_TYPE_RIDE_EXIT: + //665540 + break; + case ENTRANCE_TYPE_PARK_ENTRANCE: + //6658ED + break; + } +} + /* rct2: 0x006B9CC4 */ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* map_element) { @@ -1195,6 +1240,7 @@ void map_element_paint_setup(int x, int y) RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)map_element, 0, 0); break; case MAP_ELEMENT_TYPE_ENTRANCE: + //viewport_entrance_paint_setup(direction, height, map_element); RCT2_CALLPROC_X(0x664FD4, 0, 0, direction, height, (int)map_element, 0, 0); break; case MAP_ELEMENT_TYPE_FENCE: From 3781918957bf0025adb933fd5953d2f7a68d87cd Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 31 May 2015 13:49:39 +0100 Subject: [PATCH 06/14] Added viewport_ride_entrance_paint_setup --- src/interface/viewport.c | 179 +++++++++++++++++++++++++++++++++- src/localisation/string_ids.h | 3 + 2 files changed, 177 insertions(+), 5 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 446fa9fa25..c196c24673 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -992,6 +992,175 @@ int scrolling_text_setup(rct_string_id string_id, uint16 scroll, uint16 scrollin } } +/* rct2: 0x006629BC + * returns al + * ebp : image_id + * ax : unknown + * dx : height + * edi : unknown + */ +int sub_6629BC(int height, uint16 ax, uint32 image_id, uint32 edi){ + int eax = ax, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = edi, ebp = image_id; + + RCT2_CALLFUNC_X(0x006629BC, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp); + + return eax & 0xFF; +} + +typedef struct{ + uint32 image_id; + sint16 height; + sint16 scrolling_mode; +}rct_entrance_style; + +/* rct2: 0x0066508C */ +void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1){ + if (map_element->properties.entrance.ride_index != RCT2_GLOBAL(0x00F64DE8, uint8)) + return; + } + + rct_ride* ride = GET_RIDE(map_element->properties.entrance.ride_index); + + rct_entrance_style* style = &RCT2_ADDRESS(0x00993E7C,rct_entrance_style)[ride->entrance_style]; + + uint8 colour_1, colour_2; + uint32 image_id_1 = 0, image_id_2 = 0; + if (RCT2_ADDRESS(0x00993E1C, uint32)[ride->entrance_style * 2] & (1 << 30)){ + colour_1 = ride->track_colour_main[0] + 0x70; + image_id_1 = (colour_1 << 19) | 0x40000000; + } + + colour_1 = ride->track_colour_main[0]; + colour_2 = ride->track_colour_additional[0]; + image_id_2 = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000; + + RCT2_GLOBAL(0x009DE570, uint8) = 3; + RCT2_GLOBAL(0x009E32BC, uint32) = 0; + + if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ + RCT2_GLOBAL(0x009DE570, uint8) = 0; + image_id_2 = RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; + RCT2_GLOBAL(0x009E32BC, uint32) = image_id_2; + if (image_id_1) + image_id_1 = image_id_2; + } + + image_id_2 |= style->image_id + direction; + + // Format modifed to stop repeated code + + // Each entrance is split into 2 images for drawing + // Certain entrance styles have another 2 images to draw for coloured windows + + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, uint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x3300, image_id_2, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + if (image_id_1){ + image_id_1 |= style->image_id + direction + 16; + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, uint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x3300, image_id_1, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + } + + image_id_2 += 4; + + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 28; + RCT2_GLOBAL(0x009DEA56, uint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x3300, image_id_2, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + if (image_id_1){ + image_id_1 += 4; + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 28; + RCT2_GLOBAL(0x009DEA56, uint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x3300, image_id_1, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + } + + uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF); + if (direction & 1){ + RCT2_ADDRESS(0x009E30B6, uint32)[RCT2_GLOBAL(0x141F56B, uint8) / 2] = eax; + RCT2_GLOBAL(0x141F56B, uint8)++; + } + else{ + RCT2_ADDRESS(0x009E3138, uint32)[RCT2_GLOBAL(0x141F56A, uint8) / 2] = eax; + RCT2_GLOBAL(0x141F56A, uint8)++; + } + + if (!(map_element->flags & MAP_ELEMENT_FLAG_GHOST) && + map_element->properties.entrance.ride_index != 0xFF){ + + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0; + RCT2_GLOBAL(0x13CE956, uint32) = 0; + + rct_string_id string_id = STR_RIDE_ENTRANCE_CLOSED; + + if (ride->status == RIDE_STATUS_OPEN && + !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){ + + RCT2_GLOBAL(0x0013CE954, uint32) = ride->name_arguments; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, rct_string_id) = ride->name; + + string_id = STR_RIDE_ENTRANCE_NAME; + } + + uint8 entrance_string[MAX_PATH]; + format_string(entrance_string, string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void)); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0x1C0; + + uint16 string_width = gfx_get_string_width(entrance_string); + uint16 scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) / 2) % string_width; + + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, uint16) = height + style->height; + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x3300, scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, height + style->height, 0x1C, 0x1C, 0); + } + + uint32 image_id = RCT2_GLOBAL(0x009E32BC, uint32); + if (!image_id){ + image_id = 0x20B80000; + } + + if (direction & 1){ + sub_6629BC(height, 0, image_id, 1); + } + else{ + sub_6629BC(height, 0, image_id, 0); + } + + RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF; + + if (RCT2_GLOBAL(0x141E9D8, sint16) < height + 56){ + RCT2_GLOBAL(0x141E9D8, sint16) = height + 56; + RCT2_GLOBAL(0x141E9DA, uint8) = 32; + } +} + /* rct2: 0x00664FD4 */ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ RCT2_GLOBAL(0x9DE570, uint8_t) = 0xB; @@ -1026,7 +1195,7 @@ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* switch (map_element->properties.entrance.type){ case ENTRANCE_TYPE_RIDE_ENTRANCE: - //66508C + viewport_ride_entrance_paint_setup(direction, height, map_element); break; case ENTRANCE_TYPE_RIDE_EXIT: //665540 @@ -1055,7 +1224,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m RCT2_GLOBAL(0x9DEA56, uint16_t) = height + 2; - RCT2_GLOBAL(0x9DEA52, uint32_t) = RCT2_ADDRESS(0x98D884, uint32_t)[direction * 2]; + RCT2_GLOBAL(0x9DEA52, uint32_t) = RCT2_ADDRESS(0x98D884, uint32)[direction * 2]; uint32 base_id = (direction << 1) + banner_scenery->image; uint32 image_id = base_id; @@ -1063,7 +1232,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m if (map_element->flags & MAP_ELEMENT_FLAG_GHOST)//if being placed { RCT2_GLOBAL(0x9DE570, uint8_t) = 0; - image_id |= RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8_t)]; + image_id |= RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; } else{ image_id |= @@ -1240,8 +1409,8 @@ void map_element_paint_setup(int x, int y) RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)map_element, 0, 0); break; case MAP_ELEMENT_TYPE_ENTRANCE: - //viewport_entrance_paint_setup(direction, height, map_element); - RCT2_CALLPROC_X(0x664FD4, 0, 0, direction, height, (int)map_element, 0, 0); + viewport_entrance_paint_setup(direction, height, map_element); + //RCT2_CALLPROC_X(0x664FD4, 0, 0, direction, height, (int)map_element, 0, 0); break; case MAP_ELEMENT_TYPE_FENCE: RCT2_CALLPROC_X(0x6E44B0, 0, 0, direction, height, (int)map_element, 0, 0); diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 6b01892cd7..2e040cf311 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -324,6 +324,9 @@ enum { STR_OPTIONS_TITLE = 1168, STR_SOUND_NONE = 1169, + STR_RIDE_ENTRANCE_CLOSED = 1171, + STR_RIDE_ENTRANCE_NAME = 1172, + STR_BUILD_FOOTPATH_TIP = 1173, STR_BANNER_SIGN_IN_THE_WAY = 1174, From cb7d579c9a6d9231106b717d414f9eaa50ff4cad Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 1 Jun 2015 18:11:54 +0100 Subject: [PATCH 07/14] Refactor of sprite_paint_setup and litter_setup. Also generalized entrance_setup so that it can be used for exits as well --- src/interface/viewport.c | 166 ++++++++++++++++++++------------------- src/world/sprite.h | 2 +- 2 files changed, 86 insertions(+), 82 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index c196c24673..7423c0a001 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -769,42 +769,29 @@ int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ /** -* Litter Paint Setup?? +* Litter Paint Setup * rct2: 0x006736FC */ -void sub_0x6736FC(rct_litter* litter, int ebx, int edx){ +void viewport_litter_paint_setup(rct_litter* litter, int image_direction, int height){ rct_drawpixelinfo* dpi; dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); if (dpi->zoom_level != 0)return; //If zoomed at all no litter drawn - int ebp = litter->var_01; - //push litter - ebx >>= 3; - ebx &= RCT2_ADDRESS(0x97EF6C, uint32)[ebp * 2 + 1]; - ebx += RCT2_ADDRESS(0x97EF6C, uint32)[ebp * 2]; - int ecx = 0; - int edi = 4; - int esi = 4; - int eax = 0xFF00; + // litter has no sprite direction so remove that + image_direction >>= 3; + // Some litter types have only 1 direction so remove + // anything that isn't required. + image_direction &= RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2 + 1]; + + uint32 image_id = image_direction + RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2]; + RCT2_GLOBAL(0x9DEA52, uint16) = 0xFFFC; RCT2_GLOBAL(0x9DEA54, uint16) = 0xFFFC; - RCT2_GLOBAL(0x9DEA56, uint16) = edx + 2; + RCT2_GLOBAL(0x9DEA56, uint16) = height + 2; - switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ - case 0: - //0x686806 - break; - case 1: - //0x6869b2 - break; - case 2: - //0x686b6f - break; - case 3: - //0x686d31 - break; - } + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0xFF00, image_id, 0, height, 4, 4, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } @@ -812,7 +799,7 @@ void sub_0x6736FC(rct_litter* litter, int ebx, int edx){ * Paint Quadrant * rct2: 0x0069E8B0 */ -void sub_0x69E8B0(uint16 eax, uint16 ecx){ +void sprite_paint_setup(uint16 eax, uint16 ecx){ uint32 _eax = eax, _ecx = ecx; rct_drawpixelinfo* dpi; @@ -842,30 +829,33 @@ void sub_0x69E8B0(uint16 eax, uint16 ecx){ if (dpi->x + dpi->width <= spr->unknown.sprite_left)continue; if (spr->unknown.sprite_right <= dpi->x)continue; - int ebx = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); + int image_direction = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); + image_direction <<= 3; + image_direction += spr->unknown.sprite_direction; + image_direction &= 0x1F; + RCT2_GLOBAL(0x9DE578, uint32) = (uint32)spr; int ebp = spr->unknown.sprite_identifier; - ebx <<= 3; - eax = spr->unknown.x; - ebx += spr->unknown.sprite_direction; - ecx = spr->unknown.y; - ebx &= 0x1F; + RCT2_GLOBAL(0x9DE568, uint16) = spr->unknown.x; RCT2_GLOBAL(0x9DE570, uint8) = 2; RCT2_GLOBAL(0x9DE56C, uint16) = spr->unknown.y; - int edx = spr->unknown.z; + switch (spr->unknown.sprite_identifier){ case SPRITE_IDENTIFIER_VEHICLE: - RCT2_CALLPROC_X(0x6D4244, eax, ebx, ecx, edx, (int)spr, (int)dpi, ebp); + RCT2_CALLPROC_X(0x6D4244, spr->unknown.x, image_direction, spr->unknown.y, spr->unknown.z, (int)spr, (int)dpi, ebp); break; case SPRITE_IDENTIFIER_PEEP: - RCT2_CALLPROC_X(0x68F0FB, eax, ebx, ecx, edx, (int)spr, (int)dpi, ebp); + RCT2_CALLPROC_X(0x68F0FB, spr->unknown.x, image_direction, spr->unknown.y, spr->unknown.z, (int)spr, (int)dpi, ebp); break; case SPRITE_IDENTIFIER_MISC: - RCT2_CALLPROC_X(0x672AC9, eax, ebx, ecx, edx, (int)spr, (int)dpi, ebp); + RCT2_CALLPROC_X(0x672AC9, spr->unknown.x, image_direction, spr->unknown.y, spr->unknown.z, (int)spr, (int)dpi, ebp); break; case SPRITE_IDENTIFIER_LITTER: - RCT2_CALLPROC_X(0x6736FC, eax, ebx, ecx, edx, (int)spr, (int)dpi, ebp); + viewport_litter_paint_setup((rct_litter*)spr, image_direction, spr->unknown.z); + break; + default: + assert(false); break; } } @@ -1013,9 +1003,10 @@ typedef struct{ sint16 scrolling_mode; }rct_entrance_style; -/* rct2: 0x0066508C */ -void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ +/* rct2: 0x0066508C & 0x00665540 */ +void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_map_element* map_element){ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + uint8 is_exit = map_element->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT; if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1){ if (map_element->properties.entrance.ride_index != RCT2_GLOBAL(0x00F64DE8, uint8)) @@ -1027,29 +1018,33 @@ void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_ele rct_entrance_style* style = &RCT2_ADDRESS(0x00993E7C,rct_entrance_style)[ride->entrance_style]; uint8 colour_1, colour_2; - uint32 image_id_1 = 0, image_id_2 = 0; + uint32 transparant_image_id = 0, image_id = 0; if (RCT2_ADDRESS(0x00993E1C, uint32)[ride->entrance_style * 2] & (1 << 30)){ colour_1 = ride->track_colour_main[0] + 0x70; - image_id_1 = (colour_1 << 19) | 0x40000000; + transparant_image_id = (colour_1 << 19) | 0x40000000; } colour_1 = ride->track_colour_main[0]; colour_2 = ride->track_colour_additional[0]; - image_id_2 = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000; + image_id = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000; RCT2_GLOBAL(0x009DE570, uint8) = 3; RCT2_GLOBAL(0x009E32BC, uint32) = 0; if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ RCT2_GLOBAL(0x009DE570, uint8) = 0; - image_id_2 = RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; - RCT2_GLOBAL(0x009E32BC, uint32) = image_id_2; - if (image_id_1) - image_id_1 = image_id_2; + image_id = RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; + RCT2_GLOBAL(0x009E32BC, uint32) = image_id; + if (transparant_image_id) + transparant_image_id = image_id; } - image_id_2 |= style->image_id + direction; - + if (is_exit){ + image_id |= style->image_id + direction + 8; + } + else{ + image_id |= style->image_id + direction; + } // Format modifed to stop repeated code // Each entrance is split into 2 images for drawing @@ -1059,36 +1054,43 @@ void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, uint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x3300, image_id_2, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + uint16 ax = is_exit ? 0x2300 : 0x3300; - if (image_id_1){ - image_id_1 |= style->image_id + direction + 16; + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + if (transparant_image_id){ + if (is_exit){ + transparant_image_id |= style->image_id + direction + 16; + } + else{ + transparant_image_id |= style->image_id + direction + 24; + } RCT2_GLOBAL(0x009DEA52, uint16) = 2; RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, uint16) = height; RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x3300, image_id_1, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } - image_id_2 += 4; + image_id += 4; RCT2_GLOBAL(0x009DEA52, uint16) = 2; RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x3300, image_id_2, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); - if (image_id_1){ - image_id_1 += 4; + if (transparant_image_id){ + transparant_image_id += 4; RCT2_GLOBAL(0x009DEA52, uint16) = 2; RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x3300, image_id_1, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF); @@ -1101,7 +1103,8 @@ void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x141F56A, uint8)++; } - if (!(map_element->flags & MAP_ELEMENT_FLAG_GHOST) && + if (!is_exit && + !(map_element->flags & MAP_ELEMENT_FLAG_GHOST) && map_element->properties.entrance.ride_index != 0xFF){ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0; @@ -1133,7 +1136,7 @@ void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_ele 0x3300, scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, height + style->height, 0x1C, 0x1C, 0); } - uint32 image_id = RCT2_GLOBAL(0x009E32BC, uint32); + image_id = RCT2_GLOBAL(0x009E32BC, uint32); if (!image_id){ image_id = 0x20B80000; } @@ -1155,8 +1158,9 @@ void viewport_ride_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF; RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF; - if (RCT2_GLOBAL(0x141E9D8, sint16) < height + 56){ - RCT2_GLOBAL(0x141E9D8, sint16) = height + 56; + height += is_exit ? 40 : 56; + if (RCT2_GLOBAL(0x141E9D8, sint16) < height){ + RCT2_GLOBAL(0x141E9D8, sint16) = height; RCT2_GLOBAL(0x141E9DA, uint8) = 32; } } @@ -1195,10 +1199,10 @@ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* switch (map_element->properties.entrance.type){ case ENTRANCE_TYPE_RIDE_ENTRANCE: - viewport_ride_entrance_paint_setup(direction, height, map_element); + viewport_ride_entrance_exit_paint_setup(direction, height, map_element); break; case ENTRANCE_TYPE_RIDE_EXIT: - //665540 + viewport_ride_entrance_exit_paint_setup(direction, height, map_element); break; case ENTRANCE_TYPE_PARK_ENTRANCE: //6658ED @@ -1496,22 +1500,22 @@ void viewport_paint_setup(){ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; mapTile.y += 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; mapTile.y -= 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.y += 32; } @@ -1525,22 +1529,22 @@ void viewport_paint_setup(){ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; mapTile.y -= 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.y += 32; map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; mapTile.y += 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; } @@ -1554,22 +1558,22 @@ void viewport_paint_setup(){ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; mapTile.y -= 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; mapTile.y += 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.y -= 32; } @@ -1583,22 +1587,22 @@ void viewport_paint_setup(){ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; mapTile.y += 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.y -= 32; map_element_paint_setup(mapTile.x, mapTile.y); - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x -= 32; mapTile.y -= 32; - sub_0x69E8B0(mapTile.x, mapTile.y); + sprite_paint_setup(mapTile.x, mapTile.y); mapTile.x += 32; } diff --git a/src/world/sprite.h b/src/world/sprite.h index ed2cfe109a..7a93a7c1c8 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -79,7 +79,7 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 - uint8 var_01; // 0x01 + uint8 type; // 0x01 uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 From 4911ad5a9dc4f9916530a9b04bd461046e7dabe9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 2 Jun 2015 18:34:09 +0100 Subject: [PATCH 08/14] Started implementing entrance_paint_setup --- src/interface/viewport.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 7423c0a001..0fc6a6a9c3 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -26,6 +26,8 @@ #include "../world/map.h" #include "../world/sprite.h" #include "../world/banner.h" +#include "../world/entrance.h" +#include "../world/footpath.h" #include "../world/scenery.h" #include "viewport.h" #include "window.h" @@ -1165,6 +1167,31 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma } } +/* rct2: 0x006658ED */ +void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ + if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) + return; + + RCT2_GLOBAL(0x009DE570, uint8) = 8; + RCT2_GLOBAL(0x009E32BC, uint32) = 0; + uint32 image_id, ghost_id; + if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ + RCT2_GLOBAL(0x009DE570, uint8) = 0; + ghost_id = RCT2_ADDRESS(0x993CC4, uint32)[RCT2_GLOBAL(0x9AACBF, uint8)]; + RCT2_GLOBAL(0x009E32BC, uint32) = ghost_id; + } + + rct_path_type* path_entry = g_pathTypeEntries[map_element->properties.entrance.path_type]; + + switch ((map_element->properties.entrance.index & 0xF << 2) | direction){ + case 0: + image_id = (path_entry->image + 5) | ghost_id; + //665988 + break; + //665939 + } +} + /* rct2: 0x00664FD4 */ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ RCT2_GLOBAL(0x9DE570, uint8_t) = 0xB; @@ -1205,7 +1232,7 @@ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* viewport_ride_entrance_exit_paint_setup(direction, height, map_element); break; case ENTRANCE_TYPE_PARK_ENTRANCE: - //6658ED + viewport_park_entrance_paint_setup(direction, height, map_element); break; } } From dc7f83d667b0197cd5e812166b9d8de5ba93e7ec Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 7 Jun 2015 20:31:44 +0100 Subject: [PATCH 09/14] Implement more of park entrance paint setup I've changed the order of some of this code so its possible this wont display quite the same. Will need extensive testing. --- src/interface/viewport.c | 87 ++++++++++++++++++++++++++++++++++++++-- src/world/entrance.h | 4 +- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 0fc6a6a9c3..cbe65752c7 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1174,7 +1174,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DE570, uint8) = 8; RCT2_GLOBAL(0x009E32BC, uint32) = 0; - uint32 image_id, ghost_id; + uint32 image_id, ghost_id = 0; if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ RCT2_GLOBAL(0x009DE570, uint8) = 0; ghost_id = RCT2_ADDRESS(0x993CC4, uint32)[RCT2_GLOBAL(0x9AACBF, uint8)]; @@ -1183,13 +1183,92 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele rct_path_type* path_entry = g_pathTypeEntries[map_element->properties.entrance.path_type]; - switch ((map_element->properties.entrance.index & 0xF << 2) | direction){ + switch (((map_element->properties.entrance.index & 0xF) << 2) | direction){ + case 1: + case 2: + case 3: case 0: - image_id = (path_entry->image + 5) | ghost_id; - //665988 + image_id = (path_entry->image + 5 * (1 + (direction & 1))) | ghost_id; + RCT2_GLOBAL(0x009DEA52, uint16) = 0; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, sint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + rct_entrance_type* entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; + image_id = (entrance->image_id + direction * 3) | ghost_id; + + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, sint16) = height + 32; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x2F00, image_id, 0, height, 0x1C, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + + if ((direction + 1) & (1 << 1)) + break; + if (ghost_id != 0) + break; + + rct_string_id park_text_id = 1730; + RCT2_GLOBAL(0x0013CE952, uint32) = 0; + RCT2_GLOBAL(0x0013CE956, uint32) = 0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN){ + RCT2_GLOBAL(0x0013CE952, rct_string_id) = RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME, rct_string_id); + RCT2_GLOBAL(0x0013CE954, rct_string_id) = RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME_ARGS, rct_string_id); + + park_text_id = 1731; + } + + uint8 park_name[MAX_PATH]; + format_string(park_name, park_text_id, RCT2_ADDRESS(0x0013CE952, void)); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0x1C0; + uint16 string_width = gfx_get_string_width(park_name); + uint16 scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) / 2) % string_width; + + if (entrance->scrolling_mode == 0xFF) + break; + + RCT2_GLOBAL(0x009DEA52, uint16) = 2; + RCT2_GLOBAL(0x009DEA54, uint16) = 2; + RCT2_GLOBAL(0x009DEA56, sint16) = height + entrance->text_height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x2F00, scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, height + entrance->text_height, 0x1C, 0x1C, 0); break; //665939 } + + image_id = ghost_id; + if (!image_id){ + image_id = 0x20B80000; + } + + if (direction & 1){ + sub_6629BC(height, 0, image_id, 1); + } + else{ + sub_6629BC(height, 0, image_id, 0); + } + + RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF; + RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF; + + height += 80; + if (RCT2_GLOBAL(0x141E9D8, sint16) < height){ + RCT2_GLOBAL(0x141E9D8, sint16) = height; + RCT2_GLOBAL(0x141E9DA, uint8) = 32; + } } /* rct2: 0x00664FD4 */ diff --git a/src/world/entrance.h b/src/world/entrance.h index 6705c623f0..291a14f905 100644 --- a/src/world/entrance.h +++ b/src/world/entrance.h @@ -26,8 +26,8 @@ typedef struct { rct_string_id string_idx; // 0x00 uint32 image_id; // 0x02 - uint8 var_06; - uint8 var_07; + uint8 scrolling_mode; // 0x06 + uint8 text_height; // 0x07 } rct_entrance_type; #endif \ No newline at end of file From eac5cea701ffe1fb7015ab647b5000e1924f48b4 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 8 Jun 2015 17:47:51 +0100 Subject: [PATCH 10/14] Implement left and right parts of the entrance. --- src/interface/viewport.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index cbe65752c7..5f19bc6a90 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1183,10 +1183,13 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele rct_path_type* path_entry = g_pathTypeEntries[map_element->properties.entrance.path_type]; - switch (((map_element->properties.entrance.index & 0xF) << 2) | direction){ - case 1: - case 2: - case 3: + // Index to which part of the entrance + // Middle, left, right + uint8 part_index = map_element->properties.entrance.index & 0xF; + rct_entrance_type* entrance; + uint8 di = (direction / 2 + part_index / 2) & 1 ? 0x1A : 0x20; + + switch (part_index){ case 0: image_id = (path_entry->image + 5 * (1 + (direction & 1))) | ghost_id; RCT2_GLOBAL(0x009DEA52, uint16) = 0; @@ -1196,7 +1199,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], 0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); - rct_entrance_type* entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; + entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; image_id = (entrance->image_id + direction * 3) | ghost_id; RCT2_GLOBAL(0x009DEA52, uint16) = 2; @@ -1239,7 +1242,18 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], 0x2F00, scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, height + entrance->text_height, 0x1C, 0x1C, 0); break; - //665939 + case 1: + case 2: + entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; + image_id = (entrance->image_id + part_index + direction * 3) | ghost_id; + + RCT2_GLOBAL(0x009DEA52, uint16) = 3; + RCT2_GLOBAL(0x009DEA54, uint16) = 3; + RCT2_GLOBAL(0x009DEA56, sint16) = height; + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + 0x4F00, image_id, 0, height, di, 0x1A, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + break; } image_id = ghost_id; From 8554d2183c4c82b97bd8e4eb3229f280c99ec026 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 8 Jun 2015 18:52:47 +0100 Subject: [PATCH 11/14] Implemented more of the paint_struct setup code --- src/addresses.h | 3 ++ src/drawing/drawing.h | 12 +++++ src/drawing/sprite.c | 11 ---- src/interface/viewport.c | 105 +++++++++++++++++++++++++++------------ src/interface/viewport.h | 3 +- 5 files changed, 91 insertions(+), 43 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 48520d6404..224a5966f4 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -201,6 +201,9 @@ #define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E #define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560 +// Of type viewport interaction +#define RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE 0x009DE570 + #define RCT2_ADDRESS_PALETTE_EFFECT_FRAME_NO 0x009DE584 // Flags: diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index dc231df1e7..55217eff9c 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -57,6 +57,17 @@ enum{ IMAGE_TYPE_UNKNOWN = (1<<3) }; +typedef struct { + uint32 num_entries; + uint32 total_size; +} rct_g1_header; + +typedef struct { + rct_g1_header header; + rct_g1_element *elements; + void *data; +} rct_gx; + extern const uint16 palette_to_g1_offset[]; extern const uint8 peep_palette[]; extern uint8 text_palette[]; @@ -65,6 +76,7 @@ extern int gLastDrawStringX; extern int gLastDrawStringY; extern rct_g1_element *g1Elements; +extern rct_gx g2; // rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height); diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 024675facd..c5ddced9ed 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -25,19 +25,8 @@ #include "../platform/platform.h" #include "../openrct2.h" -typedef struct { - uint32 num_entries; - uint32 total_size; -} rct_g1_header; - void *_g1Buffer = NULL; -typedef struct { - rct_g1_header header; - rct_g1_element *elements; - void *data; -} rct_gx; - rct_gx g2; rct_g1_element *g1Elements = (rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS; diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 5f19bc6a90..252c8b9367 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -68,13 +68,13 @@ struct paint_struct{ uint8 var_1B; paint_struct* attached_ps; //0x1C paint_struct* var_20; - paint_struct* var_24; + paint_struct* next_quadrant_ps; // 0x24 uint8 sprite_type; //0x28 uint8 var_29; uint16 pad_2A; uint16 map_x; // 0x2C uint16 map_y; // 0x2E - rct_map_element *mapElement; // 0x30 + rct_map_element *mapElement; // 0x30 (or sprite pointer) }; /** @@ -663,9 +663,9 @@ void paint_attached_ps(paint_struct* ps, paint_struct* attached_ps, rct_drawpixe void sub_688485(){ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); paint_struct* ps = RCT2_GLOBAL(0xEE7884, paint_struct*); - paint_struct* previous_ps = ps->var_24; + paint_struct* previous_ps = ps->next_quadrant_ps; - for (ps = ps->var_24; ps;){ + for (ps = ps->next_quadrant_ps; ps;){ sint16 x = ps->x; sint16 y = ps->y; if (ps->sprite_type == 2){ @@ -715,17 +715,17 @@ void sub_688485(){ } paint_attached_ps(ps, ps->attached_ps, dpi); - ps = previous_ps->var_24; + ps = previous_ps->next_quadrant_ps; previous_ps = ps; } } -int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ +int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 di, sint16 si){ int ebp = (eax >> 8) & 0xFF; edx <<= 16; ebp += RCT2_GLOBAL(0x9DEA56, uint16); - RCT2_GLOBAL(0xF1AD28, uint32) = 0; + RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; RCT2_GLOBAL(0xF1AD2C, uint32) = 0; edx = (edx >> 16) | (ebp << 16); @@ -736,7 +736,15 @@ int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ ps->image_id = image_id; - rct_g1_element *g1Element = &g1Elements[image_id & 0x7FFFF]; + rct_g1_element *g1Element; + uint32 image_element = image_id & 0x7FFFF; + + if (image_element < SPR_G2_BEGIN) { + g1Element = &g1Elements[image_element]; + } + else { + g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; + } eax = (eax & 0xFF) + RCT2_GLOBAL(0x9DE568, uint16); ecx = (ecx & 0xFF) + RCT2_GLOBAL(0x9DE56C, uint16); @@ -763,9 +771,44 @@ int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ if (left > dpi->x + dpi->width) return 1; if (bottom > dpi->y + dpi->height) return 1; - RCT2_GLOBAL(0x9DE568, uint16); //686918 not finished + ps->other_x = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); + ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); + ps->other_y = si - 1 + RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->var_1A = 0; + ps->attached_x = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); + ps->attached_y = RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->attached_ps = NULL; + ps->var_20 = NULL; + ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint16); + ps->map_x = RCT2_GLOBAL(0x9DE574, uint16); + ps->map_y = RCT2_GLOBAL(0x9DE576, uint16); + ps->mapElement = RCT2_GLOBAL(0x9DE578, rct_map_element*); + RCT2_GLOBAL(0xF1AD28, uint32) = ps; + + di = ps->attached_y + ps->attached_x; + if (di < 0) + di = 0; + + di /= 32; + if (di > 511) + di = 511; + + ps->var_18 = di; + paint_struct* old_ps = RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di]; + RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di] = ps; + ps->next_quadrant_ps = old_ps; + + if (di < RCT2_GLOBAL(0x00F1AD0C, sint32)){ + RCT2_GLOBAL(0x00F1AD0C, sint32) = di; + } + + if (di > RCT2_GLOBAL(0x00F1AD10, sint32)){ + RCT2_GLOBAL(0x00F1AD10, sint32) = di; + } + + RCT2_GLOBAL(0xEE7888, paint_struct*) += sizeof(paint_struct); return 0; } @@ -840,7 +883,7 @@ void sprite_paint_setup(uint16 eax, uint16 ecx){ int ebp = spr->unknown.sprite_identifier; RCT2_GLOBAL(0x9DE568, uint16) = spr->unknown.x; - RCT2_GLOBAL(0x9DE570, uint8) = 2; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_SPRITE; RCT2_GLOBAL(0x9DE56C, uint16) = spr->unknown.y; switch (spr->unknown.sprite_identifier){ @@ -1030,11 +1073,11 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma colour_2 = ride->track_colour_additional[0]; image_id = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000; - RCT2_GLOBAL(0x009DE570, uint8) = 3; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE; RCT2_GLOBAL(0x009E32BC, uint32) = 0; if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ - RCT2_GLOBAL(0x009DE570, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE; image_id = RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; RCT2_GLOBAL(0x009E32BC, uint32) = image_id; if (transparant_image_id) @@ -1172,11 +1215,11 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) return; - RCT2_GLOBAL(0x009DE570, uint8) = 8; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_PARK; RCT2_GLOBAL(0x009E32BC, uint32) = 0; uint32 image_id, ghost_id = 0; if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){ - RCT2_GLOBAL(0x009DE570, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE; ghost_id = RCT2_ADDRESS(0x993CC4, uint32)[RCT2_GLOBAL(0x9AACBF, uint8)]; RCT2_GLOBAL(0x009E32BC, uint32) = ghost_id; } @@ -1287,7 +1330,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele /* rct2: 0x00664FD4 */ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){ - RCT2_GLOBAL(0x9DE570, uint8_t) = 0xB; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_LABEL; rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); @@ -1335,7 +1378,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m { rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); - RCT2_GLOBAL(0x9DE570, uint8_t) = 0xC; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_BANNER; if (dpi->zoom_level > 1 || RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) return; @@ -1355,7 +1398,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m if (map_element->flags & MAP_ELEMENT_FLAG_GHOST)//if being placed { - RCT2_GLOBAL(0x9DE570, uint8_t) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE; image_id |= RCT2_ADDRESS(0x993CC4, uint32_t)[RCT2_GLOBAL(0x9AACBF, uint8)]; } else{ @@ -1471,7 +1514,7 @@ void map_element_paint_setup(int x, int y) RCT2_GLOBAL(0x9DE568, uint16) = x; RCT2_GLOBAL(0x9DE56C, uint16) = y; - RCT2_GLOBAL(0x9DE570, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE; RCT2_GLOBAL(0x9DEA52, uint16) = 0; RCT2_GLOBAL(0x9DEA54, uint16) = 0; RCT2_GLOBAL(0x9DEA56, uint16) = arrowZ + 18; @@ -1588,7 +1631,7 @@ void map_element_paint_setup(int x, int y) if (dx >= dpi->y) return; RCT2_GLOBAL(0x9DE568, uint16_t) = x; RCT2_GLOBAL(0x9DE56C, uint16_t) = y; - RCT2_GLOBAL(0x9DE570, uint8_t) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE; RCT2_CALLPROC_X((int)RCT2_ADDRESS(0x98196C, uint32_t*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], 0xFF00, 3123, y & 0xFF00, 16, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } @@ -1737,14 +1780,14 @@ void sub_688217_helper(uint16 ax, uint8 flag) do { ps = ps_next; - ps_next = ps_next->var_24; + ps_next = ps_next->next_quadrant_ps; if (ps_next == NULL) return; } while (ax > ps_next->var_18); RCT2_GLOBAL(0x00F1AD14, paint_struct*) = ps; do { - ps = ps->var_24; + ps = ps->next_quadrant_ps; if (ps == NULL) break; if (ps->var_18 > ax + 1) { @@ -1760,7 +1803,7 @@ void sub_688217_helper(uint16 ax, uint8 flag) while (true) { while (true) { - ps_next = ps->var_24; + ps_next = ps->next_quadrant_ps; if (ps_next == NULL) return; if (ps_next->var_1B & (1 << 7)) return; if (ps_next->var_1B & (1 << 0)) break; @@ -1779,7 +1822,7 @@ void sub_688217_helper(uint16 ax, uint8 flag) while (true) { ps = ps_next; - ps_next = ps_next->var_24; + ps_next = ps_next->next_quadrant_ps; if (ps_next == NULL) break; if (ps_next->var_1B & (1 << 7)) break; if (!(ps_next->var_1B & (1 << 1))) continue; @@ -1809,10 +1852,10 @@ void sub_688217_helper(uint16 ax, uint8 flag) } if (yes) { - ps->var_24 = ps_next->var_24; - paint_struct *ps_temp = RCT2_GLOBAL(0x00F1AD18, paint_struct*)->var_24; - RCT2_GLOBAL(0x00F1AD18, paint_struct*)->var_24 = ps_next; - ps_next->var_24 = ps_temp; + ps->next_quadrant_ps = ps_next->next_quadrant_ps; + paint_struct *ps_temp = RCT2_GLOBAL(0x00F1AD18, paint_struct*)->next_quadrant_ps; + RCT2_GLOBAL(0x00F1AD18, paint_struct*)->next_quadrant_ps = ps_next; + ps_next->next_quadrant_ps = ps_temp; ps_next = ps; } } @@ -1831,7 +1874,7 @@ void sub_688217() paint_struct *ps_next; RCT2_GLOBAL(0x00EE7888, uint32) += 0x34; // 0x34 is size of paint_struct? RCT2_GLOBAL(0x00EE7884, paint_struct*) = ps; - ps->var_24 = NULL; + ps->next_quadrant_ps = NULL; uint32 edi = RCT2_GLOBAL(0x00F1AD0C, uint32); if (edi == -1) return; @@ -1839,10 +1882,10 @@ void sub_688217() do { ps_next = RCT2_GLOBAL(0x00F1A50C + 4 * edi, paint_struct*); if (ps_next != NULL) { - ps->var_24 = ps_next; + ps->next_quadrant_ps = ps_next; do { ps = ps_next; - ps_next = ps_next->var_24; + ps_next = ps_next->next_quadrant_ps; } while (ps_next != NULL); } } while (++edi <= RCT2_GLOBAL(0x00F1AD10, uint32)); @@ -2270,7 +2313,7 @@ void sub_68862C() paint_struct *ps = RCT2_GLOBAL(0x00EE7884, paint_struct*), *old_ps, *next_ps, *attached_ps; uint32 eax = 0xBBBBBBBB, ebx = 0xBBBBBBBB, ecx = 0xBBBBBBBB, edx = 0xBBBBBBBB, esi = 0xBBBBBBBB, edi = 0xBBBBBBBB, ebp = 0xBBBBBBBB; - while ((ps = ps->var_24) != NULL) { + while ((ps = ps->next_quadrant_ps) != NULL) { old_ps = ps; next_ps = ps; diff --git a/src/interface/viewport.h b/src/interface/viewport.h index eae091355d..429b91602e 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -56,7 +56,8 @@ enum { VIEWPORT_INTERACTION_ITEM_PARK, VIEWPORT_INTERACTION_ITEM_WALL, VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY, - VIEWPORT_INTERACTION_ITEM_BANNER = 12, + VIEWPORT_INTERACTION_ITEM_LABEL, + VIEWPORT_INTERACTION_ITEM_BANNER, }; From 48d3f6e7e38698101df32f471805406961e7c3ff Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 9 Jun 2015 20:11:54 +0100 Subject: [PATCH 12/14] Switch on setup_image_on_viewport rotation 0. --- src/interface/viewport.c | 60 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 252c8b9367..607b8322aa 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -721,8 +721,21 @@ void sub_688485(){ } -int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 di, sint16 si){ - int ebp = (eax >> 8) & 0xFF; +int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di); + +int sub_98197C(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di, uint32 rotation){ + switch (rotation){ + case 0: + return sub_0x686806(eax, image_id, ecx, edx, si, di); + default: + RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], + eax, image_id, ecx, edx, si, di, 0); + return 1; + } +} + +int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di){ + int ebp = (sint8)((eax >> 8) & 0xFF); edx <<= 16; ebp += RCT2_GLOBAL(0x9DEA56, uint16); RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; @@ -774,18 +787,20 @@ int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 di, sint16 si){ //686918 not finished ps->other_x = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); + ps->some_y = edx >> 16; ps->other_y = si - 1 + RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); ps->var_1A = 0; ps->attached_x = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); ps->attached_y = RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); ps->attached_ps = NULL; ps->var_20 = NULL; - ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint16); + ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8); + ps->var_29 = RCT2_GLOBAL(0x9DE571, uint8); ps->map_x = RCT2_GLOBAL(0x9DE574, uint16); ps->map_y = RCT2_GLOBAL(0x9DE576, uint16); ps->mapElement = RCT2_GLOBAL(0x9DE578, rct_map_element*); - RCT2_GLOBAL(0xF1AD28, uint32) = ps; + RCT2_GLOBAL(0xF1AD28, paint_struct*) = ps; di = ps->attached_y + ps->attached_x; if (di < 0) @@ -835,8 +850,7 @@ void viewport_litter_paint_setup(rct_litter* litter, int image_direction, int he RCT2_GLOBAL(0x9DEA54, uint16) = 0xFFFC; RCT2_GLOBAL(0x9DEA56, uint16) = height + 2; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0xFF00, image_id, 0, height, 4, 4, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0xFF00, image_id, 0, height, 4, 4, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } @@ -1101,8 +1115,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma uint16 ax = is_exit ? 0x2300 : 0x3300; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if (transparant_image_id){ if (is_exit){ @@ -1115,8 +1128,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, uint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } image_id += 4; @@ -1125,8 +1137,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if (transparant_image_id){ transparant_image_id += 4; @@ -1134,8 +1145,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF); @@ -1239,8 +1249,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, sint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; image_id = (entrance->image_id + direction * 3) | ghost_id; @@ -1249,8 +1258,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, sint16) = height + 32; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x2F00, image_id, 0, height, 0x1C, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0x2F00, image_id, 0, height, 0x1C, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if ((direction + 1) & (1 << 1)) break; @@ -1294,8 +1302,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 3; RCT2_GLOBAL(0x009DEA56, sint16) = height; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x4F00, image_id, 0, height, di, 0x1A, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0x4F00, image_id, 0, height, di, 0x1A, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); break; } @@ -1355,8 +1362,7 @@ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* RCT2_GLOBAL(0x009DEA56, sint16) = z; RCT2_GLOBAL(0x009DEA56, uint16) += 64; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 16, image_id, 16, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(16, image_id, 16, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } } @@ -1407,13 +1413,11 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m 0x20000000; } - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); RCT2_GLOBAL(0x9DEA52, uint32) = RCT2_ADDRESS(0x98D888, uint32)[direction * 2]; image_id++; - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - 0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); // Opposite direction direction ^= 2; @@ -1519,9 +1523,7 @@ void map_element_paint_setup(int x, int y) RCT2_GLOBAL(0x9DEA54, uint16) = 0; RCT2_GLOBAL(0x9DEA56, uint16) = arrowZ + 18; - RCT2_CALLPROC_X( - (int)RCT2_ADDRESS(0x0098197C, uint32*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)], - 0xFF00, imageId, y & 0xFF00, arrowZ, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); + sub_98197C(0xFF00, imageId, y & 0xFF00, arrowZ, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); } int bx = dx + 52; From 2c6312a86d8ce7f947ba0aad1ef276927680627c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 21 Jun 2015 14:07:57 +0100 Subject: [PATCH 13/14] Implemented 2nd rotation. Small refactor of parameter list --- src/interface/viewport.c | 161 ++++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 36 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 607b8322aa..3290d06643 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -721,26 +721,27 @@ void sub_688485(){ } -int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di); +int sub_0x686806(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di); +int sub_0x6869B2(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di); -int sub_98197C(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di, uint32 rotation){ +int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, sint16 di, uint32 rotation){ switch (rotation){ case 0: - return sub_0x686806(eax, image_id, ecx, edx, si, di); + return sub_0x686806(al, ah, image_id, cl, edx, si, di); + case 1: + return sub_0x6869B2(al, ah, image_id, cl, edx, si, di); default: RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - eax, image_id, ecx, edx, si, di, 0); + al | (ah << 8), image_id, cl, edx, si, di, 0); return 1; } } -int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di){ - int ebp = (sint8)((eax >> 8) & 0xFF); - edx <<= 16; - ebp += RCT2_GLOBAL(0x9DEA56, uint16); +int sub_0x686806(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di){ + int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16); + RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; RCT2_GLOBAL(0xF1AD2C, uint32) = 0; - edx = (edx >> 16) | (ebp << 16); //Not a paint struct but something similar paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); @@ -759,11 +760,11 @@ int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di){ g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; } - eax = (eax & 0xFF) + RCT2_GLOBAL(0x9DE568, uint16); - ecx = (ecx & 0xFF) + RCT2_GLOBAL(0x9DE56C, uint16); + int eax = al + RCT2_GLOBAL(0x9DE568, sint16); + int ecx = cl + RCT2_GLOBAL(0x9DE56C, sint16); int x = ecx - eax; - int y = (ecx + eax) / 2 - (edx & 0xFFFF); + int y = (ecx + eax) / 2 - edx; ps->x = x; ps->y = y; @@ -784,10 +785,9 @@ int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di){ if (left > dpi->x + dpi->width) return 1; if (bottom > dpi->y + dpi->height) return 1; - //686918 not finished ps->other_x = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); - ps->some_y = edx >> 16; + ps->some_y = ebp; ps->other_y = si - 1 + RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); ps->var_1A = 0; ps->attached_x = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); @@ -827,6 +827,95 @@ int sub_0x686806(int eax, int image_id, int ecx, int edx, sint16 si, sint16 di){ return 0; } +int sub_0x6869B2(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di){ + int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16); + + RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; + RCT2_GLOBAL(0xF1AD2C, uint32) = 0; + + //Not a paint struct but something similar + paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); + + if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; + + ps->image_id = image_id; + + rct_g1_element *g1Element; + uint32 image_element = image_id & 0x7FFFF; + + if (image_element < SPR_G2_BEGIN) { + g1Element = &g1Elements[image_element]; + } + else { + g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; + } + + int eax = cl + RCT2_GLOBAL(0x9DE568, sint16); + int ecx = -al + RCT2_GLOBAL(0x9DE56C, sint16); + + int x = -eax - ecx; + int y = (ecx - eax) / 2 - edx; + + ps->x = x; + ps->y = y; + + int left = x + g1Element->x_offset; + int bottom = y + g1Element->y_offset; + + int right = left + g1Element->width; + int top = bottom + g1Element->height; + + RCT2_GLOBAL(0xF1AD1C, uint16) = left; + RCT2_GLOBAL(0xF1AD1E, uint16) = bottom; + + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (right <= dpi->x)return 1; + if (top <= dpi->y)return 1; + if (left > dpi->x + dpi->width) return 1; + if (bottom > dpi->y + dpi->height) return 1; + + ps->other_x = -si - RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x9DE568, sint16); + ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); + ps->some_y = ebp; + ps->other_y = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->var_1A = 0; + ps->attached_x = -RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x9DE568, sint16); + ps->attached_y = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->attached_ps = NULL; + ps->var_20 = NULL; + ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8); + ps->var_29 = RCT2_GLOBAL(0x9DE571, uint8); + ps->map_x = RCT2_GLOBAL(0x9DE574, uint16); + ps->map_y = RCT2_GLOBAL(0x9DE576, uint16); + ps->mapElement = RCT2_GLOBAL(0x9DE578, rct_map_element*); + + RCT2_GLOBAL(0xF1AD28, paint_struct*) = ps; + + di = ps->attached_y - ps->attached_x + 0x2000; + if (di < 0) + di = 0; + + di /= 32; + if (di > 511) + di = 511; + + ps->var_18 = di; + paint_struct* old_ps = RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di]; + RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di] = ps; + ps->next_quadrant_ps = old_ps; + + if (di < RCT2_GLOBAL(0x00F1AD0C, sint32)){ + RCT2_GLOBAL(0x00F1AD0C, sint32) = di; + } + + if (di > RCT2_GLOBAL(0x00F1AD10, sint32)){ + RCT2_GLOBAL(0x00F1AD10, sint32) = di; + } + + RCT2_GLOBAL(0xEE7888, paint_struct*) += sizeof(paint_struct); + return 0; +} /** * Litter Paint Setup @@ -850,7 +939,7 @@ void viewport_litter_paint_setup(rct_litter* litter, int image_direction, int he RCT2_GLOBAL(0x9DEA54, uint16) = 0xFFFC; RCT2_GLOBAL(0x9DEA56, uint16) = height + 2; - sub_98197C(0xFF00, image_id, 0, height, 4, 4, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0xFF, image_id, 0, height, 4, 4, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } @@ -896,9 +985,9 @@ void sprite_paint_setup(uint16 eax, uint16 ecx){ RCT2_GLOBAL(0x9DE578, uint32) = (uint32)spr; int ebp = spr->unknown.sprite_identifier; - RCT2_GLOBAL(0x9DE568, uint16) = spr->unknown.x; + RCT2_GLOBAL(0x9DE568, sint16) = spr->unknown.x; RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_SPRITE; - RCT2_GLOBAL(0x9DE56C, uint16) = spr->unknown.y; + RCT2_GLOBAL(0x9DE56C, sint16) = spr->unknown.y; switch (spr->unknown.sprite_identifier){ case SPRITE_IDENTIFIER_VEHICLE: @@ -1113,9 +1202,9 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, uint16) = height; - uint16 ax = is_exit ? 0x2300 : 0x3300; + sint8 ah = is_exit ? 0x23 : 0x33; - sub_98197C(ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, ah, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if (transparant_image_id){ if (is_exit){ @@ -1128,7 +1217,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, uint16) = height; - sub_98197C(ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, ah, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } image_id += 4; @@ -1137,7 +1226,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; - sub_98197C(ax, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, ah, image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if (transparant_image_id){ transparant_image_id += 4; @@ -1145,7 +1234,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma RCT2_GLOBAL(0x009DEA54, uint16) = 28; RCT2_GLOBAL(0x009DEA56, uint16) = height; - sub_98197C(ax, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, ah, transparant_image_id, 0, height, 2, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF); @@ -1249,7 +1338,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, sint16) = height; - sub_98197C(0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0, image_id, 0, height, 0x1C, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0]; image_id = (entrance->image_id + direction * 3) | ghost_id; @@ -1258,7 +1347,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 2; RCT2_GLOBAL(0x009DEA56, sint16) = height + 32; - sub_98197C(0x2F00, image_id, 0, height, 0x1C, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0x2F, image_id, 0, height, 0x1C, 0x1C, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); if ((direction + 1) & (1 << 1)) break; @@ -1302,7 +1391,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele RCT2_GLOBAL(0x009DEA54, uint16) = 3; RCT2_GLOBAL(0x009DEA56, sint16) = height; - sub_98197C(0x4F00, image_id, 0, height, di, 0x1A, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0x4F, image_id, 0, height, di, 0x1A, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); break; } @@ -1362,7 +1451,7 @@ void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* RCT2_GLOBAL(0x009DEA56, sint16) = z; RCT2_GLOBAL(0x009DEA56, uint16) += 64; - sub_98197C(16, image_id, 16, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(16, 0, image_id, 16, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); } } @@ -1413,11 +1502,11 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m 0x20000000; } - sub_98197C(0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0x15, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); RCT2_GLOBAL(0x9DEA52, uint32) = RCT2_ADDRESS(0x98D888, uint32)[direction * 2]; image_id++; - sub_98197C(0x1500, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); + sub_98197C(0, 0x15, image_id, 0, height, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); // Opposite direction direction ^= 2; @@ -1516,14 +1605,14 @@ void map_element_paint_setup(int x, int y) int arrowZ = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Z, uint16); - RCT2_GLOBAL(0x9DE568, uint16) = x; - RCT2_GLOBAL(0x9DE56C, uint16) = y; + RCT2_GLOBAL(0x9DE568, sint16) = x; + RCT2_GLOBAL(0x9DE56C, sint16) = y; RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE; RCT2_GLOBAL(0x9DEA52, uint16) = 0; RCT2_GLOBAL(0x9DEA54, uint16) = 0; RCT2_GLOBAL(0x9DEA56, uint16) = arrowZ + 18; - sub_98197C(0xFF00, imageId, y & 0xFF00, arrowZ, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); + sub_98197C(0, 0xFF, imageId, y & 0xFF00, arrowZ, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); } int bx = dx + 52; @@ -1553,9 +1642,9 @@ void map_element_paint_setup(int x, int y) if (dx >= dpi->y) return; - RCT2_GLOBAL(0x9DE568, uint16_t) = x; - RCT2_GLOBAL(0x9DE56C, uint16_t) = y; - RCT2_GLOBAL(0x9DE57C, uint16_t) = 0; + RCT2_GLOBAL(0x9DE568, sint16) = x; + RCT2_GLOBAL(0x9DE56C, sint16) = y; + RCT2_GLOBAL(0x9DE57C, uint16) = 0; do{ int direction = (map_element->type + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)) & MAP_ELEMENT_DIRECTION_MASK; int height = map_element->base_height * 8; @@ -1631,8 +1720,8 @@ void map_element_paint_setup(int x, int y) dx -= 20; dx -= dpi->height; if (dx >= dpi->y) return; - RCT2_GLOBAL(0x9DE568, uint16_t) = x; - RCT2_GLOBAL(0x9DE56C, uint16_t) = y; + RCT2_GLOBAL(0x9DE568, sint16) = x; + RCT2_GLOBAL(0x9DE56C, sint16) = y; RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE; RCT2_CALLPROC_X((int)RCT2_ADDRESS(0x98196C, uint32_t*)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], 0xFF00, 3123, y & 0xFF00, 16, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)); From d5c19437ac3dd725bb6b236cd2a9c0388671cae3 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 21 Jun 2015 16:22:09 +0100 Subject: [PATCH 14/14] Make generic version of 98197C rotations. Refactor. I've added a new function coordinate 3d to 2d. There are still quite a few different versions of this same code throughout the project that should be changed to use this function. --- src/interface/viewport.c | 283 ++++++++++++++++----------------------- src/interface/window.c | 33 ++--- src/world/map.c | 24 ++++ src/world/map.h | 1 + 4 files changed, 150 insertions(+), 191 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 3290d06643..d105331b7b 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -118,6 +118,7 @@ void viewport_init_all() format_string((char*)0x0141FA44, STR_CANCEL, NULL); format_string((char*)0x0141F944, STR_OK, NULL); } + /** * rct:0x006EB0C1 * x : ax @@ -130,24 +131,13 @@ void viewport_init_all() void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_viewport* viewport){ int start_x = x; - switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ - case 0: - x = y - x; - y = (y + start_x) / 2 - z; - break; - case 1: - x = -y - x; - y = (y - start_x) / 2 - z; - break; - case 2: - x = -y + x; - y = (-y - start_x) / 2 - z; - break; - case 3: - x = y + x; - y = (-y + start_x) / 2 - z; - break; - } + rct_xyz16 coord_3d = { + .x = x, + .y = y, + .z = z + }; + + rct_xy16 coord_2d = coordinate_3d_to_2d(&coord_3d, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)); // If the start location was invalid // propagate the invalid location to the output. @@ -158,8 +148,8 @@ void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_view return; } - *out_x = x - viewport->view_width / 2; - *out_y = y - viewport->view_height / 2; + *out_x = coord_2d.x - viewport->view_width / 2; + *out_y = coord_2d.y - viewport->view_height / 2; } /** @@ -721,77 +711,103 @@ void sub_688485(){ } -int sub_0x686806(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di); -int sub_0x6869B2(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di); - +/* rct2: 0x00686806, 0x006869B2, 0x00686B6F, 0x00686D31, 0x0098197C */ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, sint16 di, uint32 rotation){ + int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16); + + RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; + RCT2_GLOBAL(0xF1AD2C, uint32) = 0; + + //Not a paint struct but something similar + paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); + + if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; + + ps->image_id = image_id; + + rct_g1_element *g1Element; + uint32 image_element = image_id & 0x7FFFF; + + if (image_element < SPR_G2_BEGIN) { + g1Element = &g1Elements[image_element]; + } + else { + g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; + } + + rct_xyz16 coord_3d = { + .x = al, + .y = cl, + .z = edx + }; + + rotate_map_coordinates(&coord_3d.x, &coord_3d.y, rotation); + + coord_3d.x += RCT2_GLOBAL(0x9DE568, sint16); + coord_3d.y += RCT2_GLOBAL(0x9DE56C, sint16); + + rct_xy16 map = coordinate_3d_to_2d(&coord_3d, rotation); + + ps->x = map.x; + ps->y = map.y; + + int left = map.x + g1Element->x_offset; + int bottom = map.y + g1Element->y_offset; + + int right = left + g1Element->width; + int top = bottom + g1Element->height; + + RCT2_GLOBAL(0xF1AD1C, uint16) = left; + RCT2_GLOBAL(0xF1AD1E, uint16) = bottom; + + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (right <= dpi->x)return 1; + if (top <= dpi->y)return 1; + if (left > dpi->x + dpi->width) return 1; + if (bottom > dpi->y + dpi->height) return 1; + + rct_xy16 unk = { + .x = di, + .y = si + }; + + rct_xy16 s_unk = { + .x = RCT2_GLOBAL(0x9DEA52, sint16), + .y = RCT2_GLOBAL(0x9DEA54, sint16) + }; + + // Unsure why rots 1 and 3 need to swap switch (rotation){ case 0: - return sub_0x686806(al, ah, image_id, cl, edx, si, di); + rotate_map_coordinates(&unk.x, &unk.y, 0); + rotate_map_coordinates(&s_unk.x, &s_unk.y, 0); + unk.x--; + unk.y--; + break; case 1: - return sub_0x6869B2(al, ah, image_id, cl, edx, si, di); - default: - RCT2_CALLPROC_X(RCT2_ADDRESS(0x98197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)], - al | (ah << 8), image_id, cl, edx, si, di, 0); - return 1; - } -} - -int sub_0x686806(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di){ - int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16); - - RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; - RCT2_GLOBAL(0xF1AD2C, uint32) = 0; - - //Not a paint struct but something similar - paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); - - if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; - - ps->image_id = image_id; - - rct_g1_element *g1Element; - uint32 image_element = image_id & 0x7FFFF; - - if (image_element < SPR_G2_BEGIN) { - g1Element = &g1Elements[image_element]; - } - else { - g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; + rotate_map_coordinates(&unk.x, &unk.y, 3); + rotate_map_coordinates(&s_unk.x, &s_unk.y, 3); + unk.y--; + break; + case 2: + rotate_map_coordinates(&unk.x, &unk.y, 2); + rotate_map_coordinates(&s_unk.x, &s_unk.y, 2); + break; + case 3: + rotate_map_coordinates(&unk.x, &unk.y, 1); + rotate_map_coordinates(&s_unk.x, &s_unk.y, 1); + unk.x--; + break; } - int eax = al + RCT2_GLOBAL(0x9DE568, sint16); - int ecx = cl + RCT2_GLOBAL(0x9DE56C, sint16); - - int x = ecx - eax; - int y = (ecx + eax) / 2 - edx; - - ps->x = x; - ps->y = y; - - int left = x + g1Element->x_offset; - int bottom = y + g1Element->y_offset; - - int right = left + g1Element->width; - int top = bottom + g1Element->height; - - RCT2_GLOBAL(0xF1AD1C, uint16) = left; - RCT2_GLOBAL(0xF1AD1E, uint16) = bottom; - - rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); - - if (right <= dpi->x)return 1; - if (top <= dpi->y)return 1; - if (left > dpi->x + dpi->width) return 1; - if (bottom > dpi->y + dpi->height) return 1; - - ps->other_x = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); + ps->other_x = unk.x + s_unk.x + RCT2_GLOBAL(0x9DE568, sint16); ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); ps->some_y = ebp; - ps->other_y = si - 1 + RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->other_y = unk.y + s_unk.y + RCT2_GLOBAL(0x009DE56C, sint16); ps->var_1A = 0; - ps->attached_x = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x9DE568, sint16); - ps->attached_y = RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); + ps->attached_x = s_unk.x + RCT2_GLOBAL(0x9DE568, sint16); + ps->attached_y = s_unk.y + RCT2_GLOBAL(0x009DE56C, sint16); ps->attached_ps = NULL; ps->var_20 = NULL; ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8); @@ -802,97 +818,26 @@ int sub_0x686806(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 RCT2_GLOBAL(0xF1AD28, paint_struct*) = ps; - di = ps->attached_y + ps->attached_x; - if (di < 0) - di = 0; + rct_xy16 attach = { + .x = ps->attached_x, + .y = ps->attached_y + }; - di /= 32; - if (di > 511) - di = 511; - - ps->var_18 = di; - paint_struct* old_ps = RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di]; - RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di] = ps; - ps->next_quadrant_ps = old_ps; - - if (di < RCT2_GLOBAL(0x00F1AD0C, sint32)){ - RCT2_GLOBAL(0x00F1AD0C, sint32) = di; + rotate_map_coordinates(&attach.x, &attach.y, rotation); + switch (rotation){ + case 0: + break; + case 1: + case 3: + attach.x += 0x2000; + break; + case 2: + attach.x += 0x4000; + break; } - if (di > RCT2_GLOBAL(0x00F1AD10, sint32)){ - RCT2_GLOBAL(0x00F1AD10, sint32) = di; - } + di = attach.x + attach.y; - RCT2_GLOBAL(0xEE7888, paint_struct*) += sizeof(paint_struct); - return 0; -} - -int sub_0x6869B2(sint8 al, sint8 ah, int image_id, sint8 cl, sint16 edx, sint16 si, sint16 di){ - int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16); - - RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0; - RCT2_GLOBAL(0xF1AD2C, uint32) = 0; - - //Not a paint struct but something similar - paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); - - if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; - - ps->image_id = image_id; - - rct_g1_element *g1Element; - uint32 image_element = image_id & 0x7FFFF; - - if (image_element < SPR_G2_BEGIN) { - g1Element = &g1Elements[image_element]; - } - else { - g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; - } - - int eax = cl + RCT2_GLOBAL(0x9DE568, sint16); - int ecx = -al + RCT2_GLOBAL(0x9DE56C, sint16); - - int x = -eax - ecx; - int y = (ecx - eax) / 2 - edx; - - ps->x = x; - ps->y = y; - - int left = x + g1Element->x_offset; - int bottom = y + g1Element->y_offset; - - int right = left + g1Element->width; - int top = bottom + g1Element->height; - - RCT2_GLOBAL(0xF1AD1C, uint16) = left; - RCT2_GLOBAL(0xF1AD1E, uint16) = bottom; - - rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); - - if (right <= dpi->x)return 1; - if (top <= dpi->y)return 1; - if (left > dpi->x + dpi->width) return 1; - if (bottom > dpi->y + dpi->height) return 1; - - ps->other_x = -si - RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x9DE568, sint16); - ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16); - ps->some_y = ebp; - ps->other_y = di - 1 + RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); - ps->var_1A = 0; - ps->attached_x = -RCT2_GLOBAL(0x9DEA54, sint16) + RCT2_GLOBAL(0x9DE568, sint16); - ps->attached_y = RCT2_GLOBAL(0x9DEA52, sint16) + RCT2_GLOBAL(0x009DE56C, sint16); - ps->attached_ps = NULL; - ps->var_20 = NULL; - ps->sprite_type = RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8); - ps->var_29 = RCT2_GLOBAL(0x9DE571, uint8); - ps->map_x = RCT2_GLOBAL(0x9DE574, uint16); - ps->map_y = RCT2_GLOBAL(0x9DE576, uint16); - ps->mapElement = RCT2_GLOBAL(0x9DE578, rct_map_element*); - - RCT2_GLOBAL(0xF1AD28, paint_struct*) = ps; - - di = ps->attached_y - ps->attached_x + 0x2000; if (di < 0) di = 0; diff --git a/src/interface/window.c b/src/interface/window.c index 2c210a78ac..5a88d463f1 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1270,6 +1270,12 @@ void window_scroll_to_viewport(rct_window *w) */ void window_scroll_to_location(rct_window *w, int x, int y, int z) { + rct_xyz16 location_3d = { + .x = x, + .y = y, + .z = z + }; + if (w->viewport) { sint16 height = map_element_height(x, y); if (z < height - 16) { @@ -1283,26 +1289,9 @@ void window_scroll_to_location(rct_window *w, int x, int y, int z) window_invalidate(w); } } - sint16 sx; - sint16 sy; - switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)) { - case 0: - sx = y - x; - sy = ((x + y) / 2) - z; - break; - case 1: - sx = -y - x; - sy = ((-x + y) / 2) - z; - break; - case 2: - sx = -y + x; - sy = ((-x - y) / 2) - z; - break; - case 3: - sx = y + x; - sy = ((x - y) / 2) - z; - break; - } + + rct_xy16 map_coordinate = coordinate_3d_to_2d(&location_3d, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)); + int i = 0; if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO)) { int found = 0; @@ -1336,8 +1325,8 @@ void window_scroll_to_location(rct_window *w, int x, int y, int z) // rct2: 0x006E7C76 if (w->viewport_target_sprite == -1) { if (!(w->flags & WF_2)) { - w->saved_view_x = sx - (sint16)(w->viewport->view_width * window_scroll_locations[i][0]); - w->saved_view_y = sy - (sint16)(w->viewport->view_height * window_scroll_locations[i][1]); + w->saved_view_x = map_coordinate.x - (sint16)(w->viewport->view_width * window_scroll_locations[i][0]); + w->saved_view_y = map_coordinate.y - (sint16)(w->viewport->view_height * window_scroll_locations[i][1]); w->flags |= WF_SCROLLING_TO_LOCATION; } } diff --git a/src/world/map.c b/src/world/map.c index 09e4170305..c4dfe17bbc 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -87,6 +87,30 @@ void rotate_map_coordinates(sint16* x, sint16* y, uint8 rotation){ } } +rct_xy16 coordinate_3d_to_2d(const rct_xyz16* coordinate_3d, uint8 rotation){ + rct_xy16 coordinate_2d; + + switch (rotation){ + case 0: + coordinate_2d.x = coordinate_3d->y - coordinate_3d->x; + coordinate_2d.y = (coordinate_3d->y + coordinate_3d->x) / 2 - coordinate_3d->z; + break; + case 1: + coordinate_2d.x = -coordinate_3d->y - coordinate_3d->x; + coordinate_2d.y = (coordinate_3d->y - coordinate_3d->x) / 2 - coordinate_3d->z; + break; + case 2: + coordinate_2d.x = -coordinate_3d->y + coordinate_3d->x; + coordinate_2d.y = (-coordinate_3d->y - coordinate_3d->x) / 2 - coordinate_3d->z; + break; + case 3: + coordinate_2d.x = coordinate_3d->y + coordinate_3d->x; + coordinate_2d.y = (-coordinate_3d->y + coordinate_3d->x) / 2 - coordinate_3d->z; + break; + } + return coordinate_2d; +} + void map_element_iterator_begin(map_element_iterator *it) { it->x = 0; diff --git a/src/world/map.h b/src/world/map.h index 0271d4d185..c1f1c9de23 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -283,6 +283,7 @@ rct_map_element *map_element_insert(int x, int y, int z, int flags); int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *clearFunc, uint8 bl); int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl); void rotate_map_coordinates(sint16* x, sint16* y, uint8 rotation); +rct_xy16 coordinate_3d_to_2d(const rct_xyz16* coordinate_3d, uint8 rotation); money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags); money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags); money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags);