/*============================================================================
NuSYSTEM sample program SNAKE TAIL HACK
main.c
Copyright (C) 1997, NINTENDO Co,Ltd.
============================================================================*/
#include <nusys.h>
#include <nualsgi_n.h>
#include "main.h"
#include "para.h"
/* The structure for creating Controller trigger data */
NUContData ContTriger[NU_CONT_MAXCONTROLLERS];
NUContPakFile* file_chk;
/* For game replay */
ContTrace ConTrace[100*60][4];
int TraceIdx;
int ReplayMode;
/* The buffer for saving the Controller data */
u8 SaveBuf[100*60*4];
int SaveIdx[4];
int SaveOfsIdx;
int ContPakError;
int ContPakOpen[4];
int ContPakFileOpen[4];
/* The stage number*/
volatile int stage;
/* Declaration of the prototype */
void gamemain(int);
void gametitle(int);
void gameover(int);
void pakerr(int);
void pakrwerr(int);
void SavePadData( void );
void ReplayPadData( void );
void SaveContPak( void );
void LoadContPak( void );
void ContPakOpenAll( void );
void NoteOpenAll( void );
int ChkPakStat( void );
/* Declaration of extern */
/* gamemain.c */
extern void makegameDL(void);
extern void updateGame(void);
extern void InitSnake( void );
extern void InitShotTail( void );
extern float View;
/* gametitle.c */
extern void maketitleDL(void);
extern void updateTitle(void);
/* gameover.c */
extern void makegameoverDL(void);
extern void updateGameOver(void);
/* gamepakerr.c */
extern void makepakerrDL(void);
extern void updatePakErr(void);
extern int NoSave;
/* gameparwkerr.c */
extern void makepakrwerrDL(void);
extern void updateRwPakErr(void);
/* main.c */
extern int Pause;
/* For n_audio */
extern u8 n_aspMainTextStart[],n_aspMainTextEnd[];
extern u8 n_aspMainDataStart[],n_aspMainDataEnd[];
extern u8 _midibankSegmentRomStart[],_midibankSegmentRomEnd[];
extern u8 _miditableSegmentRomStart[],_miditableSegmentRomEnd[];
extern u8 _seq1SegmentRomStart[],_seq1SegmentRomEnd[];
extern u8 _sfxbankSegmentRomStart[],_sfxbankSegmentRomEnd[];
extern u8 _sfxtableSegmentRomStart[],_sfxtableSegmentRomEnd[];
NUContPakFile pakFile[4];
/*----------------------*/
/* The main process */
/* IN: None */
/* RET:None */
/*----------------------*/
void
mainproc(void)
{
extern ALSynConfig auSynConfig;
/* The initialization of graphic*/
nuGfxInit();
/* The initialization of the controller manager*/
nuContInit();
/* The initialization of the audio manager */
nuAuInit();
/*Register the bank to the sound player */
nuAuSndPlayerBankSet(_sfxbankSegmentRomStart,
_sfxbankSegmentRomEnd - _sfxbankSegmentRomStart,
_sfxtableSegmentRomStart
);
/*Register the bank to the sequence player */
nuAuSeqPlayerBankSet(_midibankSegmentRomStart,
_midibankSegmentRomEnd - _midibankSegmentRomStart,
_miditableSegmentRomStart
);
/*Register the sequence bank to the sequence player*/
nuAuSeqPlayerSeqSet(_seq1SegmentRomStart);
/* Set the stage number to 0*/
stage = 0;
/* Select the call-back routine depending on stage numbers.
The call-back sets the value to stage for specifying the call-back
routine registering next when stage ends.*/
InitSnake();
InitShotTail();
View = 0.0;
Pause = 1;
TraceIdx = 0;
SaveIdx[0] = 0;
SaveIdx[1] = 0;
SaveIdx[2] = 0;
SaveIdx[3] = 0;
SaveOfsIdx = 0;
ReplayMode = 0;
while(1){
switch(stage){
case 0:/*Title*/
/* Set stage to the different value from the stage number first so
that you can notice the call-back has set the value */
stage = -1;
/* Play sequence of the title */
nuAuSeqPlayerSetNo(0,0);
nuAuSeqPlayerPlay(0);
/* Call-back register */
nuGfxFuncSet((NUGfxFunc)gametitle);
/* Start to display*/
nuGfxDisplayOn();
break;
case 1:/*Main of the game*/
stage = -1;
/* Play sequence of this game volume */
nuAuSeqPlayerSetNo(0,2);
nuAuSeqPlayerPlay(0);
/* Call-back register*/
nuGfxFuncSet((NUGfxFunc)gamemain);
/* Start to display*/
nuGfxDisplayOn();
break;
case 2:/*Game-over */
stage = -1;
/* Play sequence at game-over */
nuAuSeqPlayerSetNo(0,1);
nuAuSeqPlayerPlay(0);
/* Call-back register */
nuGfxFuncSet((NUGfxFunc)gameover);
/* Start to display*/
nuGfxDisplayOn();
break;
case 3:/*Pack error*/
stage = -1;
/* Call-back register */
nuGfxFuncSet((NUGfxFunc)pakerr);
/* Start to display */
nuGfxDisplayOn();
break;
case 4:/*Pack error*/
stage = -1;
/* Call-back register */
nuGfxFuncSet((NUGfxFunc)pakrwerr);
/*Start to display*/
nuGfxDisplayOn();
break;
default:
break;
}
/* Wait for switching the scene */
while(stage == -1);
/* Clear the display */
nuGfxDisplayOff();
}
}
/*----------------------*/
/* The title process */
/* IN: pendingGfx */
/* RET:None */
/*----------------------*/
void
gametitle(int pendingGfx)
{
/* Provide the display process if there is only one task which is processing or waiting for the process.*/
if(pendingGfx < 2){
maketitleDL();
/*Create trigger data*/
nuContDataGetExAll(&ContTriger[0]);
/* The title progressing process */
updateTitle();
}
}
/*------------------------------*/
/* The process of game main */
/* IN: pendingGfx */
/* RET:None */
/*------------------------------*/
void
gamemain(int pendingGfx)
{
/* Provide the display process if there is only one task which is processing or waiting for the process. */
if(pendingGfx < 2){
makegameDL();
/*In the case of selecting the REPLAY MODE at the title*/
if(ReplayMode){
ReplayPadData();
Pause = 0;
}
/*Create trigger data*/
nuContDataGetExAll(&ContTriger[0]);
/*In the case of selecting PADDATA SAVE at the title*/
if(NoSave == 0){
if(ReplayMode == 0 && Pause == 0){
SavePadData();
}
}
/* The game progressing process */
updateGame();
}
}
/*------------------------------*/
/* The process of game-over */
/* IN: pendingGfx */
/* RET:None */
/*------------------------------*/
void
gameover(int pendingGfx)
{
/* Provide the display process if there is only one task which is processing or waiting for the process. */
if(pendingGfx < 2){
makegameoverDL();
/*Create trigger data*/
nuContDataGetExAll(&ContTriger[0]);
/* The game-over progressing process */
updateGameOver();
}
}
/*----------------------------------------------*/
/* The Controller Pak error process */
/* IN: pendingGfx */
/* RET:None */
/*----------------------------------------------*/
void
pakerr(int pendingGfx)
{
/* Provide the display process if there is only one task which is processing or waiting for the process. */
if(pendingGfx < 2){
makepakerrDL();
/*Create tigger data*/
nuContDataGetExAll(&ContTriger[0]);
/* The game-over progressing process*/
updatePakErr();
}
}
/*----------------------------------------------*/
/* The Controller Pak error process */
/* IN: pendingGfx */
/* RET:None */
/*----------------------------------------------*/
void
pakrwerr(int pendingGfx)
{
/* Provide the display process if there is only one task which is processing or waiting for the process.*/
if(pendingGfx < 2){
makepakrwerrDL();
/*Create trigger data*/
nuContDataGetExAll(&ContTriger[0]);
/*The game-over progressing process*/
updateRwPakErr();
}
}
/*--------------------------------------*/
/* Record pad data to the buffer */
/* IN: None */
/* RET:None */
/*--------------------------------------*/
void
SavePadData( void )
{
int idx;
for(idx = 0; idx < 4; idx++){
ConTrace[TraceIdx][idx].button = nuContData[idx].button;
ConTrace[TraceIdx][idx].stick_x = nuContData[idx].stick_x;
ConTrace[TraceIdx][idx].stick_y = nuContData[idx].stick_y;
}
TraceIdx++;
}
/*------------------------------------------------------*/
/* Record pad data to the Controller Pak */
/* IN: None */
/* RET:None */
/*------------------------------------------------------*/
void
SaveContPak( void )
{
int idx1, idx2, idx3;
u8 _al, _ah, stx, sty;
/*100*60*/
for(idx1 = 0; idx1 < 4; idx1++){
for(idx2 = 0, idx3 = 0; idx3 < 100*60; idx2+=4, idx3++){
/* To each work once with the u8 size from the buffer*/
_al = (u8)ConTrace[idx3][idx1].button;
_ah = (u8)(ConTrace[idx3][idx1].button >> 8);
stx = (u8)ConTrace[idx3][idx1].stick_x;
sty = (u8)ConTrace[idx3][idx1].stick_y;
SaveBuf[idx2] = _al;
SaveBuf[idx2 + 1] = _ah;
SaveBuf[idx2 + 2] = stx;
SaveBuf[idx2 + 3] = sty;
}
/* Save to the pack, practically */
nuContPakFileWrite(&pakFile[idx1], 0, 100*60*4,SaveBuf);
ContPakOpen[idx1] = pakFile[idx1].error;
}
}
/*------------------------------------------------------*/
/* Read pad data from the Controller Pak */
/* IN: None */
/* RET:None */
/*------------------------------------------------------*/
void
LoadContPak( void )
{
int idx1, idx2, idx3;
u8 _al, _ah, stx, sty;
/* Register the company code and game code */
nuContPakCodeSet("64", "snake");
for(idx1 = 0; idx1 < 4; idx1++){
/* Open the note*/
nuContPakFileOpenJis(&pakFile[idx1], "snake tail hack", ""
,NU_CONT_PAK_MODE_NOCREATE, GAME_NOTE_SIZE + 31);
/* Load from the pack, practically */
nuContPakFileRead(&pakFile[idx1], 0, 100*60*4,SaveBuf);
ContPakOpen[idx1] = pakFile[idx1].error;
if(pakFile[idx1].error == 0){
for(idx2 = 0, idx3 = 0; idx3 < 100*60; idx2+=4, idx3++){
/* To each work once with the u8 size from the buffer */
_al = SaveBuf[idx2];
_ah = SaveBuf[idx2 + 1];
stx = SaveBuf[idx2 + 2];
sty = SaveBuf[idx2 + 3];
ConTrace[idx3][idx1].button = (_ah << 8) + _al;
ConTrace[idx3][idx1].stick_x = stx;
ConTrace[idx3][idx1].stick_y = sty;
}
}
}
}
/*--------------------------------------*/
/* Play back saved pad data */
/* IN: None */
/* RET:None */
/*--------------------------------------*/
void
ReplayPadData( void )
{
int idx;
for(idx = 0; idx < 4; idx++){
nuContData[idx].button = ConTrace[TraceIdx][idx].button;
nuContData[idx].stick_x = ConTrace[TraceIdx][idx].stick_x;
nuContData[idx].stick_y = ConTrace[TraceIdx][idx].stick_y;
}
TraceIdx++;
}
/*--------------------------------------*/
/* Open the Controller Pak */
/* IN: None */
/* RET:None */
/*--------------------------------------*/
void
ContPakOpenAll( void )
{
int idx;
for(idx = 0; idx < 4; idx++){
/* Recognize the controller pack */
nuContPakOpen(&pakFile[idx], idx);
if(pakFile[idx].type == NU_CONT_PAK_TYPE_RUMBLE){
ContPakOpen[idx] = RUMBLE_PAK;
}else{
ContPakOpen[idx] = pakFile[idx].error;
}
/*PFS_ERR_NOPACK, PFS_ERR_NEW_PACK, PFS_ERR_CONTRFAIL*/
/*The error process about PFS_ERR_ID_FATAL and PFS_ERR_DEVICE*/
#if 0
switch(ContPakOpen[idx]){
case 0:
osSyncPrintf("PACK%d\tOK\n",idx);
break;
case PFS_ERR_NOPACK:
osSyncPrintf("PACK%d\tPFS_ERR_NOPACK\n",idx);
break;
case PFS_ERR_NEW_PACK:
osSyncPrintf("PACK%d\tPFS_ERR_NEW_PACK\n",idx);
break;
case PFS_ERR_CONTRFAIL:
osSyncPrintf("PACK%d\tPFS_ERR_CONTRFAIL\n",idx);
break;
case PFS_ERR_ID_FATAL:
osSyncPrintf("PACK%d\tPFS_ERR_ID_FATAL\n",idx);
break;
case PFS_ERR_DEVICE:
osSyncPrintf("PACK%d\tPFS_ERR_DEVICE\n",idx);
break;
case RUMBLE_PAK:
osSyncPrintf("PACK%d\tRUMBLE_PACK DETECTED\n",idx);
break;
default:
break;
}
#endif
}
}
/*--------------------------------------------------------------*/
/* Check the status of the opened Controller Pak */
/* IN: None */
/* RET:None */
/*--------------------------------------------------------------*/
int
ChkPakStat( void )
{
int idx;
for(idx = 0; idx < 4; idx++){
if(ContPakOpen[idx] != 0){
return(idx);
}
}
return(-1);
}
/*--------------------------------------*/
/* Open the game note of the opened */
/* Controller Pak */
/* IN: None */
/* RET:None */
/*--------------------------------------*/
void
NoteOpenAll( void )
{
int idx;
/* Register the company and game codes */
nuContPakCodeSet("64", "snake");
for(idx = 0; idx < 4; idx++){
/* Open the note */
nuContPakFileOpenJis(&pakFile[idx], "snake tail hack", ""
,NU_CONT_PAK_MODE_CREATE, GAME_NOTE_SIZE + 31);
if(pakFile[idx].error == PFS_DATA_FULL || pakFile[idx].error == PFS_DIR_FULL){
pakFile[idx].error = NOT_CREAT;
ContPakOpen[idx] = pakFile[idx].error;
}else{
ContPakOpen[idx] = 0;
}
}
}