Alchemy
Loading...
Searching...
No Matches

render.c

Go to the documentation of this file.
1/// @file
2/// The frame's sprite lists: affine matrices, depth slots and the OAM build.
3/// Part of runtime.c, the runtime object, compiled only through it.
4
6
7extern u8 IwramClearWords[];
8
9/// Starts a new frame of sprites: frees the affine matrices and empties the
10/// 256 depth slots sprites are linked into. Called by WaitFrames after each
11/// VBlank.
16}
17
18typedef void (*OamBuildRoutine)(void *work);
19
21
22/// Hands out the next OAM affine matrix for a sprite drawn with `source`'s
23/// scale and rotation and fills it in. Called by the field sprites and the
24/// windows' scaled sprites. Returns the matrix number, 0 to 31. When all 32
25/// are taken it fills nothing and still returns 0, which a caller cannot tell
26/// from matrix 0: the sprite is drawn with whatever matrix 0 holds.
28 union AffineMatrix *matrix;
29 s16 *coefficient;
30 s32 xScale;
31 s32 yScale;
32 s32 angle;
33 u8 index;
34
35 index = gObjAffineCount;
36 xScale = (s16)source->scaleX;
37 yScale = (s16)source->scaleY;
38 angle = source->angle;
39 if (index >= OBJ_AFFINE_MATRIX_COUNT)
40 return 0;
41
42 matrix = &gObjAffineMatrices[index];
43 coefficient = matrix->coefficients;
44 if ((xScale == yScale || -xScale == yScale) && angle == 0) {
45 // Unrotated and evenly scaled (or mirrored): only the diagonal is set
46 s32 reciprocal;
47 s32 xReciprocal;
48
49 reciprocal = Iwram_SignedDivide(0x10000, yScale);
50 xReciprocal = reciprocal;
51 if (-xScale == yScale)
52 xReciprocal = -reciprocal;
53
54 matrix->rows[0] = (u16)xReciprocal;
55 matrix->rows[1] = (u32)reciprocal << 16;
56 } else {
57 // The inverse of rotate-then-scale
58 s32 sine;
59 s32 cosine;
60
61 sine = Trig_Sin(angle);
62 cosine = Trig_Cos(angle);
63 *coefficient = cosine / xScale;
64 coefficient++;
65 *coefficient = sine / xScale;
66 coefficient++;
67 *coefficient = (-sine) / yScale;
68 coefficient++;
69 *coefficient = cosine / yScale;
70 }
71
72 gObjAffineCount = index + 1;
73 return index;
74}
75
76/// Links a sprite entry into depth slot `slot` (clamped to 0..255) for this
77/// frame. The entry's first word becomes its link to the next entry. Called
78/// by everything that draws a sprite, before WaitFrames builds the OAM list.
79void Runtime_PushSlotEntry(void *slotEntry, s32 slot) {
80 void **head;
81 void *previousHead;
82
83 if (slot >= RENDER_DEPTH_SLOT_COUNT)
84 slot = RENDER_DEPTH_SLOT_COUNT - 1;
85 if (slot < 0)
86 slot = 0;
87 head = &gRenderSlotHeads[slot];
88 previousHead = *head;
89 *head = slotEntry;
90 *(void **)slotEntry = previousHead;
91}
92
93/// Builds this frame's OAM list in `work` from the sprites linked into the
94/// depth slots, with a RAM copy of the ARM builder. Called by WaitFrames into
95/// the frame scratch heap slot.
96void Render_BuildOamList(void *work) {
97 OamBuildRoutine routine;
98
100 routine(work);
101 MemFree((void *)routine);
102}
union AffineMatrix gObjAffineMatrices[]
u8 gObjAffineCount
The matrices handed out this frame (up to 32), copied into OAM with the sprites.
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
void * gRenderSlotHeads[]
static s32 Iwram_SignedDivide(s32 dividend, s32 divisor)
Definition iwram_call.h:73
void MemFree(void *buffer)
#define RamCode_Load(to, code, bytes)
Allocates a heap copy; release it with MemFree when finished.
Definition ramcode.h:15
@ OBJ_AFFINE_MATRIX_COUNT
Definition render.c:20
@ RENDER_DEPTH_SLOT_COUNT
Definition render.c:20
void Render_ResetFrame(void)
Starts a new frame of sprites: frees the affine matrices and empties the 256 depth slots sprites are ...
Definition render.c:12
s32 AffineMatrix_BuildForEffect(struct AffineTransform *source)
Hands out the next OAM affine matrix for a sprite drawn with source's scale and rotation and fills it...
Definition render.c:27
void Runtime_PushSlotEntry(void *slotEntry, s32 slot)
Links a sprite entry into depth slot slot (clamped to 0..255) for this frame.
Definition render.c:79
void(*) OamBuildRoutine(void *work)
Definition render.c:18
void Render_BuildOamList(void *work)
Builds this frame's OAM list in work from the sprites linked into the depth slots,...
Definition render.c:96
u8 IwramClearWords[]
What every part of the runtime object shares: its includes and the library call two parts make.
s32 _call_via_r3(s32, s32, s32, s32)
A sprite's rotation and scale: scales in 8.8 fixed point (0x100 is full size), the angle in 1/65536 t...
Definition affine.h:13
u16 angle
1/65536 turns
Definition affine.h:16
u16 scaleY
8.8 fixed point, read signed
Definition affine.h:15
u16 scaleX
8.8 fixed point, read signed: negative mirrors the sprite
Definition affine.h:14
u8 LoadedRuntime_Size[]
const u8 Render_BuildOamListKernel[]
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
One OAM rotation-scaling matrix: pa, pb, pc and pd in 8.8 fixed point, the inverse of the transform t...
Definition affine.h:22
s16 coefficients[4]
pa, pb, pc and pd
Definition affine.h:23
u32 rows[2]
pa and pb, then pc and pd, written whole when only the diagonal is set.
Definition affine.h:25