Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
movie.c
Go to the documentation of this file.
1/* The movies, streamed from the disc and decoded with libpress */
2
3#include "menus/title.h"
4
5/* Resets the GPU and clears the whole VRAM to black, around the movies */
7 ResetGraph(1);
8 ClearImage2(&STDWTITL_vramRect, 0, 0, 0);
9 DrawSync(0);
10}
11
12/* Sets up the movie decoder: its VLC and slice buffers, and the two places in VRAM
13 (x0, y0 and x1, y1) its frames alternate between */
14void STDWTITL_initDecEnv(DecEnv *dec, s16 x0, s16 y0, s16 x1, s16 y1) {
17 dec->vlcid = GFX.buffer ^ 1;
20 dec->imgid = GFX.buffer ^ 1;
21 dec->rect[0].x = x0;
22 dec->rect[0].y = y0;
23 dec->rect[1].x = x1;
24 dec->rect[1].y = y1;
25 dec->rectid = GFX.buffer ^ 1;
26 dec->slice.x = x0;
27 dec->slice.y = y0;
28 dec->slice.w = 24;
29 dec->isdone = 0;
30}
31
32/* Seeks the CD to loc and starts streaming the movie from there, retrying until it works */
33void STDWTITL_readStream(CdlLOC *loc) {
34 u_char param;
35
36 param = CdlModeSpeed;
37 do {
38 /* libcd takes a command's parameters as bytes */
39 while (CdControl(CdlSetloc, (u_char *)loc, 0) == 0) {
40 }
41 while (CdControl(CdlSetmode, &param, 0) == 0) {
42 }
43 } while (CdRead2(CdlModeStream | CdlModeSpeed | CdlModeRT | CdlModeSize1) == 0);
44}
45
46/* Resets the MDEC, has callback run for each decoded slice, sets up the ring buffer
47 and starts streaming the movie from loc */
48void STDWTITL_initStream(CdlLOC *loc, void (*callback)()) {
49 DecDCTReset(0);
50 DecDCToutCallback(callback);
51 StSetRing(STDWTITL_ringBuffer, 32);
52 StSetStream(1, 1, -1, 0, 0);
54}
55
56/* Waits for the next movie frame in the ring buffer and returns it (NULL if none
57 came); flags the movie's end at its last frame and clears VRAM when the size changes */
59 u_long *addr;
60 StHEADER *sector;
61 s32 count = 2000;
62
63 /* libcd hands the sector's header back as words */
64 while (StGetNext(&addr, (u_long **)&sector) != 0) {
65 if (--count == 0) {
66 return NULL;
67 }
68 }
69 if (sector->frameCount >= STDWTITL_movieEndFrame) {
71 }
72 if (STDWTITL_movieWidth != sector->width || STDWTITL_movieHeight != sector->height) {
74 STDWTITL_movieWidth = sector->width;
75 STDWTITL_movieHeight = sector->height;
76 }
77 dec->rect[0].w = dec->rect[1].w = STDWTITL_movieWidth * 3 / 2;
78 dec->rect[0].h = dec->rect[1].h = STDWTITL_movieHeight;
80 return addr;
81}
82
83/* Takes the next movie frame and decodes its VLC data into the other VLC buffer;
84 -1 if no frame came, 0 otherwise */
86 s32 count = 2000;
87 u_long *next;
88
89 while ((next = STDWTITL_getNextFrame(dec)) == NULL) {
90 if (--count == 0) {
91 return -1;
92 }
93 }
94 dec->vlcid = dec->vlcid == 0;
95 DecDCTvlc2(next, dec->vlcbuf[dec->vlcid], STDWTITL_vlcTable);
96 StFreeRing(next);
97 return 0;
98}
99
100/* Called by the MDEC for each decoded slice of a movie frame: copies it to VRAM
101 and decodes the next one, or marks the frame done and switches to the other buffer */
103 RECT rect;
104 s32 id;
105
106 if (StCdIntrFlag) {
107 StCdInterrupt();
108 StCdIntrFlag = 0;
109 }
111 rect = STDWTITL_decEnv.slice;
115 rect.x += 480;
116 }
117 rect.y = 36;
120 } else {
125 }
126 DrawSync(0);
127 LoadImage(&rect, STDWTITL_decEnv.imgbuf[id]);
128}
129
130/* Waits until the MDEC has decoded the whole frame (switching buffers itself if it
131 takes far too long); mode is not used */
133 volatile s32 count = 0x800000;
134
135 while (dec->isdone == 0) {
136 if (--count == 0) {
137 dec->isdone = 1;
138 dec->rectid = dec->rectid == 0;
139 dec->slice.x = dec->rect[dec->rectid].x;
140 dec->slice.y = dec->rect[dec->rectid].y;
141 }
142 }
143 dec->isdone = 0;
144}
145
146/* The movie player's task: allocates its buffers and starts the movie, then shows a
147 frame each update until the movie's last frame or Start; when killed, stops the
148 CD, frees the buffers and clears VRAM */
150 switch (task->state) {
151 case TASK_INIT:
152 default:
154 STDWTITL_ringBuffer = HEAP.alloc(0x10000, 2);
155 STDWTITL_vlcBuffer0 = HEAP.alloc(0x28000, 2);
156 STDWTITL_vlcBuffer1 = HEAP.alloc(0x28000, 2);
157 STDWTITL_imageBuffer0 = HEAP.alloc(0x4E00, 2);
158 STDWTITL_imageBuffer1 = HEAP.alloc(0x4E00, 2);
159 STDWTITL_vlcTable = HEAP.alloc(0x11000, 2);
160 STDWTITL_initDecEnv(&STDWTITL_decEnv, 0, 0, 0, 416);
163 DecDCTvlcBuild(STDWTITL_vlcTable);
166 task->nextState(task);
167 /* fallthrough */
168 case TASK_RUN:
173 if (STDWTITL_movieEnded == 1 || (PAD.getPressed(0) & (1 << PAD_START))) {
174 task->setState(task, TASK_KILL);
175 }
176 break;
177 case TASK_DONE:
178 break;
179 case TASK_KILL:
180 CdControlB(CdlPause, 0, 0);
181 DecDCToutCallback(NULL);
182 StUnSetRing();
189 DrawSync(0);
192 break;
193 }
194}
195
196/* Creates the movie player (task) for the movie in file, which ends on frame endFrame */
199
200 STDWTITL_movieFile = file;
201 STDWTITL_movieEndFrame = endFrame;
202 return task;
203}
204
205/* A movie's task: picks the movie's file and next mode (the European version's last
206 movie by the language), plays it, then reloads the font and goes on to that mode */
208 switch (task->state) {
209 case TASK_INIT:
210 default:
211 GFX.funcs.reset();
212 GFX.funcs.allocPrimBuffers(0x2800);
213 GFX.funcs.setDisplayMode(320, 480, 1, 1);
214#if VERSION_US
215 if (task->movie != 10) {
217 task->nextMode = STDWTITL_movies[task->movie].nextMode;
218 } else {
219 *player = STDWTITL_startMoviePlayerTask(STDWTITL_movies[11].file, STDWTITL_movies[11].endFrame);
221 }
222#elif VERSION_EU || VERSION_JP
223 /* movie 11 is one of three, by the language */
224 if (task->movie != 11) {
226 } else {
227 switch (LANGUAGE) {
228 case 0:
229 *player = STDWTITL_startMoviePlayerTask(STDWTITL_movies[11].file, STDWTITL_movies[11].endFrame);
230 break;
231 case 1:
232 *player = STDWTITL_startMoviePlayerTask(STDWTITL_movies[12].file, STDWTITL_movies[12].endFrame);
233 break;
234 case 2 ... 6:
235 *player = STDWTITL_startMoviePlayerTask(STDWTITL_movies[13].file, STDWTITL_movies[13].endFrame);
236 break;
237 }
238 }
239 if (task->movie != 11) {
240 task->nextMode = STDWTITL_movies[task->movie].nextMode;
241 if (task->movie == 2 && GAME.progress == STORY_EXTRA) {
242 task->nextMode = 0x276;
243 }
244 } else {
245 switch (LANGUAGE) {
246 case 0:
248 break;
249 case 1:
251 break;
252 case 2 ... 6:
254 break;
255 }
256 }
257#endif
258 SOUND.stopAll();
259 task->nextState(task);
260 break;
261 case TASK_RUN:
262 if (*player == NULL) {
263 FONT.load();
264 GAME.funcs.requestMode(task->nextMode, 0);
265 task->setState(task, TASK_DONE);
266 }
267 break;
268 case TASK_DONE:
269 case TASK_KILL:
270 break;
271 }
272}
273
274/* Creates the task that plays STDWTITL_movies[movie] */
277
278 task->movie = movie;
279 return task;
280}
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
unsigned int u32
Definition common.h:12
signed short s16
Definition common.h:9
s32 STDWTITL_movieFile
Definition movie.c:13
u_long * STDWTITL_vlcBuffer1
Definition movie.c:9
u_short * STDWTITL_vlcTable
Definition movie.c:7
s32 STDWTITL_movieEnded
Definition movie.c:12
DecEnv STDWTITL_decEnv
Definition movie.c:5
u_long * STDWTITL_vlcBuffer0
Definition movie.c:8
u_long * STDWTITL_imageBuffer0
Definition movie.c:10
u_long * STDWTITL_ringBuffer
Definition movie.c:6
u_long * STDWTITL_imageBuffer1
Definition movie.c:11
u32 STDWTITL_movieEndFrame
Definition movie.c:14
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
GameState GAME
The save data, the game mode and the methods.
Definition state.c:64
#define TASK_RUN
Definition task.h:35
#define TASK_KILL
Definition task.h:37
#define TASK_INIT
Tasks: every game object is a task, a heap block that starts with this header and is updated once per...
Definition task.h:34
#define TASK_DONE
Definition task.h:36
s32 LANGUAGE
The European version's settings, in the small data (.sdata) between file/file_table....
Definition eu_settings.c:13
FileTableFuncs FILE_TABLE
The disc's file table.
Font FONT
decode is declared without a prototype, as callers would truncate the u8 mode, so decodeChar is cast ...
Definition font.c:78
#define SCREEN_WIDTH
The screen the modes draw on (setDisplayMode, their layers' rects)
Definition gfx.h:36
#define SCREEN_HEIGHT
Definition gfx.h:37
Heap HEAP
The functions that return what a call left in v0 (allocMemHigh, findTask) and the ones that take othe...
Definition heap.c:184
void STDWTITL_initStream(CdlLOC *loc, void(*callback)())
Resets the MDEC, has callback run for each decoded slice, sets up the ring buffer and starts streamin...
Definition movie.c:48
void STDWTITL_waitFrameDecoded(DecEnv *dec, s32 mode)
Waits until the MDEC has decoded the whole frame (switching buffers itself if it takes far too long);...
Definition movie.c:132
MovieTask * STDWTITL_startMovieTask(s32 movie)
Creates the task that plays STDWTITL_movies[movie].
Definition movie.c:275
s32 STDWTITL_decodeNextFrame(DecEnv *dec)
Takes the next movie frame and decodes its VLC data into the other VLC buffer; -1 if no frame came,...
Definition movie.c:85
void STDWTITL_readStream(CdlLOC *loc)
Seeks the CD to loc and starts streaming the movie from there, retrying until it works.
Definition movie.c:33
void STDWTITL_tickMoviePlayer(MoviePlayerTask *task)
The movie player's task: allocates its buffers and starts the movie, then shows a frame each update u...
Definition movie.c:149
MoviePlayerTask * STDWTITL_startMoviePlayerTask(s32 file, u32 endFrame)
Creates the movie player (task) for the movie in file, which ends on frame endFrame.
Definition movie.c:197
void STDWTITL_initDecEnv(DecEnv *dec, s16 x0, s16 y0, s16 x1, s16 y1)
Sets up the movie decoder: its VLC and slice buffers, and the two places in VRAM (x0,...
Definition movie.c:14
void STDWTITL_tickMovie(MovieTask *task, MoviePlayerTask **player)
A movie's task: picks the movie's file and next mode (the European version's last movie by the langua...
Definition movie.c:207
u_long * STDWTITL_getNextFrame(DecEnv *dec)
Waits for the next movie frame in the ring buffer and returns it (NULL if none came); flags the movie...
Definition movie.c:58
void STDWTITL_clearVram(void)
Resets the GPU and clears the whole VRAM to black, around the movies.
Definition movie.c:6
void STDWTITL_onSliceDecoded(void)
Called by the MDEC for each decoded slice of a movie frame: copies it to VRAM and decodes the next on...
Definition movie.c:102
PadState PAD
Controller input: cleared by initPad, then the methods.
Definition pad.c:168
#define PAD_START
Definition pad.h:21
SoundState SOUND
rsin and rcos (libgte) read rsin_tbl[a - 0x800] and the like: their addresses before the table fall i...
Definition sound.c:180
RECT STDWTITL_vramRect
Definition stdwtitl.c:19
MovieInfo STDWTITL_movies[]
Each movie's file, the frame it ends on and the game mode after it.
Definition stdwtitl.c:22
s32 STDWTITL_movieHeight
Definition stdwtitl.c:18
s32 STDWTITL_movieWidth
Definition stdwtitl.c:17
@ STORY_EXTRA
WSTAG780, event 1500, in the European and Japanese versions: the extra chapter, whose stages are FIEL...
Definition story.h:149
Movies: PsyQ's STR player.
Definition title.h:82
u_long * vlcbuf[2]
Definition title.h:83
s32 isdone
set by STDWTITL_onSliceDecoded, the MDEC's callback
Definition title.h:90
RECT rect[2]
Definition title.h:87
s32 imgid
Definition title.h:86
RECT slice
Definition title.h:89
s32 rectid
Definition title.h:88
s32 vlcid
Definition title.h:84
u_long * imgbuf[2]
16-bit pixels, as words for DecDCTout and LoadImage
Definition title.h:85
void(* getPos)(s32 file, s32 offset, void *loc)
Definition file.h:19
void(* load)()
Definition text.h:214
void(* requestMode)(s32 mode, s32 arg)
Definition game_state.h:21
GameFuncs funcs
Definition game_state.h:582
void(* reset)(void)
Definition gfx.h:17
void(* allocPrimBuffers)(s32 size)
Definition gfx.h:18
void(* setDisplayMode)(s32 w, s32 h, s32 hires, s32 interlace)
Definition gfx.h:26
void(* setDisplayArea)()
Definition gfx.h:27
s32 buffer
the one being drawn
Definition gfx.h:73
GfxFuncs funcs
Definition gfx.h:77
void *(* alloc)(s32 size, s32 tag)
Definition heap.h:29
void(* free)(void *ptr)
Definition heap.h:27
s32 file
Definition title.h:94
s32 nextMode
Definition title.h:96
u32 endFrame
Definition title.h:95
CdlLOC loc
Definition title.h:107
void(* nextState)(struct MoviePlayerTask *task)
Definition title.h:106
void(* setState)(struct MoviePlayerTask *task, s32 state)
Definition title.h:106
s32 movie
Definition title.h:101
void(* setState)(struct MovieTask *task, s32 state)
Definition title.h:100
void(* nextState)(struct MovieTask *task)
Definition title.h:100
s32 nextMode
Definition title.h:102
s32 state
Definition title.h:100
s32(* getPressed)(s32 pad)
Definition pad.h:125
void(* stopAll)(void)
Definition sound.h:194
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
STDWTITL.PRO: the title screen, the opening movies and a notice screen.
u_char StCdIntrFlag
libcd's flag that StCdInterrupt is pending: libcd sets it as a word, the game reads and clears its lo...