Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
layer.c
Go to the documentation of this file.
1#include "engine/game.h"
2#include <libgs.h>
3#include <libetc.h>
4#include <libsnd.h>
5
6/* The layer with id `id`, or NULL */
8 s32 i;
9
10 for (i = 0; i < LAYER_COUNT; i++) {
11 if (GFX.layers[i] != NULL && GFX.layerIds[i] == id) {
12 return GFX.layers[i];
13 }
14 }
15 return NULL;
16}
17
18/* The slot of the layer with this id; id 0 finds a free slot */
20 s32 i;
21
22 for (i = 0; i < LAYER_COUNT; i++) {
23 if (id != 0) {
24 if (GFX.layers[i] != NULL && GFX.layerIds[i] == id) {
25 return i;
26 }
27 } else if (GFX.layers[i] == NULL) {
28 return i;
29 }
30 }
31 return -1;
32}
33
34/* Closes the gap of a removed layer in the draw order */
35void removeLayerSlot(s32 index) {
36 for (; index < LAYER_COUNT - 1; index++) {
37 GFX.layers[index] = GFX.layers[index + 1];
38 GFX.layerIds[index] = GFX.layerIds[index + 1];
39 }
40}
41
42/* Puts a layer at position `index` of the draw order, moving the later ones back */
43void insertLayerSlot(s32 index, Layer *layer, s32 id) {
44 s32 i;
45
46 for (i = LAYER_COUNT - 1; i != index; i--) {
47 GFX.layers[i] = GFX.layers[i - 1];
48 GFX.layerIds[i] = GFX.layerIds[i - 1];
49 }
50 GFX.layers[index] = layer;
51 GFX.layerIds[index] = id;
52}
53
54/*
55 * A new layer drawing to `rect`, with an OT of OT_LENGTHS[otShift - 1] entries; NULL when all are
56 * in use
57 */
58Layer *createLayer(RECT *rect, s32 otShift, s32 id) {
59 DRAWENV env;
60 s32 index = findLayerSlot(0);
61
62 if (index != -1) {
63 SetDefDrawEnv(&env, rect->x, rect->y, rect->w, rect->h);
64 GFX.layerIds[index] = id;
65 return GFX.layers[index] = newLayer(&env, otShift);
66 }
67 return NULL;
68}
69
70/* Frees the layer with id `id`; 0 if there is none */
72 s32 index = findLayerSlot(id);
73 Layer *layer;
74
75 if (index != -1) {
76 layer = GFX.layers[index];
77 layer->free(layer);
78 HEAP.free(GFX.layers[index]);
79 removeLayerSlot(index);
80 return 1;
81 }
82 return 0;
83}
84
85/* Moves a layer to the position of another one (plus delta) in the draw order */
86void moveLayer(s32 id, s32 targetId, s32 delta) {
87 s32 from = findLayerSlot(id);
88 s32 to = findLayerSlot(targetId);
89 s32 pos;
90 Layer *layer;
91 s32 layerId;
92
93 if (from != -1 && to != -1) {
94 pos = to + delta;
95 layer = GFX.layers[from];
96 layerId = GFX.layerIds[from];
97 if (pos <= 0) {
98 pos = 0;
99 }
100 removeLayerSlot(from);
101 insertLayerSlot(pos, layer, layerId);
102 }
103}
104
105/* Layer method: clears the OT of the buffer being drawn */
106void layerClearOt(Layer *layer) {
107 ClearOTagR(layer->ot[GFX.buffer], layer->otLen);
108}
109
110/* Links every run of empty OT entries past itself, so the GPU skips it */
112 u_long mask = 0xFFFFFF;
113 u_long *ot = layer->ot[GFX.buffer];
114 u_long *p = ot + layer->otLen - 1;
115 u_long *q;
116
117 while (p != ot) {
118 q = p - 1;
119 if ((*p & mask) == ((u_long)q & mask)) {
120 while ((*q & mask) == ((u_long)(q - 1) & mask)) {
121 q--;
122 }
123 *p = (u_long)q & mask;
124 }
125 p = q;
126 }
127}
128
129/* Layer method: sends the OT of the finished buffer, after its DRAWENV with the layer's offset */
130void layerDraw(Layer *layer) {
131 DRAWENV env = layer->env;
132 DR_ENV *dr;
133 u_long *ot;
134 u_long *tag;
135
136 env.ofs[0] = layer->offsetX;
137 env.ofs[1] = layer->offsetY;
138 layerSkipEmptyOt(layer);
139 dr = GFX.prim;
140 ot = layer->ot[GFX.buffer] + layer->otLen;
141 tag = ot - 1;
142 if (GFX.buffer != 0) {
143 env.clip.y += 256;
144 env.ofs[1] += 256;
145 }
146 SetDrawEnv(dr, &env);
147 addPrim(ot - 1, dr);
148 dr++;
149 GFX.prim = dr;
150 DrawOTag(tag);
151}
152
153/* Layer method: the OT entry at `depth` in the buffer being drawn */
154u_long *layerGetOtEntry(Layer *layer, s32 depth) {
155 return layer->ot[GFX.buffer] + depth;
156}
157
158/* Layer method: the OT entry for a 16-bit Z, scaled to the OT's length */
159u_long *layerGetOtEntryZ(Layer *layer, s32 z) {
160 s32 i = z >> (16 - layer->otShift);
161
162 return layer->ot[GFX.buffer] + i;
163}
164
165/* Layer method: the OT of the buffer being drawn */
166u_long *layerGetOt(Layer *layer) {
167 return layer->ot[GFX.buffer];
168}
169
170/* Layer method: the OT size it was created with */
172 return layer->otShift;
173}
174
175/*
176 * Layer method: the color the layer's area is cleared to (black: not
177 * cleared). An old-style definition, as Layer.setBgColor's unprototyped
178 * callers suit: they pass ints, which it takes as bytes.
179 */
180void layerSetBgColor(layer, r, g, b)
181LayerView *layer;
182u8 r;
183u8 g;
184u8 b;
185{
186 layer->bgR = r;
187 layer->bgB = b;
188 layer->bgG = g;
189 if (r | g | b) {
190 layer->isbg = 1;
191 } else {
192 layer->isbg = 0;
193 }
194}
195
196/* Layer method: the drawing offset. Old-style, as layerSetBgColor */
197void layerSetOffset(layer, x, y)
198LayerView *layer;
199s16 x;
200s16 y;
201{
202 layer->offsetX = x;
203 layer->offsetY = y;
204}
205
206/* Layer method: the scroll position, in pixels */
207void layerGetScroll(LayerView *layer, Vec2 *out) {
208 out->x = layer->scrollX >> 8;
209 out->y = layer->scrollY >> 8;
210}
211
212/* Layer method: sets the scroll position (8.8 fixed point) */
213void layerSetScroll(LayerView *layer, s32 x, s32 y) {
214 layer->scrollX = x;
215 layer->scrollY = y;
216}
217
218/* Layer method: scrolls by (dx, dy) (8.8 fixed point) */
219void layerAddScroll(LayerView *layer, s32 dx, s32 dy) {
220 layer->scrollX += dx;
221 layer->scrollY += dy;
222}
223
224/* Layer method: moves the clip rectangle. Old-style, as layerSetBgColor */
225void layerSetClipPos(layer, x, y)
226LayerView *layer;
227s16 x;
228s16 y;
229{
230 layer->x = x;
231 layer->y = y;
232}
233
234/* Layer method: resizes the clip rectangle. Old-style, as layerSetBgColor */
235void layerSetClipSize(layer, w, h)
236LayerView *layer;
237s16 w;
238s16 h;
239{
240 layer->w = w;
241 layer->h = h;
242}
243
244/* Layer method: the part of the scrolled world the clip rectangle shows */
245void layerGetViewRect(LayerView *layer, Rect16 *rect) {
246 rect->x = layer->x - layer->offsetX + (layer->scrollX >> 8);
247 rect->y = layer->y - layer->offsetY + (layer->scrollY >> 8);
248 rect->w = layer->w;
249 rect->h = layer->h;
250}
251
252/* Layer method: frees its OTs and draw callbacks, once the GPU is done with them */
253void layerFree(Layer *layer) {
254 DrawSync(0);
255 HEAP.free(layer->ot[0]);
256 HEAP.free(layer->ot[1]);
257 if (layer->callbackCap != 0) {
258 HEAP.free(layer->callbacks);
259 }
260}
261
262/* Layer method: empties the draw callbacks, but for the head entry, which sorts first */
264 layer->callbacks->priority = 0x7FFFFFFF;
265 layer->callbacks->param = 0;
266 layer->callbacks->func = NULL;
267 layer->callbacks->arg = 0;
268 layer->callbacks->next = NULL;
269 layer->callbackCount = 1;
270}
271
272/* Layer method: room for `count` draw callbacks */
273void layerAllocCallbacks(Layer *layer, s32 count) {
274 layer->callbacks = HEAP.alloc(count * sizeof(DrawCallback), MEM_MODE);
275 layer->callbackCap = count;
276 layerResetCallbacks(layer);
277}
278
279/* Layer method: adds a draw callback in order of priority, highest first */
280void layerAddSortedCallback(Layer *layer, void (*func)(s32, void *, s32), s32 arg, s32 priority, s32 param) {
281 DrawCallback *cur;
282 DrawCallback *prev;
283 DrawCallback *e;
284 s32 i;
285 s32 cap;
286
287 if (layer->callbackCount < layer->callbackCap) {
288 cur = layer->callbacks;
289 e = &cur[layer->callbackCount];
290 e->func = func;
291 e->arg = arg;
292 e->priority = priority;
293 e->param = param;
294 prev = NULL;
295 if (layer->callbackCount != 0) {
296 cap = layer->callbackCap;
297 for (i = 0; i < cap; i++) {
298 if (cur->priority < priority) {
299 cur = prev;
300 break;
301 }
302 prev = cur;
303 if (cur->next == NULL) {
304 break;
305 }
306 cur = cur->next;
307 }
308 if (cur->next == NULL) {
309 cur->next = e;
310 e->next = NULL;
311 } else {
312 e->next = cur->next;
313 cur->next = e;
314 }
315 } else {
316 e->next = NULL;
317 }
318 layer->callbackCount++;
319 }
320}
321
322/* Layer method: adds a draw callback at the end of the list */
323void layerAddCallback(Layer *layer, void (*func)(s32, void *, s32), s32 arg) {
324 DrawCallback *cb;
325
326 if (layer->callbackCount < layer->callbackCap) {
327 cb = &layer->callbacks[layer->callbackCount];
328 cb->func = func;
329 cb->arg = arg;
330 cb->priority = 0;
331 cb->param = 0;
332 cb->next = NULL;
333 if (layer->callbackCount != 0) {
334 cb[-1].next = cb;
335 }
336 layer->callbackCount++;
337 }
338}
339
340/* Layer method: runs the draw callbacks in order, then empties the list */
342 DrawCallback *cb;
343
344 if (layer->callbackCount) {
345 cb = layer->callbacks;
346 do {
347 if (cb->func != NULL) {
348 cb->func(cb->arg, layer, cb->param);
349 }
350 cb = cb->next;
351 } while (cb != NULL);
352 layerResetCallbacks(layer);
353 }
354}
355
356/* Layer method: keeps the current world-screen matrix and projection for this buffer's drawing */
357void layerSetKeepView(Layer *layer, s32 enable, s32 projection) {
358 layer->keepView = enable;
359 if (enable) {
360 layer->projection = projection;
361 layer->view[GFX.buffer] = GsWSMATRIX;
362 }
363}
364
365/* Layer method: restores the view that setKeepView kept */
366void layerLoadView(Layer *layer) {
367 GsSetProjection(layer->projection);
368 GsWSMATRIX = layer->view[GFX.buffer];
369}
370
371/* Layer method: keeps the current light matrix for this buffer's drawing */
372void layerSetKeepLightMatrix(Layer *layer, s32 enable) {
373 layer->keepLightMatrix = enable;
374 if (enable) {
375 layer->lightMatrix[GFX.buffer] = GsLIGHTWSMATRIX;
376 }
377}
378
379/* Layer method: restores the light matrix that setKeepLightMatrix kept */
381 GsLIGHTWSMATRIX = layer->lightMatrix[GFX.buffer];
382}
383
384/* Allocates a layer with its two OTs and methods */
385Layer *newLayer(DRAWENV *env, s32 otShift) {
386 Layer *layer = HEAP.allocZeroed(sizeof(Layer), MEM_MODE);
387
388 layer->env = *env;
389 layer->otShift = otShift;
390 layer->otLen = OT_LENGTHS[otShift - 1];
391 layer->ot[0] = HEAP.alloc(layer->otLen * sizeof(u_long), MEM_MODE);
392 layer->ot[1] = HEAP.alloc(layer->otLen * sizeof(u_long), MEM_MODE);
393 ClearOTagR(layer->ot[0], layer->otLen);
394 ClearOTagR(layer->ot[1], layer->otLen);
396 layer->draw = layerDraw;
397 layer->clearOt = layerClearOt;
400 layer->free = layerFree;
403 layer->setOffset = layerSetOffset;
404 layer->setScroll = layerSetScroll;
405 layer->addScroll = layerAddScroll;
406 layer->getScroll = layerGetScroll;
408 layer->getOt = layerGetOt;
415 layer->loadView = layerLoadView;
418 return layer;
419}
420
421/* A layer's ordering table length, by its otShift - 1 */
423 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000,
424};
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
signed short s16
Definition common.h:9
unsigned char u8
Definition common.h:8
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
#define LAYER_COUNT
The drawing layers GFX holds at most.
Definition gfx.h:40
Heap HEAP
The functions that return what a call left in v0 (allocMemHigh, findTask) and the ones that take othe...
Definition heap.c:184
#define MEM_MODE
the current mode's: freed by main whenever the mode task ends
Definition heap.h:17
u_long * layerGetOtEntryZ(Layer *layer, s32 z)
Layer method: the OT entry for a 16-bit Z, scaled to the OT's length.
Definition layer.c:159
void layerLoadLightMatrix(Layer *layer)
Layer method: restores the light matrix that setKeepLightMatrix kept.
Definition layer.c:380
void layerClearOt(Layer *layer)
Layer method: clears the OT of the buffer being drawn.
Definition layer.c:106
void layerFree(Layer *layer)
Layer method: frees its OTs and draw callbacks, once the GPU is done with them.
Definition layer.c:253
void layerSetClipPos(LayerView *layer, s16 x, s16 y)
Layer method: moves the clip rectangle.
Definition layer.c:225
void layerSetOffset(LayerView *layer, s16 x, s16 y)
Layer method: the drawing offset.
Definition layer.c:197
void layerRunCallbacks(Layer *layer)
Layer method: runs the draw callbacks in order, then empties the list.
Definition layer.c:341
s32 findLayerSlot(s32 id)
The slot of the layer with this id; id 0 finds a free slot.
Definition layer.c:19
void layerSkipEmptyOt(Layer *layer)
Links every run of empty OT entries past itself, so the GPU skips it.
Definition layer.c:111
void layerAddCallback(Layer *layer, void(*func)(s32, void *, s32), s32 arg)
Layer method: adds a draw callback at the end of the list.
Definition layer.c:323
void insertLayerSlot(s32 index, Layer *layer, s32 id)
Puts a layer at position index of the draw order, moving the later ones back.
Definition layer.c:43
u_long * layerGetOtEntry(Layer *layer, s32 depth)
Layer method: the OT entry at depth in the buffer being drawn.
Definition layer.c:154
void layerDraw(Layer *layer)
Layer method: sends the OT of the finished buffer, after its DRAWENV with the layer's offset.
Definition layer.c:130
void layerSetClipSize(LayerView *layer, s16 w, s16 h)
Layer method: resizes the clip rectangle.
Definition layer.c:235
void layerGetScroll(LayerView *layer, Vec2 *out)
Layer method: the scroll position, in pixels.
Definition layer.c:207
void layerAddSortedCallback(Layer *layer, void(*func)(s32, void *, s32), s32 arg, s32 priority, s32 param)
Layer method: adds a draw callback in order of priority, highest first.
Definition layer.c:280
Layer * getLayer(s32 id)
The layer with id id, or NULL.
Definition layer.c:7
void layerSetScroll(LayerView *layer, s32 x, s32 y)
Layer method: sets the scroll position (8.8 fixed point)
Definition layer.c:213
void layerSetBgColor(LayerView *layer, u8 r, u8 g, u8 b)
Layer method: the color the layer's area is cleared to (black: not cleared).
Definition layer.c:180
u_long * layerGetOt(Layer *layer)
Layer method: the OT of the buffer being drawn.
Definition layer.c:166
void layerGetViewRect(LayerView *layer, Rect16 *rect)
Layer method: the part of the scrolled world the clip rectangle shows.
Definition layer.c:245
s32 destroyLayer(s32 id)
Frees the layer with id id; 0 if there is none.
Definition layer.c:71
s32 layerGetOtShift(LayerView *layer)
Layer method: the OT size it was created with.
Definition layer.c:171
void layerAllocCallbacks(Layer *layer, s32 count)
Layer method: room for count draw callbacks.
Definition layer.c:273
Layer * newLayer(DRAWENV *env, s32 otShift)
Allocates a layer with its two OTs and methods.
Definition layer.c:385
void layerSetKeepLightMatrix(Layer *layer, s32 enable)
Layer method: keeps the current light matrix for this buffer's drawing.
Definition layer.c:372
void layerResetCallbacks(Layer *layer)
Layer method: empties the draw callbacks, but for the head entry, which sorts first.
Definition layer.c:263
s16 OT_LENGTHS[]
A layer's ordering table length, by its otShift - 1.
Definition layer.c:422
Layer * createLayer(RECT *rect, s32 otShift, s32 id)
A new layer drawing to rect, with an OT of OT_LENGTHS[otShift - 1] entries; NULL when all are in use.
Definition layer.c:58
void layerAddScroll(LayerView *layer, s32 dx, s32 dy)
Layer method: scrolls by (dx, dy) (8.8 fixed point)
Definition layer.c:219
void layerSetKeepView(Layer *layer, s32 enable, s32 projection)
Layer method: keeps the current world-screen matrix and projection for this buffer's drawing.
Definition layer.c:357
void moveLayer(s32 id, s32 targetId, s32 delta)
Moves a layer to the position of another one (plus delta) in the draw order.
Definition layer.c:86
void removeLayerSlot(s32 index)
Closes the gap of a removed layer in the draw order.
Definition layer.c:35
void layerLoadView(Layer *layer)
Layer method: restores the view that setKeepView kept.
Definition layer.c:366
A function that a layer calls when it is drawn (Layer.addDrawCallback)
Definition gfx.h:116
s32 param
Definition gfx.h:118
void(* func)(s32 arg, void *layer, s32 param)
Definition gfx.h:119
struct DrawCallback * next
Definition gfx.h:121
s32 arg
Definition gfx.h:120
s32 priority
Definition gfx.h:117
void * prim
next free byte of the packet buffer
Definition gfx.h:69
s32 buffer
the one being drawn
Definition gfx.h:73
struct Layer * layers[30]
Definition gfx.h:75
s32 layerIds[30]
Definition gfx.h:76
void *(* alloc)(s32 size, s32 tag)
Definition heap.h:29
void *(* allocZeroed)(s32 size, s32 tag)
Definition heap.h:31
void(* free)(void *ptr)
Definition heap.h:27
Layer as its clip/scroll methods see it: the clip rect as unsigned.
Definition gfx.h:81
s16 y
Definition gfx.h:83
s16 offsetX
Definition gfx.h:99
s32 scrollX
Definition gfx.h:101
s32 otShift
Definition gfx.h:98
s16 offsetY
Definition gfx.h:100
s16 x
Definition gfx.h:82
s32 scrollY
Definition gfx.h:102
u16 h
Definition gfx.h:85
u8 bgR
Definition gfx.h:92
u16 w
Definition gfx.h:84
A drawing layer (GFX.funcs.createLayer): a DRAWENV with a pair of ordering tables,...
Definition gfx.h:128
s32 callbackCount
Definition gfx.h:138
void(* addCallback)()
Definition gfx.h:161
void(* getScroll)()
Definition gfx.h:148
void(* loadLightMatrix)(struct Layer *)
Definition gfx.h:165
void(* runCallbacks)(struct Layer *)
Definition gfx.h:162
u_long *(* getOtEntry)(struct Layer *, s32 depth)
Definition gfx.h:155
void(* setScroll)()
Definition gfx.h:149
void(* setBgColor)()
no prototype: callers would truncate u8 args
Definition gfx.h:152
void(* setOffset)()
no prototype: callers would truncate s16 args
Definition gfx.h:147
s32(* getOtShift)()
Definition gfx.h:158
s32 projection
Definition gfx.h:141
void(* draw)(struct Layer *)
Definition gfx.h:153
DrawCallback * callbacks
Definition gfx.h:139
void(* loadView)(struct Layer *)
Definition gfx.h:163
void(* addScroll)()
Definition gfx.h:150
void(* clearOt)(struct Layer *)
Definition gfx.h:154
s32 keepView
Definition gfx.h:140
s32 otShift
Definition gfx.h:132
s32 otLen
Definition gfx.h:131
s32 keepLightMatrix
Definition gfx.h:143
s32 callbackCap
Definition gfx.h:137
void(* setClipSize)()
no prototype: callers would truncate s16 args
Definition gfx.h:146
u_long *(* getOtEntryZ)(struct Layer *layer, s32 z)
Definition gfx.h:156
DRAWENV env
Definition gfx.h:129
void(* setKeepLightMatrix)()
Definition gfx.h:166
s16 offsetX
Definition gfx.h:133
MATRIX view[2]
Definition gfx.h:142
MATRIX lightMatrix[2]
Definition gfx.h:144
void(* allocCallbacks)()
Definition gfx.h:159
u_long * ot[2]
Definition gfx.h:130
void(* setKeepView)()
Definition gfx.h:164
void(* free)(struct Layer *)
Definition gfx.h:167
void(* setClipPos)()
no prototype: callers would truncate s16 args
Definition gfx.h:145
void(* addSortedCallback)()
Definition gfx.h:160
s16 offsetY
Definition gfx.h:134
u_long *(* getOt)(struct Layer *)
Definition gfx.h:157
void(* getViewRect)()
Definition gfx.h:151
Definition gfx.h:108
s16 y
Definition gfx.h:110
u16 w
Definition gfx.h:111
u16 h
Definition gfx.h:112
s16 x
Definition gfx.h:109
Definition gfx.h:352
s32 y
Definition gfx.h:354
s32 x
Definition gfx.h:353