1148 lines
33 KiB
C
1148 lines
33 KiB
C
/********************************************************************************
|
|
Ultra 64 MARIO Brothers
|
|
|
|
game module
|
|
|
|
Copyright 1996 Nintendo co., ltd. All rights reserved
|
|
|
|
June 24, 1996
|
|
********************************************************************************/
|
|
|
|
#include "headers.h"
|
|
#include "include/ending.h"
|
|
|
|
|
|
#define GM_NORMAL 0
|
|
#define GM_GAMEOVER 1
|
|
#define GM_PAUSE 2
|
|
#define GM_FREEZE 3
|
|
#define GM_EXIT 4
|
|
#define GM_STILL 5
|
|
|
|
#define CHANGE_STAGE 1
|
|
#define CHANGE_SCENE 2
|
|
#define CHANGE_PORT 3
|
|
|
|
#define ANGLE180 0x8000
|
|
|
|
MeterRecord playerMeter; /* player meter record */
|
|
PlayerRecord playerWorks[1]; /* player control work */
|
|
PlayerPtr marioWorks = &playerWorks[0]; /* pointer to the mario works */
|
|
|
|
static short gameProcess; /* game process number */
|
|
static short gameCounter; /* allpurpose counter */
|
|
static short freezeCounter; /* game freezing counter */
|
|
static FreezeProc freezeProcedure; /* pointer to the freezeing proce */
|
|
|
|
|
|
static EntrantRecord playerEntry; /* player entry work */
|
|
static short gameExitCode; /* game routine exit code */
|
|
|
|
static short fadeoutMode; /* scene fade mode */
|
|
static short fadeoutCount; /* scene fade counter */
|
|
static short fadeoutPort; /* scene fade trip port number */
|
|
static ulong fadeoutInfo; /* scene fade aux information */
|
|
|
|
|
|
static short currentCourse = 0;
|
|
static short messageNo;
|
|
static char stopWatchSw;
|
|
static char middlePointSw = 0;
|
|
|
|
char mesgCastle;
|
|
|
|
static void ExecuteGame(short *counter);
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* Control stop watch. */
|
|
/* */
|
|
/********************************************************************************/
|
|
extern ushort
|
|
GmStopWatch(int mode)
|
|
{
|
|
switch (mode) {
|
|
case 0: setflag(playerMeter.flags, METER_TIMER);
|
|
stopWatchSw = FALSE;
|
|
playerMeter.timer = 0;
|
|
break;
|
|
|
|
case 1: stopWatchSw = TRUE;
|
|
break;
|
|
|
|
case 2: stopWatchSw = FALSE;
|
|
break;
|
|
|
|
case 3: clrflag(playerMeter.flags, METER_TIMER);
|
|
stopWatchSw = FALSE;
|
|
playerMeter.timer = 0;
|
|
break;
|
|
}
|
|
return(playerMeter.timer);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* Check pause request. */
|
|
/********************************************************************************/
|
|
static int
|
|
CheckPauseRequest(void)
|
|
{
|
|
int DispMesg = (GetMessageNo() >= 0);
|
|
int demoMode = ((marioWorks->status & PS_TYPE_DEMO) != 0);
|
|
|
|
if (!(demoMode || DispMesg || wipeControl.active || fadeoutMode)) {
|
|
if (cont1p->trigger & CONT_START) return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
/********************************************************************************/
|
|
/* Change game process. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeProcess(short proc)
|
|
{
|
|
gameProcess = proc;
|
|
gameCounter = 0;
|
|
}
|
|
/********************************************************************************/
|
|
/* Change game process. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeExitMode(int code)
|
|
{
|
|
gameProcess = GM_EXIT;
|
|
gameCounter = 0;
|
|
gameExitCode = code;
|
|
}
|
|
/********************************************************************************/
|
|
/* Exit game mode. */
|
|
/********************************************************************************/
|
|
extern void
|
|
PL_ExitGameMode(int code, int color)
|
|
{
|
|
if (color != 0) color = 255;
|
|
|
|
AudStopMusic(AudFadeOutTime(16+8));
|
|
SnStartFader(WIPE_FADE_OUT, 16, color, color, color);
|
|
// FreezeGame(15, NULL);
|
|
FreezeGame(30, NULL);
|
|
ChangeExitMode(code);
|
|
}
|
|
/********************************************************************************/
|
|
/* Check player's reset request. */
|
|
/********************************************************************************/
|
|
static void
|
|
CheckReset(void)
|
|
{
|
|
#if DEVELOP
|
|
if (!wipeControl.active && (cont1p->status == (CONT_BACK | CONT_XL | CONT_XR | CONT_START)) && (cont1p->trigger & CONT_START)) {
|
|
MessageEnforcedDestroy();
|
|
if (sysDebugFlag ) PL_ExitGameMode(PL_RETURN_SELECT, 1);
|
|
else PL_ExitGameMode(PL_RETURN_TITLE , 0);
|
|
}
|
|
#endif
|
|
}
|
|
/********************************************************************************/
|
|
/* */
|
|
/* Display message. */
|
|
/* */
|
|
/********************************************************************************/
|
|
extern void
|
|
PL_DisplayMessage(int mesgno)
|
|
{
|
|
int condition;
|
|
int message = snSceneInfo->message[mesgno];
|
|
|
|
switch (message) {
|
|
case 129: condition = BuGetItemFlag() & BU_ITEM_BLUESW; break;
|
|
case 130: condition = BuGetItemFlag() & BU_ITEM_GREENSW; break;
|
|
case 131: condition = BuGetItemFlag() & BU_ITEM_REDSW; break;
|
|
case 255: condition = 1; break;
|
|
default: condition = BuGetStarFlag(activePlayerNo-1, activeCourseNo-1); break;
|
|
}
|
|
if (condition == 0) {
|
|
FreezeGame(-1,NULL);
|
|
CallMessage(message);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* scene chnage rotuines
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Move player to front of door. */
|
|
/********************************************************************************/
|
|
static void
|
|
MoveToFrontDoor(ActorPtr actor, ulong auxinfo)
|
|
{
|
|
if (auxinfo & 2) actor->angle[_AY] += ANGLE180;
|
|
|
|
actor->position[_AX] += 300.0f * sin(actor->angle[_AY]);
|
|
actor->position[_AZ] += 300.0f * cos(actor->angle[_AY]);
|
|
}
|
|
/********************************************************************************/
|
|
/* Change to special cap. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeSpecialCap(PlayerPtr player)
|
|
{
|
|
int index = activeCourseNo - 20;
|
|
|
|
switch (index) {
|
|
case 0: setflag(player->flags, PL_FLAG_HEADCAP|PL_FLAG_METALCAP); player->special = 600; break;
|
|
case 1: setflag(player->flags, PL_FLAG_HEADCAP|PL_FLAG_WINGCAP ); player->special = 1200; break;
|
|
case 2: setflag(player->flags, PL_FLAG_HEADCAP|PL_FLAG_GHOSTCAP); player->special = 600; break;
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Changle port. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeStatus(PlayerPtr player, int type, ulong auxinfo)
|
|
{
|
|
switch (type) {
|
|
case SN_TRIP_DOOR : PL_ChangePlayerStatus(player, PS_TRIPDOOR , auxinfo); break;
|
|
case SN_TRIP_STAR : PL_ChangePlayerStatus(player, PS_WAITING , 0); break;
|
|
case SN_TRIP_CHIMNEY : PL_ChangePlayerStatus(player, PS_CHIMNEY , 0); break;
|
|
case SN_WARP_POINT : PL_ChangePlayerStatus(player, PS_WARPOUT , 0); break;
|
|
case SN_ENTER_WAITING : PL_ChangePlayerStatus(player, PS_WAITING , 0); break;
|
|
case SN_ENTER_LANDING : PL_ChangePlayerStatus(player, PS_LANDENTER , 0); break;
|
|
case SN_ENTER_FALLING : PL_ChangePlayerStatus(player, PS_JBACKDOWN , 0); break;
|
|
case SN_ENTER_ROLLING : PL_ChangePlayerStatus(player, PS_ROLLJUMP , 0); break;
|
|
case SN_ENTER_DOWNING : PL_ChangePlayerStatus(player, PS_DOWNLOSER , 0); break;
|
|
case SN_ENTER_PICTURE : PL_ChangePlayerStatus(player, PS_ROLLJUMP , 0); break;
|
|
case SN_ENTER_FLIGHT : PL_ChangePlayerStatus(player, PS_FLIGHT , 2); break;
|
|
case SN_ENTER_SWIMMING : PL_ChangePlayerStatus(player, PS_SWIMNWAIT , 1); break;
|
|
case SN_ENTER_WINNER : PL_ChangePlayerStatus(player, PS_ENTWINNER , 0); break;
|
|
case SN_ENTER_LOSER : PL_ChangePlayerStatus(player, PS_ENTLOSER , 0); break;
|
|
case SN_ENTER_LANDWINNER: PL_ChangePlayerStatus(player, PS_LNDWINNER , 0); break;
|
|
case SN_ENTER_LANDLOSER : PL_ChangePlayerStatus(player, PS_LANDLOSER , 0); break;
|
|
case SN_ENTER_PUSHOUT : PL_ChangePlayerStatus(player, PS_PUSHOUT , 0); break;
|
|
case SN_ENTER_PUSHDOWN : PL_ChangePlayerStatus(player, PS_PUSHDOWN , 0); break;
|
|
}
|
|
ChangeSpecialCap(player);
|
|
}
|
|
/********************************************************************************/
|
|
/* Changle port. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangePort(void)
|
|
{
|
|
PortPtr port = SnGetPortPtr(playerEntry.port);
|
|
int type = SnGetPortType(port->stratp);
|
|
|
|
|
|
if (marioWorks->status != PS_INACTIVE) {
|
|
|
|
starringActor[0].position[_AX] = (short)port->stratp->s[stw_worldX].f;
|
|
starringActor[0].position[_AY] = (short)port->stratp->s[stw_worldY].f;
|
|
starringActor[0].position[_AZ] = (short)port->stratp->s[stw_worldZ].f;
|
|
|
|
starringActor[0].angle[_AX] = 0;
|
|
starringActor[0].angle[_AY] = port->stratp->s[stw_angleY].d;
|
|
starringActor[0].angle[_AZ] = 0;
|
|
|
|
if (type == SN_TRIP_DOOR) MoveToFrontDoor(&starringActor[0], playerEntry.auxinfo);
|
|
|
|
if (playerEntry.type == CHANGE_STAGE || playerEntry.type == CHANGE_SCENE) {
|
|
starringActor[0].sceneNo = playerEntry.scene;
|
|
SnEnterPlayer();
|
|
}
|
|
InitPlayer();
|
|
ChangeStatus(marioWorks, type, playerEntry.auxinfo);
|
|
marioWorks->collide = port->stratp;
|
|
marioWorks->couple = port->stratp;
|
|
}
|
|
InitGameCamera(snSceneInfo->camera);
|
|
playerEntry.type = 0;
|
|
fadeoutMode = 0;
|
|
|
|
switch (type) {
|
|
case SN_TRIP_CHIMNEY : SnStartFader(WIPE_STAR_WIN_OPEN , 16, 0, 0, 0); break;
|
|
case SN_TRIP_DOOR : SnStartFader(WIPE_CIRCLE_WIN_OPEN, 16, 0, 0, 0); break;
|
|
case SN_WARP_POINT : SnStartFader(WIPE_FADE_IN , 20,255,255,255); break;
|
|
case SN_ENTER_PICTURE : SnStartFader(WIPE_FADE_IN , 26,255,255,255); break;
|
|
case SN_ENTER_ROLLING : SnStartFader(WIPE_CIRCLE_WIN_OPEN, 16, 0, 0, 0); break;
|
|
case SN_ENTER_STAFFROLL: SnStartFader(WIPE_FADE_IN , 16, 0, 0, 0); break;
|
|
default : SnStartFader(WIPE_STAR_WIN_OPEN , 16, 0, 0, 0); break;
|
|
}
|
|
if (autoDemoPtr == NULL) {
|
|
AudPlayMusic(snSceneInfo->audmode, snSceneInfo->musicno, 0);
|
|
if (marioWorks->flags & PL_FLAG_METALCAP ) AudPlaySpecialMusic(NA_METAL_BGM );
|
|
if (marioWorks->flags & (PL_FLAG_GHOSTCAP|PL_FLAG_WINGCAP)) AudPlaySpecialMusic(NA_MUTEKI_BGM);
|
|
|
|
if (activeStageNo == 9 && AudGetPlayingMusic() != NA_RACE_BGM && stopWatchSw) {
|
|
Na_MusicStart(NA_MUS_HANDLE, NA_RACE_BGM, 0);
|
|
}
|
|
if (playerEntry.stage == 6 && playerEntry.scene == 1 && (playerEntry.port == 31 || playerEntry.port == 32)) {
|
|
Na_FixSeFlagEntry(NA_SYS_RETURN_CASTLE);
|
|
}
|
|
if (playerEntry.stage == 16 && playerEntry.scene == 1) {
|
|
if (playerEntry.port == 7 || playerEntry.port == 10 || playerEntry.port == 20 || playerEntry.port == 30) {
|
|
Na_FixSeFlagEntry(NA_SYS_RETURN_CASTLE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Changle scene. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeScene(void)
|
|
{
|
|
if (playerEntry.type != 0) {
|
|
if (playerEntry.type == CHANGE_SCENE) {
|
|
GmHideTimer();
|
|
SnExitPlayer();
|
|
SnOpenScene(playerEntry.scene);
|
|
}
|
|
ChangePort();
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Changle stage. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeStage(void)
|
|
{
|
|
activeStageNo = playerEntry.stage;
|
|
GmHideTimer();
|
|
SnOpenScene(playerEntry.scene);
|
|
ChangePort();
|
|
}
|
|
/********************************************************************************/
|
|
/* Changle ending stage. */
|
|
/********************************************************************************/
|
|
static void
|
|
ChangeEndingStage(void)
|
|
{
|
|
ulong status;
|
|
|
|
|
|
switch (playerEntry.port) {
|
|
case PORT_START_ENDING: status = PS_ENTENDING; break;
|
|
case PORT_STAFF_ROLL : status = PS_STAFFROLL; break;
|
|
case PORT_FIN_ENDING : status = PS_FINGAME; break;
|
|
}
|
|
activeStageNo = playerEntry.stage;
|
|
SnOpenScene(playerEntry.scene);
|
|
|
|
SetSVector(starringActor[0].position, snEndingScene->posx, snEndingScene->posy, snEndingScene->posz);
|
|
SetSVector(starringActor[0].angle, 0, snEndingScene->angle << 8, 0);
|
|
|
|
starringActor[0].sceneNo = playerEntry.scene;
|
|
SnEnterPlayer();
|
|
InitPlayer();
|
|
PL_ChangePlayerStatus(marioWorks, status, 0);
|
|
InitGameCamera(snSceneInfo->camera);
|
|
playerEntry.type = 0;
|
|
fadeoutMode = 0;
|
|
|
|
SnStartFader(WIPE_FADE_IN, 20, 0, 0, 0);
|
|
if (snEndingScene == NULL || snEndingScene == endingSceneList) AudPlayMusic(snSceneInfo->audmode, snSceneInfo->musicno, 0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Do scene connecttion. */
|
|
/********************************************************************************/
|
|
static void
|
|
CheckSceneConnection(void)
|
|
{
|
|
short panning;
|
|
BGCheckData *plane;
|
|
|
|
if (activeStageNo == 6 && BuGetTotalStars(activePlayerNo-1) >= 70) return;
|
|
|
|
if((plane = marioWorks->grPlane) != NULL) {
|
|
int number = plane->BGattr - 27;
|
|
|
|
if (0 <= number && number <= 3 && snSceneInfo->connect != NULL) {
|
|
ConnectPtr connect = &snSceneInfo->connect[number];
|
|
|
|
if (connect->flags) {
|
|
marioWorks->position[_AX] += (float)connect->offset[_AX];
|
|
marioWorks->position[_AY] += (float)connect->offset[_AY];
|
|
marioWorks->position[_AZ] += (float)connect->offset[_AZ];
|
|
marioWorks->strategy->s[stw_worldX].f = marioWorks->position[_AX];
|
|
marioWorks->strategy->s[stw_worldY].f = marioWorks->position[_AY];
|
|
marioWorks->strategy->s[stw_worldZ].f = marioWorks->position[_AZ];
|
|
|
|
panning = marioWorks->sceneinf->camera->panning;
|
|
SnChangeScene(connect->scene);
|
|
marioWorks->sceneinf = snSceneInfo;
|
|
Crou_camBlockofs((float)connect->offset[_AX], (float)connect->offset[_AY], (float)connect->offset[_AZ]);
|
|
marioWorks->sceneinf->camera->panning = panning; /* for BUG */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Stage exit rotuines
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Set player entrant record. */
|
|
/********************************************************************************/
|
|
static int
|
|
CheckSameMusic(short portno)
|
|
{
|
|
PortPtr port = SnGetPortPtr(portno);
|
|
short stage = port->stage & 0x7f;
|
|
short scene = port->scene;
|
|
short result = TRUE;
|
|
|
|
if (stage == 9 && stage == activeStageNo && scene == activeSceneNo) {
|
|
short music = AudGetPlayingMusic();
|
|
|
|
if (music == NA_NOKO_SLIP_BGM || music == NA_MUTEKI_BGM) result = FALSE;
|
|
}
|
|
else {
|
|
ushort mode = stageScenes[scene].audmode;
|
|
ushort music = stageScenes[scene].musicno;
|
|
|
|
result = (stage == activeStageNo && mode == snSceneInfo->audmode && music == snSceneInfo->musicno);
|
|
if (AudGetPlayingMusic() != music) result = FALSE;
|
|
}
|
|
return(result);
|
|
}
|
|
/********************************************************************************/
|
|
/* Set player entrant record. */
|
|
/********************************************************************************/
|
|
static void
|
|
SetPlayerEntrant(short stage, short scene, short port, ulong auxinfo)
|
|
{
|
|
if (port >= PORT_START_ENDING ) playerEntry.type = CHANGE_STAGE;
|
|
else if (stage != activeStageNo ) playerEntry.type = CHANGE_STAGE;
|
|
else if (scene != snSceneInfo->sceneNo) playerEntry.type = CHANGE_SCENE;
|
|
else playerEntry.type = CHANGE_PORT;
|
|
|
|
playerEntry.stage = stage;
|
|
playerEntry.scene = scene;
|
|
playerEntry.port = port;
|
|
playerEntry.auxinfo = auxinfo;
|
|
}
|
|
/********************************************************************************/
|
|
/* Check BG change scene. */
|
|
/********************************************************************************/
|
|
static BGPortPtr
|
|
GetBGPortPointer(void)
|
|
{
|
|
BGPortPtr portpt = NULL;
|
|
int portno = marioWorks->grPlane->BGattr - 211;
|
|
|
|
|
|
if (0 <= portno && portno <= 44) {
|
|
if ((portno < 42) || ((marioWorks->position[_AY] - marioWorks->grLevel) < 80.0f)) {
|
|
portpt = &snSceneInfo->bgport[portno];
|
|
}
|
|
}
|
|
return(portpt);
|
|
}
|
|
/********************************************************************************/
|
|
/* Check BG change scene. */
|
|
/********************************************************************************/
|
|
static void
|
|
CheckBGPort(void)
|
|
{
|
|
BGPortRecord bgport, *portptr;
|
|
|
|
if (snSceneInfo->bgport != NULL && marioWorks->grPlane != NULL) {
|
|
if ((portptr = GetBGPortPointer()) != NULL) {
|
|
if (marioWorks->status & PS_TYPE_DEMO) {
|
|
AudPictWaveSound();
|
|
}
|
|
else if (portptr->flags) {
|
|
bgport = *portptr;
|
|
if (!(bgport.stage & 0x80)) middlePointSw = BuGetMidPoint(&bgport);
|
|
SetPlayerEntrant(bgport.stage & 0x7f, bgport.scene, bgport.port, 0);
|
|
BuSetMidPoint(&bgport);
|
|
SnDelayFader(WIPE_FADE_OUT, 30, 255,255,255, 45);
|
|
FreezeGame(74, ExecuteGame);
|
|
PL_ChangePlayerStatus(marioWorks, PS_FREEZE, 0);
|
|
MapDisable(&marioWorks->strategy->map);
|
|
Na_FixSeFlagEntry(NA_SE2_SET);
|
|
AudStopMusic(AudFadeOutTime(50));
|
|
SendMotorEvent(80,70); /* MOTOR 1997.5.27 */
|
|
SendMotorDecay(1); /* MOTOR 1997.5.30 */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* */
|
|
/* Exit player with screen fade out. */
|
|
/* */
|
|
/********************************************************************************/
|
|
extern int
|
|
PL_StartFadeout(PlayerPtr player, int mode)
|
|
{
|
|
int audioFadeout = TRUE;
|
|
|
|
if (fadeoutMode == 0) {
|
|
player->invincible = -1; /* player invincible */
|
|
fadeoutInfo = 0;
|
|
fadeoutMode = mode;
|
|
|
|
switch (mode) {
|
|
case PL_FADE_RESTART:
|
|
case PL_FADE_GOTITLE: fadeoutCount = 20;
|
|
fadeoutPort = PORT_GAME_CLEAR;
|
|
ramSaveCourse = 0;
|
|
audioFadeout = FALSE;
|
|
SnStartFader(WIPE_STAR_WIN_CLOSE, 20, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_GAMEEND: fadeoutCount = 60;
|
|
fadeoutPort = PORT_GAME_CLEAR;
|
|
audioFadeout = FALSE;
|
|
ramSaveCourse = 0;
|
|
SnStartFader(WIPE_FADE_OUT, 60, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_WINNING: fadeoutCount = 32;
|
|
fadeoutPort = PORT_GAME_CLEAR;
|
|
ramSaveCourse = 0;
|
|
SnStartFader(WIPE_MARIO_WIN_CLOSE, 32, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_LOSING : if (player->nlifes == 0) fadeoutMode = PL_FADE_GAMEOVR;
|
|
fadeoutCount = 48;
|
|
fadeoutPort = PORT_GAME_OVER;
|
|
SnStartFader(WIPE_KOPA_WIN_CLOSE, 48, 0, 0, 0);
|
|
Na_FixSeFlagEntry(NA_SYS_KUPPA_LAUGH);
|
|
break;
|
|
|
|
case PL_FADE_FALLING: fadeoutPort = PORT_COURSE_OUT;
|
|
if (SnGetPortPtr(fadeoutPort) == NULL) {
|
|
if (player->nlifes == 0) fadeoutMode = PL_FADE_GAMEOVR;
|
|
else fadeoutPort = PORT_GAME_OVER;
|
|
}
|
|
fadeoutCount = 20;
|
|
SnStartFader(WIPE_CIRCLE_WIN_CLOSE, 20, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_VIEWROOF: fadeoutCount = 30;
|
|
fadeoutPort = PORT_VIEW_ROOF;
|
|
SnStartFader(WIPE_FADE_OUT, 30, 255, 255, 255);
|
|
Na_FixSeFlagEntry(NA_SE2_SET);
|
|
break;
|
|
|
|
case PL_FADE_TRIPKAGO: fadeoutCount = 30;
|
|
fadeoutPort = SnGetPortNumber(player->couple);
|
|
SnStartFader(WIPE_FADE_OUT, 30, 255, 255, 255);
|
|
break;
|
|
|
|
case PL_FADE_WARPIN: fadeoutCount = 20;
|
|
fadeoutPort = SnGetPortNumber(player->couple);
|
|
audioFadeout = !CheckSameMusic(fadeoutPort);
|
|
SnStartFader(WIPE_FADE_OUT, 20, 255, 255, 255);
|
|
break;
|
|
|
|
case PL_FADE_TRIPDOOR: fadeoutCount = 20;
|
|
fadeoutInfo = player->auxinfo;
|
|
fadeoutPort = SnGetPortNumber(player->couple);
|
|
audioFadeout = !CheckSameMusic(fadeoutPort);
|
|
SnStartFader(WIPE_CIRCLE_WIN_CLOSE, 20, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_TRIPTUBE: fadeoutCount = 20;
|
|
fadeoutPort = SnGetPortNumber(player->couple);
|
|
audioFadeout = !CheckSameMusic(fadeoutPort);
|
|
SnStartFader(WIPE_STAR_WIN_CLOSE, 20, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_ENDING: fadeoutCount = 30;
|
|
SnStartFader(WIPE_FADE_OUT, 30, 0, 0, 0);
|
|
break;
|
|
|
|
case PL_FADE_STAFFROLL: if (snEndingScene == endingSceneList) {
|
|
fadeoutCount = 60;
|
|
SnStartFader(WIPE_FADE_OUT, 60,0,0,0);
|
|
} else {
|
|
fadeoutCount = 20;
|
|
// SnStartFader(WIPE_FADE_OUT, 20, 0, 64, 56);
|
|
SnStartFader(WIPE_FADE_OUT, 20, 0, 0, 0);
|
|
}
|
|
audioFadeout = FALSE;
|
|
break;
|
|
}
|
|
if (audioFadeout && autoDemoPtr == NULL) {
|
|
AudStopMusic(AudFadeOutTime(fadeoutCount*3/2));
|
|
}
|
|
}
|
|
return(fadeoutCount);
|
|
}
|
|
/********************************************************************************/
|
|
/* Check game fade out. */
|
|
/********************************************************************************/
|
|
static void
|
|
CheckGameFadeout(void)
|
|
{
|
|
PortPtr port;
|
|
int portno;
|
|
|
|
if (fadeoutMode != 0) {
|
|
if (--fadeoutCount == 0) {
|
|
MessageEnforcedDestroy();
|
|
|
|
if (sysDebugFlag && (fadeoutMode & 0x10)) {
|
|
ChangeExitMode(PL_RETURN_SELECT);
|
|
}
|
|
else if (autoDemoPtr != NULL) {
|
|
if (fadeoutMode == PL_FADE_RESTART) ChangeExitMode(PL_RETURN_LOGO );
|
|
else ChangeExitMode(PL_RETURN_TITLE);
|
|
}
|
|
else {
|
|
switch (fadeoutMode) {
|
|
case PL_FADE_GAMEOVR:
|
|
BuRestoreBackUp();
|
|
ChangeExitMode(PL_GAME_OVER);
|
|
break;
|
|
|
|
case PL_FADE_GAMEEND:
|
|
ChangeExitMode(PL_GAME_CLEAR);
|
|
Na_Enddemo_UnlockSe();
|
|
break;
|
|
|
|
case PL_FADE_GOTITLE:
|
|
ChangeExitMode(PL_RETURN_TITLE);
|
|
break;
|
|
|
|
case PL_FADE_ENDING:
|
|
snEndingScene = endingSceneList;
|
|
SetPlayerEntrant(snEndingScene->stage, snEndingScene->scene, PORT_START_ENDING, 0);
|
|
break;
|
|
|
|
case PL_FADE_STAFFROLL:
|
|
Na_Ending_LockSe();
|
|
snEndingScene++;
|
|
activeLevelNo = snEndingScene->info & 0x07;
|
|
portno = (snEndingScene[1].stage == 0) ? PORT_FIN_ENDING : PORT_STAFF_ROLL;
|
|
SetPlayerEntrant(snEndingScene->stage, snEndingScene->scene, portno, 0);
|
|
break;
|
|
|
|
default:
|
|
port = SnGetPortPtr(fadeoutPort);
|
|
SetPlayerEntrant(port->stage & 0x7f, port->scene, port->port, fadeoutInfo);
|
|
BuSetMidPoint((BGPortPtr)port);
|
|
|
|
if (playerEntry.type != CHANGE_STAGE) {
|
|
FreezeGame(2, NULL);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Game rotuines
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Set player meter. */
|
|
/********************************************************************************/
|
|
static void
|
|
SetPlayerMeter(void)
|
|
{
|
|
if (snEndingScene == NULL) {
|
|
short power = (marioWorks->npowers > 0) ? marioWorks->npowers >> 8 : 0;
|
|
|
|
if (1 <= activeCourseNo) setflag(playerMeter.flags, METER_COIN);
|
|
else clrflag(playerMeter.flags, METER_COIN);
|
|
|
|
if (playerMeter.coin < marioWorks->ncoins) {
|
|
if (frameCounter & 1) {
|
|
ulong sound = (marioWorks->status & (PS_TYPE_SWIM|PS_TYPE_SINK)) ? NA_SE2_COIN+NA_IN_WATER : NA_SE2_COIN+NA_IN_OUTDOOR;
|
|
|
|
playerMeter.coin += 1;
|
|
AudStartSound(marioWorks->strategy, sound);
|
|
}
|
|
}
|
|
if (marioWorks->nlifes > 100) marioWorks->nlifes = 100; /* for sefty */
|
|
if (marioWorks->ncoins > 999) marioWorks->ncoins = 999; /* for sefty */ /* JPBUG */
|
|
if (playerMeter.coin > 999) playerMeter.coin = 999; /* for sefty */ /* JPBUG */
|
|
|
|
playerMeter.star = marioWorks->nstars;
|
|
playerMeter.life = marioWorks->nlifes;
|
|
playerMeter.key = marioWorks->nkeys;
|
|
|
|
if (power > playerMeter.power) Na_FixSeFlagEntry(NA_SYS_RECOVER);
|
|
playerMeter.power = power;
|
|
|
|
if (marioWorks->damage > 0) setflag(playerMeter.flags, METER_DAMAGE);
|
|
else clrflag(playerMeter.flags, METER_DAMAGE);
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* execute game for freeze process. */
|
|
/********************************************************************************/
|
|
static void
|
|
ExecuteGame(short *counter)
|
|
{
|
|
SnExecuteStrategy();
|
|
SetPlayerMeter();
|
|
if (snSceneInfo != NULL) CtrlGameCamera(snSceneInfo->camera);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game normal process. */
|
|
/********************************************************************************/
|
|
static int
|
|
NormalProcess(void)
|
|
{
|
|
if (autoDemoPtr != NULL) {
|
|
SnDisplayDemoMessage();
|
|
|
|
if (cont1p->trigger & CONT_EXIT) {
|
|
PL_StartFadeout(marioWorks, (activeStageNo == 27) ? PL_FADE_RESTART : PL_FADE_GOTITLE);
|
|
}
|
|
else if (!wipeControl.active && !fadeoutMode && (cont1p->trigger & CONT_START)) {
|
|
PL_StartFadeout(marioWorks, PL_FADE_GOTITLE);
|
|
}
|
|
}
|
|
ChangeScene();
|
|
CheckSceneConnection();
|
|
|
|
if (stopWatchSw && playerMeter.timer < 10*60*30-1) playerMeter.timer += 1;
|
|
|
|
SnExecuteStrategy();
|
|
SetPlayerMeter();
|
|
if (snSceneInfo != NULL) CtrlGameCamera(snSceneInfo->camera);
|
|
|
|
CheckBGPort();
|
|
CheckGameFadeout();
|
|
|
|
if (gameProcess == GM_NORMAL) {
|
|
if (playerEntry.type == CHANGE_STAGE) {
|
|
ChangeProcess(GM_EXIT);
|
|
}
|
|
else if (freezeCounter != 0) {
|
|
ChangeProcess(GM_FREEZE);
|
|
}
|
|
else if (CheckPauseRequest()) {
|
|
AudStartMute(AUD_MUTE_PAUSE);
|
|
ResetMotorPack();
|
|
setflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
ChangeProcess(GM_PAUSE );
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Game pause rotuines
|
|
*
|
|
*/
|
|
/********************************************************************************/
|
|
/* Game pause process. */
|
|
/********************************************************************************/
|
|
static int
|
|
PauseProcess(void)
|
|
{
|
|
#if DEVELOP
|
|
if ((cont1p->trigger & CONT_START) && (cont1p->status & CONT_XB)) ChangeProcess(GM_STILL);
|
|
#endif
|
|
|
|
if (mesgEvent == 0) {
|
|
CallSelectMessage(1);
|
|
}
|
|
else if (mesgEvent == 1) {
|
|
AudEndMute(AUD_MUTE_PAUSE);
|
|
clrflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
ChangeProcess(GM_NORMAL);
|
|
}
|
|
else {
|
|
if (sysDebugFlag) {
|
|
PL_ExitGameMode(PL_RETURN_SELECT, 1);
|
|
} else {
|
|
SetPlayerEntrant(6, 1, 31, 0);
|
|
PL_ExitGameMode(0, 0);
|
|
ramSaveCourse = 0;
|
|
}
|
|
clrflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
}
|
|
return(0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game still process. */
|
|
/********************************************************************************/
|
|
static int
|
|
StillProcess(void)
|
|
{
|
|
if (cont1p->trigger & CONT_DOWN) {
|
|
clrflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
NormalProcess();
|
|
}
|
|
else if (cont1p->trigger & CONT_START) {
|
|
clrflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
AudEndMute(AUD_MUTE_PAUSE);
|
|
ChangeProcess(GM_NORMAL);
|
|
}
|
|
else {
|
|
setflag(gameCameraControl, CAM_FLAG_PAUSE);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Game freeze rotuines
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Change process mode. */
|
|
/********************************************************************************/
|
|
extern void
|
|
FreezeGame(short count, FreezeProc proc)
|
|
{
|
|
freezeCounter = count;
|
|
freezeProcedure = proc;
|
|
}
|
|
/********************************************************************************/
|
|
/* Game freeze process. */
|
|
/********************************************************************************/
|
|
static int
|
|
FreezeProcess(void)
|
|
{
|
|
if (freezeProcedure == (void *)-1) CtrlGameCamera(snSceneInfo->camera);
|
|
else if (freezeProcedure != NULL) freezeProcedure(&freezeCounter);
|
|
|
|
if (freezeCounter > 0) freezeCounter -= 1;
|
|
|
|
if (freezeCounter == 0) {
|
|
freezeProcedure = NULL;
|
|
ChangeProcess(GM_NORMAL);
|
|
}
|
|
return(0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game exit process. */
|
|
/********************************************************************************/
|
|
static int
|
|
ExitProcess(void)
|
|
{
|
|
if (freezeProcedure != NULL) freezeProcedure(&freezeCounter);
|
|
|
|
if (--freezeCounter == -1) {
|
|
playerMeter.flags = 0;
|
|
freezeCounter = 0;
|
|
freezeProcedure = NULL;
|
|
|
|
if (playerEntry.type) return(playerEntry.stage );
|
|
else return(gameExitCode );
|
|
}
|
|
return(0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Freeze player process. */
|
|
/********************************************************************************/
|
|
static int
|
|
FreezePlayerProcess(void)
|
|
{
|
|
if (--freezeCounter == -1) {
|
|
playerMeter.flags = 0;
|
|
|
|
if (playerEntry.type) return(playerEntry.stage );
|
|
else return(gameExitCode );
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Game main rotuines
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Game main process. */
|
|
/********************************************************************************/
|
|
static ulong
|
|
PlayGame(void)
|
|
{
|
|
int result;
|
|
|
|
switch (gameProcess) {
|
|
case GM_NORMAL : result = NormalProcess(); break;
|
|
case GM_PAUSE : result = PauseProcess(); break;
|
|
case GM_FREEZE : result = FreezeProcess(); break;
|
|
case GM_EXIT : result = ExitProcess(); break;
|
|
case GM_STILL : result = StillProcess(); break;
|
|
}
|
|
#if DEBUGSW
|
|
if (gameProcess != GM_EXIT) CheckReset();
|
|
#endif
|
|
if (result) {
|
|
AudResetMute();
|
|
AudUnlockSound();
|
|
}
|
|
return(result);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game stage initialize process. */
|
|
/********************************************************************************/
|
|
static ulong
|
|
InitGame(void)
|
|
{
|
|
int whitein = FALSE;
|
|
|
|
ChangeProcess(GM_NORMAL);
|
|
fadeoutMode = 0;
|
|
freezeCounter = 0;
|
|
gameExitCode = 0;
|
|
playerMeter.flags = (snEndingScene == NULL) ? METER_ALL - METER_TIMER : 0;
|
|
stopWatchSw = 0;
|
|
|
|
if (playerEntry.type != 0) {
|
|
if (playerEntry.port >= PORT_START_ENDING) ChangeEndingStage();
|
|
else ChangeStage();
|
|
}
|
|
else {
|
|
if (starringActor[0].sceneNo >= 0) {
|
|
SnEnterPlayer();
|
|
InitPlayer();
|
|
}
|
|
if (snSceneInfo != NULL) {
|
|
InitGameCamera(snSceneInfo->camera);
|
|
if (autoDemoPtr != NULL) {
|
|
PL_ChangePlayerStatus(marioWorks, PS_WAITING, 0);
|
|
}
|
|
else if (!sysDebugFlag && marioWorks->status != PS_INACTIVE) {
|
|
if (BuIsActive(activePlayerNo-1)) {
|
|
PL_ChangePlayerStatus(marioWorks, PS_WAITING, 0);
|
|
} else {
|
|
PL_ChangePlayerStatus(marioWorks, PS_CAMDEMO, 0);
|
|
whitein = TRUE;
|
|
}
|
|
}
|
|
}
|
|
if (whitein) SnStartFader(WIPE_FADE_IN , 90, 255, 255, 255);
|
|
else SnStartFader(WIPE_STAR_WIN_OPEN, 16, 255, 255, 255);
|
|
|
|
if (autoDemoPtr == NULL) AudPlayMusic(snSceneInfo->audmode, snSceneInfo->musicno, 0);
|
|
}
|
|
if (autoDemoPtr == NULL) ResetMotorPack();
|
|
|
|
// SnExecuteStrategy();
|
|
if (marioWorks->status == PS_CAMDEMO) Na_Opening_LockSe();
|
|
return(TRUE);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game main process. */
|
|
/********************************************************************************/
|
|
extern ulong
|
|
GameProcess(short code, long param)
|
|
{
|
|
ulong result = 0;
|
|
|
|
switch (code) {
|
|
case 0: result = InitGame(); break;
|
|
case 1: result = PlayGame(); break;
|
|
}
|
|
return(result);
|
|
}
|
|
/********************************************************************************/
|
|
/* Game initialize process. */
|
|
/********************************************************************************/
|
|
extern ulong
|
|
GameInitialize(short code, long param)
|
|
{
|
|
playerEntry.type = 0;
|
|
fadeoutMode = 0;
|
|
mesgCastle = !BuIsActive(activePlayerNo-1);
|
|
activeStageNo = param;
|
|
activeCourseNo = 0;
|
|
ramSaveCourse = 0;
|
|
snEndingScene = NULL;
|
|
buYosshiJump = 0;
|
|
|
|
InitPlayerWorks();
|
|
BuClearRamStorage();
|
|
BuRestoreHat();
|
|
InitCamera_1st();
|
|
iwa_StratInit();
|
|
|
|
return(param);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* Check course start menu. */
|
|
/********************************************************************************/
|
|
extern ulong
|
|
CheckCourseMenu(short code, long param)
|
|
{
|
|
int middlePoint = middlePointSw;
|
|
|
|
|
|
middlePointSw = 0;
|
|
activeStageNo = param;
|
|
activeCourseNo = BuGetCourseNumber(param);
|
|
|
|
if (autoDemoPtr != NULL || snEndingScene != NULL || activeCourseNo == 0) return(FALSE);
|
|
|
|
if (activeStageNo != 30 && activeStageNo != 33 && activeStageNo != 34) {
|
|
marioWorks->ncoins = 0;
|
|
playerMeter.coin = 0;
|
|
BuSetStartingStar();
|
|
}
|
|
if (ramSaveCourse != activeCourseNo) {
|
|
ramSaveCourse = activeCourseNo;
|
|
InitCourse();
|
|
BuClearRamStorage();
|
|
}
|
|
if ((activeCourseNo > 15) || middlePoint) return(FALSE);
|
|
if (sysDebugFlag && !sysProcessMeter ) return(FALSE);
|
|
|
|
|
|
#if 0
|
|
if (ramSaveCourse == activeCourseNo) {
|
|
/* Restore RAM save data */
|
|
return(FALSE);
|
|
} else {
|
|
ramSaveCourse = activeCourseNo;
|
|
InitCourse();
|
|
BuClearRamStorage();
|
|
|
|
if (activeCourseNo > 15) return(FALSE);
|
|
if (sysDebugFlag && !sysProcessMeter) return(FALSE);
|
|
}
|
|
#endif
|
|
return(TRUE);
|
|
}
|
|
/********************************************************************************/
|
|
/* Check course start menu. */
|
|
/********************************************************************************/
|
|
extern ulong
|
|
GameTheEnd(short code, long param)
|
|
{
|
|
Na_FixSeFlagEntry(NA_SYS_END_MESSAGE);
|
|
return(1);
|
|
}
|