Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
display.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/* Small variables, addressed through $gp (see the Makefile) */
7static s32 GFX_STARTED = 0;
9
10/*
11 * Every vsync: advances the time counters and the play time, runs GFX.vsyncFunc, shows the
12 * finished buffer and ticks the music
13 */
14void vsyncCallback(void) {
15#if PAL_VIDEO
16 if (NTSC_MODE) {
20 } else {
24 }
25#else
29#endif
30 if (GFX.vsyncFunc != NULL) {
32 }
33 if (FLIP_PENDING != 0) {
35 PutDispEnv(&GFX.disp[GFX.dispBuffer]);
36 }
37 SsSeqCalledTbyT();
38 FLIP_PENDING = 0;
39}
40
41/* Installs vsyncCallback */
43 VSyncCallback(vsyncCallback);
44}
45
46/*
47 * Ends a frame: lets the layers run their draw callbacks, waits for the GPU
48 * and for the vsync that shows the finished buffer, then sends every layer
49 * of that buffer and clears the ones of the next.
50 */
51void drawFrame(s32 draw) {
52 s32 i;
53 Layer *layer;
54
55 if (draw) {
56 s32 j;
57
58 for (j = 0; j < LAYER_COUNT; j++) {
59 layer = GFX.layers[j];
60 if (layer != NULL) {
61 if (layer->keepView != 0) {
62 layer->loadView(layer);
63 }
64 if (layer->keepLightMatrix != 0) {
65 layer->loadLightMatrix(layer);
66 }
67 layer->runCallbacks(layer);
68 }
69 }
70 }
71 DrawSync(0);
72 FLIP_PENDING = 1;
73 while (*(volatile s32 *)&FLIP_PENDING != 0) {
74 }
75 if (GFX.prim != NULL) {
76 for (i = 0; i < LAYER_COUNT; i++) {
77 if (GFX.layers[i] != NULL) {
78 GFX.layers[i]->draw(GFX.layers[i]);
79 }
80 }
81 }
82 GFX.buffer = GFX.buffer == 0;
83#if PAL_VIDEO
84 if (NTSC_MODE) {
86 } else {
88 }
89#else
91#endif
93 GFX.time = GFX.timeCounter >> 8;
95 GFX.frameTimeCounter &= 0xFF;
98 for (i = 0; i < LAYER_COUNT; i++) {
99 if (GFX.layers[i] != NULL) {
100 GFX.layers[i]->clearOt(GFX.layers[i]);
101 }
102 }
103}
104
105/* The frames drawn since boot */
107 return GFX.frameCount;
108}
109
110/* The vsyncs since boot (in 60 Hz frames) */
112 return GFX.time;
113}
114
115/* The vsyncs the last frame took (in 60 Hz frames) */
117 return GFX.frameTime;
118}
119
120/*
121 * Destroys every layer and clears the packet buffers' state; the first call just picks the buffers
122 */
123void resetGraphics(void) {
124 s32 i;
125
126 if (GFX_STARTED != 0) {
127 for (i = 0; i < LAYER_COUNT; i++) {
128 if (GFX.layers[i] != NULL) {
130 i--;
131 }
132 }
133 HEAP.zero(&GFX.prim, 0x18);
134 } else {
135 GFX.buffer = 1;
136 GFX.dispBuffer = 0;
137 GFX_STARTED = 1;
138 }
139}
140
141/* Allocates the two GPU packet buffers, `size` bytes each, at the end of the heap */
143 GFX.primBufSize = size;
144 GFX.primBufs[0] = HEAP.allocHigh(size, MEM_MODE);
145 GFX.primBufs[1] = HEAP.allocHigh(size, MEM_MODE);
147}
148
149/* The next free byte of the packet buffer being drawn */
150void *getPrim(void) {
151 return GFX.prim;
152}
153
154/* Moves the packet buffer's free pointer past the primitives just written */
155void setPrim(void *next) {
156 GFX.prim = next;
157}
158
159/* Frees the two packet buffers */
160void freePrimBuffers(void) {
161 if (GFX.primBufs[0] != NULL) {
162 HEAP.free(GFX.primBufs[0]);
163 }
164 if (GFX.primBufs[1] != NULL) {
165 HEAP.free(GFX.primBufs[1]);
166 }
167 GFX.primBufs[0] = NULL;
168 GFX.primBufs[1] = NULL;
169}
170
171/*
172 * Sets up the two display buffers: side by side in hi-res (interlaced 320x480 24-bit), else one
173 * above the other
174 */
175void setDisplayMode(s32 w, s32 h, s32 hires, s32 interlace) {
176 if (hires != 0) {
177 if (interlace != 0) {
178 SetDefDispEnv(&GFX.disp[0], 0, 0, 320, 480);
179 GFX.disp[0].isinter = 1;
180 GFX.disp[0].isrgb24 = 1;
181 SetDefDispEnv(&GFX.disp[1], 480, 0, 320, 480);
182 GFX.disp[1].isinter = 1;
183 GFX.disp[1].isrgb24 = 1;
184 } else {
185 SetDefDispEnv(&GFX.disp[0], 0, 0, w, h);
186 SetDefDispEnv(&GFX.disp[1], w, 0, w, h);
187 }
188 } else {
189 SetDefDispEnv(&GFX.disp[0], 0, 0, w, h);
190 SetDefDispEnv(&GFX.disp[1], 0, 256, w, h);
191 }
192#if PAL_VIDEO
193 if (SHIFT_PAL_SCREEN) {
194 GFX.disp[0].screen.y = 0x18;
195 GFX.disp[1].screen.y = 0x18;
196 }
197#endif
198 GsInit3D();
199 SetGeomOffset(0, 0);
200}
201
202/* Shows the same VRAM area from both display buffers */
203void setDisplayArea(s32 x, s32 y, s32 w, s32 h) {
204 SetDefDispEnv(&GFX.disp[0], x, y, w, h);
205 SetDefDispEnv(&GFX.disp[1], x, y, w, h);
206}
207
208/* GFX: the graphics state and its methods */
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
static s32 GFX_STARTED
Small variables, addressed through $gp (see the Makefile)
Definition display.c:7
void * getPrim(void)
The next free byte of the packet buffer being drawn.
Definition display.c:150
void allocPrimBuffers(s32 size)
Allocates the two GPU packet buffers, size bytes each, at the end of the heap.
Definition display.c:142
void freePrimBuffers(void)
Frees the two packet buffers.
Definition display.c:160
void setDisplayArea(s32 x, s32 y, s32 w, s32 h)
Shows the same VRAM area from both display buffers.
Definition display.c:203
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
void vsyncCallback(void)
Every vsync: advances the time counters and the play time, runs GFX.vsyncFunc, shows the finished buf...
Definition display.c:14
void drawFrame(s32 draw)
Ends a frame: lets the layers run their draw callbacks, waits for the GPU and for the vsync that show...
Definition display.c:51
void resetGraphics(void)
Destroys every layer and clears the packet buffers' state; the first call just picks the buffers.
Definition display.c:123
s32 getTime(void)
The vsyncs since boot (in 60 Hz frames)
Definition display.c:111
void setPrim(void *next)
Moves the packet buffer's free pointer past the primitives just written.
Definition display.c:155
void setDisplayMode(s32 w, s32 h, s32 hires, s32 interlace)
Sets up the two display buffers: side by side in hi-res (interlaced 320x480 24-bit),...
Definition display.c:175
s32 getFrameCount(void)
The frames drawn since boot.
Definition display.c:106
s32 getFrameTime(void)
The vsyncs the last frame took (in 60 Hz frames)
Definition display.c:116
void startVSyncCallback(void)
Installs vsyncCallback.
Definition display.c:42
static s32 FLIP_PENDING
Definition display.c:8
GameState GAME
The save data, the game mode and the methods.
Definition state.c:64
s32 NTSC_MODE
The European version runs at 50 Hz (PAL) unless NTSC_MODE is set; its clocks then advance 0x133,...
Definition eu_settings.c:14
s32 SHIFT_PAL_SCREEN
moves both display areas 0x18 lines down
Definition eu_settings.c:15
#define VSYNC_STEP_PAL
Definition gfx.h:52
#define LAYER_COUNT
The drawing layers GFX holds at most.
Definition gfx.h:40
#define VSYNC_STEP_NTSC
What a vsync adds to the 8.8 time counters: a frame of the 60 Hz game, or 1.2 of them at 50 Hz so tha...
Definition gfx.h:51
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
Layer * getLayer(s32 id)
The layer with id id, or NULL.
Definition layer.c:7
s32 destroyLayer(s32 id)
Frees the layer with id id; 0 if there is none.
Definition layer.c:71
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 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(* updatePlayTime)()
Definition game_state.h:40
PlayTime playTime
Definition game_state.h:508
GameFuncs funcs
Definition game_state.h:582
s32(* destroyLayer)(s32 id)
Definition gfx.h:25
The graphics state: double-buffered display, the GPU packet buffers that primitives are written to (g...
Definition gfx.h:60
DISPENV disp[2]
Definition gfx.h:74
void * prim
next free byte of the packet buffer
Definition gfx.h:69
s32 frameTimeCounter
Definition gfx.h:68
void * primBufs[2]
Definition gfx.h:70
void(* vsyncFunc)(s32 arg)
Definition gfx.h:61
s32 buffer
the one being drawn
Definition gfx.h:73
GfxFuncs funcs
Definition gfx.h:77
struct Layer * layers[30]
Definition gfx.h:75
s32 vsyncArg
Definition gfx.h:62
s32 dispBuffer
Definition gfx.h:72
s32 timeCounter
Definition gfx.h:66
s32 frameCount
Definition gfx.h:63
s32 frameCounter
Definition gfx.h:64
s32 layerIds[30]
Definition gfx.h:76
s32 primBufSize
Definition gfx.h:71
s32 time
vsyncs since boot
Definition gfx.h:65
s32 frameTime
vsyncs that the last frame took
Definition gfx.h:67
void(* zero)(void *ptr, s32 size)
Definition heap.h:32
void *(* allocHigh)(s32 size, s32 tag)
from the end of the heap
Definition heap.h:30
void(* free)(void *ptr)
Definition heap.h:27
A drawing layer (GFX.funcs.createLayer): a DRAWENV with a pair of ordering tables,...
Definition gfx.h:128
void(* loadLightMatrix)(struct Layer *)
Definition gfx.h:165
void(* runCallbacks)(struct Layer *)
Definition gfx.h:162
void(* draw)(struct Layer *)
Definition gfx.h:153
void(* loadView)(struct Layer *)
Definition gfx.h:163
void(* clearOt)(struct Layer *)
Definition gfx.h:154
s32 keepView
Definition gfx.h:140
s32 keepLightMatrix
Definition gfx.h:143
s32 frames
8.8, counted by the vsync callback
Definition game_state.h:331