gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > How to shrink sprites?

#144254 - felix123 - Tue Oct 30, 2007 10:40 pm

I'm having a problem with scaling. I want to shrink something at a constant rate from double size to half size in one second, and assuming a framerate of 60fps, I worked out the following code:
Code:

function spriteScale(u8 spriteindex, u16 scale) {
    // modify OAM
}

// ...

int main() {

    // ...

    u8 x=1;
    spriteScale(0, 128);

    while (true) {

        // ...

        spritescale(0, (u16)pow(2,7+(x/30));
        x++;

        swiWaitForVblank();
    }

    return 0;
}

However, math.h doesn't seem to be supported, and with no floating point hardware, I assume this would be too time-consuming. Is there a better way to do this?
_________________
Nintendo DS homebrew on Wikipedia

#144257 - Lick - Tue Oct 30, 2007 10:45 pm

Try fixed-point arithmetic, and try to find a pow() implementation for fixed-point numbers.
_________________
http://licklick.wordpress.com

#144267 - knight0fdragon - Wed Oct 31, 2007 12:18 am

shifting bits left or right raises and lowers the values by the power of 2

so
(1 << 0) = 2^0
(1 << 1) = 2^1
(1 << 2) = 2^2

so just replace (u16)pow(2,7+(x/30)); with (u16)(1 << (7 + (x / 30)));

These work for integer based values btw
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#144274 - tepples - Wed Oct 31, 2007 1:55 am

knight0fdragon wrote:
shifting bits left or right raises and lowers the values by the power of 2

so
(1 << 0) = 2^0
(1 << 1) = 2^1
(1 << 2) = 2^2

But do the bitwise shift operators treat a fractional shift amount as an exponent in the way that one would expect? I'm pretty sure they don't in standard C (don't have a copy of the standard handy to check though), and I don't know of any compiler that provides it as an extension.

Quote:
so just replace (u16)pow(2,7+(x/30)); with (u16)(1 << (7 + (x / 30)));

If x is an integer, the division will be truncated to an integer. If << doesn't support fractional shift amounts, the quantity (7.0 + x / 30.0) will be truncated to an integer. In either case, the result won't be smooth; it'll jump from double directly to single and half size. Try this linear interpolation code (untested but should show you how I'd do it):
Code:
#define N_LERP_STEPS 16  // linear interpolated steps per keyframe
#define LEN(array) (sizeof(array)/sizeof(array[0]))

// 128 is double size; 256 is full size; 512 is half size
const int scalingKeyframes[7] = {128, 161, 203, 256, 322, 406, 512};

void scalingAnimation() {
  for (int keyframe = 0; keyframe < LEN(scalingKeyframes) - 1; ++keyframe) {
    int thisKfValue = scalingKeyframes[keyframe];
    int nextKfValue = scalingKeyframes[keyframe + 1];

    for (int lerpStep = 1; lerpStep <= N_LERP_STEPS; ++lerpStep) {
      int thisFrameValue = thisKfValue + (nextKfValue - thisKfValue) * lerpStep / N_LERP_STEPS;
      setSpriteScaleFactorTo(thisFrameValue);
      vsync();
    }
  }
}

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#144276 - Yota_VGA - Wed Oct 31, 2007 2:05 am

tepples wrote:
But do the bitwise shift operators treat a fractional shift amount as an exponent in the way that one would expect? I'm pretty sure they don't in standard C (don't have a copy of the standard handy to check though), and I don't know of any compiler that provides it as an extension.


This can't be made fast, and the shift operator isn't made for the multiplication and division, but only for the shift. Multiplication and division are only an application of this operator.
It isn't C89 neiter C99, surely, and I doubt that a man can have interest to have an operation that do exactly a division between floating values with a strange syntax :)

#144286 - knight0fdragon - Wed Oct 31, 2007 3:57 am

well that is why I said it was integer based
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#144290 - felix123 - Wed Oct 31, 2007 5:00 am

Thanks, got it working.
_________________
Nintendo DS homebrew on Wikipedia