Ejemplo n.º 1
0
/** rct2: 0x008AE1DC */
static void paint_monorail_track_25_deg_up_to_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, sint32 height, rct_map_element * mapElement)
{
    rct_xy16 position = {gPaintMapPosition.x, gPaintMapPosition.y};

    uint32 imageId = monorail_track_pieces_25_deg_up_to_flat[direction] | gTrackColours[SCHEME_TRACK];

    if (direction == 0 || direction == 2) {
        sub_98196C(imageId, 0, 6, 32, 20, 3, height, get_current_rotation());
    } else {
        sub_98196C(imageId, 6, 0, 20, 32, 3, height, get_current_rotation());
    }

    switch (direction) {
        case 0: paint_util_push_tunnel_left(height - 8, TUNNEL_6); break;
        case 1: paint_util_push_tunnel_right(height + 8, TUNNEL_14); break;
        case 2: paint_util_push_tunnel_left(height + 8, TUNNEL_14); break;
        case 3: paint_util_push_tunnel_right(height - 8, TUNNEL_6); break;
    }

    if (track_paint_util_should_paint_supports(position)) {
        metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 4, 6, height, gTrackColours[SCHEME_SUPPORTS]);
    }

    paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0);
    paint_util_set_general_support_height(height + 40, 0x20);
}
Ejemplo n.º 2
0
/** rct2: 0x00760260 */
static void paint_swinging_inverter_ship(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement)
{
	uint8 relativeTrackSequence = track_map_1x4[direction][trackSequence];

	rct_ride * ride = get_ride(rideIndex);

	uint32 imageId;

	if (relativeTrackSequence != 1 && relativeTrackSequence != 3) {
		if (direction & 1) {
			metal_a_supports_paint_setup(0, 6, 0, height, gTrackColours[SCHEME_SUPPORTS]);
			metal_a_supports_paint_setup(0, 7, 0, height, gTrackColours[SCHEME_SUPPORTS]);
		} else {
			metal_a_supports_paint_setup(0, 5, 0, height, gTrackColours[SCHEME_SUPPORTS]);
			metal_a_supports_paint_setup(0, 8, 0, height, gTrackColours[SCHEME_SUPPORTS]);
		}

		imageId = SPR_STATION_BASE_D | gTrackColours[SCHEME_SUPPORTS];
		sub_98196C(imageId, 0, 0, 32, 32, 1, height, get_current_rotation());

		switch (direction) {
			case 0:
				imageId = SPR_STATION_PLATFORM_SW_NE | gTrackColours[SCHEME_TRACK];
				sub_98196C(imageId, 0, 24, 32, 8, 1, height + 9, get_current_rotation());
				break;
			case 1:
				imageId = SPR_STATION_PLATFORM_NW_SE | gTrackColours[SCHEME_TRACK];
				sub_98196C(imageId, 24, 0, 8, 32, 1, height + 9, get_current_rotation());
				break;
			case 2:
				imageId = SPR_STATION_PLATFORM_SW_NE | gTrackColours[SCHEME_TRACK];
				sub_98199C(imageId, 0, 0, 32, 8, 1, height + 9, -2, 0, height, get_current_rotation());
				break;
			case 3:
				imageId = SPR_STATION_PLATFORM_NW_SE | gTrackColours[SCHEME_TRACK];
				sub_98199C(imageId, 0, 0, 8, 32, 1, height + 9, 0, -2, height, get_current_rotation());
				break;
		}
	}

	switch (relativeTrackSequence) {
		case 1: paint_swinging_inverter_ship_structure(ride, direction, 48, height + 7); break;
		case 2: paint_swinging_inverter_ship_structure(ride, direction, 16, height + 7); break;
		case 0: paint_swinging_inverter_ship_structure(ride, direction, -16, height + 7); break;
		case 3: paint_swinging_inverter_ship_structure(ride, direction, -48, height + 7); break;
	}

	paint_util_set_segment_support_height(SEGMENTS_ALL, 0xFFFF, 0);
	paint_util_set_general_support_height(height + 176, 0x20);
}
Ejemplo n.º 3
0
/**
 *
 *  rct2: 0x0068B60E
 */
static void blank_tiles_paint(sint32 x, sint32 y)
{
    rct_drawpixelinfo *dpi = unk_140E9A8;

    sint32 dx = 0;
    switch (get_current_rotation()) {
    case 0:
        dx = x + y;
        break;
    case 1:
        x += 32;
        dx = y - x;
        break;
    case 2:
        x += 32;
        y += 32;
        dx = -(x + y);
        break;
    case 3:
        y += 32;
        dx = x - y;
        break;
    }
    dx /= 2;
    dx -= 16;
    sint32 bx = dx + 32;
    if (bx <= dpi->y) return;
    dx -= 20;
    dx -= dpi->height;
    if (dx >= dpi->y) return;
    gUnk9DE568 = x;
    gUnk9DE56C = y;
    gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_NONE;
    sub_98196C(3123, 0, 0, 32, 32, -1, 16, get_current_rotation());
}
Ejemplo n.º 4
0
/** rct2: 0x00898514 */
static void paint_magic_carpet(uint8 rideIndex, uint8 trackSequence, uint8 direction, sint32 height, rct_map_element * mapElement)
{
    uint8 relativeTrackSequence = track_map_1x4[direction][trackSequence];

    // The end tiles do not have a platform
    switch (relativeTrackSequence) {
    case 0:
    case 2:
        if (direction & 1) {
            metal_a_supports_paint_setup(METAL_SUPPORTS_TUBES, 6, 0, height, gTrackColours[SCHEME_SUPPORTS]);
            metal_a_supports_paint_setup(METAL_SUPPORTS_TUBES, 7, 0, height, gTrackColours[SCHEME_SUPPORTS]);
        } else {
            metal_a_supports_paint_setup(METAL_SUPPORTS_TUBES, 5, 0, height, gTrackColours[SCHEME_SUPPORTS]);
            metal_a_supports_paint_setup(METAL_SUPPORTS_TUBES, 8, 0, height, gTrackColours[SCHEME_SUPPORTS]);
        }

        uint32 imageId = SPR_STATION_BASE_D | gTrackColours[SCHEME_SUPPORTS];
        sub_98196C(imageId, 0, 0, 32, 32, 1, height, get_current_rotation());
        break;
    }

    rct_ride *ride = get_ride(rideIndex);
    switch (relativeTrackSequence) {
    case 3: paint_magic_carpet_structure(ride, direction, -48, height); break;
    case 0: paint_magic_carpet_structure(ride, direction, -16, height); break;
    case 2: paint_magic_carpet_structure(ride, direction,  16, height); break;
    case 1: paint_magic_carpet_structure(ride, direction,  48, height); break;
    }

    paint_util_set_segment_support_height(SEGMENTS_ALL, 0xFFFF, 0);
    paint_util_set_general_support_height(height + 176, 0x20);
}
Ejemplo n.º 5
0
static void wooden_wild_mouse_track_left_quarter_turn_1(
    paint_session *          session,
    uint8                    rideIndex,
    uint8                    trackSequence,
    uint8                    direction,
    sint32                   height,
    const rct_tile_element * tileElement)
{
    static constexpr const uint32 imageIds[4] = {
        SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SW_NE,
        SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NW_SE,
        SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NE_SW,
        SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SE_NW,
    };
    static uint8 supportType[] = { 5, 2, 3, 4 };

    uint32 imageId = imageIds[direction] | session->TrackColours[SCHEME_TRACK];
    switch (direction)
    {
    case 0:
        sub_98197C(session, imageId, 6, 0, 26, 24, 1, height, 6, 2, height);
        break;
    case 1:
        sub_98196C(session, imageId, 0, 0, 26, 26, 1, height);
        break;
    case 2:
        sub_98197C(session, imageId, 0, 6, 24, 26, 1, height, 2, 6, height);
        break;
    case 3:
        sub_98196C(session, imageId, 6, 6, 24, 24, 1, height);
        break;
    }
    wooden_a_supports_paint_setup(session, supportType[direction], 0, height, session->TrackColours[SCHEME_SUPPORTS], nullptr);
    track_paint_util_left_quarter_turn_1_tile_tunnel(session, direction, height, 0, TUNNEL_0, 0, TUNNEL_0);
    paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
    paint_util_set_general_support_height(session, height + 32, 0x20);
}
Ejemplo n.º 6
0
/**
 *  rct2: 0x006A2ECC
 *
 * @param supportType (edi)
 * @param special (ax)
 * @param height (dx)
 * @param imageColourFlags (ebp)
 * @param pathEntry (0x00F3EF6C)
 * @param[out] underground (Carry Flag)
 *
 * @return Whether supports were drawn
 */
bool path_a_supports_paint_setup(paint_session * session, sint32 supportType, sint32 special, sint32 height, uint32 imageColourFlags,
                                 rct_footpath_entry * pathEntry, bool * underground)
{
    if (underground != nullptr) {
        *underground = false; // AND
    }

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        return false;
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        return false;
    }

    uint16 baseHeight = ceil2(session->Support.height, 16);
    sint32 supportLength = height - baseHeight;
    if (supportLength < 0) {
        if (underground != nullptr) *underground = true; // STC
        return false;
    }

    bool hasSupports = false;

    sint16 heightSteps = supportLength / 16;

    if (session->Support.slope & 0x20) {
        //save dx2
        sub_98196C(session, (pathEntry->bridge_image + 48) | imageColourFlags, 0, 0, 32, 32, 0, baseHeight - 2);
        hasSupports = true;
    } else if (session->Support.slope & 0x10) {
        heightSteps -= 2;
        if (heightSteps < 0) {
            if (underground != nullptr) *underground = true; // STC
            return false;
        }

        uint32 imageId = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK] + pathEntry->bridge_image;

        sub_98197C(session, imageId | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);
        baseHeight += 16;

        sub_98197C(session, (imageId + 4) | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);
        baseHeight += 16;

        hasSupports = true;

    } else if (session->Support.slope & 0x0F) {
        heightSteps -= 1;
        if (heightSteps < 0) {
            if (underground != nullptr) *underground = true; // STC
            return false;
        }

        uint32 ebx = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK] + pathEntry->bridge_image;

        sub_98197C(session, ebx | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);

        hasSupports = true;
        baseHeight += 16;
    }

    while (heightSteps > 0) {
        if (baseHeight & 0x10 || heightSteps == 1 || baseHeight + 16 == session->WaterHeight) {

            uint32 imageId = (supportType * 24) + pathEntry->bridge_image + 23;

            sub_98196C(session, imageId | imageColourFlags, 0, 0, 32, 32, ((heightSteps == 1) ? 7 : 12), baseHeight);
            heightSteps -= 1;
            baseHeight += 16;
            hasSupports = true;
        } else {
            uint32 imageId = (supportType * 24) + pathEntry->bridge_image + 22;

            sub_98196C(session, imageId | imageColourFlags, 0, 0, 32, 32, ((heightSteps == 2) ? 23 : 28), baseHeight);
            heightSteps -= 2;
            baseHeight += 32;
            hasSupports = true;
        }
    }

    if (special != 0) {
        uint16 specialIndex = (special - 1) & 0xFFFF;

        uint32 imageId = pathEntry->bridge_image + 55 + specialIndex;

        unk_supports_desc supportsDesc = byte_98D8D4[specialIndex];
        unk_supports_desc_bound_box boundBox = supportsDesc.bounding_box;

        if (supportsDesc.var_6 == 0 || session->WoodenSupportsPrependTo == nullptr) {
            sub_98197C(
                session, imageId | imageColourFlags, 0, 0, boundBox.length.y, boundBox.length.x, boundBox.length.z, baseHeight,
                boundBox.offset.x, boundBox.offset.y, baseHeight + boundBox.offset.z);
            hasSupports = true;
        } else {
            paint_struct * paintStruct = sub_98198C(
                session, imageId | imageColourFlags, 0, 0, boundBox.length.y, boundBox.length.x, boundBox.length.z, baseHeight,
                boundBox.offset.x, boundBox.offset.y, baseHeight + boundBox.offset.z);
            hasSupports = true;
            if (paintStruct != nullptr) {
                session->WoodenSupportsPrependTo->var_20 = paintStruct;
            }
        }
    }

    if (underground != nullptr) *underground = false; // AND

    return hasSupports;
}
Ejemplo n.º 7
0
/**
 * Metal pole supports
 *  rct2: 0x00663584
 *
 * @param supportType (edi)
 * @param segment (ebx)
 * @param special (ax)
 * @param height (edx)
 * @param imageColourFlags (ebp)
 *
 * @return (Carry Flag)
 */
bool metal_b_supports_paint_setup(paint_session * session, uint8 supportType, uint8 segment, sint32 special, sint32 height, uint32 imageColourFlags)
{
    support_height * supportSegments = session->SupportSegments;
    uint8 originalSegment = segment;

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        return false; // AND
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        return false; // AND
    }

    uint16 _9E3294 = 0xFFFF;
    sint32 baseHeight = height;

    if (height < supportSegments[segment].height) {
        _9E3294 = height;

        baseHeight -= supportTypeToHeight[supportType];
        if (baseHeight < 0) {
            return false; // AND
        }

        uint16 baseIndex = session->CurrentRotation * 2;

        uint8 ebp = _97AF32[baseIndex + segment * 8];
        if (baseHeight <= supportSegments[ebp].height) {
            baseIndex += 9 * 4 * 2; // 9 segments, 4 directions, 2 values
            uint8 ebp2 = _97AF32[baseIndex + segment * 8];
            if (baseHeight <= supportSegments[ebp2].height) {
                baseIndex += 9 * 4 * 2;
                uint8 ebp3 = _97AF32[baseIndex + segment * 8];
                if (baseHeight <= supportSegments[ebp3].height) {
                    baseIndex += 9 * 4 * 2;
                    uint8 ebp4 = _97AF32[baseIndex + segment * 8];
                    if (baseHeight <= supportSegments[ebp4].height) {
                        return true; // STC
                    }
                }

            }
        }

        ebp = _97AF32[baseIndex + segment * 8 + 1];
        if (ebp >= 4) {
            return true; // STC
        }

        sub_98196C(
            session, _metalSupportTypeToCrossbeamImages[supportType][ebp] | imageColourFlags,
            loc_97AF20[originalSegment].x + loc_97B052[ebp].x, loc_97AF20[originalSegment].y + loc_97B052[ebp].y,
            _97B062[ebp].x, _97B062[ebp].y, 1, baseHeight);
    }

    sint32 si = baseHeight;

    if ((supportSegments[segment].slope & 0x20)
        || (baseHeight - supportSegments[segment].height < 6)
        || (_97B15C[supportType].base_id == 0)) {
        baseHeight = supportSegments[segment].height;
    } else {
        uint32 imageOffset = metal_supports_slope_image_map[supportSegments[segment].slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];
        uint32 imageId = _97B15C[supportType].base_id + imageOffset;

        sub_98196C(
            session, imageId | imageColourFlags, loc_97AF20[segment].x, loc_97AF20[segment].y, 0, 0, 5,
            supportSegments[segment].height);

        baseHeight = supportSegments[segment].height + 6;
    }

    sint16 heightDiff = floor2(baseHeight + 16, 16);
    if (heightDiff > si) {
        heightDiff = si;
    }

    heightDiff -= baseHeight;
    if (heightDiff > 0) {
        sub_98196C(
            session, (_97B15C[supportType].beam_id + (heightDiff - 1)) | imageColourFlags, loc_97AF20[segment].x,
            loc_97AF20[segment].y, 0, 0, heightDiff - 1, baseHeight);
    }

    baseHeight += heightDiff;


    sint16 endHeight;


    sint32 i = 1;
    while (true) {
        endHeight = baseHeight + 16;
        if (endHeight > si) {
            endHeight = si;
        }

        sint16 beamLength = endHeight - baseHeight;

        if (beamLength <= 0) {
            break;
        }

        uint32 imageId = _97B15C[supportType].beam_id + (beamLength - 1);

        if (i % 4 == 0) {
            // Each fourth run, draw a special image
            if (beamLength == 16) {
                imageId += 1;
            }
        }

        sub_98196C(
            session, imageId | imageColourFlags, loc_97AF20[segment].x, loc_97AF20[segment].y, 0, 0, beamLength - 1,
            baseHeight);

        baseHeight += beamLength;
        i++;
    }

    supportSegments[segment].height = _9E3294;
    supportSegments[segment].slope = 0x20;

    if (special != 0) {
        baseHeight = height;
        si = height + special;
        while (true) {
            endHeight = baseHeight + 16;
            if (endHeight > si) {
                endHeight = si;
            }

            sint16 beamLength = endHeight - baseHeight;
            if (beamLength <= 0) {
                break;
            }

            uint32 imageId = _97B15C[supportType].beam_id + (beamLength - 1);
            sub_98197C(
                session, imageId | imageColourFlags, loc_97AF20[originalSegment].x, loc_97AF20[originalSegment].y, 0, 0, 0,
                baseHeight, loc_97AF20[originalSegment].x, loc_97AF20[originalSegment].y, height);
            baseHeight += beamLength;
        }
    }

    return false; // AND
}
Ejemplo n.º 8
0
/**
 * Metal pole supports
 * @param supportType (edi)
 * @param segment (ebx)
 * @param special (ax)
 * @param height (edx)
 * @param imageColourFlags (ebp)
 *  rct2: 0x00663105
 */
bool metal_a_supports_paint_setup(paint_session * session, uint8 supportType, uint8 segment, sint32 special, sint32 height, uint32 imageColourFlags)
{
    support_height * supportSegments = session->SupportSegments;

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        return false;
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        return false;
    }

    sint16 originalHeight = height;
    sint32 originalSegment = segment;

    const uint8 rotation = session->CurrentRotation;
    sint16 unk9E3294 = -1;
    if (height < supportSegments[segment].height){
        unk9E3294 = height;

        height -= supportTypeToHeight[supportType];
        if (height < 0)
            return false;

        const uint8* esi = &(_97AF32[rotation * 2]);

        uint8 newSegment = esi[segment * 8];
        if (height <= supportSegments[newSegment].height) {
            esi += 72;
            newSegment = esi[segment * 8];
            if (height <= supportSegments[newSegment].height) {
                esi += 72;
                newSegment = esi[segment * 8];
                if (height <= supportSegments[newSegment].height) {
                    esi += 72;
                    newSegment = esi[segment * 8];
                    if (height <= supportSegments[newSegment].height) {
                        return false;
                    }
                }
            }
        }

        uint8 ebp = esi[segment * 8 + 1];

        sint8 xOffset = loc_97AF20[segment].x;
        sint8 yOffset = loc_97AF20[segment].y;
        xOffset += loc_97B052[ebp].x;
        yOffset += loc_97B052[ebp].y;

        sint16 boundBoxLengthX = _97B062[ebp].x;
        sint16 boundBoxLengthY = _97B062[ebp].y;

        uint32 image_id = _metalSupportTypeToCrossbeamImages[supportType][ebp];
        image_id |= imageColourFlags;
        sub_98196C(session, image_id, xOffset, yOffset, boundBoxLengthX, boundBoxLengthY, 1, height);

        segment = newSegment;
    }
    sint16 si = height;
    if (supportSegments[segment].slope & (1 << 5) ||
        height - supportSegments[segment].height < 6 ||
        _97B15C[supportType].base_id == 0
        ) {

        height = supportSegments[segment].height;
    }else{
        sint8 xOffset = loc_97AF20[segment].x;
        sint8 yOffset = loc_97AF20[segment].y;

        uint32 image_id = _97B15C[supportType].base_id;
        image_id += metal_supports_slope_image_map[supportSegments[segment].slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];
        image_id |= imageColourFlags;

        sub_98196C(session, image_id, xOffset, yOffset, 0, 0, 5, supportSegments[segment].height);

        height = supportSegments[segment].height + 6;
    }


    // Work out if a small support segment required to bring support to normal
    // size (aka floor2(x, 16))
    sint16 heightDiff = floor2(height + 16, 16);
    if (heightDiff > si) {
        heightDiff = si;
    }

    heightDiff -= height;

    if (heightDiff > 0) {
        sint8 xOffset = loc_97AF20[segment].x;
        sint8 yOffset = loc_97AF20[segment].y;

        uint32 image_id = _97B15C[supportType].beam_id;
        image_id += heightDiff - 1;
        image_id |= imageColourFlags;

        sub_98196C(session, image_id, xOffset, yOffset, 0, 0, heightDiff - 1, height);
    }

    height += heightDiff;
    //6632e6

    for (uint8 count = 0; ;count++) {
        if (count >= 4)
            count = 0;

        sint16 z = height + 16;
        if (z > si) {
            z = si;
        }

        z -= height;
        if (z <= 0)
            break;

        sint8 xOffset = loc_97AF20[segment].x;
        sint8 yOffset = loc_97AF20[segment].y;

        uint32 image_id = _97B15C[supportType].beam_id;
        image_id += z - 1;
        image_id |= imageColourFlags;

        if (count == 3 && z == 0x10)
            image_id++;

        sub_98196C(session, image_id, xOffset, yOffset, 0, 0, z - 1, height);

        height += z;
    }

    supportSegments[segment].height = unk9E3294;
    supportSegments[segment].slope = 0x20;

    height = originalHeight;
    segment = originalSegment;
    if (special == 0)
        return true;

    if (special < 0) {
        special = -special;
        height--;
    }

    sint16 boundBoxOffsetX = loc_97AF20[segment].x;
    sint16 boundBoxOffsetY = loc_97AF20[segment].y;
    sint16 boundBoxOffsetZ = height;
    si = height + special;

    while (1) {
        sint16 z = height + 16;
        if (z > si) {
            z = si;
        }

        z -= height;
        if (z <= 0)
            break;

        sint8 xOffset = loc_97AF20[segment].x;
        sint8 yOffset = loc_97AF20[segment].y;

        uint32 image_id = _97B190[supportType].beam_id;
        image_id += z - 1;
        image_id |= imageColourFlags;

        sub_98197C(session, image_id, xOffset, yOffset, 0, 0, 0, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ);

        height += z;
    }

    return true;

    //sint32 eax = special, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags;
    //RCT2_CALLFUNC_X(0x00663105, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp);
    //return eax & 0xFF;
}
Ejemplo n.º 9
0
/**
 * 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(paint_session * session, sint32 supportType, sint32 special, sint32 height, uint32 imageColourFlags, bool * underground)
{
    bool _9E32B1 = false;

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        if (underground != nullptr) *underground = false; // AND
        return false;
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        if (underground != nullptr) *underground = false; // AND
        return false;
    }

    uint16 baseHeight = ceil2(session->Support.height, 16);
    sint16 supportLength = height - baseHeight;

    if (supportLength < 0) {
        if (underground != nullptr) *underground = true; // STC
        return false;
    }

    sint16 heightSteps = supportLength / 16;

    bool goTo662E8B = false;

    if (session->Support.slope & 0x20) {
        goTo662E8B = true;
    } else if (session->Support.slope & 0x10) {
        heightSteps -= 2;
        if (heightSteps < 0) {
            if (underground != nullptr) *underground = true; // STC
            return false;
        }

        uint32 imageId = WoodenSupportImageIds[supportType].slope;
        if (imageId == 0) {
            baseHeight += 32;
            goTo662E8B = true;
        } else {
            imageId += word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];

            sub_98197C(session, imageId | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);
            baseHeight += 16;

            sub_98197C(session, (imageId + 4) | imageColourFlags, 0, 0, 32, 32, 3, baseHeight, 0, 0, baseHeight + 2);
            baseHeight += 16;

            _9E32B1 = true;
        }
    } else if ((session->Support.slope & 0x0F) != 0) {
        heightSteps -= 1;
        if (heightSteps < 0) {
            if (underground != nullptr) *underground = true; // STC
            return false;
        }

        uint32 imageId = WoodenSupportImageIds[supportType].slope;
        if (imageId == 0) {
            baseHeight += 16;
            goTo662E8B = true;
        } else {
            imageId += word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];

            sub_98197C(session, imageId | imageColourFlags, 0, 0, 32, 32, 3, baseHeight, 0, 0, baseHeight + 2);
            baseHeight += 16;

            _9E32B1 = true;
        }
    }

    bool skipTo663004 = false;
    if (goTo662E8B) {
        if (heightSteps == 0) {
            skipTo663004 = true;
        } else {
            sub_98196C(session, WoodenSupportImageIds[supportType].flat | imageColourFlags, 0, 0, 32, 32, 0, baseHeight - 2);
            _9E32B1 = true;
        }
    }

    if (!skipTo663004) {
        while (heightSteps > 0) {
            if (baseHeight & 0x10 || heightSteps == 1 || baseHeight + 16 == session->WaterHeight) {
                sub_98196C(
                    session, WoodenSupportImageIds[supportType].half | imageColourFlags, 0, 0, 32, 32,
                    ((heightSteps == 1) ? 7 : 12), baseHeight);
                heightSteps -= 1;
                baseHeight += 16;
                _9E32B1 = true;
            } else {
                sub_98196C(
                    session, WoodenSupportImageIds[supportType].full | imageColourFlags, 0, 0, 32, 32,
                    ((heightSteps == 2) ? 23 : 28), baseHeight);
                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 || session->WoodenSupportsPrependTo == nullptr) {
                sub_98197C(
                    session, imageId | imageColourFlags, 0, 0, boundBox.length.x, boundBox.length.y, boundBox.length.z,
                    baseHeight, boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight);
                _9E32B1 = true;
            } else {
                paint_struct * paintStruct = sub_98198C(
                    session, imageId | imageColourFlags, 0, 0, boundBox.length.x, boundBox.length.y, boundBox.length.z,
                    baseHeight, boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight);
                _9E32B1 = true;
                if (paintStruct != nullptr) {
                    session->WoodenSupportsPrependTo->var_20 = paintStruct;
                }
            }
        }
    }

    if (underground != nullptr) *underground = false; // AND
    return _9E32B1;
}
Ejemplo n.º 10
0
/**
 * Adds paint structs for wooden supports.
 *  rct2: 0x006629BC
 * @param supportType (edi) Type and direction of supports.
 * @param special (ax) Used for curved supports.
 * @param height (dx) The height of the supports.
 * @param imageColourFlags (ebp) The colour and palette flags for the support sprites.
 * @param[out] underground (Carry flag) true if underground.
 * @returns (al) true if any supports have been drawn, otherwise false.
 */
bool wooden_a_supports_paint_setup(paint_session * session, sint32 supportType, sint32 special, sint32 height, uint32 imageColourFlags, bool* underground)
{
    if (underground != nullptr){
        *underground = false;
    }

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        return false;
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        return false;
    }

    sint32 z = floor2(session->Support.height + 15, 16);
    height -= z;
    if (height < 0) {
        if (underground != nullptr) {
            *underground = true;
        }
        return false;
    }
    height /= 16;

    bool hasSupports = false;
    bool drawFlatPiece = false;

    // Draw base support (usually shaped to the slope)
    sint32 slope = session->Support.slope;
    if (slope & (1 << 5)) {
        // Above scenery (just put a base piece above it)
        drawFlatPiece = true;
    } else if (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) {
        // Steep diagonal (place the correct shaped support for the slope)
        height -= 2;
        if (height < 0) {
            if (underground != nullptr) {
                *underground = true;
            }
            return false;
        }

        sint32 imageId = WoodenSupportImageIds[supportType].slope;
        if (imageId == 0) {
            drawFlatPiece = true;
        } else {
            imageId += word_97B3C4[slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];
            imageId |= imageColourFlags;
            sub_98197C(session, imageId, 0, 0, 32, 32, 11, z, 0, 0, z + 2);

            sub_98197C(session, imageId + 4, 0, 0, 32, 32, 11, z + 16, 0, 0, z + 16 + 2);

            hasSupports = true;
        }
        z += 32;
    } else if ((slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != 0) {
        // 1 to 3 quarters up
        height--;
        if (height < 0) {
            if (underground != nullptr) {
                *underground = true;
            }
            return false;
        }

        sint32 imageId = WoodenSupportImageIds[supportType].slope;
        if (imageId == 0) {
            drawFlatPiece = true;
        } else {
            imageId += word_97B3C4[slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];
            imageId |= imageColourFlags;

            sub_98197C(session, imageId, 0, 0, 32, 32, 11, z, 0, 0, z + 2);
            hasSupports = true;
        }
        z += 16;
    }

    // Draw flat base support
    if (drawFlatPiece) {
        sint32 imageId = WoodenSupportImageIds[supportType].flat | imageColourFlags;
        sub_98196C(session, imageId, 0, 0, 32, 32, 0, z - 2);
        hasSupports = true;
    }

    // Draw repeated supports for left over space
    while (height != 0) {
        if ((z & 16) == 0 && height >= 2 && z + 16 != session->WaterHeight) {
            // Full support
            sint32 imageId = WoodenSupportImageIds[supportType].full | imageColourFlags;
            uint8 ah = height == 2 ? 23 : 28;
            sub_98196C(session, imageId, 0, 0, 32, 32, ah, z);
            hasSupports = true;
            z += 32;
            height -= 2;
        } else {
            // Half support
            sint32 imageId = WoodenSupportImageIds[supportType].half | imageColourFlags;
            uint8 ah = height == 1 ? 7 : 12;
            sub_98196C(session, imageId, 0, 0, 32, 32, ah, z);
            hasSupports = true;
            z += 16;
            height -= 1;
        }
    }

    // Draw special pieces, e.g. curved supports
    if (special != 0) {
        special = (special - 1) & 0xFFFF;

        sint32 imageId = WoodenCurveSupportImageIds[supportType];
        if (imageId != 0 && byte_97B23C[special].var_7 != 0) {
            imageId += special;
            imageId |= imageColourFlags;

            unk_supports_desc_bound_box bBox = byte_97B23C[special].bounding_box;

            if (byte_97B23C[special].var_6 == 0 || session->WoodenSupportsPrependTo == nullptr) {
                sub_98197C(
                    session, imageId, 0, 0, bBox.length.x, bBox.length.y, bBox.length.z, z, bBox.offset.x, bBox.offset.y,
                    bBox.offset.z + z);
                hasSupports = true;
            } else {
                hasSupports = true;
                paint_struct * ps = sub_98198C(
                    session, imageId, 0, 0, bBox.length.x, bBox.length.y, bBox.length.z, z, bBox.offset.x, bBox.offset.y,
                    bBox.offset.z + z);
                if (ps != nullptr) {
                    paint_struct* edi = session->WoodenSupportsPrependTo;
                    edi->var_20 = ps;
                }
            }
        }
    }

    return hasSupports;
}
Ejemplo n.º 11
0
/**
 *
 *  rct2: 0x006A326B
 *
 * @param segment (ebx)
 * @param special (ax)
 * @param height (dx)
 * @param imageColourFlags (ebp)
 * @param pathEntry (0x00F3EF6C)
 *
 * @return Whether supports were drawn
 */
bool path_b_supports_paint_setup(paint_session * session, sint32 segment, sint32 special, sint32 height, uint32 imageColourFlags,
                                 rct_footpath_entry * pathEntry)
{
    support_height * supportSegments = session->SupportSegments;

    if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
        return false; // AND
    }

    if (!(session->Unk141E9DB & G141E9DB_FLAG_1)) {
        return false; // AND
    }

    if (height < supportSegments[segment].height) {
        return true; // STC
    }

    uint16 baseHeight;

    if ((supportSegments[segment].slope & 0x20)
        || (height - supportSegments[segment].height < 6)
        || !(pathEntry->flags & FOOTPATH_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE)) {
        baseHeight = supportSegments[segment].height;
    } else {
        uint8 imageOffset = metal_supports_slope_image_map[supportSegments[segment].slope & TILE_ELEMENT_SURFACE_SLOPE_MASK];
        baseHeight = supportSegments[segment].height;

        sub_98196C(
            session, (pathEntry->bridge_image + 37 + imageOffset) | imageColourFlags, loc_97AF20[segment].x,
            loc_97AF20[segment].y, 0, 0, 5, baseHeight);
        baseHeight += 6;
    }

    // si = height
    // dx = baseHeight

    sint16 heightDiff = floor2(baseHeight + 16, 16);
    if (heightDiff > height) {
        heightDiff = height;
    }

    heightDiff -= baseHeight;

    if (heightDiff > 0) {
        sub_98196C(
            session, (pathEntry->bridge_image + 20 + (heightDiff - 1)) | imageColourFlags, loc_97AF20[segment].x,
            loc_97AF20[segment].y, 0, 0, heightDiff - 1, baseHeight);
    }

    baseHeight += heightDiff;

    bool keepGoing = true;
    while (keepGoing) {
        sint16 z;

        for (sint32 i = 0; i < 4; ++i) {
            z = baseHeight + 16;
            if (z > height) {
                z = height;
            }
            z -= baseHeight;

            if (z <= 0) {
                keepGoing = false;
                break;
            }

            if (i == 3) {
                // Only do the z check in the fourth run.
                break;
            }

            sub_98196C(
                session, (pathEntry->bridge_image + 20 + (z - 1)) | imageColourFlags, loc_97AF20[segment].x,
                loc_97AF20[segment].y, 0, 0, (z - 1), baseHeight);

            baseHeight += z;
        }

        if (keepGoing == false) {
            break;
        }

        uint32 imageId = pathEntry->bridge_image + 20 + (z - 1);
        if (z == 16) {
            imageId += 1;
        }

        sub_98196C(
            session, imageId | imageColourFlags, loc_97AF20[segment].x, loc_97AF20[segment].y, 0, 0, (z - 1), baseHeight);

        baseHeight += z;
    }

    // loc_6A34D8
    supportSegments[segment].height = 0xFFFF;
    supportSegments[segment].slope = 0x20;

    if (special != 0) {
        sint16 si = special + baseHeight;

        while (true) {
            sint16 z = baseHeight + 16;
            if (z > si) {
                z = si;
            }

            z -= baseHeight;
            if (z <= 0) {
                break;
            }

            uint32 imageId = pathEntry->bridge_image + 20 + (z - 1);
            sub_98197C(
                session, imageId | imageColourFlags, loc_97AF20[segment].x, loc_97AF20[segment].y, 0, 0, 0, baseHeight,
                loc_97AF20[segment].x, loc_97AF20[segment].y, baseHeight);

            baseHeight += z;
        }
    }

    return false; // AND
}
Ejemplo n.º 12
0
/** rct2: 0x008AE24C */
static void paint_monorail_track_s_bend_right(uint8 rideIndex, uint8 trackSequence, uint8 direction, sint32 height, rct_map_element * mapElement)
{
    if (direction == 2 || direction == 3) {
        trackSequence = 3 - trackSequence;
    }

    const rct_xy16 offsetList[] = {
        {0, 6},
        {0, 6},
        {0, 0},
        {0, 6},
    };

    const rct_xy16 boundsList[] = {
        {32, 20},
        {32, 26},
        {32, 26},
        {32, 20},
    };

    uint32 imageId = monorail_track_pieces_s_bend_right[direction&1][trackSequence] | gTrackColours[SCHEME_TRACK];
    rct_xy16 offset = offsetList[trackSequence];
    rct_xy16 bounds = boundsList[trackSequence];
    if (direction == 0 || direction == 2) {
        sub_98196C(imageId, (sint8) offset.x, (sint8) offset.y, bounds.x, bounds.y, 3, height, get_current_rotation());
    } else {
        sub_98196C(imageId, (sint8) offset.y, (sint8) offset.x, bounds.y, bounds.x, 3, height, get_current_rotation());
    }

    if (direction == 0 || direction == 2) {
        if (trackSequence == 0) {
            paint_util_push_tunnel_left(height, TUNNEL_6);
        }

        switch (trackSequence) {
            case 0: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 4, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
            case 1: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 8, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
            case 3: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 4, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
        }
    } else {
        if (trackSequence == 3) {
            paint_util_push_tunnel_right(height, TUNNEL_6);
        }

        switch (trackSequence) {
            case 0: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 4, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
            case 1: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 7, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
            case 3: metal_a_supports_paint_setup(METAL_SUPPORTS_BOXED, 4, 0, height, gTrackColours[SCHEME_SUPPORTS]); break;
        }
    }

    sint32 blockedSegments = 0;
    switch (trackSequence) {
        case 0: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_BC; break;
        case 1: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_C0 | SEGMENT_D4 | SEGMENT_BC; break;
        case 2: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_B8 | SEGMENT_C8 | SEGMENT_B4; break;
        case 3: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_B8; break;
    }
    paint_util_set_segment_support_height(paint_util_rotate_segments(blockedSegments, direction & 1), 0xFFFF, 0);

    paint_util_set_general_support_height(height + 32, 0x20);
}