#131730 - gyokimae - Tue Jun 19, 2007 3:03 pm
Hi,
.. The subject says it all,
In the BG_Rotation demo, etc, I see macros like,
s16 s = SIN[angle & 0x1FF] >> 4;
The best I could understand from information gathered is that this macro is refering to a look up table of 512 steps which is perhaps part of the libnds (opposed to standard C functions).
Where can I find resources on
* Type of value returned from this macro (s16 for sure... any obscure rules like fixed point?)
* Usage of 0x1FF (which I am assuming is some sort of mask).
* Significance of the 4 bit bit-shifting.
I grepped through header files in libnds but found no answer.
Straight answers or even pointers to documents are highly appreciated.
Thanks.
#131738 - Lick - Tue Jun 19, 2007 4:42 pm
I think it's 12.4 fixed point. As you said the total number of bits equals 16 and the example shifts 4 to the right. The only logical reason for this shift would be to get the whole values (discarding the 4 bits).
Logical-AND-ing with a power-of-two-minus-one, is the same as modulus the power-of-two. It should be faster though.
(11 % 4 == 11 & 3)
Like I said, the 4-bit shifting is to get the "whole" value from the fixed point.
Let's say the fixed point stored "2,5" then you shift away the 4 bits you'd get "2".
_________________
http://licklick.wordpress.com
#131739 - knight0fdragon - Tue Jun 19, 2007 4:44 pm
the look up table is in 4.12 fixed point
the BG registers are in 8.8 fixed point
so what you need to do is shift the returned value of 4 over so that it becomes an 8.8 fixed point number
0x1FF is a mask, because we never want the angle to go above 511 degrees
in libnds trig LUT, one rotation is from 0 to 511
which means 512 will get us back to 0
same concept as 0-359 degrees
_________________
http://www.myspace.com/knight0fdragonds
MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206
#131740 - knight0fdragon - Tue Jun 19, 2007 4:45 pm
haha you beat me to a response lick, that was funny
_________________
http://www.myspace.com/knight0fdragonds
MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206
#131741 - gyokimae - Tue Jun 19, 2007 5:23 pm
Thanks for the valuable information.
I really find you mates incurreging for a newbie like me.
You mind if I ask how you discover all this?
Is the function documented somewhere or is the only option currently available to dive in to source code of the library?
#131742 - gyokimae - Tue Jun 19, 2007 5:33 pm
oh, wait a minute,
that is two different theories.
12.4 >> 4 -> get real number
4.12 >> 4 -> convert to 8.8
oh well, I guess I can find out for myself.
Helpful info though. Especially the concept with the modulus.
#131748 - Lick - Tue Jun 19, 2007 6:20 pm
knight0fdragon was right, it's 4.12. I confused the goal to be 'getting the whole values' instead of 'getting a 8.8 value'.
It makes much more sense though, 4.12 allows much smaller steps than 12.4. Hehe.
_________________
http://licklick.wordpress.com
#131759 - kusma - Tue Jun 19, 2007 8:48 pm
is it just me, or is it plain stupid to have 4 bits of integer range for a sine-table?
#131760 - wintermute - Tue Jun 19, 2007 9:03 pm
kusma wrote: |
is it just me, or is it plain stupid to have 4 bits of integer range for a sine-table? |
The purpose is to match up with the 4.12 format for vectors. Whether that was a good idea or not I can't say, you're the first person to mention it and it was inherited from the former ndslib.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#131780 - tepples - Wed Jun 20, 2007 1:45 am
I'd suggest using 2.14 for a 257-entry table, then doing linear interpolation.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#131785 - DekuTree64 - Wed Jun 20, 2007 2:27 am
tepples wrote: |
I'd suggest using 2.14 for a 257-entry table, then doing linear interpolation. |
Maybe store the table as 2.14, and interpolate to 2.30? I like to keep as few fixed-point formats in circulation as possible, so .12 for general use and .30 for things that are always between -1 and 1 seems like a pretty good setup.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#131806 - wintermute - Wed Jun 20, 2007 8:40 am
I'd suggest submitting a patch for consideration.
Such a patch should also update examples where necessary.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#131809 - kusma - Wed Jun 20, 2007 10:57 am
DekuTree64 wrote: |
tepples wrote: | I'd suggest using 2.14 for a 257-entry table, then doing linear interpolation. |
Maybe store the table as 2.14, and interpolate to 2.30? I like to keep as few fixed-point formats in circulation as possible, so .12 for general use and .30 for things that are always between -1 and 1 seems like a pretty good setup. |
since the sign-bit is implicit in the lut index (top bit: sin(x) = -sin(x - pi), and the range for our lut is 0..2pi), we can get away without storing it. Also, there's a symmetry around the top and bottom of the sine-wave that can be exploited simply, just by picking some bits.
Here's some code to do just that. Note that the macro SIN_TABLE_LOG2_SIZE and SIN_TABLE_SIZE are the sizes of the "virtual" sine-table, that is, before the symmetry exploitations i mentioned above.
Code: |
#define SIN_TABLE_LOG2_SIZE 9
#define SIN_TABLE_SIZE (1 << SIN_TABLE_LOG2_SIZE)
extern const unsigned short sin_lut[(SIN_TABLE_SIZE / 4) + 1];
inline int sin_lookup(int i)
{
int idx = i & ((SIN_TABLE_SIZE >> 2) - 1);
switch ((i >> (SIN_TABLE_LOG2_SIZE - 2)) & 0x3)
{
case 0: return +int(sin_lut[idx]);
case 1: return +int(sin_lut[(SIN_TABLE_SIZE / 4) - idx]);
case 2: return -int(sin_lut[idx]);
case 3: return -int(sin_lut[(SIN_TABLE_SIZE / 4) - idx]);
}
}
inline int cos_lookup(int i)
{
return sin_lookup(i + (SIN_TABLE_SIZE / 4));
}
|
Interpolation could be done on top of this. I'm using 0:16 fixed point myself. Yes, I know, the biggest value in the LUT (1.0) must then be clamped to some almost zero value. What can be done to defeat coordinate systems to implode, is to map 0..1 to 0..65535 (instead of 65536), and do to "renormalize" it to 0..65536 after interpolation.
#132580 - NeX - Wed Jun 27, 2007 10:46 pm
I would like to know how the extended rotation bg registers work.... I am trying to place a 128x128 bg in the middle of the subscreen and rotate it. But, due to a lack of documentation, I really don't know what I'm doing, and although sometimes I get close, the bg is pretty much always off centre. And if it's rotating around the centre properly, it's in the wrong place. I could use a 256x256 image, but that would be a waste of memory.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.
#132583 - NeX - Wed Jun 27, 2007 11:00 pm
Looking at it, the BG ROTATION example isn't quite on centre either.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.
#132585 - Lick - Wed Jun 27, 2007 11:13 pm