517 lines
15 KiB
C
517 lines
15 KiB
C
/********************************************************************************
|
|
Ultra 64 MARIO Brothers
|
|
|
|
scene management module
|
|
|
|
Copyright 1996 Nintendo co., ltd. All rights reserved
|
|
|
|
April 23, 1996
|
|
********************************************************************************/
|
|
|
|
#include "headers.h"
|
|
|
|
|
|
extern void DrawMessage(void);
|
|
extern short MessageEvent(void);
|
|
extern void MeterGaugeEvent(void);
|
|
|
|
|
|
|
|
MapNode *shapeList[SN_NUMSHAPES]; /* shape list memory */
|
|
SceneRecord sceneList[SN_NUMSCENES]; /* scene list memory */
|
|
|
|
ActorRecord starringActor[1]; /* Mario's actor record */
|
|
ActorPtr marioActor = &starringActor[0]; /* pointer to the Mario'actor */
|
|
|
|
MapNode **stageShapes = shapeList; /* pointer to the shape list */
|
|
SceneRecord *stageScenes = sceneList; /* pointer to the scene list */
|
|
|
|
ScenePtr snSceneInfo = NULL; /* pointer to the active scene information */
|
|
EndingPtr snEndingScene = NULL; /* pointer to the ending scene information */
|
|
|
|
SnWipeCtrl wipeControl; /* wipe control record */
|
|
|
|
static Vp *snViewPort = NULL; /* pointer to the optional view port */
|
|
static Vp *snTrimming = NULL; /* pointer to the trimming port */
|
|
static short faderDelay = 0; /* delayed fader counter */
|
|
static ulong backColor = 0; /* back color (out of trimming) */
|
|
static ulong blankColor = 0; /* software blanking color */
|
|
static uchar blankColorR = 0; /* software bankking color red level */
|
|
static uchar blankColorG = 0; /* software blanking color green level */
|
|
static uchar blankColorB = 0; /* software blanking color green level */
|
|
|
|
short activePlayerNo = 1; /* active player number */
|
|
short activeCourseNo; /* active course number */
|
|
short activeLevelNo; /* active star level number */
|
|
short activeStageNo = 1; /* active stage number */
|
|
short activeSceneNo; /* active scene number */
|
|
short ramSaveCourse; /* RAM save course number */
|
|
|
|
short mesgEvent; /* result of message routine */
|
|
short mesgLatch; /* latch for message result */
|
|
|
|
/********************************************************************************/
|
|
/* Player entrant path name lists. */
|
|
/********************************************************************************/
|
|
|
|
#define NUM_PATHNAMES 20
|
|
|
|
extern Path e_player_waiting[];
|
|
extern Path e_player_landing[];
|
|
extern Path e_player_falling[];
|
|
extern Path e_player_rolling[];
|
|
extern Path e_player_downing[];
|
|
extern Path e_player_entpict[];
|
|
extern Path e_player_flight[];
|
|
extern Path e_player_swimming[];
|
|
|
|
extern Path e_player_entwinner[];
|
|
extern Path e_player_entloser[];
|
|
extern Path e_player_landwinner[];
|
|
extern Path e_player_landloser[];
|
|
extern Path e_player_pushout[];
|
|
extern Path e_player_pushdown[];
|
|
|
|
|
|
static Path *pathNameList[NUM_PATHNAMES] = {
|
|
e_tripdoor,
|
|
e_tripstar,
|
|
e_tripchimney,
|
|
e_tripchimney2,
|
|
e_dokan,
|
|
e_warp,
|
|
e_player_waiting,
|
|
e_player_landing,
|
|
e_player_falling,
|
|
e_player_rolling,
|
|
e_player_downing,
|
|
e_player_entpict,
|
|
e_player_flight,
|
|
e_player_swimming,
|
|
|
|
e_player_entwinner,
|
|
e_player_entloser,
|
|
e_player_landwinner,
|
|
e_player_landloser,
|
|
e_player_pushout,
|
|
e_player_pushdown
|
|
};
|
|
static uchar portNameList[NUM_PATHNAMES] = {
|
|
SN_TRIP_DOOR,
|
|
SN_TRIP_STAR,
|
|
SN_TRIP_CHIMNEY,
|
|
SN_TRIP_CHIMNEY,
|
|
SN_TRIP_CHIMNEY,
|
|
SN_WARP_POINT,
|
|
SN_ENTER_WAITING,
|
|
SN_ENTER_LANDING,
|
|
SN_ENTER_FALLING,
|
|
SN_ENTER_ROLLING,
|
|
SN_ENTER_DOWNING,
|
|
SN_ENTER_PICTURE,
|
|
SN_ENTER_FLIGHT,
|
|
SN_ENTER_SWIMMING,
|
|
|
|
SN_ENTER_WINNER,
|
|
SN_ENTER_LOSER,
|
|
SN_ENTER_LANDWINNER,
|
|
SN_ENTER_LANDLOSER,
|
|
SN_ENTER_PUSHOUT,
|
|
SN_ENTER_PUSHDOWN
|
|
};
|
|
/********************************************************************************/
|
|
/* Standard view port record. */
|
|
/********************************************************************************/
|
|
|
|
static Vp viewport = {
|
|
320*2, 240*2, G_MAXZ/2, 0,
|
|
320*2, 240*2, G_MAXZ/2, 0,
|
|
};
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Trip port support routines.
|
|
*
|
|
*/
|
|
|
|
#define SnGetBlankColor(r,g,b) (r=blankColorR,g=blankColorG,b=blankColorB)
|
|
|
|
/********************************************************************************/
|
|
/* Set view port. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnSetViewPort(Vp *viewing, Vp *trimming, uchar red, uchar green, uchar blue)
|
|
{
|
|
ushort color = RGBA16(red>>3,green>>3,blue>>3,1);
|
|
|
|
backColor = (color << 16) | color;
|
|
snViewPort = viewing;
|
|
snTrimming = trimming;
|
|
}
|
|
/********************************************************************************/
|
|
/* Set software blanking color. */
|
|
/********************************************************************************/
|
|
static void
|
|
SnSetBlankColor(uchar red, uchar green, uchar blue)
|
|
{
|
|
ushort color = RGBA16(red>>3,green>>3,blue>>3,1);
|
|
|
|
blankColor = (color << 16) | color;
|
|
blankColorR = red;
|
|
blankColorG = green;
|
|
blankColorB = blue;
|
|
}
|
|
/********************************************************************************/
|
|
/* Display demo message. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnDisplayDemoMessage(void)
|
|
{
|
|
#if CHINA
|
|
unsigned char str[] ={0xb0, 0x00};
|
|
#endif
|
|
if ((frameCounter & 0x1f) < 20) {
|
|
if (contConnection == 0) {
|
|
dcprintf(160,20, "NO CONTROLLER");
|
|
} else {
|
|
#if CHINA
|
|
dcprintf(60,38, str);
|
|
#else
|
|
dcprintf(60,38, "PRESS");
|
|
#endif
|
|
dcprintf(60,20, "START");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Trip port support routines.
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************/
|
|
/* Get trip port type. */
|
|
/********************************************************************************/
|
|
extern int
|
|
SnGetPortType(StrategyPtr stratp)
|
|
{
|
|
int count;
|
|
Path *pathname = VirtualToSegment(SEGMENT_PATHDATA, stratp->pathname);
|
|
|
|
for (count = 0; count < NUM_PATHNAMES; count++) {
|
|
if (pathname == pathNameList[count]) return((int)portNameList[count]);
|
|
}
|
|
return(0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Get port pointer. */
|
|
/********************************************************************************/
|
|
extern PortPtr
|
|
SnGetPortPtr(uchar code)
|
|
{
|
|
PortPtr port = NULL;
|
|
|
|
for (port = snSceneInfo->ports; port != NULL; port = port->next) {
|
|
if (port->number == code) break;
|
|
}
|
|
return(port);
|
|
}
|
|
/********************************************************************************/
|
|
/* Find port pointer. */
|
|
/********************************************************************************/
|
|
extern PortPtr
|
|
SnFindPortPtr(StrategyPtr stratp)
|
|
{
|
|
uchar code = (stratp->s[stw_actorcode].d & 0x00ff0000) >> 16;
|
|
|
|
return( SnGetPortPtr(code));
|
|
}
|
|
/********************************************************************************/
|
|
/* Check player transfer. */
|
|
/********************************************************************************/
|
|
static void
|
|
InitPorts(void)
|
|
{
|
|
PortPtr port;
|
|
MapNode *node = strategyGroup.child;
|
|
|
|
do {
|
|
StrategyPtr stratp = (StrategyPtr)node;
|
|
|
|
if ((stratp->status != 0) && SnGetPortType(stratp)) {
|
|
if ((port = SnFindPortPtr(stratp)) != NULL) port->stratp = stratp;
|
|
}
|
|
} while ((node = node->next) != strategyGroup.child);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
*
|
|
*
|
|
* Scene management routines.
|
|
*
|
|
*/
|
|
|
|
//********************************************************************************/
|
|
/* */
|
|
/* Initialize scene informations. */
|
|
/* */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnInitSceneInfo(void)
|
|
{
|
|
int count;
|
|
|
|
snSceneInfo = NULL;
|
|
wipeControl.active = 0;
|
|
wipeControl.blank = 0;
|
|
marioActor->sceneNo = -1;
|
|
|
|
for (count = 0; count < SN_NUMSCENES; count++) {
|
|
sceneList[count].sceneNo = count;
|
|
sceneList[count].entrant = 0;
|
|
sceneList[count].environment = 0;
|
|
sceneList[count].mapScene = NULL;
|
|
sceneList[count].mapInfo = NULL;
|
|
sceneList[count].areaInfo = NULL;
|
|
sceneList[count].tagInfo = NULL;
|
|
sceneList[count].ports = NULL;
|
|
sceneList[count].bgport = NULL;
|
|
sceneList[count].connect = NULL;
|
|
sceneList[count].actors = NULL;
|
|
sceneList[count].camera = NULL;
|
|
sceneList[count].windzone = NULL;
|
|
sceneList[count].waterjet[0] = NULL;
|
|
sceneList[count].waterjet[1] = NULL;
|
|
sceneList[count].message[0] = 255;
|
|
sceneList[count].message[1] = 255;
|
|
sceneList[count].audmode = 0;
|
|
sceneList[count].musicno = 0;
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Dispose scene. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnDisposeScene(void)
|
|
{
|
|
int count;
|
|
|
|
if (snSceneInfo != NULL) {
|
|
MapSendMessage(snSceneInfo->mapScene, MAP_CBACK_SUSPEND);
|
|
snSceneInfo = NULL;
|
|
wipeControl.active = 0;
|
|
}
|
|
for (count = 0; count < SN_NUMSCENES; count++) {
|
|
if (sceneList[count].mapScene != NULL) {
|
|
MapSendMessage(sceneList[count].mapScene, MAP_CBACK_DISPOSE);
|
|
sceneList[count].mapScene = NULL;
|
|
}
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Open the scene. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnOpenScene(int sceneNo)
|
|
{
|
|
if (snSceneInfo == NULL && sceneList[sceneNo].mapScene != NULL) {
|
|
snSceneInfo = &sceneList[sceneNo];
|
|
activeSceneNo = snSceneInfo->sceneNo;
|
|
|
|
if (snSceneInfo->mapInfo != NULL) mcInitBGCheck(sceneNo, snSceneInfo->mapInfo, snSceneInfo->areaInfo, snSceneInfo->tagInfo);
|
|
if (snSceneInfo->actors != NULL) SetStrategy(0, snSceneInfo->actors);
|
|
|
|
InitPorts();
|
|
MapSendMessage(snSceneInfo->mapScene, MAP_CBACK_ACTIVAT);
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Close the scene. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnCloseScene(void)
|
|
{
|
|
if (snSceneInfo != NULL) {
|
|
RemoveStrategy(0, snSceneInfo->sceneNo);
|
|
MapSendMessage(snSceneInfo->mapScene, MAP_CBACK_SUSPEND);
|
|
snSceneInfo->entrant = 0;
|
|
snSceneInfo = NULL;
|
|
wipeControl.active = 0;
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Enter the player. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnEnterPlayer(void)
|
|
{
|
|
Na_LevelSeAllStop();
|
|
SnOpenScene(marioActor->sceneNo);
|
|
if (snSceneInfo->sceneNo == marioActor->sceneNo) {
|
|
setflag(snSceneInfo->entrant, 1);
|
|
SetStrategy(0, marioActor);
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Exit the player. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnExitPlayer(void)
|
|
{
|
|
if (snSceneInfo != NULL && (snSceneInfo->entrant & 1)) {
|
|
RemoveStrategy(0, marioActor->actorID);
|
|
clrflag(snSceneInfo->entrant, 1);
|
|
|
|
if (snSceneInfo->entrant == 0) SnCloseScene();
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Change the scene. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnChangeScene(int newScene)
|
|
{
|
|
int entrant = snSceneInfo->entrant;
|
|
|
|
if (activeSceneNo != newScene) {
|
|
SnCloseScene();
|
|
SnOpenScene(newScene);
|
|
snSceneInfo->entrant = entrant;
|
|
player1stp->s[stw_effect].d = 0;
|
|
}
|
|
if (entrant & 1) player1stp->map.sceneNo = newScene, marioActor->sceneNo = newScene;
|
|
}
|
|
/********************************************************************************/
|
|
/* Do strategy execution. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnExecuteStrategy(void)
|
|
{
|
|
animationCounter += 1;
|
|
ExecStrategy(0);
|
|
}
|
|
/********************************************************************************/
|
|
/* Start screen fader. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnStartFader(short mode, short frame, uchar red, uchar green, uchar blue)
|
|
{
|
|
wipeControl.active = TRUE;
|
|
wipeControl.mode = mode;
|
|
wipeControl.frame = frame;
|
|
wipeControl.blank = 0;
|
|
|
|
if (mode & 1) SnSetBlankColor(red, green, blue);
|
|
else SnGetBlankColor(red, green, blue);
|
|
|
|
if (mode < 8) {
|
|
wipeControl.params.screen.red = red;
|
|
wipeControl.params.screen.green = green;
|
|
wipeControl.params.screen.blue = blue;
|
|
} else {
|
|
wipeControl.params.window.red = red;
|
|
wipeControl.params.window.green = green;
|
|
wipeControl.params.window.blue = blue;
|
|
|
|
wipeControl.params.window.start_xo = 160;
|
|
wipeControl.params.window.start_yo = 120;
|
|
wipeControl.params.window.end_xo = 160;
|
|
wipeControl.params.window.end_yo = 120;
|
|
wipeControl.params.window.angle_inc = 0;
|
|
|
|
if (mode & 1) {
|
|
wipeControl.params.window.start_side = 320;
|
|
wipeControl.params.window.end_side = (mode >= WIPE_DOCRO_WIN_CLOSE) ? 16 : 0;
|
|
} else {
|
|
wipeControl.params.window.start_side = (mode >= WIPE_DOCRO_WIN_OPEN ) ? 16 : 0;
|
|
wipeControl.params.window.end_side = 320;
|
|
}
|
|
}
|
|
}
|
|
/********************************************************************************/
|
|
/* Start screen fader with delay. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnDelayFader(short mode, short frame, uchar red, uchar green, uchar blue, short delay)
|
|
{
|
|
faderDelay = delay;
|
|
SnStartFader(mode, frame, red, green, blue);
|
|
}
|
|
/********************************************************************************/
|
|
/* Draw screens. */
|
|
/********************************************************************************/
|
|
extern void
|
|
SnDrawScreen(void)
|
|
{
|
|
if (snSceneInfo != NULL && wipeControl.blank == 0) {
|
|
DrawScene(snSceneInfo->mapScene, snViewPort, snTrimming, backColor);
|
|
gSPViewport(graphPtr++, K0_TO_PHYS(&viewport));
|
|
gDPSetScissor(graphPtr++, G_SC_NON_INTERLACE, 0, CLIP_UPPER, SCREEN_WIDTH, CLIP_LOWER);
|
|
MeterGaugeEvent();
|
|
|
|
gDPSetScissor(graphPtr++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
DrawMessage();
|
|
EndingDemoMessageEvent();
|
|
DrawStaffRoll();
|
|
|
|
gDPSetScissor(graphPtr++, G_SC_NON_INTERLACE, 0, CLIP_UPPER, SCREEN_WIDTH, CLIP_LOWER);
|
|
if ((mesgEvent = MessageEvent()) != 0) mesgLatch = mesgEvent;
|
|
|
|
|
|
if (snTrimming != NULL) SetTrimmingRectangle(snTrimming);
|
|
else gDPSetScissor(graphPtr++, G_SC_NON_INTERLACE, 0, CLIP_UPPER, SCREEN_WIDTH, CLIP_LOWER);
|
|
|
|
if (wipeControl.active) {
|
|
if (faderDelay == 0) {
|
|
wipeControl.active = !Wipe(0, wipeControl.mode, wipeControl.frame, (void *)&wipeControl.params);
|
|
if (wipeControl.active == 0) {
|
|
if (wipeControl.mode & 1) wipeControl.blank = 1;
|
|
else SnSetBlankColor(0, 0, 0);
|
|
}
|
|
} else {
|
|
faderDelay -= 1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
DrawMessage();
|
|
if (snTrimming != NULL) SoftwareTrimBlanking(snTrimming, blankColor);
|
|
else SoftwareBlanking(blankColor);
|
|
}
|
|
snViewPort = NULL;
|
|
snTrimming = NULL;
|
|
}
|