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++ > Just Another Stupid Question(TM)

#264 - Japster - Sun Jan 05, 2003 6:51 pm

Ok, this code is (almost) straigth copy from GBA Junkie's tutorial and it doesn't work.
signed long pa,pb,pc,pd;
pa = COS[45]>>8;
pb = SIN[45]>>8;
pc = -SIN[45]>>8;
pd = COS[45]>>8;


This is what GCC says:
invalid operands of types `const double'
and `int' to binary `operator>>'

Should I use another compiler(Im using GCC)?

Jasper (If I keep asking you these stupid questions you have soon wrote 98% of my code...)

#265 - Touchstone - Sun Jan 05, 2003 7:09 pm

It looks like your arrays COS and SIN are made up of floats (doubles) instead of integers and the >> operator only works on integers as opposed to floats. Build yourself new arrays of integers instead of floats, that will save you memory and speed performance. Ok, it's not necessarely more memory efficient but if you want to you can just store one quarter of SIN and then calculate all angles of SIN and COS from there.

#276 - Costis - Sun Jan 05, 2003 8:54 pm

Hi,

I don't know what fixed point ratio your program is supposed to use, but it looks like you may be using 16:16 or 8:16. Anyway, here's some code to create the COS and SIN arrays for a 16:16 fixed point ratio:

Code:

...

// PI definition. You can add more digits for better accuracy if you like
#define PI                3.14159

// COS and SIN fixed point arrays
unsigned long COS[360], SIN[360];

void AGBMain (void)
{
   int i;
   ...

   // Fill the SIN and COS arrays with the correct sin and cos values in fixed point
   for (i = 0; i < 360; i++)
   {
         SIN[i] = sin(i * PI / 180) * 65536;
         COS[i] = cos(i * PI / 180) * 65536;
   }
   ...
}

...


I haven't test this code out, but it should work without any problems.

Costis

#6911 - joris-fr - Wed Jun 04, 2003 2:20 pm

Costis,

when the COS & SIN arrays are filled with fixed point value,
how do I use those arrays' values ?

(I don't mean how to access them).

For an example,
if I use those statements

Code:

int x = 120 + (COS[i] >> 16) * 50;
int y = 80 + (SIN[i] >> 16) * 50;



the values returned aren't what I expected.

I managed to realize a radar using float numbers, but now I want to try using Fixed Point.
_________________
Joris

#6919 - Torlus - Wed Jun 04, 2003 3:49 pm

Two things :

- about Costis' code, SIN & COS should'nt be declared unsigned, but signed.
- about your code, if you shift SIN or COS values by 16 before multiplying you'll "always" get 0.

So you should try :

Code:

x = 120 + ( (COS[i]*50) >> 16 );
y = 80 + ( (SIN[i]*50) >> 16 );


Some other tricks :
- Instead of having a 360 entries table, why not consider having a 256 entries table ? Then you could use bit masking to make out-of-bounds angle values fit in your table range. (Angle &= 0xFF).
- Instead of having 2 tables, one for sin and one for cos, you can make a (in your case, 360+90) entries SIN table, and then have COS declared as :
Code:

long *COS = SIN + 90;


or if you use a 256 entries table and don't want to waste memory, just declare a SIN table and do :
Code:

#declare COS(a) SIN[ ((a)+64) & 0xFF ]


Hope this helps
_________________
GBA,GC,NGPC,GP32,FPGA,DS stuff at http://torlus.com/


Last edited by Torlus on Wed Jun 04, 2003 4:10 pm; edited 1 time in total

#6925 - Touchstone - Wed Jun 04, 2003 4:10 pm

Torlus wrote:
long *COS = SIN + 90;

Nah, COS[255] will be way of.

And if you want to save memory you can easily do a table with just one quarter of a circle and have functions to access the table (to calculate actual offset in table)
_________________
You can't beat our meat

#6926 - Torlus - Wed Jun 04, 2003 4:14 pm

I meant SIN + 90 for a 360 entries table. For a 256 entries table it would be SIN + 64.
But I'm guilty, as I edited my previous post many times :)
_________________
GBA,GC,NGPC,GP32,FPGA,DS stuff at http://torlus.com/

#6943 - joris-fr - Wed Jun 04, 2003 10:23 pm

Torlus wrote:
Two things :

- about Costis' code, SIN & COS should'nt be declared unsigned, but signed.
- about your code, if you shift SIN or COS values by 16 before multiplying you'll "always" get 0.

So you should try :

Code:

x = 120 + ( (COS[i]*50) >> 16 );
y = 80 + ( (SIN[i]*50) >> 16 );


Some other tricks :
- Instead of having a 360 entries table, why not consider having a 256 entries table ? Then you could use bit masking to make out-of-bounds angle values fit in your table range. (Angle &= 0xFF).
- Instead of having 2 tables, one for sin and one for cos, you can make a (in your case, 360+90) entries SIN table, and then have COS declared as :
Code:

long *COS = SIN + 90;


or if you use a 256 entries table and don't want to waste memory, just declare a SIN table and do :
Code:

#declare COS(a) SIN[ ((a)+64) & 0xFF ]


Hope this helps


Ouais !!!

Now I understand why it didn't work. When I think of it, I am disapointed not to resolve it myself !!!

Maintenant, pour le reste :
Vu que je suis pas top en maths, les optimisations dont tu me parles me passent un peu au dessus de la t?te, il va falloir que j'?tudie ?a de plus pr?s.

Demain j'aurais le temps de mettre tout ?a en oeuvre.

Merci beaucoup Torlus.

...et en passant, vraiment bien ton moteur 3D :-)
_________________
Joris

#7014 - mpowell - Fri Jun 06, 2003 6:52 am

If you create a SIN table on the fly in Main, it will be stored in RAM as opposed to having a table already filled out in a .c or .h file and having the constant table compiled into ROM with the code.

Does anyone know if pulling look up entries from ROM is much slower than pulling them from RAM? I know that the RAM memory is faster on the GBA than ROM but has anyone done any tests comparing the speeds from RAM, ROM, and calling the original SIN function? Is it worth while using the precious RAM for a table that could sit in ROM with code?

#7018 - Quirky - Fri Jun 06, 2003 8:11 am

If the table is in iwram it will be the fastest. If it's in ewram it will be either as fast as rom or slightly slower (but not faster than rom) it depends on if you have rom prefetch disabled or not. Basically, reading from rom is not as big a speed hit as you might imagine, in fact it's damn fast :)