So, as the title suggests I've been messing with GBA dev. and so far, I have a decent grasp of operating in the bitmap modes, so I've moved onto tile modes. I can work with the text backgrounds, and work with the rotational backgrounds up until the point of actually rotating. My attempt at it (following instruction in the "Programming the Gameboy Advance" PDF book thingy) just causes distortion of the image. Essentially, I was hoping someone could explain to me the registers used on the map rotation - REG_BG2X REG_BG2Y REG_BG2PA REG_BG2PB REG_BG2PC REG_BG2PD And then, if possible, give me an idea of the maths used in such rotations. My code already uses a lookup table for sin/cosine values. Thanks in advance! I can provide code if needed.
was browsing thru here and caught this, so a bit of a late response. i'm planning on helping a friend of mine learn to program on the gba so i'd appreciate it if you let me know if my explanation here coherent/adequate. now i'm gonna throw a lot of info at you for a moment, i don't know how much you know about these things already so i'll try and start from the ground up. first, if you don't already have Martin Korth's gbatek document, grab it here , lots of good stuff in there, pretty much all you need to know about the gba's hardware. he describes all the io registers in detail so you can look through that to see how each component pa, pb, pc, and pd will affect what's displayed about pa,pc,pc,pd; although these can be used to achieve a bunch of crazy effects, for rotation you should think of them as the coefficients of a rotation matrix, arranged like this: [ pa pb ] [ pc pd ] which for a rotation by A degrees should be set to: [ cosA -sinA ] [ sinA cosA ] if this is your first time using a rotation matrix, let me explain to you what they're good for by using a rotation matrix we can pick any point about the origin, and rotate that point by R degrees, just by using it's original location more specifically... say that you have a point at x0,y0, the length of the vector from the origin to this point will be L, and you want to rotate it R degrees to get to x1,y1. our goal is to formulate an equation that will allow us to do this by using only x0,y0 and the angle of rotation R to get x1,y1 say that the angle between x0,y0 and the x axis is A say that the angle between x1,y1 and the x axis is B known variables: x0, y0, R unknowns: L, A, B unknown and need to find: x1, y1 that said you can derive the following info B-A = R, the rotation amount, rearranging this we get.. B = R+A L*cosA = x0 L*sinA = y0 L*cosB = x1 L*sinB = y1 substitute R+A for B x1 = L*cos(R+A) y1 = L*sin(R+A) using the angle sum trig identity we can expand the R+A in the sin/cos to x1 = L*(cosR*cosA - sinR*sinA) y1 = L*(sinR*cosA + cosR*sinA) distribute L and substitute x0 and y0 where possible and you're left with x1 = x0*cosR - y0*sinR y1 = x0*sinR + y0*cosR in matrix form this would be [ cosR -sinR ] * [ x0 ] [ sinR cosR ] [ y0 ] and we're done, multiply the matrix against the vector x0,y0 and you'll be left with a vector pointing to x1,y1 so if you want to rotate the screen by R degrees, all you have to do is calculate the rotation matrix for R and store each entry in its corresponding io register. by doing so the screen will be rotated over the bkg, about the screens upper left corner, ie screen point 0,0 on the screen, by R degrees. notice where i said the screen will be rotated over the bkg, i'm not sure if this is technically correct but i find it's easiest to visualize the rotation this way. for example, if you took a piece of paper, placed it over your desk, and held it at its upper left corner (screen point 0,0) while you rotate it about that point, the paper would be the screen, and the desk would be the bkg, completely stationary. the x and y reference point registers let us set the location of screen point 0,0 over the bkg. going back to the piece of paper example, increasing the x value here would be the same as moving the paper directly to the right over your desk, no matter what orientation the screen is currently at. if you wanted to rotate the screen about some point on the bkg, you could do the following (all the following values are vectors with an x and y component, hence prefixed with v): vrpoint = the point to rotate the screen about on the bkg vpos = position of the center of the screen about vrpoint (vrpoint will be the origin for this vector) vhscreen = vector pointing from the center of the screen to screen point 0,0 in screen space, so on the gba this is a constant vector of (0-(240/2),0-(160/2)) = (-120,-80) dorient = degree of rotation for the screen 1. calculate rotation matrix using dorient and set the pa,pb,pc,pd variables 2. add vpos+vhscreen to get v0 3. rotate v0 by the same amount of degrees as the screen, to do this multiply the rotation matrix calculated in step 1 with v0 to get v1 4. adding v1 and vrpoint will give you the new x, y reference points to set in io mem this will create the effect of the bkg rotating around a single point, specifically vrpoint. when vpos is (0,0) the screen's center will be directly over vrpoint. by adjusting vpos x and y components you'll be able to pan over the bkg while it's still rotating about vrpoint. that's pretty much all you need to know, here's a small demo i put together which demonstrates what i wrote out above, you can grab it from here (i uploaded it to sendmefile so you can't just right click save as on the link, the zip file includes an assembled binary and its .s thumb source file). in the demo i did the above steps manually (sans generating the rotation matrix, which i used bios routine 0x0f, objaffineset) so you could get an idea of the math behind it. but by using using bios call 0x0e, bgaffineset, you can save yourself some work as it will generate the rotation matrix and the x and y reference points specifically for the bkg using mostly the same variables used in the above steps.
Thanks for the reply But I had already figured it out with some help from the TONK tutorials! Plus, as I was using c, my macros for pa,pb,pc,pd was the wrong type (doh!). Thanks anyway though And yeah, your tutorial makes sense to me. Though it seems like it'd work better explained in person rather than as a written tutorial (the style is more dictation than tutorial).