diff --git a/src/paint/map_element/scenery.c b/src/paint/map_element/scenery.c index 263cf9c90e..cadfd4e054 100644 --- a/src/paint/map_element/scenery.c +++ b/src/paint/map_element/scenery.c @@ -269,9 +269,9 @@ void scenery_paint(uint8 direction, int height, rct_map_element* mapElement) { supportImageColourFlags = dword_F64EB0; } if (direction & 1) { - wooden_b_supports_paint_setup(1, ax, supportHeight, supportImageColourFlags); + wooden_b_supports_paint_setup(1, ax, supportHeight, supportImageColourFlags, NULL); } else { - wooden_b_supports_paint_setup(0, ax, supportHeight, supportImageColourFlags); + wooden_b_supports_paint_setup(0, ax, supportHeight, supportImageColourFlags, NULL); } } } diff --git a/src/paint/map_element/scenery_multiple.c b/src/paint/map_element/scenery_multiple.c index 0504f8f9a3..8b61b1762a 100644 --- a/src/paint/map_element/scenery_multiple.c +++ b/src/paint/map_element/scenery_multiple.c @@ -46,7 +46,7 @@ static void scenery_multiple_paint_supports(uint8 direction, uint16 height, rct_ supportImageColourFlags = dword_F4387C; } - wooden_b_supports_paint_setup((direction & 1), ax, supportHeight, supportImageColourFlags); + wooden_b_supports_paint_setup((direction & 1), ax, supportHeight, supportImageColourFlags, NULL); int clearanceHeight = ceil2(mapElement->clearance_height * 8 + 15, 16); diff --git a/src/paint/supports.c b/src/paint/supports.c index acd490f779..692b8ae923 100644 --- a/src/paint/supports.c +++ b/src/paint/supports.c @@ -483,16 +483,199 @@ bool wooden_a_supports_paint_setup(int supportType, int special, int height, uin /** * Wooden supports * rct2: 0x00662D5C + * + * @param supportType (edi) + * @param special (ax) + * @param height (dx) + * @param imageColourFlags (ebp) + * @param[out] underground (Carry Flag) + * + * @return (al) whether supports have been drawn */ -bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags) +bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool * underground) { -#ifdef NO_RCT2 - return 0; -#else - int eax = special, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags; - RCT2_CALLFUNC_X(0x00662D5C, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp); - return eax & 0xFF; +#ifndef NO_RCT2 + if (gUseOriginalRidePaint) { + int eax = special, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags; + RCT2_CALLFUNC_X(0x00662D5C, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp); + return eax & 0xFF; + } #endif + + bool _9E32B1 = false; + + if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) { + if (underground != NULL) *underground = false; // AND + return false; + } + + if (!(g141E9DB & G141E9DB_FLAG_1)) { + if (underground != NULL) *underground = false; // AND + return false; + } + + uint16 baseHeight = ceil2(gSupport.height, 16); + sint16 supportLength = height - baseHeight; + + if (supportLength < 0) { + if (underground != NULL) *underground = true; // STC + return false; + } + + sint16 heightSteps = supportLength / 16; + + bool goTo662E8B = false; + + if (gSupport.slope & 0x20) { + goTo662E8B = true; + } else if (gSupport.slope & 0x10) { + heightSteps -= 2; + if (heightSteps < 0) { + if (underground != NULL) *underground = true; // STC + return false; + } + + uint32 imageId = WoodenSupportImageIds[supportType].slope; + if (imageId == 0) { + baseHeight += 32; + goTo662E8B = true; + } else { + imageId += word_97B3C4[gSupport.slope & 0x1F]; + + sub_98197C( + imageId | imageColourFlags, + 0, 0, + 32, 32, 11, + baseHeight, + 0, 0, baseHeight + 2, + get_current_rotation() + ); + baseHeight += 16; + + sub_98197C( + (imageId + 4) | imageColourFlags, + 0, 0, + 32, 32, 3, + baseHeight, + 0, 0, baseHeight + 2, + get_current_rotation() + ); + baseHeight += 16; + + _9E32B1 = true; + } + } else if ((gSupport.slope & 0x0F) != 0) { + heightSteps -= 1; + if (heightSteps < 0) { + if (underground != NULL) *underground = true; // STC + return false; + } + + uint32 imageId = WoodenSupportImageIds[supportType].slope; + if (imageId == 0) { + baseHeight += 16; + goTo662E8B = true; + } else { + imageId += word_97B3C4[gSupport.slope & 0x1F]; + + sub_98197C( + imageId | imageColourFlags, + 0, 0, + 32, 32, 3, + baseHeight, + 0, 0, baseHeight + 2, + get_current_rotation() + ); + baseHeight += 16; + + _9E32B1 = true; + } + } + + bool skipTo663004 = false; + if (goTo662E8B) { + if (heightSteps == 0) { + skipTo663004 = true; + } else { + sub_98196C( + WoodenSupportImageIds[supportType].flat | imageColourFlags, + 0, 0, + 32, 32, 0, + baseHeight - 2, + get_current_rotation() + ); + _9E32B1 = true; + } + } + + if (!skipTo663004) { + while (heightSteps > 0) { + if (baseHeight & 0x10 || heightSteps == 1 || baseHeight + 16 == gUnk141E9DC) { + sub_98196C( + WoodenSupportImageIds[supportType].half | imageColourFlags, + 0, 0, + 32, 32, ((heightSteps == 1) ? 7 : 12), + baseHeight, + get_current_rotation() + ); + heightSteps -= 1; + baseHeight += 16; + _9E32B1 = true; + } else { + sub_98196C( + WoodenSupportImageIds[supportType].full | imageColourFlags, + 0, 0, + 32, 32, ((heightSteps == 2) ? 23 : 28), + baseHeight, + get_current_rotation() + ); + heightSteps -= 2; + baseHeight += 32; + _9E32B1 = true; + } + } + } + + if (special != 0) { + uint16 specialIndex = (special - 1) & 0xFFFF; + + uint32 imageId = WoodenCurveSupportImageIds[supportType]; + unk_supports_desc supportsDesc = byte_97B23C[specialIndex]; + + if (imageId != 0 && supportsDesc.var_7 != 0) { // byte_97B23C[special].var_7 is never 0 + imageId = (imageId + specialIndex) | imageColourFlags; + + unk_supports_desc_bound_box boundBox = supportsDesc.bounding_box; + + if (supportsDesc.var_6 == 0 || gWoodenSupportsPrependTo == NULL) { + sub_98197C( + imageId | imageColourFlags, + 0, 0, + boundBox.length.y, boundBox.length.x, boundBox.length.z, + baseHeight, + boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight, + get_current_rotation() + ); + _9E32B1 = true; + } else { + paint_struct * paintStruct = sub_98198C( + imageId | imageColourFlags, + 0, 0, + boundBox.length.x, boundBox.length.y, boundBox.length.z, + baseHeight, + boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight, + get_current_rotation() + ); + _9E32B1 = true; + if (paintStruct != NULL) { + gWoodenSupportsPrependTo->var_20 = paintStruct; + } + } + } + } + + if (underground != NULL) *underground = false; // AND + return _9E32B1; } /** diff --git a/src/paint/supports.h b/src/paint/supports.h index d59c0d428d..06e4feb187 100644 --- a/src/paint/supports.h +++ b/src/paint/supports.h @@ -27,7 +27,7 @@ extern paint_struct * gWoodenSupportsPrependTo; #endif bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool* underground); -bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags); +bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool* underground); bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags); bool metal_b_supports_paint_setup(int supportType, uint8 segment, int special, int height, uint32 imageColourFlags); bool path_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, rct_footpath_entry * pathEntry, bool * underground); diff --git a/test/testpaint/intercept.c b/test/testpaint/intercept.c index f67af3b1e5..b450854a9b 100644 --- a/test/testpaint/intercept.c +++ b/test/testpaint/intercept.c @@ -168,7 +168,7 @@ bool wooden_a_supports_paint_setup(int supportType, int special, int height, uin return false; } -bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags) { +bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { function_call call = { .function = SUPPORTS_WOOD_B, @@ -720,7 +720,7 @@ static uint32 intercept_wooden_a_supports(uint32 eax, uint32 ebx, uint32 edx, ui static uint32 intercept_wooden_b_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp}; - wooden_b_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp); + wooden_b_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp, NULL); return 0; }