void date_update() { int32_t monthTicks = gDateMonthTicks + 4; if (monthTicks >= 0x10000) { gDateMonthTicks = 0; gDateMonthsElapsed++; } else { gDateMonthTicks = floor2((uint16_t)monthTicks, 4); } }
int main(int argc, char** argv) { if(argc!=2) { std::cerr << "Usage: " << argv[0] << " <file-name>" << std::endl; return -1; } World world; //(COLOR(0.3, 0.3, 1.0)); Light light1(&world, POINT3D(2.0, 3.0, 2.0)); //Light light2(&world, POINT3D(-4.0, 5.0, 5.0), LIGHT(COLOR_YELLOW)); //Light light3(&world, POINT3D(2.0, 0.0, 5.0)); material_t blue_ball_mat = MATERIAL_DEFAULT, green_ball_mat = MATERIAL_DEFAULT; blue_ball_mat.color = COLOR_WHITE; green_ball_mat.color = COLOR(0.7,0.7,0.7); blue_ball_mat.specular = green_ball_mat.specular = COLOR_WHITE; blue_ball_mat.ka = 0.075; green_ball_mat.ka = 0.15; blue_ball_mat.kd = 0.075; green_ball_mat.kd = 0.25; blue_ball_mat.ks = 0.2; green_ball_mat.ks = 1.0; blue_ball_mat.ke = green_ball_mat.ke = 20.0; blue_ball_mat.kr = 0.05; green_ball_mat.kr = 0.75; blue_ball_mat.kt = 0.85; blue_ball_mat.n = 0.95; blue_ball_mat.texture = green_ball_mat.texture = 0; Sphere blue(&world, blue_ball_mat, 0.15, POINT3D(0.45, 0.3, 0.75)); Sphere green(&world, green_ball_mat, 0.15, POINT3D(0.3, 0.2, 0.5)); Object floor(&world); material_t floor_mat = MATERIAL_DEFAULT; floor_mat.color = COLOR_RED; floor_mat.specular = COLOR_WHITE; floor_mat.ka = 0.7; floor_mat.kd = 0.2; floor_mat.ks = 0.2; floor_mat.ke = 10.0; floor_mat.texture = floor_texture1; Triangle floor1(&floor, floor_mat, POINT3D(-0.7, 0.0, 1.0), POINT3D(1.05, 0.0, 1.0), POINT3D(1.05, 0.0, -1.5)); Triangle floor2(&floor, floor_mat, POINT3D(-0.7, 0.0, 1.0), POINT3D(1.05, 0.0, -1.5), POINT3D(-0.7, 0.0, -1.5)); //Cube cube(&world, MATERIAL(COLOR_YELLOW), POINT3D(0.4, 0.4, 0.4), POINT3D(1.0, 0.5, -0.5), POINT3D(M_PI/4.0, -M_PI / 4.0, M_PI/4.0)); //Cone cone(&world, MATERIAL(COLOR_YELLOW), 1.0, 5, 0.5, 20, POINT3D(0.0, 0.5, -0.5), POINT3D(-M_PI/16.0,0.0,0.0)); Camera cam(&world, POINT3D(0.5, 0.3, 1.5), POINT3D(0.5, 0.3, 0.0), POINT3D(0.0, 1.0, 0.0), 45.0, 0.01, 10.0, 10); Image img(1024,768); cam.snap(&img); Image::save(&img, argv[1]); return 0; }
void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) { int x, y; double sy1, sy2, sx1, sx2; for (y = dstY; y < dstY + dstH; y++) { sy1 = ((double)y - (double)dstY) * (double)srcH / (double)dstH; sy2 = ((double)(y + 1) - (double)dstY) * (double)srcH / (double)dstH; for (x = dstX; x < dstX + dstW; x++) { double sx, sy; double spixels = 0; double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; sx1 = ((double)x - (double)dstX) * (double)srcW / (double)dstW; sx2 = ((double)(x + 1) - (double)dstX) * (double)srcW / (double)dstW; sy = sy1; do { double yportion; if (floor2(sy) == floor2(sy1)) { yportion = 1.0 - (sy - floor2(sy)); if (yportion > sy2 - sy1) yportion = sy2 - sy1; sy = floor2(sy); } else if (sy == floor2(sy2)) { yportion = sy2 - floor2(sy2); } else { yportion = 1.0; } sx = sx1; do { double xportion; double pcontribution; int p; if (floor2(sx) == floor2(sx1)) { xportion = 1.0 - (sx - floor2(sx)); if (xportion > sx2 - sx1) xportion = sx2 - sx1; sx = floor2 (sx); } else if (sx == floor2(sx2)) { xportion = sx2 - floor2(sx2); } else { xportion = 1.0; } pcontribution = xportion * yportion; p = gdImageGetTrueColorPixel(src, (int)sx + srcX, (int)sy + srcY); red += gdTrueColorGetRed (p) * pcontribution; green += gdTrueColorGetGreen (p) * pcontribution; blue += gdTrueColorGetBlue (p) * pcontribution; spixels += xportion * yportion; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { red /= spixels; green /= spixels; blue /= spixels; } if (red > 255.0) red = 255.0; if (green > 255.0) green = 255.0; if (blue > 255.0) blue = 255.0; gdImageSetPixel(dst, x, y, gdTrueColorAlpha((int)red, (int)green, (int)blue, 0)); } } }
void image_downsize_gd(image *im) { int x, y; float sy1, sy2, sx1, sx2; int dstX = 0, dstY = 0, srcX = 0, srcY = 0; float width_scale, height_scale; int dstW = im->target_width; int dstH = im->target_height; int srcW = im->width; int srcH = im->height; if (im->height_padding) { dstY = im->height_padding; dstH = im->height_inner; } if (im->width_padding) { dstX = im->width_padding; dstW = im->width_inner; } width_scale = (float)srcW / dstW; height_scale = (float)srcH / dstH; for (y = dstY; (y < dstY + dstH); y++) { sy1 = (float)(y - dstY) * height_scale; sy2 = (float)((y + 1) - dstY) * height_scale; for (x = dstX; (x < dstX + dstW); x++) { float sx, sy; float spixels = 0; float red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; if (!im->has_alpha) alpha = 255.0; sx1 = (float)(x - dstX) * width_scale; sx2 = (float)((x + 1) - dstX) * width_scale; sy = sy1; //DEBUG_TRACE("sx1 %.2f, sx2 %.2f, sy1 %.2f, sy2 %.2f\n", sx1, sx2, sy1, sy2); do { float yportion; //DEBUG_TRACE(" yportion(sy %.2f, sy1 %.2f, sy2 %.2f) = ", sy, sy1, sy2); if (floor2(sy) == floor2(sy1)) { yportion = 1.0 - (sy - floor2(sy)); if (yportion > sy2 - sy1) { yportion = sy2 - sy1; } sy = floor2(sy); } else if (sy == floor2(sy2)) { yportion = sy2 - floor2(sy2); } else { yportion = 1.0; } //DEBUG_TRACE("%.2f\n", yportion); sx = sx1; do { float xportion = 1.0; float pcontribution; pix p; //DEBUG_TRACE(" xportion(sx %.2f, sx1 %.2f, sx2 %.2f) = ", sx, sx1, sx2); if (floor2(sx) == floor2(sx1)) { xportion = 1.0 - (sx - floor2(sx)); if (xportion > sx2 - sx1) { xportion = sx2 - sx1; } sx = floor2(sx); } else if (sx == floor2(sx2)) { xportion = sx2 - floor2(sx2); } else { xportion = 1.0; } //DEBUG_TRACE("%.2f\n", xportion); pcontribution = xportion * yportion; p = get_pix(im, (int32_t)sx + srcX, (int32_t)sy + srcY); /* DEBUG_TRACE(" merging with pix %d, %d: src %x (%d %d %d %d), pcontribution %.2f\n", (int32_t)sx + srcX, (int32_t)sy + srcY, p, COL_RED(p), COL_GREEN(p), COL_BLUE(p), COL_ALPHA(p), pcontribution); */ red += COL_RED(p) * pcontribution; green += COL_GREEN(p) * pcontribution; blue += COL_BLUE(p) * pcontribution; if (im->has_alpha) alpha += COL_ALPHA(p) * pcontribution; spixels += pcontribution; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { //DEBUG_TRACE(" rgba (%.2f %.2f %.2f %.2f) spixels %.2f\n", red, green, blue, alpha, spixels); spixels = 1 / spixels; red *= spixels; green *= spixels; blue *= spixels; if (im->has_alpha) alpha *= spixels; } /* Clamping to allow for rounding errors above */ if (red > 255.0) red = 255.0; if (green > 255.0) green = 255.0; if (blue > 255.0) blue = 255.0; if (im->has_alpha && alpha > 255.0) alpha = 255.0; /* DEBUG_TRACE(" -> %d, %d %x (%d %d %d %d)\n", x, y, COL_FULL((int)red, (int)green, (int)blue, (int)alpha), (int)red, (int)green, (int)blue, (int)alpha); */ if (im->orientation != ORIENTATION_NORMAL) { int ox, oy; // new destination pixel coordinates after rotating image_get_rotated_coords(im, x, y, &ox, &oy); if (im->orientation >= 5) { // 90 and 270 rotations, width/height are swapped so we have to use alternate put_pix method put_pix_rotated( im, ox, oy, im->target_height, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } else { put_pix( im, ox, oy, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } } else { put_pix( im, x, y, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } } } }
void gdImageCopyResampled (uint8_t *dst, uint8_t *src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) { int x, y; double sy1, sy2, sx1, sx2; for (y = dstY; (y < dstY + dstH); y++) { sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH; sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH; for (x = dstX; (x < dstX + dstW); x++) { double sx, sy; double spixels = 0; double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; sx1 = ((double) x - (double) dstX) * (double) srcW / dstW; sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW; sy = sy1; do { double yportion; if (floor2 (sy) == floor2 (sy1)) { yportion = 1.0 - (sy - (double)floor2 (sy)); if (yportion > sy2 - sy1) { yportion = sy2 - sy1; } sy = (double)floor2 (sy); } else if (sy == floor2 (sy2)) { yportion = sy2 - (double)floor2 (sy2); } else { yportion = 1.0; } sx = sx1; do { double xportion; double pcontribution; int p; if (floor2 (sx) == floor2 (sx1)) { xportion = 1.0 - (sx - (double)floor2 (sx)); if (xportion > sx2 - sx1) { xportion = sx2 - sx1; } sx = (double)floor2 (sx); } else if (sx == floor2 (sx2)) { xportion = sx2 - (double)floor2 (sx2); } else { xportion = 1.0; } pcontribution = xportion * yportion; /* 2.08: previously srcX and srcY were ignored. Andrew Pattison */ p = gdImageGetTrueColorPixel (src, (int) sx + srcX, (int) sy + srcY, srcW); red += gdTrueColorGetRed (p) * pcontribution; green += gdTrueColorGetGreen (p) * pcontribution; blue += gdTrueColorGetBlue (p) * pcontribution; alpha += gdTrueColorGetAlpha (p) * pcontribution; spixels += xportion * yportion; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { red /= spixels; green /= spixels; blue /= spixels; alpha /= spixels; } /* Clamping to allow for rounding errors above */ if (red > 255.0) { red = 255.0; } if (green > 255.0) { green = 255.0; } if (blue > 255.0) { blue = 255.0; } if (alpha > gdAlphaMax) { alpha = gdAlphaMax; } gdImageSetPixel (dst, x, y, gdTrueColorAlpha ((int) red, (int) green, (int) blue, (int) alpha), dstW); } } }
/** * 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 }
/** * 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; }
/** * 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; }
/** * * 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 }