Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
windows.c
Go to the documentation of this file.
1#include "common.h"
2#include "nu/nusys.h"
3
9
10typedef struct SimpleWindowUpdateData {
11 /* 0x00 */ u8 flags;
12 /* 0x01 */ u8 windowFlagsSet;
13 /* 0x02 */ u8 windowFlagsUnset;
14 /* 0x03 */ u8 darkening;
15 /* 0x04 */ u8 opacity;
16} SimpleWindowUpdateData; // size = 0x05
17
18typedef struct WindowGroup {
19 /* 0x00 */ u8 min;
20 /* 0x01 */ u8 max;
21} WindowGroup; // size = 0x02
22
24
43
45 {
46 .flags = 0,
47 .windowFlagsSet = 0,
48 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
49 .darkening = 0,
50 .opacity = 0
51 },
52 {
53 .flags = 0,
54 .windowFlagsSet = 0,
56 .darkening = 0,
57 .opacity = 0
58 },
59 {
60 .flags = 0,
61 .windowFlagsSet = WINDOW_FLAG_HIDDEN,
62 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
63 .darkening = 0,
64 .opacity = 0
65 },
66 {
68 .windowFlagsSet = 0,
69 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
70 .darkening = 0,
71 .opacity = 0
72 },
73 {
75 .windowFlagsSet = 0,
76 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
77 .darkening = 100,
78 .opacity = 0
79 },
80 {
82 .windowFlagsSet = 0,
83 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
84 .darkening = 0,
85 .opacity = 0
86 },
87 {
89 .windowFlagsSet = 0,
90 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
91 .darkening = 0,
92 .opacity = 184
93 },
94 {
96 .windowFlagsSet = 0,
97 .windowFlagsUnset = WINDOW_FLAG_INITIAL_ANIMATION,
98 .darkening = 0,
99 .opacity = 255
100 },
101 {
103 .windowFlagsSet = 0,
105 .darkening = 0,
106 .opacity = 184
107 },
108 {
110 .windowFlagsSet = 0,
112 .darkening = 100,
113 .opacity = 0
114 },
115 {},
116 {},
117 {},
118 {}
119};
120
121u8 gWindowAppearScales[] = { 50, 80, 100, 105, 100 };
123u8 gWindowDisappearScales[] = { 105, 100, 77, 57, 40, 27, 16, 8, 3, 0 };
127
134
135void clear_windows(void) {
136 s32 i;
137
138 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
139 gWindows[i].flags = 0;
140 }
141}
142
143void update_windows(void) {
144 s32 i;
145
146 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
147 u8 flags = gWindows[i].flags;
148
149 if (!flags || (flags & WINDOW_FLAG_DISABLED)) {
150 continue;
151 }
152
154 gWindows[i].flags = flags & ~WINDOW_FLAG_FPUPDATE_CHANGED;
156 gWindows[i].updateCounter = 0;
157 }
158 }
159}
160
161void basic_window_update(s32 windowID, s32* flags, s32* posX, s32* posY, s32* posZ, f32* scaleX, f32* scaleY,
162 f32* rotX, f32* rotY, f32* rotZ, s32* darkening, s32* opacity) {
163 Window* window = &gWindows[windowID];
164 s32 counter = window->updateCounter;
165
166 if (counter == 0) {
167 window->flags &= ~WINDOW_FLAG_HIDDEN;
168 }
169
170 if (counter <= 4) {
171 *flags = gWindowAppearFlags[counter];
172 *scaleX = (f32)gWindowAppearScales[counter] * 0.01;
173 *scaleY = (f32)gWindowAppearScales[counter] * 0.01;
174 *rotZ = (4 - counter) * 3;
175 } else {
177 *scaleX = 1.0f;
178 *scaleY = 1.0f;
179 *rotZ = 0.0f;
180 window->flags &= ~WINDOW_FLAG_INITIAL_ANIMATION;
181 }
182}
183
184void basic_hidden_window_update(s32 windowID, s32* flags, s32* posX, s32* posY, s32* posZ, f32* scaleX, f32* scaleY,
185 f32* rotX, f32* rotY, f32* rotZ, s32* darkening, s32* opacity) {
186 Window* window = &gWindows[windowID];
187 s32 counter = window->updateCounter;
188
189 if (counter <= 9) {
190 *flags = gWindowDisappearFlags[counter];
191 *scaleX = (f32)gWindowDisappearScales[counter] * 0.01;
192 *scaleY = (f32)gWindowDisappearScales[counter] * 0.01;
193 *rotZ = -counter;
194 } else {
196 *scaleX = 0.0f;
197 *scaleY = 0.0f;
198 *rotZ = 0.0f;
199 window->flags &= ~WINDOW_FLAG_INITIAL_ANIMATION;
200 window->flags |= WINDOW_FLAG_HIDDEN;
201 }
202}
203
204void unused_main_menu_window_darkening(s32 windowID, s32* flags, s32* posX, s32* posY, s32* posZ, f32* scaleX, f32* scaleY,
205 f32* rotX, f32* rotY, f32* rotZ, s32* darkening, s32* opacity) {
206 Window* window = &gWindows[windowID];
207 s32 counter = window->updateCounter;
208
209 if (counter < 10) {
210 *darkening = (counter + 1) * 16;
211 } else {
212 *darkening = 160;
214 }
215}
216
217void render_windows(s32* windowsArray, s32 parent, s32 flags, s32 baseX, s32 baseY, s32 opacity, s32 darkening, f32 (*rotScaleMtx)[4]) {
218 Window* window;
219 Window* childWindow;
220 s32 i;
221 s32 childWindowID;
222 s32 counter;
223 Matrix4f matrix;
224 f32 (*outMtx)[4];
225 s32 childFlags;
226 s32 posX, posY, posZ;
227 f32 scaleX, scaleY, rotX, rotY, rotZ;
228 s32 childDarkening, childOpacity;
229 s32 boxFlags;
230 s32 boxTranslateX;
231 s32 boxTranslateY;
232 s32 fpUpdateIdx;
233 s32 width, height;
234 s32 (*fpUpdateFunc)(s32 windowIndex, s32* flags, s32* posX, s32* posY, s32* posZ, f32* scaleX, f32* scaleY,
235 f32* rotX, f32* rotY, f32* rotZ, s32* darkening, s32* opacity);
236 WindowStyle windowStyle;
237 void* fpDrawContents;
238 void* drawContentsArg0;
239
240 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
241 window = &gWindows[parent];
242 childWindowID = windowsArray[i];
243
244 if (childWindowID < 0) {
245 continue;
246 }
247
248 childWindow = &gWindows[childWindowID];
249 if (childWindow->flags == 0 || (childWindow->flags & WINDOW_FLAG_DISABLED)) {
250 continue;
251 }
252
253 fpUpdateIdx = childWindow->fpUpdate.i;
254 if (fpUpdateIdx == 0 || childWindow->parent != parent) {
255 continue;
256 }
257
258 counter = childWindow->updateCounter;
259 posX = childWindow->pos.x;
260 posY = childWindow->pos.y;
261 posZ = 0;
262 childFlags = 0;
263 rotX = rotY = rotZ = 0.0f;
264 scaleY = scaleX = 1.0f;
265 childDarkening = 0;
266 childOpacity = 255;
267 width = childWindow->width;
268 height = childWindow->height;
269
270 if (fpUpdateIdx > 0 && fpUpdateIdx < 14) {
271 SimpleWindowUpdateData* updateData = &gSimpleWindowUpdates[fpUpdateIdx];
272 childWindow->flags |= updateData->windowFlagsSet;
273 childWindow->flags &= ~updateData->windowFlagsUnset;
274
275 if (counter == 0 && (updateData->flags & SIMPLE_WINDOW_UPDATE_1)) {
276 update_window_hierarchy(childWindowID, childWindow->originalPriority);
277 }
278 if (updateData->flags & SIMPLE_WINDOW_UPDATE_DARKENING) {
279 childDarkening = updateData->darkening;
280 }
281 if (updateData->flags & SIMPLE_WINDOW_UPDATE_OPACITY) {
282 childOpacity = updateData->opacity;
283 }
284 } else {
285 //type conversion needed for matching
286 fpUpdateFunc = (s32 (*)(s32 windowIndex, s32* flags, s32* posX, s32* posY, s32* posZ, f32* scaleX, f32* scaleY,
287 f32* rotX, f32* rotY, f32* rotZ, s32* darkening, s32* opacity))(childWindow->fpUpdate.func);
288 fpUpdateFunc(childWindowID, &childFlags, &posX, &posY, &posZ, &scaleX, &scaleY, &rotX, &rotY, &rotZ, &childDarkening, &childOpacity);
289 }
290
291 if (childWindow->fpUpdate.i) {
292 if (childWindow->updateCounter < 255) {
293 childWindow->updateCounter++;
294 }
295 }
296
297 if (scaleX == 0 || scaleY == 0 || (childWindow->flags & WINDOW_FLAG_HIDDEN)) {
298 continue;
299 }
300
301 childDarkening += darkening;
302 childOpacity = childOpacity * opacity / 255;
303 fpDrawContents = childWindow->fpDrawContents;
304 drawContentsArg0 = childWindow->drawContentsArg0;
305 windowStyle = gWindowStyles[childWindowID];
306 outMtx = matrix;
307
308 if (childDarkening > 255) {
309 childDarkening = 255;
310 }
311 childFlags |= flags;
312 if (!(flags & DRAW_FLAG_ROTSCALE)) {
313 posX += baseX;
314 posY += baseY;
315 }
316
317 if (parent == WIN_NONE) {
318 boxTranslateX = SCREEN_WIDTH;
319 } else {
320 boxTranslateX = window->width;
321 }
322
323 boxTranslateY = SCREEN_HEIGHT;
324 if (parent != WIN_NONE) {
325 boxTranslateY = window->height;
326 }
327
328 boxFlags = childFlags;
329 if (childWindow->flags & WINDOW_FLAG_40) {
331 }
332
333 if (draw_box(boxFlags, windowStyle, posX, posY, posZ, width, height, childOpacity, childDarkening,
334 scaleX, scaleY, rotX, rotY, rotZ, fpDrawContents, drawContentsArg0, rotScaleMtx,
335 boxTranslateX, boxTranslateY, outMtx) == 0) {
336 if (childFlags == 0 && rotScaleMtx == 0) {
337 outMtx = NULL;
338 }
339
340 if (childWindow->flags & WINDOW_FLAG_HAS_CHILDREN) {
341 render_windows(windowsArray, childWindowID, childFlags, posX, posY, childOpacity, childDarkening, outMtx);
342 }
343 }
344 }
345}
346
348 s32 priorityArray[ARRAY_COUNT(gWindows)];
349 s32 i;
350
351 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
352 priorityArray[i] = WIN_NONE;
353 }
354
355 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
356 if (gWindows[i].flags != 0) {
357 priorityArray[gWindows[i].priority] = i;
358 }
359 }
360
361 gSPLoadGeometryMode(gMainGfxPos++, 0);
362 gSPSetGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_SHADING_SMOOTH);
363 gDPPipelineMode(gMainGfxPos++, G_PM_NPRIMITIVE);
364 gDPSetCombineMode(gMainGfxPos++, G_CC_SHADE, G_CC_SHADE);
365 gDPSetAlphaCompare(gMainGfxPos++, G_AC_NONE);
366 gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 16, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE);
367 gSPClipRatio(gMainGfxPos++, FRUSTRATIO_2);
368 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
369 gDPPipeSync(gMainGfxPos++);
370 render_windows(priorityArray, WIN_NONE, 0, 0, 0, 255, 0, NULL);
371}
372
373void set_window_properties(s32 windowID, s32 posX, s32 posY, s32 width, s32 height, u8 priority, void* fpDrawContents, void* drawContentsArg0, s8 parent) {
374 Window* window = &gWindows[windowID];
375 u8 priorityCopy = priority;
376
378 window->pos.x = posX;
379 window->pos.y = posY;
380 window->width = width;
381 window->fpUpdate.i = 0;
382 window->parent = parent;
383 window->height = height;
384 window->fpDrawContents = fpDrawContents;
385 window->drawContentsArg0 = drawContentsArg0;
386 if (parent >= 0) {
388 }
389 update_window_hierarchy(windowID, priorityCopy);
390 window->originalPriority = priority;
391}
392
393void update_window_hierarchy(s32 windowID, u8 priority) {
394 s32 priorityArray[ARRAY_COUNT(gWindows) + 1];
395 s32 curPriority;
396 s32 i;
397
398 if (priority > ARRAY_COUNT(gWindows)) {
399 priority = ARRAY_COUNT(gWindows);
400 }
401
402 for (i = 0; i < ARRAY_COUNT(priorityArray); i++) {
403 priorityArray[i] = -1;
404 }
405 priorityArray[priority] = windowID;
406
407 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
408 if (gWindows[i].flags && i != windowID) {
409 curPriority = gWindows[i].priority;
410 if (curPriority >= priority) {
411 curPriority++;
412 }
413 priorityArray[curPriority] = i;
414 }
415 }
416
417 curPriority = 0;
418 for (i = 0; i < ARRAY_COUNT(priorityArray); i++) {
419 s32 windowIdx = priorityArray[i];
420 if (windowIdx != WIN_NONE) {
421 gWindows[windowIdx].priority = curPriority++;
422 }
423 }
424}
425
426void replace_window_update(s32 windowID, s8 priority, WindowUpdateFunc pendingFunc) {
427 if (gWindows[windowID].flags & WINDOW_FLAG_INITIALIZED) {
429 gWindows[windowID].fpPending = pendingFunc;
430 gWindows[windowID].originalPriority = priority;
431 }
432}
433
434void set_window_update(s32 windowID, s32 func) {
435 if (gWindows[windowID].flags & WINDOW_FLAG_INITIALIZED) {
436 if (func == gWindows[windowID].fpUpdate.i) {
437 gWindows[windowID].flags &= ~WINDOW_FLAG_FPUPDATE_CHANGED;
438 } else {
440 gWindows[windowID].fpPending.i = func;
441 }
442 }
443}
444
445void set_windows_visible(s32 groupIdx) {
446 u8 min = gWindowGroups[groupIdx].min;
447 u8 max = gWindowGroups[groupIdx].max;
448 s32 i;
449
450 for (i = 0; i < ARRAY_COUNT(gWindows); i++) {
452 if (i < min || i > max) {
454 } else {
455 gWindows[i].flags &= ~WINDOW_FLAG_DISABLED;
456 }
457 }
458 }
459}
460
461void setup_pause_menu_tab(MenuWindowBP* bp, s32 count) {
462 s32 i;
463
464 for (i = 0; i < count; i++) {
465 set_window_properties(bp->windowID, bp->pos.x, bp->pos.y, bp->width, bp->height, bp->priority,
466 bp->fpDrawContents, bp->tab, bp->parentID);
467 if (bp->style.defaultStyleID != -1) {
468 gWindowStyles[bp->windowID] = bp->style;
469 }
471 gWindows[bp->windowID].flags |= bp->extraFlags;
472 bp++;
473 }
474}
475
u16 * nuGfxCfb_ptr
Definition cam_main.c:14
f32 Matrix4f[4][4]
s8 flags
Definition demo_api.c:15
#define draw_box
@ WINDOW_STYLE_13
Definition enums.h:6383
@ WINDOW_STYLE_0
Definition enums.h:6370
@ WINDOW_STYLE_7
Definition enums.h:6377
@ WINDOW_STYLE_12
Definition enums.h:6382
@ WINDOW_STYLE_14
Definition enums.h:6384
@ WINDOW_STYLE_9
Definition enums.h:6379
@ WINDOW_STYLE_21
Definition enums.h:6391
@ WINDOW_STYLE_10
Definition enums.h:6380
@ WINDOW_STYLE_8
Definition enums.h:6378
@ WINDOW_STYLE_11
Definition enums.h:6381
@ WINDOW_STYLE_3
Definition enums.h:6373
@ WINDOW_STYLE_1
Definition enums.h:6371
@ DRAW_FLAG_ROTSCALE
Definition enums.h:5003
@ DRAW_FLAG_ANIMATED_BACKGROUND
Definition enums.h:5004
@ WINDOW_FLAG_DISABLED
Not updated or rendered.
Definition enums.h:4998
@ WINDOW_FLAG_FPUPDATE_CHANGED
Definition enums.h:4994
@ WINDOW_FLAG_HAS_CHILDREN
Definition enums.h:4997
@ WINDOW_FLAG_40
Definition enums.h:4999
@ WINDOW_FLAG_INITIALIZED
Definition enums.h:4993
@ WINDOW_FLAG_INITIAL_ANIMATION
Definition enums.h:4996
@ WINDOW_FLAG_HIDDEN
Updated but not rendered.
Definition enums.h:4995
@ WINDOW_GROUP_FILES
Definition enums.h:5326
@ WINDOW_GROUP_BATTLE
Definition enums.h:5324
@ WINDOW_GROUP_ALL
Definition enums.h:5323
@ WINDOW_GROUP_PAUSE
Definition enums.h:5325
@ WIN_UNUSED_0
Definition enums.h:5241
@ WIN_FILES_MAIN
Definition enums.h:5288
@ WIN_PAUSE_TAB_INVIS
Definition enums.h:5286
@ WIN_BTL_POPUP
Definition enums.h:5250
@ WIN_FILES_SLOT4_TITLE
Definition enums.h:5307
@ WIN_PAUSE_MAIN
Definition enums.h:5263
@ WIN_NONE
Definition enums.h:5240
@ WIN_BTL_DESC_BOX
Definition enums.h:5249
#define SCREEN_WIDTH
Definition macros.h:105
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define SCREEN_HEIGHT
Definition macros.h:106
MenuPanel * tab
void(* fpDrawContents)(MenuPanel *menu, s32 baseX, s32 baseY, s32 width, s32 height, s32 opacity, s32 darkening)
WindowUpdateFunc fpUpdate
WindowStyle style
void * drawContentsArg0
WindowUpdateFunc fpPending
void(* fpDrawContents)(void)
WindowUpdateFunc fpUpdate
u8 originalPriority
void(* func)(s32 windowIndex, s32 *flags, s32 *posX, s32 *posY, s32 *posZ, f32 *scaleX, f32 *scaleY, f32 *rotX, f32 *rotY, f32 *rotZ, s32 *darkening, s32 *opacity)
Gfx * gMainGfxPos
Definition cam_main.c:15
void basic_window_update(s32 windowID, s32 *flags, s32 *posX, s32 *posY, s32 *posZ, f32 *scaleX, f32 *scaleY, f32 *rotX, f32 *rotY, f32 *rotZ, s32 *darkening, s32 *opacity)
Definition windows.c:161
void basic_hidden_window_update(s32 windowID, s32 *flags, s32 *posX, s32 *posY, s32 *posZ, f32 *scaleX, f32 *scaleY, f32 *rotX, f32 *rotY, f32 *rotZ, s32 *darkening, s32 *opacity)
Definition windows.c:184
void replace_window_update(s32 windowID, s8 priority, WindowUpdateFunc pendingFunc)
Definition windows.c:426
SimpleWindowUpdateFlags
Definition windows.c:4
@ SIMPLE_WINDOW_UPDATE_OPACITY
Definition windows.c:6
@ SIMPLE_WINDOW_UPDATE_DARKENING
Definition windows.c:7
@ SIMPLE_WINDOW_UPDATE_1
Definition windows.c:5
void unused_main_menu_window_darkening(s32 windowID, s32 *flags, s32 *posX, s32 *posY, s32 *posZ, f32 *scaleX, f32 *scaleY, f32 *rotX, f32 *rotY, f32 *rotZ, s32 *darkening, s32 *opacity)
Definition windows.c:204
void update_window_hierarchy(s32 windowID, u8 priority)
Definition windows.c:393
WindowStyle gWindowStyles[64]
Definition windows.c:25
u8 gWindowAppearScales[]
Definition windows.c:121
u8 gWindowDisappearScales[]
Definition windows.c:123
u8 gWindowAppearFlags[]
Definition windows.c:122
void clear_windows(void)
Definition windows.c:135
void update_windows(void)
Definition windows.c:143
void set_window_properties(s32 windowID, s32 posX, s32 posY, s32 width, s32 height, u8 priority, void *fpDrawContents, void *drawContentsArg0, s8 parent)
Definition windows.c:373
void set_windows_visible(s32 groupIdx)
Definition windows.c:445
void setup_pause_menu_tab(MenuWindowBP *bp, s32 count)
Definition windows.c:461
SimpleWindowUpdateData gSimpleWindowUpdates[]
Definition windows.c:44
void render_window_root(void)
Definition windows.c:347
Window gWindows[64]
Definition windows.c:23
u8 gWindowDisappearFlags[]
Definition windows.c:124
void render_windows(s32 *windowsArray, s32 parent, s32 flags, s32 baseX, s32 baseY, s32 opacity, s32 darkening, f32(*rotScaleMtx)[4])
Definition windows.c:217
void set_window_update(s32 windowID, s32 func)
Definition windows.c:434
WindowGroup gWindowGroups[]
Definition windows.c:128