Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/level_update.c
7858 views
1
#include <ultra64.h>
2
3
#include <stdlib.h>
4
5
#include "sm64.h"
6
#include "seq_ids.h"
7
#include "dialog_ids.h"
8
#include "audio/external.h"
9
#include "level_update.h"
10
#include "game_init.h"
11
#include "level_update.h"
12
#include "main.h"
13
#include "engine/math_util.h"
14
#include "engine/graph_node.h"
15
#include "area.h"
16
#include "save_file.h"
17
#include "sound_init.h"
18
#include "mario.h"
19
#include "camera.h"
20
#include "object_list_processor.h"
21
#include "ingame_menu.h"
22
#include "obj_behaviors.h"
23
#include "save_file.h"
24
#include "debug_course.h"
25
#ifdef VERSION_EU
26
#include "memory.h"
27
#include "eu_translation.h"
28
#include "segment_symbols.h"
29
#endif
30
#include "level_table.h"
31
#include "course_table.h"
32
#include "rumble_init.h"
33
#include "behavior_data.h"
34
#include "object_helpers.h"
35
#include "macro_special_objects.h"
36
37
#include "settings.h"
38
39
#define PLAY_MODE_NORMAL 0
40
#define PLAY_MODE_PAUSED 2
41
#define PLAY_MODE_CHANGE_AREA 3
42
#define PLAY_MODE_CHANGE_LEVEL 4
43
#define PLAY_MODE_FRAME_ADVANCE 5
44
45
#define WARP_TYPE_NOT_WARPING 0
46
#define WARP_TYPE_CHANGE_LEVEL 1
47
#define WARP_TYPE_CHANGE_AREA 2
48
#define WARP_TYPE_SAME_AREA 3
49
50
#define WARP_NODE_F0 0xF0
51
#define WARP_NODE_DEATH 0xF1
52
#define WARP_NODE_F2 0xF2
53
#define WARP_NODE_WARP_FLOOR 0xF3
54
#define WARP_NODE_CREDITS_START 0xF8
55
#define WARP_NODE_CREDITS_NEXT 0xF9
56
#define WARP_NODE_CREDITS_END 0xFA
57
58
#define WARP_NODE_CREDITS_MIN 0xF8
59
60
// TODO: Make these ifdefs better
61
const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" };
62
const char *credits02[] = { "2ASSISTANT DIRECTORS", "YOSHIAKI KOIZUMI", "TAKASHI TEZUKA" };
63
const char *credits03[] = { "2SYSTEM PROGRAMMERS", "YASUNARI NISHIDA", "YOSHINORI TANIMOTO" };
64
const char *credits04[] = { "3PROGRAMMERS", "HAJIME YAJIMA", "DAIKI IWAMOTO", "TOSHIO IWAWAKI" };
65
#if defined(VERSION_JP) || defined(VERSION_SH)
66
const char *credits05[] = { "1CAMERA PROGRAMMER", "TAKUMI KAWAGOE" };
67
const char *credits06[] = { "1MARIO FACE PROGRAMMER", "GILES GODDARD" };
68
const char *credits07[] = { "2COURSE DIRECTORS", "YOICHI YAMADA", "YASUHISA YAMAMURA" };
69
const char *credits08[] = { "2COURSE DESIGNERS", "KENTA USUI", "NAOKI MORI" };
70
const char *credits09[] = { "3COURSE DESIGNERS", "YOSHIKI HARUHANA", "MAKOTO MIYANAGA",
71
"KATSUHIKO KANNO" };
72
const char *credits10[] = { "1SOUND COMPOSER", "KOJI KONDO" };
73
74
#ifdef VERSION_SH
75
const char *credits11[] = { "4SOUND EFFECTS", "SOUND PROGRAMMER", "YOJI INAGAKI", "HIDEAKI SHIMIZU" };
76
const char *credits12[] = { "23D ANIMATORS", "YOSHIAKI KOIZUMI", "SATORU TAKIZAWA" };
77
const char *credits13[] = { "1CG DESIGNER", "MASANAO ARIMOTO" };
78
const char *credits14[] = { "3TECHNICAL SUPPORT", "TAKAO SAWANO", "HIROHITO YOSHIMOTO", "HIROTO YADA" };
79
const char *credits15[] = { "1TECHNICAL SUPPORT", "SGI. 64PROJECT STAFF" };
80
const char *credits16[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" };
81
const char *credits17[] = { "4MARIO VOICE", "PEACH VOICE", "CHARLES MARTINET", "LESLIE SWAN" };
82
const char *credits18[] = { "3SPECIAL THANKS TO", "JYOHO KAIHATUBU", "ALL NINTENDO",
83
"MARIO CLUB STAFF" };
84
const char *credits19[] = { "1PRODUCER", "SHIGERU MIYAMOTO" };
85
const char *credits20[] = { "1EXECUTIVE PRODUCER", "HIROSHI YAMAUCHI" };
86
#else // VERSION_JP
87
const char *credits11[] = { "1SOUND EFFECTS", "YOJI INAGAKI" };
88
const char *credits12[] = { "1SOUND PROGRAMMER", "HIDEAKI SHIMIZU" };
89
const char *credits13[] = { "23D ANIMATORS", "YOSHIAKI KOIZUMI", "SATORU TAKIZAWA" };
90
const char *credits14[] = { "1CG DESIGNER", "MASANAO ARIMOTO" };
91
const char *credits15[] = { "3TECHNICAL SUPPORT", "TAKAO SAWANO", "HIROHITO YOSHIMOTO", "HIROTO YADA" };
92
const char *credits16[] = { "1TECHNICAL SUPPORT", "SGI. 64PROJECT STAFF" };
93
const char *credits17[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" };
94
const char *credits18[] = { "3SPECIAL THANKS TO", "JYOHO KAIHATUBU", "ALL NINTENDO",
95
"MARIO CLUB STAFF" };
96
const char *credits19[] = { "1PRODUCER", "SHIGERU MIYAMOTO" };
97
const char *credits20[] = { "1EXECUTIVE PRODUCER", "HIROSHI YAMAUCHI" };
98
#endif
99
#else // VERSION_US || VERSION_EU
100
const char *credits05[] = {
101
"4CAMERA PROGRAMMER", "MARIO FACE PROGRAMMER", "TAKUMI KAWAGOE", "GILES GODDARD"
102
}; // US combines camera programmer and Mario face programmer
103
const char *credits06[] = { "2COURSE DIRECTORS", "YOICHI YAMADA", "YASUHISA YAMAMURA" };
104
const char *credits07[] = { "2COURSE DESIGNERS", "KENTA USUI", "NAOKI MORI" };
105
const char *credits08[] = { "3COURSE DESIGNERS", "YOSHIKI HARUHANA", "MAKOTO MIYANAGA",
106
"KATSUHIKO KANNO" };
107
#ifdef VERSION_US
108
const char *credits09[] = { "1SOUND COMPOSER", "KOJI KONDO" };
109
const char *credits10[] = { "4SOUND EFFECTS", "SOUND PROGRAMMER", "YOJI INAGAKI",
110
"HIDEAKI SHIMIZU" }; // as well as sound effects and sound programmer
111
const char *credits11[] = { "23-D ANIMATORS", "YOSHIAKI KOIZUMI", "SATORU TAKIZAWA" };
112
const char *credits12[] = { "1ADDITIONAL GRAPHICS", "MASANAO ARIMOTO" };
113
const char *credits13[] = { "3TECHNICAL SUPPORT", "TAKAO SAWANO", "HIROHITO YOSHIMOTO", "HIROTO YADA" };
114
const char *credits14[] = { "1TECHNICAL SUPPORT", "SGI N64 PROJECT STAFF" };
115
const char *credits15[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" };
116
const char *credits16[] = { "5SCREEN TEXT WRITER", "TRANSLATION", "LESLIE SWAN", "MINA AKINO",
117
"HIRO YAMADA" }; // ...in order to make room for these 2 new lines
118
#else // VERSION_EU
119
const char *credits09[] = { "7SOUND COMPOSER", "SOUND EFFECTS", "SOUND PROGRAMMER", "KOJI KONDO",
120
"YOJI INAGAKI", "HIDEAKI SHIMIZU" };
121
const char *credits10[] = { "63-D ANIMATORS", "ADDITIONAL GRAPHICS", "YOSHIAKI KOIZUMI", "SATORU TAKIZAWA",
122
"MASANAO ARIMOTO" };
123
const char *credits11[] = { "3TECHNICAL SUPPORT", "TAKAO SAWANO", "HIROHITO YOSHIMOTO", "HIROTO YADA" };
124
const char *credits12[] = { "1TECHNICAL SUPPORT", "SGI N64 PROJECT STAFF" };
125
const char *credits13[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" };
126
const char *credits14[] = { "5SCREEN TEXT WRITER", "ENGLISH TRANSLATION", "LESLIE SWAN", "MINA AKINO",
127
"HIRO YAMADA" };
128
const char *credits15[] = { "4SCREEN TEXT WRITER", "FRENCH TRANSLATION", "JULIEN BARDAKOFF",
129
"KENJI HARAGUCHI" };
130
const char *credits16[] = { "4SCREEN TEXT WRITER", "GERMAN TRANSLATION", "THOMAS GOERG",
131
"THOMAS SPINDLER" };
132
#endif
133
const char *credits17[] = { "4MARIO VOICE", "PEACH VOICE", "CHARLES MARTINET", "LESLIE SWAN" };
134
const char *credits18[] = { "3SM64 PLUS BY", "MORS", "SM64 PORT TEAM", "SM64 DECOMP TEAM" };
135
/*const char *credits18[] = { "3SPECIAL THANKS TO", "EAD STAFF", "ALL NINTENDO PERSONNEL",
136
#ifdef VERSION_US
137
"MARIO CLUB STAFF" };
138
#else // VERSION_EU
139
"SUPER MARIO CLUB STAFF" };
140
#endif*/
141
const char *credits19[] = { "1PRODUCER", "SHIGERU MIYAMOTO" };
142
const char *credits20[] = { "1EXECUTIVE PRODUCER", "HIROSHI YAMAUCHI" };
143
#endif
144
145
146
struct CreditsEntry sCreditsSequence[] = {
147
{ LEVEL_CASTLE_GROUNDS, 1, 1, -128, { 0, 8000, 0 }, NULL },
148
{ LEVEL_BOB, 1, 1, 117, { 713, 3918, -3889 }, credits01 },
149
{ LEVEL_WF, 1, 50, 46, { 347, 5376, 326 }, credits02 },
150
{ LEVEL_JRB, 1, 18, 22, { 3800, -4840, 2727 }, credits03 },
151
{ LEVEL_CCM, 2, 34, 25, { -5464, 6656, -6575 }, credits04 },
152
{ LEVEL_BBH, 1, 1, 60, { 257, 1922, 2580 }, credits05 },
153
{ LEVEL_HMC, 1, -15, 123, { -6469, 1616, -6054 }, credits06 },
154
{ LEVEL_THI, 3, 17, -32, { 508, 1024, 1942 }, credits07 },
155
{ LEVEL_LLL, 2, 33, 124, { -73, 82, -1467 }, credits08 },
156
{ LEVEL_SSL, 1, 65, 98, { -5906, 1024, -2576 }, credits09 },
157
{ LEVEL_DDD, 1, 50, 47, { -4884, -4607, -272 }, credits10 },
158
{ LEVEL_SL, 1, 17, -34, { 1925, 3328, 563 }, credits11 },
159
{ LEVEL_WDW, 1, 33, 105, { -537, 1850, 1818 }, credits12 },
160
{ LEVEL_TTM, 1, 2, -33, { 2613, 313, 1074 }, credits13 },
161
{ LEVEL_THI, 1, 51, 54, { -2609, 512, 856 }, credits14 },
162
{ LEVEL_TTC, 1, 17, -72, { -1304, -71, -967 }, credits15 },
163
{ LEVEL_RR, 1, 33, 64, { 1565, 1024, -148 }, credits16 },
164
{ LEVEL_SA, 1, 1, 24, { -1050, -1330, -1559 }, credits17 },
165
{ LEVEL_COTMC, 1, 49, -16, { -254, 415, -6045 }, credits18 },
166
{ LEVEL_DDD, 2, -111, -64, { 3948, 1185, -104 }, credits19 },
167
{ LEVEL_CCM, 1, 33, 31, { 3169, -4607, 5240 }, credits20 },
168
{ LEVEL_CASTLE_GROUNDS, 1, 1, -128, { 0, 906, -1200 }, NULL },
169
{ LEVEL_NONE, 0, 1, 0, { 0, 0, 0 }, NULL },
170
};
171
172
struct MarioState gMarioStates[1];
173
struct HudDisplay gHudDisplay;
174
s16 sCurrPlayMode;
175
u16 D_80339ECA;
176
s16 sTransitionTimer;
177
void (*sTransitionUpdate)(s16 *);
178
struct WarpDest sWarpDest;
179
s16 D_80339EE0;
180
s16 sDelayedWarpOp;
181
s16 sDelayedWarpTimer;
182
s16 sSourceWarpNodeId;
183
s32 sDelayedWarpArg;
184
#if defined(VERSION_EU) || defined(VERSION_SH)
185
s16 unusedEULevelUpdateBss1;
186
#endif
187
s8 sTimerRunning;
188
s8 gNeverEnteredCastle;
189
190
struct MarioState *gMarioState = &gMarioStates[0];
191
u8 unused1[4] = { 0 };
192
s8 sWarpCheckpointActive = FALSE;
193
u8 unused3[4];
194
u8 unused4[2];
195
196
u16 level_control_timer(s32 timerOp) {
197
switch (timerOp) {
198
case TIMER_CONTROL_SHOW:
199
gHudDisplay.flags |= HUD_DISPLAY_FLAG_TIMER;
200
sTimerRunning = FALSE;
201
gHudDisplay.timer = 0;
202
break;
203
204
case TIMER_CONTROL_START:
205
sTimerRunning = TRUE;
206
break;
207
208
case TIMER_CONTROL_STOP:
209
sTimerRunning = FALSE;
210
break;
211
212
case TIMER_CONTROL_HIDE:
213
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_TIMER;
214
sTimerRunning = FALSE;
215
gHudDisplay.timer = 0;
216
break;
217
}
218
219
return gHudDisplay.timer;
220
}
221
222
u32 pressed_pause(void) {
223
u32 dialogActive = get_dialog_id() >= 0;
224
u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0;
225
226
if (!intangible && !dialogActive && !gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE
227
&& (gPlayer1Controller->buttonPressed & START_BUTTON)) {
228
return TRUE;
229
}
230
231
return FALSE;
232
}
233
234
void set_play_mode(s16 playMode) {
235
sCurrPlayMode = playMode;
236
D_80339ECA = 0;
237
}
238
239
void warp_special(s32 arg) {
240
sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL;
241
D_80339ECA = 0;
242
D_80339EE0 = arg;
243
}
244
245
void fade_into_special_warp(u32 arg, u32 color) {
246
if (color != 0) {
247
color = 0xFF;
248
}
249
250
fadeout_music(190);
251
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x10, color, color, color);
252
level_set_transition(30, NULL);
253
254
warp_special(arg);
255
}
256
257
void stub_level_update_1(void) {
258
}
259
260
void load_level_init_text(u32 arg) {
261
s32 gotAchievement;
262
u32 dialogID = gCurrentArea->dialog[arg];
263
264
if (configSkipCutscenes)
265
return;
266
267
switch (dialogID) {
268
case DIALOG_129:
269
gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_VANISH_CAP;
270
break;
271
272
case DIALOG_130:
273
gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_METAL_CAP;
274
break;
275
276
case DIALOG_131:
277
gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_WING_CAP;
278
break;
279
280
case (u8)DIALOG_NONE: // 255, cast value to u8 to match (-1)
281
gotAchievement = TRUE;
282
break;
283
284
default:
285
gotAchievement = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
286
break;
287
}
288
289
if (!gotAchievement) {
290
level_set_transition(-1, NULL);
291
create_dialog_box(dialogID);
292
}
293
}
294
295
void init_door_warp(struct SpawnInfo *spawnInfo, u32 arg1) {
296
if (arg1 & 0x00000002) {
297
spawnInfo->startAngle[1] += 0x8000;
298
}
299
300
spawnInfo->startPos[0] += 300.0f * sins(spawnInfo->startAngle[1]);
301
spawnInfo->startPos[2] += 300.0f * coss(spawnInfo->startAngle[1]);
302
}
303
304
void set_mario_initial_cap_powerup(struct MarioState *m) {
305
u32 capCourseIndex = gCurrCourseNum - COURSE_CAP_COURSES;
306
307
switch (capCourseIndex) {
308
case COURSE_COTMC - COURSE_CAP_COURSES:
309
m->flags |= MARIO_METAL_CAP | MARIO_CAP_ON_HEAD;
310
m->capTimer = 600;
311
break;
312
313
case COURSE_TOTWC - COURSE_CAP_COURSES:
314
m->flags |= MARIO_WING_CAP | MARIO_CAP_ON_HEAD;
315
m->capTimer = 1200;
316
break;
317
318
case COURSE_VCUTM - COURSE_CAP_COURSES:
319
m->flags |= MARIO_VANISH_CAP | MARIO_CAP_ON_HEAD;
320
m->capTimer = 600;
321
break;
322
}
323
}
324
325
void set_mario_initial_action(struct MarioState *m, u32 spawnType, u32 actionArg) {
326
switch (spawnType) {
327
case MARIO_SPAWN_DOOR_WARP:
328
set_mario_action(m, ACT_WARP_DOOR_SPAWN, actionArg);
329
break;
330
case MARIO_SPAWN_UNKNOWN_02:
331
set_mario_action(m, ACT_IDLE, 0);
332
break;
333
case MARIO_SPAWN_UNKNOWN_03:
334
set_mario_action(m, ACT_EMERGE_FROM_PIPE, 0);
335
break;
336
case MARIO_SPAWN_TELEPORT:
337
set_mario_action(m, ACT_TELEPORT_FADE_IN, 0);
338
break;
339
case MARIO_SPAWN_INSTANT_ACTIVE:
340
set_mario_action(m, ACT_IDLE, 0);
341
break;
342
case MARIO_SPAWN_AIRBORNE:
343
set_mario_action(m, ACT_SPAWN_NO_SPIN_AIRBORNE, 0);
344
break;
345
case MARIO_SPAWN_HARD_AIR_KNOCKBACK:
346
set_mario_action(m, ACT_HARD_BACKWARD_AIR_KB, 0);
347
break;
348
case MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE:
349
set_mario_action(m, ACT_SPAWN_SPIN_AIRBORNE, 0);
350
break;
351
case MARIO_SPAWN_DEATH:
352
set_mario_action(m, ACT_FALLING_DEATH_EXIT, 0);
353
break;
354
case MARIO_SPAWN_SPIN_AIRBORNE:
355
set_mario_action(m, ACT_SPAWN_SPIN_AIRBORNE, 0);
356
break;
357
case MARIO_SPAWN_FLYING:
358
set_mario_action(m, ACT_FLYING, 2);
359
break;
360
case MARIO_SPAWN_SWIMMING:
361
set_mario_action(m, ACT_WATER_IDLE, 1);
362
break;
363
case MARIO_SPAWN_PAINTING_STAR_COLLECT:
364
set_mario_action(m, ACT_EXIT_AIRBORNE, 0);
365
break;
366
case MARIO_SPAWN_PAINTING_DEATH:
367
set_mario_action(m, ACT_DEATH_EXIT, 0);
368
break;
369
case MARIO_SPAWN_AIRBORNE_STAR_COLLECT:
370
set_mario_action(m, ACT_FALLING_EXIT_AIRBORNE, 0);
371
break;
372
case MARIO_SPAWN_AIRBORNE_DEATH:
373
set_mario_action(m, ACT_UNUSED_DEATH_EXIT, 0);
374
break;
375
case MARIO_SPAWN_LAUNCH_STAR_COLLECT:
376
set_mario_action(m, ACT_SPECIAL_EXIT_AIRBORNE, 0);
377
break;
378
case MARIO_SPAWN_LAUNCH_DEATH:
379
set_mario_action(m, ACT_SPECIAL_DEATH_EXIT, 0);
380
break;
381
}
382
383
set_mario_initial_cap_powerup(m);
384
}
385
386
void init_mario_after_warp(void) {
387
struct ObjectWarpNode *spawnNode = area_get_warp_node(sWarpDest.nodeId);
388
u32 marioSpawnType = get_mario_spawn_type(spawnNode->object);
389
390
if (gMarioState->action != ACT_UNINITIALIZED) {
391
gPlayerSpawnInfos[0].startPos[0] = (s16) spawnNode->object->oPosX;
392
gPlayerSpawnInfos[0].startPos[1] = (s16) spawnNode->object->oPosY;
393
gPlayerSpawnInfos[0].startPos[2] = (s16) spawnNode->object->oPosZ;
394
395
gPlayerSpawnInfos[0].startAngle[0] = 0;
396
gPlayerSpawnInfos[0].startAngle[1] = spawnNode->object->oMoveAngleYaw;
397
gPlayerSpawnInfos[0].startAngle[2] = 0;
398
399
if (marioSpawnType == MARIO_SPAWN_DOOR_WARP) {
400
init_door_warp(&gPlayerSpawnInfos[0], sWarpDest.arg);
401
}
402
403
if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL || sWarpDest.type == WARP_TYPE_CHANGE_AREA) {
404
gPlayerSpawnInfos[0].areaIndex = sWarpDest.areaIdx;
405
load_mario_area();
406
}
407
408
init_mario();
409
set_mario_initial_action(gMarioState, marioSpawnType, sWarpDest.arg);
410
411
gMarioState->interactObj = spawnNode->object;
412
gMarioState->usedObj = spawnNode->object;
413
}
414
415
reset_camera(gCurrentArea->camera);
416
sWarpDest.type = WARP_TYPE_NOT_WARPING;
417
sDelayedWarpOp = WARP_OP_NONE;
418
419
switch (marioSpawnType) {
420
case MARIO_SPAWN_UNKNOWN_03:
421
play_transition(WARP_TRANSITION_FADE_FROM_STAR, 0x10, 0x00, 0x00, 0x00);
422
break;
423
case MARIO_SPAWN_DOOR_WARP:
424
play_transition(WARP_TRANSITION_FADE_FROM_CIRCLE, 0x10, 0x00, 0x00, 0x00);
425
break;
426
case MARIO_SPAWN_TELEPORT:
427
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 0x14, 0xFF, 0xFF, 0xFF);
428
break;
429
case MARIO_SPAWN_SPIN_AIRBORNE:
430
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 0x1A, 0xFF, 0xFF, 0xFF);
431
break;
432
case MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE:
433
play_transition(WARP_TRANSITION_FADE_FROM_CIRCLE, 0x10, 0x00, 0x00, 0x00);
434
break;
435
case MARIO_SPAWN_UNKNOWN_27:
436
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 0x10, 0x00, 0x00, 0x00);
437
break;
438
default:
439
play_transition(WARP_TRANSITION_FADE_FROM_STAR, 0x10, 0x00, 0x00, 0x00);
440
break;
441
}
442
443
if (gCurrDemoInput == NULL) {
444
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
445
446
if (gMarioState->flags & MARIO_METAL_CAP) {
447
play_cap_music(SEQUENCE_ARGS(4, SEQ_EVENT_METAL_CAP));
448
}
449
450
if (gMarioState->flags & (MARIO_VANISH_CAP | MARIO_WING_CAP)) {
451
play_cap_music(SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP));
452
}
453
454
#ifndef VERSION_JP
455
if (gCurrLevelNum == LEVEL_BOB
456
&& get_current_background_music() != SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE)
457
&& sTimerRunning) {
458
play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE), 0);
459
}
460
#endif
461
462
if (sWarpDest.levelNum == LEVEL_CASTLE && sWarpDest.areaIdx == 1
463
#ifndef VERSION_JP
464
&& (sWarpDest.nodeId == 31 || sWarpDest.nodeId == 32)
465
#else
466
&& sWarpDest.nodeId == 31
467
#endif
468
)
469
play_sound(SOUND_MENU_MARIO_CASTLE_WARP, gGlobalSoundSource);
470
#ifndef VERSION_JP
471
if (sWarpDest.levelNum == LEVEL_CASTLE_GROUNDS && sWarpDest.areaIdx == 1
472
&& (sWarpDest.nodeId == 7 || sWarpDest.nodeId == 10 || sWarpDest.nodeId == 20
473
|| sWarpDest.nodeId == 30)) {
474
play_sound(SOUND_MENU_MARIO_CASTLE_WARP, gGlobalSoundSource);
475
}
476
#endif
477
}
478
}
479
480
void remain_mod_load_area()
481
{
482
struct ObjectWarpNode *spawnNode = area_get_warp_node(sWarpDest.nodeId);
483
484
if ((gCurrCourseNum == COURSE_WF) && (spawnNode->object->oBehParams == 0x000D0000))
485
{
486
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_LEVEL_GEOMETRY_08, bhvTower, 0x00000000, 0, 3584, 0, 0, 0, 0);
487
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_NONE, bhvTowerPlatformGroup, 0x00000000, 0, 3483, 0, 0, 0, 0);
488
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_WF_TOWER_DOOR, bhvTowerDoor, 0x00000000, -511, 3584, 0, 0, 0, 0);
489
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_WF_KICKABLE_BOARD, bhvKickableBoard, 0x00000000, 13, 3584, -1407, 0, 315, 0);
490
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_1UP, bhv1Up, 0x00000000, -384, 3584, 6, 0, 0, 0);
491
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_BULLET_BILL, bhvBulletBill, 0x00000000, 1280, 3712, 968, 0, 180, 0);
492
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_LEVEL_GEOMETRY_09, bhvBulletBillCannon, 0x00000000, 1280, 3584, 896, 0, 0, 0);
493
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_STAR, bhvStar, 0x01000000, 300, 5550, 0, 0, 0, 0);
494
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_BOBOMB_BUDDY, bhvBobombBuddyOpensCannon, 0x00000000, -1700, 1140, 3500, 0, 0, 0);
495
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_HOOT, bhvHoot, 0x00000000, 2560, 700, 4608, 0, 0, 0);
496
}
497
if ((gCurrCourseNum == COURSE_JRB) && (spawnNode->object->oBehParams == 0x000B0000))
498
{
499
set_camera_mode(gMarioState->area->camera, CAMERA_MODE_FREE_ROAM, 1); // Fixes a bug where camera is set to CAMERA_MODE_BEHIND_MARIO for some reason
500
501
struct Object *objToDelete;
502
503
objToDelete = cur_obj_nearest_object_with_behavior(bhvUnagi);
504
if (objToDelete != NULL)
505
{
506
obj_mark_for_deletion(objToDelete);
507
}
508
509
for (int i = 0; i < 2; i++)
510
{
511
objToDelete = cur_obj_nearest_object_with_behavior(bhvSunkenShipPart);
512
if (objToDelete != NULL) {
513
obj_mark_for_deletion(objToDelete);
514
}
515
}
516
517
for (int i = 0; i < 2; i++)
518
{
519
objToDelete = cur_obj_nearest_object_with_behavior(bhvSunkenShipPart2);
520
if (objToDelete != NULL)
521
{
522
obj_mark_for_deletion(objToDelete);
523
}
524
}
525
526
objToDelete = cur_obj_nearest_object_with_behavior(bhvInSunkenShip);
527
if (objToDelete != NULL)
528
{
529
obj_mark_for_deletion(objToDelete);
530
}
531
532
objToDelete = cur_obj_nearest_object_with_behavior(bhvInSunkenShip2);
533
if (objToDelete != NULL)
534
{
535
obj_mark_for_deletion(objToDelete);
536
}
537
538
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_STAR, bhvStar, 0x05000000, 5000, -4800, 2500, 0, 0, 0);
539
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_JRB_SHIP_LEFT_HALF_PART, bhvShipPart3, 0x00000000, 4880, 820, 2375, 0, 0, 0);
540
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_JRB_SHIP_BACK_LEFT_PART, bhvShipPart3, 0x00000000, 4880, 820, 2375, 0, 0, 0);
541
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_JRB_SHIP_RIGHT_HALF_PART, bhvShipPart3, 0x00000000, 4880, 820, 2375, 0, 0, 0);
542
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_JRB_SHIP_BACK_RIGHT_PART, bhvShipPart3, 0x00000000, 4880, 820, 2375, 0, 0, 0);
543
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_NONE, bhvInSunkenShip3, 0x00000000, 4880, 820, 2375, 0, 0, 0);
544
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_JRB_SLIDING_BOX, bhvJrbSlidingBox, 0x00000000, 4668, 1434, 2916, 0, 0, 0);
545
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_NONE, bhvJetStream, 0x00000000, 4988, -5221, 2473, 0, 0, 0);
546
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_BOBOMB_BUDDY, bhvBobombBuddyOpensCannon, 0x00000000, -1956, 1331, 6500, 0, 0, 0);
547
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_UNAGI, bhvUnagi, 0x01010000, 8270, -3130, 1846, 0, 285, 0);
548
549
gCurrentArea->whirlpools[0]->strength = -30;
550
}
551
if ((gCurrCourseNum == COURSE_DDD) && (spawnNode->object->oBehParams == 0x000C0000))
552
{
553
struct Object *objToDelete;
554
555
objToDelete = cur_obj_nearest_object_with_behavior(bhvBowserSubDoor);
556
if (objToDelete != NULL)
557
{
558
obj_mark_for_deletion(objToDelete);
559
}
560
561
objToDelete = cur_obj_nearest_object_with_behavior(bhvBowsersSub);
562
if (objToDelete != NULL)
563
{
564
obj_mark_for_deletion(objToDelete);
565
}
566
567
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x001E0000, 5120, 1005, 3584, 0, 180, 0);
568
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x00150000, 5605, 1005, 3380, 0, 270, 0);
569
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x000B0000, 1800, 1005, 1275, 0, 0, 0);
570
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x000B0000, 4000, 1005, 1075, 0, 180, 0);
571
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x00140000, 1830, 1005, 520, 0, 270, 0);
572
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x000B0000, 4000, 1005, 1275, 0, 0, 0);
573
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x00170000, 5760, 1005, 360, 0, 270, 0);
574
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x00170000, 3310, 1005, -1945, 0, 0, 0);
575
spawn_object_abs_with_rot_degrees(spawnNode->object, 0, MODEL_DDD_POLE, bhvDDDPole, 0x000D0000, 3550, 1005, -2250, 0, 0, 0);
576
577
gCurrentArea->whirlpools[1]->strength = 50;
578
}
579
if ((gCurrCourseNum == COURSE_TTC) && (spawnNode->object->oBehParams == 0x000C0000))
580
{
581
gTTCSpeedSetting = (gTTCSpeedSetting + 1) % 4;
582
despawn_macro_objects(gCurrentArea->macroObjects);
583
spawn_macro_objects(1, gCurrentArea->macroObjects);
584
}
585
}
586
587
// used for warps inside one level
588
void warp_area(void) {
589
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
590
if (sWarpDest.type == WARP_TYPE_CHANGE_AREA) {
591
level_control_timer(TIMER_CONTROL_HIDE);
592
unload_mario_area();
593
load_area(sWarpDest.areaIdx);
594
}
595
596
init_mario_after_warp();
597
598
if (configStayInCourse == 2)
599
{
600
remain_mod_load_area();
601
}
602
}
603
}
604
605
// used for warps between levels
606
void warp_level(void) {
607
gCurrLevelNum = sWarpDest.levelNum;
608
609
level_control_timer(TIMER_CONTROL_HIDE);
610
611
load_area(sWarpDest.areaIdx);
612
init_mario_after_warp();
613
}
614
615
void warp_credits(void) {
616
s32 marioAction;
617
618
switch (sWarpDest.nodeId) {
619
case WARP_NODE_CREDITS_START:
620
marioAction = ACT_END_PEACH_CUTSCENE;
621
break;
622
623
case WARP_NODE_CREDITS_NEXT:
624
marioAction = ACT_CREDITS_CUTSCENE;
625
break;
626
627
case WARP_NODE_CREDITS_END:
628
marioAction = ACT_END_WAVING_CUTSCENE;
629
break;
630
}
631
632
gCurrLevelNum = sWarpDest.levelNum;
633
634
load_area(sWarpDest.areaIdx);
635
636
vec3s_set(gPlayerSpawnInfos[0].startPos, gCurrCreditsEntry->marioPos[0],
637
gCurrCreditsEntry->marioPos[1], gCurrCreditsEntry->marioPos[2]);
638
639
vec3s_set(gPlayerSpawnInfos[0].startAngle, 0, 0x100 * gCurrCreditsEntry->marioAngle, 0);
640
641
gPlayerSpawnInfos[0].areaIndex = sWarpDest.areaIdx;
642
643
load_mario_area();
644
init_mario();
645
646
set_mario_action(gMarioState, marioAction, 0);
647
648
reset_camera(gCurrentArea->camera);
649
650
sWarpDest.type = WARP_TYPE_NOT_WARPING;
651
sDelayedWarpOp = WARP_OP_NONE;
652
653
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 0x14, 0x00, 0x00, 0x00);
654
655
if (gCurrCreditsEntry == NULL || gCurrCreditsEntry == sCreditsSequence) {
656
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
657
}
658
}
659
660
void check_instant_warp(void) {
661
s16 cameraAngle;
662
struct Surface *floor;
663
664
if (gCurrLevelNum == LEVEL_CASTLE
665
&& save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 70) {
666
return;
667
}
668
669
if ((floor = gMarioState->floor) != NULL) {
670
s32 index = floor->type - SURFACE_INSTANT_WARP_1B;
671
if (index >= INSTANT_WARP_INDEX_START && index < INSTANT_WARP_INDEX_STOP
672
&& gCurrentArea->instantWarps != NULL) {
673
struct InstantWarp *warp = &gCurrentArea->instantWarps[index];
674
675
if (warp->id != 0) {
676
gMarioState->pos[0] += warp->displacement[0];
677
gMarioState->pos[1] += warp->displacement[1];
678
gMarioState->pos[2] += warp->displacement[2];
679
680
gMarioState->marioObj->oPosX = gMarioState->pos[0];
681
gMarioState->marioObj->oPosY = gMarioState->pos[1];
682
gMarioState->marioObj->oPosZ = gMarioState->pos[2];
683
684
cameraAngle = gMarioState->area->camera->yaw;
685
686
change_area(warp->area);
687
gMarioState->area = gCurrentArea;
688
689
warp_camera(warp->displacement[0], warp->displacement[1], warp->displacement[2]);
690
691
gMarioState->area->camera->yaw = cameraAngle;
692
}
693
}
694
}
695
}
696
697
s16 music_changed_through_warp(s16 arg) {
698
struct ObjectWarpNode *warpNode = area_get_warp_node(arg);
699
s16 levelNum = warpNode->node.destLevel & 0x7F;
700
701
#if BUGFIX_KOOPA_RACE_MUSIC
702
703
s16 destArea = warpNode->node.destArea;
704
s16 val4 = TRUE;
705
s16 sp2C;
706
707
if (levelNum == LEVEL_BOB && levelNum == gCurrLevelNum && destArea == gCurrAreaIndex) {
708
sp2C = get_current_background_music();
709
if (sp2C == SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP | SEQ_VARIATION)
710
|| sp2C == SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP)) {
711
val4 = 0;
712
}
713
} else {
714
u16 val8 = gAreas[destArea].musicParam;
715
u16 val6 = gAreas[destArea].musicParam2;
716
717
val4 = levelNum == gCurrLevelNum && val8 == gCurrentArea->musicParam
718
&& val6 == gCurrentArea->musicParam2;
719
720
if (get_current_background_music() != val6) {
721
val4 = FALSE;
722
}
723
}
724
return val4;
725
726
#else
727
728
u16 val8 = gAreas[warpNode->node.destArea].musicParam;
729
u16 val6 = gAreas[warpNode->node.destArea].musicParam2;
730
731
s16 val4 = levelNum == gCurrLevelNum && val8 == gCurrentArea->musicParam
732
&& val6 == gCurrentArea->musicParam2;
733
734
if (get_current_background_music() != val6) {
735
val4 = FALSE;
736
}
737
return val4;
738
739
#endif
740
}
741
742
/**
743
* Set the current warp type and destination level/area/node.
744
*/
745
void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3) {
746
if (destWarpNode >= WARP_NODE_CREDITS_MIN) {
747
sWarpDest.type = WARP_TYPE_CHANGE_LEVEL;
748
} else if (destLevel != gCurrLevelNum) {
749
sWarpDest.type = WARP_TYPE_CHANGE_LEVEL;
750
} else if (destArea != gCurrentArea->index) {
751
sWarpDest.type = WARP_TYPE_CHANGE_AREA;
752
} else {
753
sWarpDest.type = WARP_TYPE_SAME_AREA;
754
}
755
756
sWarpDest.levelNum = destLevel;
757
sWarpDest.areaIdx = destArea;
758
sWarpDest.nodeId = destWarpNode;
759
sWarpDest.arg = arg3;
760
}
761
762
// From Surface 0xD3 to 0xFC
763
#define PAINTING_WARP_INDEX_START 0x00 // Value greater than or equal to Surface 0xD3
764
#define PAINTING_WARP_INDEX_FA 0x2A // THI Huge Painting index left
765
#define PAINTING_WARP_INDEX_END 0x2D // Value less than Surface 0xFD
766
767
/**
768
* Check if Mario is above and close to a painting warp floor, and return the
769
* corresponding warp node.
770
*/
771
struct WarpNode *get_painting_warp_node(void) {
772
struct WarpNode *warpNode = NULL;
773
s32 paintingIndex = gMarioState->floor->type - SURFACE_PAINTING_WARP_D3;
774
775
if (paintingIndex >= PAINTING_WARP_INDEX_START && paintingIndex < PAINTING_WARP_INDEX_END) {
776
if (paintingIndex < PAINTING_WARP_INDEX_FA
777
|| gMarioState->pos[1] - gMarioState->floorHeight < 80.0f) {
778
warpNode = &gCurrentArea->paintingWarpNodes[paintingIndex];
779
}
780
}
781
782
return warpNode;
783
}
784
785
/**
786
* Check is Mario has entered a painting, and if so, initiate a warp.
787
*/
788
void initiate_painting_warp(void) {
789
if (gCurrentArea->paintingWarpNodes != NULL && gMarioState->floor != NULL) {
790
struct WarpNode warpNode;
791
struct WarpNode *pWarpNode = get_painting_warp_node();
792
793
if (pWarpNode != NULL) {
794
if (gMarioState->action & ACT_FLAG_INTANGIBLE) {
795
play_painting_eject_sound();
796
} else if (pWarpNode->id != 0) {
797
warpNode = *pWarpNode;
798
799
if (!(warpNode.destLevel & 0x80)) {
800
sWarpCheckpointActive = check_warp_checkpoint(&warpNode);
801
}
802
803
initiate_warp(warpNode.destLevel & 0x7F, warpNode.destArea, warpNode.destNode, 0);
804
check_if_should_set_warp_checkpoint(&warpNode);
805
806
play_transition_after_delay(WARP_TRANSITION_FADE_INTO_COLOR, 30, 255, 255, 255, 45);
807
level_set_transition(74, basic_update);
808
809
set_mario_action(gMarioState, ACT_DISAPPEARED, 0);
810
811
gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
812
813
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
814
fadeout_music(398);
815
#if ENABLE_RUMBLE
816
queue_rumble_data(80, 70);
817
func_sh_8024C89C(1);
818
#endif
819
}
820
}
821
}
822
}
823
824
/**
825
* If there is not already a delayed warp, schedule one. The source node is
826
* based on the warp operation and sometimes Mario's used object.
827
* Return the time left until the delayed warp is initiated.
828
*/
829
s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
830
s32 val04 = TRUE;
831
832
if (sDelayedWarpOp == WARP_OP_NONE) {
833
m->invincTimer = -1;
834
sDelayedWarpArg = 0;
835
sDelayedWarpOp = warpOp;
836
837
save_file_set_num_lives(m->numLives);
838
839
switch (warpOp) {
840
case WARP_OP_DEMO_NEXT:
841
case WARP_OP_DEMO_END: sDelayedWarpTimer = 20; // Must be one line to match on -O2
842
sSourceWarpNodeId = WARP_NODE_F0;
843
gSavedCourseNum = COURSE_NONE;
844
val04 = FALSE;
845
play_transition(WARP_TRANSITION_FADE_INTO_STAR, 0x14, 0x00, 0x00, 0x00);
846
break;
847
848
case WARP_OP_CREDITS_END:
849
sDelayedWarpTimer = 60;
850
sSourceWarpNodeId = WARP_NODE_F0;
851
val04 = FALSE;
852
gSavedCourseNum = COURSE_NONE;
853
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x3C, 0x00, 0x00, 0x00);
854
break;
855
856
case WARP_OP_STAR_EXIT:
857
sDelayedWarpTimer = 32;
858
sSourceWarpNodeId = WARP_NODE_F0;
859
gSavedCourseNum = COURSE_NONE;
860
play_transition(WARP_TRANSITION_FADE_INTO_MARIO, 0x20, 0x00, 0x00, 0x00);
861
break;
862
863
case WARP_OP_CUSTOM_RESET:
864
sDelayedWarpTimer = 32;
865
sSourceWarpNodeId = WARP_NODE_F0;
866
play_transition(WARP_TRANSITION_FADE_INTO_MARIO, 0x20, 0x00, 0x00, 0x00);
867
break;
868
869
case WARP_OP_DEATH:
870
if (save_file_get_flags() & SAVE_FLAG_HARDCORE_MODE) {
871
sDelayedWarpOp = WARP_OP_GAME_OVER;
872
save_file_erase(gCurrSaveFileNum - 1);
873
}
874
if (m->numLives == 0 && configLifeMode == 0) {
875
sDelayedWarpOp = WARP_OP_GAME_OVER;
876
}
877
sDelayedWarpTimer = 48;
878
sSourceWarpNodeId = WARP_NODE_DEATH;
879
play_transition(WARP_TRANSITION_FADE_INTO_BOWSER, 0x30, 0x00, 0x00, 0x00);
880
play_sound(SOUND_MENU_BOWSER_LAUGH, gGlobalSoundSource);
881
break;
882
883
case WARP_OP_WARP_FLOOR:
884
sSourceWarpNodeId = WARP_NODE_WARP_FLOOR;
885
if (area_get_warp_node(sSourceWarpNodeId) == NULL) {
886
if (save_file_get_flags() & SAVE_FLAG_HARDCORE_MODE) {
887
sDelayedWarpOp = WARP_OP_GAME_OVER;
888
save_file_erase(gCurrSaveFileNum - 1);
889
}
890
else if (m->numLives == 0 && configLifeMode == 0) {
891
sDelayedWarpOp = WARP_OP_GAME_OVER;
892
}
893
else {
894
sSourceWarpNodeId = WARP_NODE_DEATH;
895
}
896
}
897
sDelayedWarpTimer = 20;
898
play_transition(WARP_TRANSITION_FADE_INTO_CIRCLE, 0x14, 0x00, 0x00, 0x00);
899
break;
900
901
case WARP_OP_UNKNOWN_01: // enter totwc
902
sDelayedWarpTimer = 30;
903
sSourceWarpNodeId = WARP_NODE_F2;
904
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x1E, 0xFF, 0xFF, 0xFF);
905
#ifndef VERSION_JP
906
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
907
#endif
908
break;
909
910
case WARP_OP_UNKNOWN_02: // bbh enter
911
sDelayedWarpTimer = 30;
912
sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16;
913
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x1E, 0xFF, 0xFF, 0xFF);
914
break;
915
916
case WARP_OP_TELEPORT:
917
sDelayedWarpTimer = 20;
918
sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16;
919
val04 = !music_changed_through_warp(sSourceWarpNodeId);
920
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x14, 0xFF, 0xFF, 0xFF);
921
break;
922
923
case WARP_OP_WARP_DOOR:
924
sDelayedWarpTimer = 20;
925
sDelayedWarpArg = m->actionArg;
926
sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16;
927
val04 = !music_changed_through_warp(sSourceWarpNodeId);
928
play_transition(WARP_TRANSITION_FADE_INTO_CIRCLE, 0x14, 0x00, 0x00, 0x00);
929
break;
930
931
case WARP_OP_WARP_OBJECT:
932
sDelayedWarpTimer = 20;
933
sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16;
934
val04 = !music_changed_through_warp(sSourceWarpNodeId);
935
play_transition(WARP_TRANSITION_FADE_INTO_STAR, 0x14, 0x00, 0x00, 0x00);
936
break;
937
938
case WARP_OP_CREDITS_START:
939
sDelayedWarpTimer = 30;
940
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x1E, 0x00, 0x00, 0x00);
941
break;
942
943
case WARP_OP_CREDITS_NEXT:
944
if (gCurrCreditsEntry == &sCreditsSequence[0]) {
945
sDelayedWarpTimer = 60;
946
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x3C, 0x00, 0x00, 0x00);
947
} else {
948
sDelayedWarpTimer = 20;
949
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x14, 0x00, 0x00, 0x00);
950
}
951
val04 = FALSE;
952
break;
953
}
954
955
if (val04 && gCurrDemoInput == NULL) {
956
fadeout_music((3 * sDelayedWarpTimer / 2) * 8 - 2);
957
}
958
}
959
960
return sDelayedWarpTimer;
961
}
962
963
/**
964
* If a delayed warp is ready, initiate it.
965
*/
966
void initiate_delayed_warp(void) {
967
struct ObjectWarpNode *warpNode;
968
s32 destWarpNode;
969
970
if (sDelayedWarpOp != WARP_OP_NONE && --sDelayedWarpTimer == 0) {
971
reset_dialog_render_state();
972
973
if (gDebugLevelSelect && (sDelayedWarpOp & WARP_OP_TRIGGERS_LEVEL_SELECT)) {
974
warp_special(-9);
975
} else if (gCurrDemoInput != NULL) {
976
if (sDelayedWarpOp == WARP_OP_DEMO_END) {
977
warp_special(-8);
978
} else {
979
warp_special(-2);
980
}
981
} else {
982
switch (sDelayedWarpOp) {
983
case WARP_OP_GAME_OVER:
984
save_file_reload();
985
warp_special(-3);
986
gCanMirror = 0;
987
break;
988
989
case WARP_OP_CREDITS_END:
990
warp_special(-1);
991
sound_banks_enable(SEQ_PLAYER_SFX,
992
SOUND_BANKS_ALL & ~SOUND_BANKS_DISABLED_AFTER_CREDITS);
993
gCanMirror = 0;
994
break;
995
996
case WARP_OP_DEMO_NEXT:
997
warp_special(-2);
998
gCanMirror = 0;
999
break;
1000
1001
case WARP_OP_CREDITS_START:
1002
gCurrCreditsEntry = &sCreditsSequence[0];
1003
initiate_warp(gCurrCreditsEntry->levelNum, gCurrCreditsEntry->areaIndex,
1004
WARP_NODE_CREDITS_START, 0);
1005
break;
1006
1007
case WARP_OP_CREDITS_NEXT:
1008
sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_ALL);
1009
1010
gCurrCreditsEntry += 1;
1011
gCurrActNum = gCurrCreditsEntry->unk02 & 0x07;
1012
if ((gCurrCreditsEntry + 1)->levelNum == LEVEL_NONE) {
1013
destWarpNode = WARP_NODE_CREDITS_END;
1014
} else {
1015
destWarpNode = WARP_NODE_CREDITS_NEXT;
1016
}
1017
1018
initiate_warp(gCurrCreditsEntry->levelNum, gCurrCreditsEntry->areaIndex,
1019
destWarpNode, 0);
1020
break;
1021
1022
case WARP_OP_STAR_EXIT:
1023
warpNode = area_get_warp_node(sSourceWarpNodeId);
1024
1025
initiate_warp(warpNode->node.destLevel & 0x7F, warpNode->node.destArea,
1026
warpNode->node.destNode, sDelayedWarpArg);
1027
1028
check_if_should_set_warp_checkpoint(&warpNode->node);
1029
if (sWarpDest.type != WARP_TYPE_CHANGE_LEVEL) {
1030
level_set_transition(2, NULL);
1031
}
1032
break;
1033
1034
case WARP_OP_CUSTOM_RESET:
1035
save_file_do_save(gCurrSaveFileNum - 1);
1036
warp_special(gCurrLevelNum);
1037
break;
1038
1039
default:
1040
if (configRemoveAnnoyingWarps && (sDelayedWarpOp & WARP_OP_TRIGGERS_LEVEL_SELECT) && (area_get_warp_node(sSourceWarpNodeId)->node.destLevel & 0x7F) == LEVEL_CASTLE_GROUNDS && gCurrCourseNum != COURSE_VCUTM) {
1041
warpNode = area_get_warp_node(WARP_NODE_DEATH);
1042
}
1043
else {
1044
warpNode = area_get_warp_node(sSourceWarpNodeId);
1045
}
1046
1047
initiate_warp(warpNode->node.destLevel & 0x7F, warpNode->node.destArea,
1048
warpNode->node.destNode, sDelayedWarpArg);
1049
1050
check_if_should_set_warp_checkpoint(&warpNode->node);
1051
if (sWarpDest.type != WARP_TYPE_CHANGE_LEVEL) {
1052
level_set_transition(2, NULL);
1053
}
1054
break;
1055
}
1056
}
1057
}
1058
}
1059
1060
void update_hud_values(void) {
1061
if (gCurrCreditsEntry == NULL) {
1062
s16 numHealthWedges = gMarioState->health > 0 ? gMarioState->health >> 8 : 0;
1063
1064
if (gCurrCourseNum >= COURSE_MIN) {
1065
gHudDisplay.flags |= HUD_DISPLAY_FLAG_COIN_COUNT;
1066
} else {
1067
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_COIN_COUNT;
1068
}
1069
1070
if (gHudDisplay.coins < gMarioState->numCoins) {
1071
if (gGlobalTimer & 0x00000001) {
1072
u32 coinSound;
1073
if (gMarioState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) {
1074
coinSound = SOUND_GENERAL_COIN_WATER;
1075
} else {
1076
coinSound = SOUND_GENERAL_COIN;
1077
}
1078
1079
gHudDisplay.coins += 1;
1080
play_sound(coinSound, gMarioState->marioObj->header.gfx.cameraToObject);
1081
}
1082
}
1083
1084
if (gMarioState->numLives > 100) {
1085
gMarioState->numLives = 100;
1086
save_file_set_num_lives(100);
1087
}
1088
1089
#if BUGFIX_MAX_LIVES
1090
if (gMarioState->numCoins > 999) {
1091
gMarioState->numCoins = 999;
1092
}
1093
1094
if (gHudDisplay.coins > 999) {
1095
gHudDisplay.coins = 999;
1096
}
1097
#else
1098
if (gMarioState->numCoins > 999) {
1099
gMarioState->numLives = (s8) 999; //! Wrong variable
1100
}
1101
#endif
1102
1103
gHudDisplay.stars = gMarioState->numStars;
1104
gHudDisplay.lives = gMarioState->numLives;
1105
gHudDisplay.keys = gMarioState->numKeys;
1106
1107
if (numHealthWedges > gHudDisplay.wedges) {
1108
play_sound(SOUND_MENU_POWER_METER, gGlobalSoundSource);
1109
}
1110
gHudDisplay.wedges = numHealthWedges;
1111
1112
if (gMarioState->hurtCounter > 0) {
1113
gHudDisplay.flags |= HUD_DISPLAY_FLAG_EMPHASIZE_POWER;
1114
} else {
1115
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_EMPHASIZE_POWER;
1116
}
1117
}
1118
}
1119
1120
/**
1121
* Update objects, HUD, and camera. This update function excludes things like
1122
* endless staircase, warps, pausing, etc. This is used when entering a painting,
1123
* presumably to allow painting and camera updating while avoiding triggering the
1124
* warp twice.
1125
*/
1126
void basic_update(UNUSED s16 *arg) {
1127
area_update_objects();
1128
update_hud_values();
1129
1130
if (gCurrentArea != NULL) {
1131
update_camera(gCurrentArea->camera);
1132
}
1133
}
1134
1135
s32 play_mode_normal(void) {
1136
if (gCurrDemoInput != NULL) {
1137
print_intro_text(1);
1138
if (gPlayer1Controller->buttonPressed & END_DEMO) {
1139
level_trigger_warp(gMarioState,
1140
gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT);
1141
} else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE
1142
&& (gPlayer1Controller->buttonPressed & START_BUTTON)) {
1143
level_trigger_warp(gMarioState, WARP_OP_DEMO_NEXT);
1144
}
1145
}
1146
1147
warp_area();
1148
check_instant_warp();
1149
1150
if (sTimerRunning && gHudDisplay.timer < 17999) {
1151
gHudDisplay.timer += 1;
1152
}
1153
1154
area_update_objects();
1155
update_hud_values();
1156
1157
if (gCurrentArea != NULL) {
1158
update_camera(gCurrentArea->camera);
1159
}
1160
1161
initiate_painting_warp();
1162
initiate_delayed_warp();
1163
1164
// If either initiate_painting_warp or initiate_delayed_warp initiated a
1165
// warp, change play mode accordingly.
1166
if (sCurrPlayMode == PLAY_MODE_NORMAL) {
1167
if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) {
1168
set_play_mode(PLAY_MODE_CHANGE_LEVEL);
1169
} else if (sTransitionTimer != 0) {
1170
set_play_mode(PLAY_MODE_CHANGE_AREA);
1171
} else if (pressed_pause()) {
1172
lower_background_noise(1);
1173
#if ENABLE_RUMBLE
1174
cancel_rumble();
1175
#endif
1176
gCameraMovementFlags |= CAM_MOVE_PAUSE_SCREEN;
1177
set_play_mode(PLAY_MODE_PAUSED);
1178
}
1179
}
1180
1181
return 0;
1182
}
1183
1184
s32 play_mode_paused(void) {
1185
if (gMenuOptSelectIndex == MENU_OPT_NONE) {
1186
set_menu_mode(MENU_MODE_RENDER_PAUSE_SCREEN);
1187
} else if (gMenuOptSelectIndex == MENU_OPT_DEFAULT) {
1188
raise_background_noise(1);
1189
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
1190
set_play_mode(PLAY_MODE_NORMAL);
1191
} else if (configQuitOption && gMenuOptSelectIndex == MENU_OPT_CAMERA_ANGLE_R) {
1192
exit(0);
1193
} else { // MENU_OPT_EXIT_COURSE
1194
1195
if (gDebugLevelSelect) {
1196
fade_into_special_warp(-9, 1);
1197
} else {
1198
initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0);
1199
fade_into_special_warp(0, 0);
1200
gSavedCourseNum = COURSE_NONE;
1201
}
1202
1203
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
1204
}
1205
1206
return 0;
1207
}
1208
1209
/**
1210
* Debug mode that lets you frame advance by pressing D-pad down. Unfortunately
1211
* it uses the pause camera, making it basically unusable in most levels.
1212
*/
1213
s32 play_mode_frame_advance(void) {
1214
if (gPlayer1Controller->buttonPressed & D_JPAD) {
1215
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
1216
play_mode_normal();
1217
} else if (gPlayer1Controller->buttonPressed & START_BUTTON) {
1218
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
1219
raise_background_noise(1);
1220
set_play_mode(PLAY_MODE_NORMAL);
1221
} else {
1222
gCameraMovementFlags |= CAM_MOVE_PAUSE_SCREEN;
1223
}
1224
1225
return 0;
1226
}
1227
1228
/**
1229
* Set the transition, which is a period of time after the warp is initiated
1230
* but before it actually occurs. If updateFunction is not NULL, it will be
1231
* called each frame during the transition.
1232
*/
1233
void level_set_transition(s16 length, void (*updateFunction)(s16 *)) {
1234
sTransitionTimer = length;
1235
sTransitionUpdate = updateFunction;
1236
}
1237
1238
/**
1239
* Play the transition and then return to normal play mode.
1240
*/
1241
s32 play_mode_change_area(void) {
1242
//! This maybe was supposed to be sTransitionTimer == -1? sTransitionUpdate
1243
// is never set to -1.
1244
if (sTransitionUpdate == (void (*)(s16 *)) - 1) {
1245
update_camera(gCurrentArea->camera);
1246
} else if (sTransitionUpdate != NULL) {
1247
sTransitionUpdate(&sTransitionTimer);
1248
}
1249
1250
if (sTransitionTimer > 0) {
1251
sTransitionTimer -= 1;
1252
}
1253
1254
if (sTransitionTimer == 0) {
1255
sTransitionUpdate = NULL;
1256
set_play_mode(PLAY_MODE_NORMAL);
1257
}
1258
1259
return 0;
1260
}
1261
1262
/**
1263
* Play the transition and then return to normal play mode.
1264
*/
1265
s32 play_mode_change_level(void) {
1266
if (sTransitionUpdate != NULL) {
1267
sTransitionUpdate(&sTransitionTimer);
1268
}
1269
1270
if (--sTransitionTimer == -1) {
1271
gHudDisplay.flags = HUD_DISPLAY_NONE;
1272
sTransitionTimer = 0;
1273
sTransitionUpdate = NULL;
1274
1275
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
1276
return sWarpDest.levelNum;
1277
} else {
1278
return D_80339EE0;
1279
}
1280
}
1281
1282
return 0;
1283
}
1284
1285
/**
1286
* Unused play mode. Doesn't call transition update and doesn't reset transition at the end.
1287
*/
1288
UNUSED static s32 play_mode_unused(void) {
1289
if (--sTransitionTimer == -1) {
1290
gHudDisplay.flags = HUD_DISPLAY_NONE;
1291
1292
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
1293
return sWarpDest.levelNum;
1294
} else {
1295
return D_80339EE0;
1296
}
1297
}
1298
1299
return 0;
1300
}
1301
1302
s32 update_level(void) {
1303
s32 changeLevel;
1304
1305
switch (sCurrPlayMode) {
1306
case PLAY_MODE_NORMAL:
1307
changeLevel = play_mode_normal();
1308
break;
1309
case PLAY_MODE_PAUSED:
1310
changeLevel = play_mode_paused();
1311
break;
1312
case PLAY_MODE_CHANGE_AREA:
1313
changeLevel = play_mode_change_area();
1314
break;
1315
case PLAY_MODE_CHANGE_LEVEL:
1316
changeLevel = play_mode_change_level();
1317
break;
1318
case PLAY_MODE_FRAME_ADVANCE:
1319
changeLevel = play_mode_frame_advance();
1320
break;
1321
}
1322
1323
if (changeLevel) {
1324
reset_volume();
1325
enable_background_sound();
1326
}
1327
1328
return changeLevel;
1329
}
1330
1331
s32 init_level(void) {
1332
s32 val4 = 0;
1333
1334
set_play_mode(PLAY_MODE_NORMAL);
1335
1336
sDelayedWarpOp = WARP_OP_NONE;
1337
sTransitionTimer = 0;
1338
D_80339EE0 = 0;
1339
1340
if (gCurrCreditsEntry == NULL) {
1341
gHudDisplay.flags = HUD_DISPLAY_DEFAULT;
1342
} else {
1343
gHudDisplay.flags = HUD_DISPLAY_NONE;
1344
}
1345
1346
sTimerRunning = FALSE;
1347
1348
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
1349
if (sWarpDest.nodeId >= WARP_NODE_CREDITS_MIN) {
1350
warp_credits();
1351
} else {
1352
warp_level();
1353
}
1354
} else {
1355
if (gPlayerSpawnInfos[0].areaIndex >= 0) {
1356
load_mario_area();
1357
init_mario();
1358
}
1359
1360
if (gCurrentArea != NULL) {
1361
reset_camera(gCurrentArea->camera);
1362
1363
if (gCurrDemoInput != NULL) {
1364
set_mario_action(gMarioState, ACT_IDLE, 0);
1365
} else if (!gDebugLevelSelect) {
1366
if (gMarioState->action != ACT_UNINITIALIZED) {
1367
if (save_file_exists(gCurrSaveFileNum - 1)) {
1368
set_mario_action(gMarioState, ACT_IDLE, 0);
1369
} else {
1370
set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 0);
1371
val4 = 1;
1372
if (gPlayer1Controller->buttonDown & U_CBUTTONS && gPlayer1Controller->buttonDown & R_TRIG) {
1373
level_trigger_warp(gMarioState, WARP_OP_CREDITS_START);
1374
}
1375
else if (configSkipCutscenes) {
1376
set_mario_action(gMarioState, ACT_IDLE, 0);
1377
} else {
1378
set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 0);
1379
val4 = 1;
1380
}
1381
}
1382
if (configHardSave) {
1383
gMarioState->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
1384
save_file_set_flags(SAVE_FLAG_HARD_MODE);
1385
}
1386
if (configHardcoreSave) {
1387
save_file_set_flags(SAVE_FLAG_HARDCORE_MODE);
1388
}
1389
if (configDaredevilSave) {
1390
save_file_set_flags(SAVE_FLAG_DAREDEVIL_MODE);
1391
}
1392
}
1393
}
1394
}
1395
1396
if (val4 != 0) {
1397
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 0x5A, 0xFF, 0xFF, 0xFF);
1398
} else {
1399
play_transition(WARP_TRANSITION_FADE_FROM_STAR, 0x10, 0xFF, 0xFF, 0xFF);
1400
}
1401
1402
if (gCurrDemoInput == NULL) {
1403
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
1404
}
1405
}
1406
#if ENABLE_RUMBLE
1407
if (gCurrDemoInput == NULL) {
1408
cancel_rumble();
1409
}
1410
#endif
1411
1412
if (gMarioState->action == ACT_INTRO_CUTSCENE) {
1413
sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_DISABLED_DURING_INTRO_CUTSCENE);
1414
}
1415
1416
return 1;
1417
}
1418
1419
/**
1420
* Initialize the current level if initOrUpdate is 0, or update the level if it is 1.
1421
*/
1422
s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) {
1423
s32 result = 0;
1424
1425
switch (initOrUpdate) {
1426
case 0:
1427
result = init_level();
1428
break;
1429
case 1:
1430
result = update_level();
1431
break;
1432
}
1433
1434
return result;
1435
}
1436
1437
s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
1438
#ifdef VERSION_EU
1439
s16 var = eu_get_language();
1440
switch (var) {
1441
case LANGUAGE_ENGLISH:
1442
load_segment_decompress(0x19, _translation_en_mio0SegmentRomStart,
1443
_translation_en_mio0SegmentRomEnd);
1444
break;
1445
case LANGUAGE_FRENCH:
1446
load_segment_decompress(0x19, _translation_fr_mio0SegmentRomStart,
1447
_translation_fr_mio0SegmentRomEnd);
1448
break;
1449
case LANGUAGE_GERMAN:
1450
load_segment_decompress(0x19, _translation_de_mio0SegmentRomStart,
1451
_translation_de_mio0SegmentRomEnd);
1452
break;
1453
}
1454
#endif
1455
sWarpDest.type = WARP_TYPE_NOT_WARPING;
1456
sDelayedWarpOp = WARP_OP_NONE;
1457
gNeverEnteredCastle = !save_file_exists(gCurrSaveFileNum - 1);
1458
1459
gCurrLevelNum = levelNum;
1460
gCurrCourseNum = COURSE_NONE;
1461
gSavedCourseNum = COURSE_NONE;
1462
gCurrCreditsEntry = NULL;
1463
gSpecialTripleJump = FALSE;
1464
1465
init_mario_from_save_file();
1466
disable_warp_checkpoint();
1467
save_file_move_cap_to_default_location();
1468
select_mario_cam_mode();
1469
set_yoshi_as_not_dead();
1470
1471
return levelNum;
1472
}
1473
1474
s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
1475
s32 warpCheckpointActive = sWarpCheckpointActive;
1476
1477
sWarpCheckpointActive = FALSE;
1478
gCurrLevelNum = levelNum;
1479
gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1];
1480
1481
if (gCurrDemoInput != NULL || gCurrCreditsEntry != NULL || gCurrCourseNum == COURSE_NONE) {
1482
return 0;
1483
}
1484
1485
if (gCurrLevelNum != LEVEL_BOWSER_1 && gCurrLevelNum != LEVEL_BOWSER_2
1486
&& gCurrLevelNum != LEVEL_BOWSER_3) {
1487
gMarioState->numCoins = 0;
1488
gHudDisplay.coins = 0;
1489
gCurrCourseStarFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
1490
}
1491
1492
if (gSavedCourseNum != gCurrCourseNum) {
1493
gSavedCourseNum = gCurrCourseNum;
1494
nop_change_course();
1495
disable_warp_checkpoint();
1496
}
1497
1498
if (gCurrCourseNum > COURSE_STAGES_MAX || warpCheckpointActive) {
1499
return 0;
1500
}
1501
1502
if (gDebugLevelSelect && !gShowProfiler) {
1503
return 0;
1504
}
1505
1506
if (configSkipMissionSelect) {
1507
s32 i;
1508
u8 level;
1509
u8 flag = 1;
1510
u8 starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
1511
for (i = 0; i < 7; i++, flag <<= 1) {
1512
if (!(starFlags & flag)) {
1513
level = i + 1;
1514
break;
1515
}
1516
level = 8;
1517
}
1518
if (level >= 7)
1519
return 1;
1520
gCurrActNum = level;
1521
gDialogCourseActNum = gCurrActNum;
1522
set_mario_initial_action(gMarioState, MARIO_SPAWN_SPIN_AIRBORNE, sWarpDest.arg);
1523
return 0;
1524
}
1525
1526
return 1;
1527
}
1528
1529
/**
1530
* Play the "thank you so much for to playing my game" sound.
1531
*/
1532
s32 lvl_play_the_end_screen_sound(UNUSED s16 arg0, UNUSED s32 arg1) {
1533
play_sound(SOUND_MENU_THANK_YOU_PLAYING_MY_GAME, gGlobalSoundSource);
1534
return 1;
1535
}
1536
1537
s32 credits_wait_for_reset() {
1538
if (gPlayer1Controller->buttonPressed & START_BUTTON || gPlayer1Controller->buttonPressed & A_BUTTON) {
1539
return 1;
1540
}
1541
return 0;
1542
}
1543