Example #1
0
void date_update()
{
    int32_t monthTicks = gDateMonthTicks + 4;
    if (monthTicks >= 0x10000)
    {
        gDateMonthTicks = 0;
        gDateMonthsElapsed++;
    }
    else
    {
        gDateMonthTicks = floor2((uint16_t)monthTicks, 4);
    }
}
Example #2
0
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;
}
Example #3
0
File: img.c Project: kwolekr/imgcmp
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));
		}
	}
}
Example #4
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))
        );
      }
    }
	}
}
Example #5
0
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);
        }
    }
}
Example #6
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
}
Example #7
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;
}
Example #8
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;
}
Example #9
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
}