A briefe overview of the affine mode on the VB:
The affine entry is processed through the folowing algorithem to generate the
display. Note that the GX/GY parameters are used from the world table but not
the MX/MY parameters
d_y = max_y
do {
getAffine(d_y)
d_x = max_x
do {
src_x = x_skew_y + ((d_x (+/-)paralax) * x_scale)
src_y = y_scale_y + ((d_x (+/-)paralax) * y_skew)
getpixel(src_x,src_y)
putpixel(d_x+GX (+/-)GP, d_y+GY)
} while(d_x--)
} while(d_y--)
*** How is paralax used?
The math involved is simple Afine code as seen in the GBA and such. Check out
this site for some good examples of GBA affine programming:
http://user.chem.tue.nl/jakvijn/tonc/affine.htm
=============================
Here is the equasion to map from screen coordinates back into the source bitmap.
[x',y'] = [x,y]|pa,pb|
|pc,pd|
= [x*pa+y*pc, x*pb+y*pd]
or rewriten
x' = y*pc+x*pa
y' = y*pd+x*pb
where:
x' = source pixle in the horizontal direction
y' = source pixle in the vertical direction
x = destination pixle in the horizontal direction
y = destination pixle in the vertical direction
pa = horizontal (x) scale
pb = vertical (y) skew
pc = horizontal (x) skew
pd = vertical (y) scale
=============================
In the VB's implementation of affine mode, y is precomputed into the x_skew_y and
y_scale_y parameters, as a time saver. This works because there is one affine entry
for every line in the y direction.
we can translate these into affine parameters:
x_scale = pa
y_skew = pb
x_skew_y = y*pc + bitmap_x_offset
y_scale_y = y*pd + bitmap_y_offset
leaving us with the following equastions:
x' = x_skew_y + x*x_scale
y' = y_scale_y + x*y_skew
=============================
We can perform simple rotation by using the following matrix:
[x', y'] = [x,y]| cos(a), sin(a)|
|-sin(a), cos(a)|
x' = x*cos(a)-y*sin(a)
y' = x*sin(a)+y*cos(a)
or in affine parameters
x_skew_y = -y*sin(a')
y_scale_y = y*cos(a')
x_scale = cos(a')
y_skew = sin(a')
where a' is the angle of rotation
=============================
There is one affine entry per scanline, note that x_skew and y_scale have 12
bits for the whole number and 3 bits for the fractional part. This is because
they must hold both the skew and offset parameters together. While the x_scale
and y_skew only have 6 bits for the whole number and 9 bits for the fractional
part, since they dont store the offset info.
affine {
x_skew_y /= 8.0
paralax
y_scale_y /= 8.0
x_scale /=512.0
y_skew /=512.0
unknown_1
unknown_2
unknown_3
}
affine img_affine[max_y];