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.

C/C++ > problems with rotating sprites

#6719 - [squire] - Mon Jun 02, 2003 7:11 am

could someone out there please tell me what i'm doing wrong?
boomarang, is a 16x16 pixel sprite, in 16 colours.
as soon as i set either the roation bit or double size bit, the sprite will not
be displayed, it shows up fine if neither of those 2 bits are set.
any ideas anyone?
thanks, [squire]

Code:

#include <math.h>
#include "headers\gba.h"
#include "headers\screenmode.h"
#include "headers\sprite.h"
#include "boomarang.c"

#define RADIAN(n) (((float)n)/(float)180*PI)
FIXED angle,zoom;
FIXED SIN[360],COS[360];

OAMEntry sprites[128];
u16 x,y,z;
u16 n,m,i;
s16 BoomarangX,BoomarangY;

void CopyOAM() {
   u16* temp;
   temp=(u16*)sprites;
   for(i=0;i<128*4;i++) OAMmem[i]=temp[i];
}

void InitializeSprites() {
   for(i=0;i<128;i++) {
      sprites[i].attribute0 = 160;
      sprites[i].attribute1 = 240;
   }
}

void WaitForVsync() {
   while((volatile u16)REG_VCOUNT == 160){}
   while((volatile u16)REG_VCOUNT != 160){}
}

void RotateSprite(int rotDataIndex, int angle, FIXED x_scale,FIXED y_scale) {
   FIXED pa,pb,pc,pd;

   pa = ((x_scale) * COS[angle])>>8;    //(do my fixed point multiplies and shift back down)
   pb = ((y_scale) * SIN[angle])>>8;
   pc = ((x_scale) * -SIN[angle])>>8;
   pd = ((y_scale) * COS[angle])>>8;

   rotData[rotDataIndex].pa = pa;  //put them in my data struct
   rotData[rotDataIndex].pb = pb;
   rotData[rotDataIndex].pc = pc;
   rotData[rotDataIndex].pd = pd;
}

int main() {
   //compute my Look up tables
   for(i=0;i<360;i++) {
      SIN[i]=(FIXED)(sin(RADIAN(i))*256);  //sin and cos are computed and cast to fixed                     //fixed
      COS[i]=(FIXED)(cos(RADIAN(i))*256);
   }

   SetMode(MODE_2|OBJ_ENABLE|OBJ_MAP_1D);

   for(i=0;i!=16;i++) OBJPaletteMem[i+16]=boomarang_Palette[i];

   InitializeSprites();
   BoomarangX=64;BoomarangY=64;
   for(i=0;i<(16*16/4);i++) {
      OAMdata[i+2560]=boomarang_Char[(i<<1)+1];
      OAMdata[i+2560]=(OAMdata[i+2560]<<8)+boomarang_Char[(i<<1)];
   }

   while(1) {
      if(BoomarangX<0) x=512+BoomarangX;
      else x=BoomarangX;
      if(BoomarangY<0) y=256+BoomarangY;
      else y=BoomarangY;
      RotateSprite(0,180,1,1);
      sprites[ 0].attribute0 = COLOR_16|SQUARE|SIZE_DOUBLE|ROTATION_FLAG|y;
      sprites[ 0].attribute1 = SIZE_16|ROTDATA(0)|x;
      sprites[ 0].attribute2 = PALETTE(1)|160;

      WaitForVsync();
      CopyOAM();
   }
}

#6740 - syscan - Mon Jun 02, 2003 2:25 pm

in CopyOAM() func, OAMmem is u32 defined in gba.h

"define OAM ((u16*)0x7000000)" instead of OAMmem

#6753 - [squire] - Mon Jun 02, 2003 3:39 pm

i don't think that's the problem.
as OAMmem is defined in gba.h as
Code:
#define OAMmem       ((u16*)0x7000000)

and i don't see why i would have to define the memory address twice.
the thing is, the sprite shows fine, if i don't set either the rotation bit or the
double size bit.
i'm now thinking it may be something to do with it being a 16 colour sprite.

[squire]

#6758 - Touchstone - Mon Jun 02, 2003 4:09 pm

What happen if you set the rotation registers to "1:1" mapping? In other words:
PA = 0x0100
PB = 0
PC = 0
PD = 0x0100

Are you sure rotData points to the right place?
_________________
You can't beat our meat

#6762 - [squire] - Mon Jun 02, 2003 4:50 pm

okay i've got it fixed,
my problem was the stupid overlooking of the fact the zoom scaling factor
is a fixed number and not a float.
so where i call.
Code:

      RotateSprite(0,180,1,1);

i should have called it as
Code:

      RotateSprite(0,180,1<<8,1<<8);


i'm such a dumbass.