marioparty4/src/game/minigame_seq.c
2024-01-28 14:31:50 -06:00

1263 lines
No EOL
28 KiB
C

#include "game/armem.h"
#include "game/sprite.h"
#include "game/process.h"
#include "game/gamework_data.h"
#include "game/objsub.h"
#include "game/hsfman.h"
#include "math.h"
#include "stdarg.h"
void MGSeqStub(void);
void MGSeqPauseEnableCtrl(s32 flag);
extern s16 HuSysVWaitGet(s16 param);
typedef struct seq_work SeqWork;
typedef int (*SeqUpdateFunc)(SeqWork *work);
typedef int (*SeqInitFunc)(SeqWork *work, va_list params);
typedef struct seq_work {
SeqUpdateFunc update;
char *data;
float x;
float y;
float scale_x;
float scale_y;
float unk_18;
float work_float[2];
float unk_24;
s16 time;
s16 time_max;
s16 work_s16[4];
s16 param[2];
s16 type;
s16 spr_grp[16];
s16 sprite[16];
u8 seq_no;
u8 stat;
u8 unk_7C;
u8 unk_7D;
} SeqWork;
typedef struct seq_info {
SeqInitFunc init;
SeqUpdateFunc update;
float x;
float y;
float scale_x;
float scale_y;
s32 time_max;
} SeqInfo;
static int SeqInitTimer(SeqWork *work, va_list params);
static int SeqUpdateTimer(SeqWork *work);
static int SeqInitType2(SeqWork *work, va_list params);
static int SeqUpdateType2(SeqWork *work);
static int SeqInitMGBasic(SeqWork *work, va_list params);
static int SeqUpdateMGBasic(SeqWork *work);
static int SeqInitMGCommon(SeqWork *work, va_list params);
static int SeqUpdateMG1vs3(SeqWork *work);
static int SeqUpdateMGBattle(SeqWork *work);
static int SeqUpdateMGStory(SeqWork *work);
static int SeqUpdateMG2vs2(SeqWork *work);
static int SeqUpdateMGBowser(SeqWork *work);
static int SeqInitWin(SeqWork *work, va_list params);
static int SeqUpdateWin(SeqWork *work);
static int SeqInitDraw(SeqWork *work, va_list params);
static int SeqUpdateDraw(SeqWork *work);
static int SeqInitRecord(SeqWork *work, va_list params);
static int SeqUpdateRecord(SeqWork *work);
static int SeqInitFlip(SeqWork *work, va_list params);
static int SeqUpdateFlip(SeqWork *work);
s32 mgSeqInitF = -1;
static SeqInfo seqInfoTbl[] = {
{ NULL, NULL, 292.0f, 240.0f, 1.0f, 1.0f, 60 },
{ SeqInitTimer, SeqUpdateTimer, 292.0f, 64.0f, 1.0f, 1.0f, 60 },
{ SeqInitType2, SeqUpdateType2, 292.0f, 240.0f, 0.5f, 0.5f, 60 },
{ SeqInitMGBasic, SeqUpdateMGBasic, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGCommon, SeqUpdateMG1vs3, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitWin, SeqUpdateWin, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGCommon, SeqUpdateMGBattle, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGCommon, SeqUpdateMGStory, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGBasic, SeqUpdateMGBasic, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGCommon, SeqUpdateMG2vs2, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitFlip, SeqUpdateFlip, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitMGCommon, SeqUpdateMGBowser, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitWin, SeqUpdateWin, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ SeqInitDraw, SeqUpdateDraw, 292.0f, 240.0f, 1.0f, 1.0f, 60 },
{ SeqInitRecord, SeqUpdateRecord, 292.0f, 240.0f, 1.0f, 1.0f, 180 },
{ NULL, NULL, 292.0f, 240.0f, 1.0f, 1.0f, 60 },
{ NULL, NULL, 292.0f, 240.0f, 1.0f, 1.0f, 60 },
};
static s32 seqType2SprTbl[6] = {
0, 0, 0, 0, 0, 0
};
static s16 mgSeqTypeTbl[9] = {
8,
4,
9,
11,
6,
10,
7,
11,
7
};
static char lbl_8012F336[] = {
0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0,
0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
0xD9, 0xDA, 0xDB, 0xDC, 0xA6, 0xDD, 0xA7, 0xA8,
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB6,
0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xCA, 0xCB, 0xCC,
0xCD, 0xCE, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0x21,
0x3F, 0xB0, 0x00
};
static char lbl_8012F389[] = "x first\n";
static char lbl_8012F392[] = "y first\n";
static s16 seqMaxTime[8];
static SeqWork seqWorkData[8];
static s16 seqTimer;
static u8 seqDoneF;
u8 lbl_801D3D94;
static s16 seqSpeed;
static s16 seqPauseF;
static s32 seqRecordVal;
static s32 pauseWaitF;
static s32 pauseExitF;
static s32 pauseActiveF;
static Process *pauseProcess;
static s32 seqLanguage;
void fn_80036BC8(void);
void MGSeqInit(void)
{
int i;
SeqWork *work;
work = &seqWorkData[0];
for(i=8; i!=0; i--, work++) {
work->seq_no = 0;
work->data = NULL;
}
seqPauseF = 0;
seqDoneF = 0;
lbl_801D3D94 = 0;
seqTimer = 30;
HuAR_DVDtoARAM(MAKE_DIR_NUM(DATADIR_GAMEMES));
HuAR_DVDtoARAM(MAKE_DIR_NUM(DATADIR_MGCONST));
while(HuARDMACheck());
fn_80036BC8();
mgSeqInitF = -1;
seqLanguage = GWLanguageGet();
}
void MGSeqMain(void)
{
SeqInfo *info;
s32 i;
s32 j;
s32 alive_flag;
u8 stat;
SeqWork *work;
seqSpeed = HuSysVWaitGet(seqSpeed);
if(Hu3DPauseF) {
return;
}
alive_flag = 0;
stat = 0;
work = &seqWorkData[0];
for(i=0; i<8; i++, work++) {
if(work->stat == 0) {
continue;
}
if(work->update) {
alive_flag = work->update(work);
} else {
info = &seqInfoTbl[work->seq_no];
if(work->seq_no != 0 && NULL != info->update) {
alive_flag = info->update(work);
}
}
if(!alive_flag) {
work->stat = 0;
if(!lbl_801D3D94) {
for(j=0; j<8; j++) {
if(seqWorkData[j].stat) {
break;
}
}
}
if(!work->data) {
HuMemDirectFree(work->data);
work->data = NULL;
}
}
stat |= work->stat;
}
if(!stat || stat & 0x4) {
if(seqTimer > 0) {
seqTimer -= seqSpeed;
}
}
}
static s16 CreateSeq(u8 seq_no, va_list params)
{
SeqWork *work;
SeqInfo *info;
int i;
int temp;
work = seqWorkData;
info = &seqInfoTbl[seq_no];
for(i=0; i<8; i++, work++) {
if(work->stat == 0) {
break;
}
}
if(i >= 8) {
return -1;
}
work->stat |= 0x1;
if(work->data) {
HuMemDirectFree(work->data);
}
work->data = NULL;
work->seq_no = (s32)seq_no;
work->time = 0;
work->x = info->x;
work->y = info->y;
work->scale_x = info->scale_x;
work->scale_y = info->scale_y;
work->unk_18 = 0.0f;
work->unk_7D = 255;
work->time_max = info->time_max;
work->work_s16[0] = work->work_s16[1] = work->work_s16[2] = work->work_s16[3] = 0;
work->work_float[0] = work->work_float[1] = 0.0f;
work->param[0] = work->param[1] = 0;
for(temp=0; temp<16; temp++) {
work->sprite[temp] = work->spr_grp[temp] = -1;
}
if(NULL != info->init) {
temp = info->init(work, params);
if(temp == 0) {
work->stat = 0;
return -1;
}
}
seqTimer = 30;
return i;
}
s16 MGSeqCreate(s16 type, ...)
{
s16 ret;
va_list params;
va_start(params, type);
if(type == 3) {
if(GWSystem.mg_next == 0xFFFF) {
type = 8;
} else {
type = mgSeqTypeTbl[mgInfoTbl[GWSystem.mg_next].type];
}
}
//FIXME: Fix truncation of type
ret = CreateSeq(type, params);
va_end(params);
return ret;
}
u8 MGSeqStatGet(s16 id)
{
SeqWork *work;
u8 ret = 0;
if(id < 0) {
int i;
work = seqWorkData;
for(i=8; i != 0; i--, work++) {
ret |= work->stat;
}
} else {
if(id < 8) {
ret = seqWorkData[id].stat;
}
}
return ret;
}
void MGSeqPosSet(s16 id, float x, float y)
{
if(id >= 0 && id < 8) {
seqWorkData[id].x = x;
seqWorkData[id].y = y;
}
}
void MGSeqParamSet(s16 id, s16 param1, s16 param2)
{
if(id >= 0 && id < 8) {
seqWorkData[id].param[0] = param1;
seqWorkData[id].param[1] = param2;
}
}
void MGSeqKill(s16 id, s16 param1, s16 param2)
{
if(id >= 0 && id < 8) {
if(seqWorkData[id].stat != 0) {
seqWorkData[id].stat = 8;
}
}
}
void MGSeqKillAll(s16 id, s16 param1, s16 param2)
{
seqDoneF = 1;
MGSeqMain();
seqDoneF = 0;
MGSeqStub();
lbl_801D3D94 = 0;
}
s32 MGSeqDoneCheck(void)
{
u8 stat = MGSeqStatGet(-1);
if(stat == 0 || (stat & 0xC)) {
if(seqTimer <= 0 || (stat & 0x8)) {
return 1;
}
}
return 0;
}
void MGSeqStub(void)
{
}
void MGSeqSprKill(SeqWork *work)
{
int i;
for(i=0; i<16; i++) {
if(work->spr_grp[i] >= 0) {
HuSprGrpKill(work->spr_grp[i]);
}
if(work->sprite[i] >= 0) {
HuSprKill(work->sprite[i]);
}
}
}
static void *SeqReadFile(s32 file)
{
return HuAR_ARAMtoMRAMFileRead(file, MEMORY_DEFAULT_NUM, HEAP_DATA);
}
static int SeqInitTimer(SeqWork *work, va_list params)
{
AnimData *spr_anim;
s16 sprite;
s16 spr_grp;
int duration, x, y;
s16 i;
duration = va_arg(params, int);
x = va_arg(params, int);
y = va_arg(params, int);
if(duration <= 0 && duration > 99) {
duration = 99;
}
work->work_s16[0] = duration;
if(x >= 0) {
work->x = x;
}
if(y >= 0) {
work->y = y;
}
work->work_s16[2] = 0;
work->work_s16[1] = 2;
work->work_float[0] = 0;
work->spr_grp[0] = spr_grp = HuSprGrpCreate(4);
HuSprGrpScaleSet(spr_grp, work->scale_x, work->scale_y);
spr_anim = HuSprAnimRead(SeqReadFile(MAKE_DATA_NUM(DATADIR_GAMEMES, 2)));
x = 12;
for(i=0; i<2; i++) {
sprite = HuSprCreate(spr_anim, 5, 0);
HuSprGrpMemberSet(spr_grp, i, sprite);
HuSprSpeedSet(spr_grp, i, 0);
HuSprPosSet(spr_grp, i, x, 0);
HuSprColorSet(spr_grp, i, 112, 233, 255);
x -= 24;
(void)i; //Hack for Matching
}
spr_anim = HuSprAnimRead(SeqReadFile(MAKE_DATA_NUM(DATADIR_GAMEMES, 1)));
sprite = HuSprCreate(spr_anim, 7, 0);
HuSprGrpMemberSet(spr_grp, 2, sprite);
HuSprPosSet(spr_grp, 2, 0, 0);
HuSprTPLvlSet(spr_grp, 2, 0.5f);
HuSprColorSet(spr_grp, 2, 0, 0, 0);
spr_anim = HuSprAnimRead(SeqReadFile(MAKE_DATA_NUM(DATADIR_GAMEMES, 0)));
sprite = HuSprCreate(spr_anim, 6, 0);
HuSprGrpMemberSet(spr_grp, 3, sprite);
HuSprPosSet(spr_grp, 3, 0, 0);
if(seqPauseF) {
work->work_s16[1] = 1;
for(i=0; i<2; i++) {
HuSprAttrSet(spr_grp, i, SPRITE_ATTR_HIDDEN);
(void)i; //Hack for Matching
}
}
return 1;
}
static int SeqUpdateTimer(SeqWork *work)
{
float scale;
float tp_lvl;
u8 digits[2];
s16 i;
s16 spr_grp = work->spr_grp[0];
if(work->param[0] != 0 && work->work_s16[1] != -1) {
switch(work->param[0]) {
case 2:
switch(work->param[1]) {
case -1:
work->stat |= 0x4;
work->work_s16[1] = -1;
work->work_float[0] = 0.0f;
break;
case 0:
work->work_s16[1] = 2;
work->work_float[0] = 0.0f;
break;
case 1:
work->work_s16[1] = 3;
work->work_float[0] = 0.0f;
break;
default:
break;
}
work->param[0] = 0;
break;
case 1:
if(work->param[1] < 0 && !(work->stat & 0x4)) {
work->stat |= 0x4;
work->work_s16[1] = -1;
work->work_float[0] = 0.0f;
} else {
if(work->param[1] > 99) {
work->work_s16[0] = 99;
} else {
if(work->work_s16[0] != work->param[1]) {
work->work_s16[0] = work->param[1];
if(work->param[1] <= 5) {
HuAudFXPlay(6);
work->work_s16[1] = 3;
work->work_float[0] = 0.0f;
HuSprColorSet(spr_grp, 0, 255, 112, 160);
HuSprColorSet(spr_grp, 1, 255, 112, 160);
} else {
HuSprColorSet(spr_grp, 0, 112, 233, 255);
HuSprColorSet(spr_grp, 1, 112, 233, 255);
}
}
}
}
work->param[0] = 0;
break;
case 3:
for(i=0; i<2; i++) {
HuSprAttrReset(spr_grp, i, SPRITE_ATTR_HIDDEN);
}
work->work_s16[1] = 3;
work->param[0] = 0;
break;
default:
work->param[0] = 0;
break;
}
}
if(work->work_s16[1] == 1) {
return 1;
}
if(work->work_s16[0] > 99) {
digits[0] = digits[1] = 9;
} else {
s32 value;
value = work->work_s16[0]/10;
digits[1] = value;
digits[0] = work->work_s16[0]-(value*10);
}
HuSprGrpPosSet(spr_grp, work->x, work->y);
HuSprGrpScaleSet(spr_grp, work->scale_x, work->scale_y);
for(i=0; i<2; i++) {
HuSprBankSet(spr_grp, i, digits[i]);
}
if(work->work_s16[1] != 0) {
switch(work->work_s16[1]) {
case 2:
{
float scale_x, scale_y;
scale = fabs(((sin((work->work_float[0]*M_PI)/180)*5.0f)+1.0f)-(sin((130*M_PI)/180)*5.0f));
scale_x = work->scale_x*scale;
scale_y = work->scale_y*scale;
work->work_float[0] += seqSpeed*5.0f;
if(work->work_float[0] > 130.0f) {
work->work_s16[1] = 0;
break;
}
HuSprGrpScaleSet(spr_grp, scale_x, scale_y);
}
break;
case 3:
{
scale = sin((work->work_float[0]*M_PI)/180)+1.0;
tp_lvl = 1.0-(sin((work->work_float[0]*M_PI)/180)*0.5);
work->work_float[0] += seqSpeed*18.0f;
if(work->work_float[0] > 180.0f) {
work->work_s16[1] = 0;
scale = 1.0f;
tp_lvl = 1.0f;
}
for(i=0; i<2; i++) {
HuSprScaleSet(spr_grp, i, scale, scale);
HuSprTPLvlSet(spr_grp, i, tp_lvl);
}
}
break;
case -1:
HuSprGrpScaleSet(spr_grp, work->scale_x, work->scale_y);
for(i=0; i<2; i++) {
HuSprScaleSet(spr_grp, i, 1.0f, 1.0f);
}
work->work_float[0] += 1.0f;
if(work->work_float[0] < 60.0f) {
break;
}
tp_lvl = 1.0-((work->work_float[0]-60.0f)/20.0f);
if(tp_lvl <= 0.0f) {
tp_lvl = 0.0f;
work->work_s16[1] = 0;
work->stat |= 0x8;
}
for(i=0; i<4; i++) {
HuSprTPLvlSet(spr_grp, i, tp_lvl);
}
break;
default:
break;
}
}
if(seqDoneF || (work->stat & 0x8)) {
MGSeqSprKill(work);
return 0;
} else {
return 1;
}
}
static int SeqInitType2(SeqWork *work, va_list params)
{
s16 spr_idx;
s16 spr_grp;
AnimData *anim_tbl[6];
s32 i;
s16 len;
char *str;
char c;
int time_max;
int x, y;
work->data = va_arg(params, void *);
time_max = va_arg(params, int);
x = va_arg(params, int);
y = va_arg(params, int);
if(time_max < 0) {
time_max = -1;
}
work->time_max = time_max;
if(x >= 0) {
work->x = x;
}
if(y >= 0) {
work->y = y;
}
work->work_s16[1] = 0;
work->work_float[0] = 0.0f;
x = 0;
len = 0;
str=work->data;
while(c=*str++) {
if(c >= '0' && c <= '9') {
x |= 1;
len++;
} else if(c >= 'A' && c <= 'Z') {
x |= 2;
len++;
} else if(c >= 'a' && c <= 'z') {
x |= 4;
len++;
} else if(c == '!' || c == '?') {
x |= 8;
len++;
}
}
work->work_s16[3] = len;
for(i=0; i<6; i++) {
if(x & (1 << i)) {
anim_tbl[i] = HuSprAnimRead(SeqReadFile(seqType2SprTbl[i]));
} else {
anim_tbl[i] = NULL;
}
}
work->spr_grp[0] = spr_grp = HuSprGrpCreate(len);
x = 0;
spr_idx = 0;
str=work->data;
while(c=*str++) {
i = -2;
if(c >= '0' && c <= '9') {
c -= '0';
i = 0;
} else if(c >= 'A' && c <= 'Z') {
c -= 'A';
i = 1;
} else if(c >= 'a' && c <= 'z') {
c -= 'a';
i = 2;
} else if(c == '!' || c == '?') {
if(c == '!') {
c = 0;
} else {
c = 1;
}
i = 3;
} else if(c == ' ') {
i = -1;
}
work->work_s16[2] = x;
if(i == -1) {
x += 32;
} else if(i >= 0) {
s16 sprite = HuSprCreate(anim_tbl[i], 5, c);
HuSprGrpMemberSet(spr_grp, spr_idx, sprite);
HuSprSpeedSet(spr_grp, spr_idx, 0.0f);
HuSprPosSet(spr_grp, spr_idx, x, 0.0f);
spr_idx++;
x += 64;
}
}
if(seqPauseF) {
work->work_s16[1] = 1;
for(i=0; i<work->work_s16[3]; i++) {
HuSprAttrSet(spr_grp, i, SPRITE_ATTR_HIDDEN);
}
}
return 1;
}
static int SeqUpdateType2(SeqWork *work)
{
float tp_lvl;
s16 spr_grp;
spr_grp = work->spr_grp[0];
HuSprGrpPosSet(spr_grp, work->x-((0.5f*work->scale_x)*work->work_s16[2]), work->y);
HuSprGrpScaleSet(spr_grp, work->scale_x, work->scale_y);
if(work->param[0] != 0 && work->work_s16[1] != -1) {
switch(work->param[0]) {
case 2:
if(work->param[1] != -1) {
(void)work; //HACK: to introduce extra branch
} else {
work->work_s16[1] = -1;
work->work_float[0] = 0.0f;
}
work->param[0] = 0;
break;
case 1:
work->time_max = work->param[1];
work->param[0] = 0;
break;
case 3:
{
s32 i;
for(i=0; i<work->work_s16[3]; i++) {
HuSprAttrReset(spr_grp, i, SPRITE_ATTR_HIDDEN);
(void)i;
}
work->work_s16[1] = 0;
work->param[0] = 0;
}
break;
default:
work->param[0] = 0;
break;
}
}
if(work->work_s16[1] == 1) {
return 1;
}
work->time += seqSpeed;
if(work->time >= work->time_max && work->work_s16[1] != -1) {
work->stat |= 0x4;
work->work_s16[1] = -1;
work->work_float[0] = 0.0f;
}
if(work->work_s16[1] != 0) {
if(work->work_s16[1] != -1) {
(void)work; //HACK: to introduce extra branch
} else {
s16 i;
work->work_float[0] += seqSpeed*0.1f;
tp_lvl = 1.0f-work->work_float[0];
if(tp_lvl <= 0.0f) {
tp_lvl = 0.0f;
work->work_s16[1] = 0;
work->stat |= 0x8;
}
for(i=0; i<work->work_s16[3]; i++) {
HuSprTPLvlSet(spr_grp, i, tp_lvl);
(void)i;
}
}
}
if(seqDoneF || (work->stat & 0x8)) {
MGSeqSprKill(work);
return 0;
} else {
return 1;
}
}
static char seqFontAlphaTbl[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '\0'
};
static char seqFontKanaTbl[] = {
0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0,
0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
0xD9, 0xDA, 0xDB, 0xDC, 0xA6, 0xDD, 0xA7, 0xA8,
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB6,
0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xCA, 0xCB,
0xCC, 0xCD, 0xCE, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE,
0xB0, 0x00
};
static char seqFontNumTbl[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '\0'
};
static s32 *letterBufTbl[5] = { };
static char wordStartE[] = "START!";
static char seqPunctTbl[] = {
'!', '?', '\0'
};
static char wordStartJ[] = {
0xBD, 0xC0, 0xB0, 0xC4, 0x21, 0x00
};
static char wordFinishJ[] = {
0xCC, 0xA8, 0xC6, 0xAF, 0xBC, 0xAD, 0x21, 0x00
};
static char wordDrawJ[] = {
0xCB, 0xB7, 0xDC, 0xB9, 0x21, 0x00
};
static char wordFinishE[] = "FINISH!";
static char wordDrawE[] = "DRAW!";
static char *wordMgTbl[6] = {
wordStartJ, wordFinishJ, wordDrawJ,
wordStartE, wordFinishE, wordDrawE,
};
void fn_80036BC8(void)
{
if(!letterBufTbl[0]) {
letterBufTbl[0] = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s32)*strlen(seqFontAlphaTbl));
memset(letterBufTbl[0], 0, sizeof(s32)*strlen(seqFontAlphaTbl));
}
if(!letterBufTbl[1]) {
letterBufTbl[1] = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s32)*strlen(seqFontKanaTbl));
memset(letterBufTbl[1], 0, sizeof(s32)*strlen(seqFontKanaTbl));
}
if(!letterBufTbl[2]) {
letterBufTbl[2] = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s32)*strlen(seqFontKanaTbl));
memset(letterBufTbl[2], 0, sizeof(s32)*strlen(seqFontKanaTbl));
}
if(!letterBufTbl[3]) {
letterBufTbl[3] = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s32)*strlen(seqFontNumTbl));
memset(letterBufTbl[3], 0, sizeof(s32)*strlen(seqFontNumTbl));
}
if(!letterBufTbl[4]) {
letterBufTbl[4] = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s32)*strlen(seqPunctTbl));
memset(letterBufTbl[4], 0, sizeof(s32)*strlen(seqPunctTbl));
}
}
static AnimData *SeqLoadFontChar(char *str, s16 flags);
static s32 SeqMakeWord(SeqWork *work, char *str, s16 flags)
{
s16 *char_pos;
char *str_ptr;
s16 spr_grp;
s16 i;
s16 x;
s16 grp_idx;
s16 len;
AnimData **char_anim;
for(grp_idx=0; grp_idx<16; grp_idx++) {
if(work->spr_grp[grp_idx] == -1) {
break;
}
}
if(grp_idx == 16) {
return -1;
}
char_anim = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(AnimData *)*100);
char_pos = HuMemDirectMalloc(HEAP_SYSTEM, sizeof(s16)*100);
str_ptr = str;
x = 0;
len = 0;
while(*str_ptr != 0) {
char_anim[len] = SeqLoadFontChar(str_ptr, flags);
if(char_anim[len]) {
char_pos[len] = x;
x += 56;
len++;
}
str_ptr++;
}
work->spr_grp[grp_idx] = spr_grp = HuSprGrpCreate(len);
x = (x/2)-28;
for(i=0; i<len; i++) {
s16 sprite = HuSprCreate(char_anim[i], 5, 0);
HuSprGrpMemberSet(spr_grp, i, sprite);
HuSprPosSet(spr_grp, i, char_pos[i]-x, 0.0f);
}
work->work_s16[3] = len;
HuMemDirectFree(char_anim);
HuMemDirectFree(char_pos);
return grp_idx;
}
static s32 SeqCloneWord(SeqWork *work, s16 grp_idx)
{
s16 i;
return i;
}
static AnimData *SeqLoadFontChar(char *str, s16 flags)
{
s32 data_num;
s16 id;
char *list;
char c = *str;
if(c == 222 || c == 223) {
return NULL;
}
if(c == 32) {
return HuSprAnimRead(SeqReadFile(MAKE_DATA_NUM(DATADIR_GAMEMES, 10)));
}
for(id = 0, list=seqFontAlphaTbl; *list != 0; id++, list++) {
if(*list == c) {
data_num = MAKE_DATA_NUM(DATADIR_GAMEMES, id+21);
return HuSprAnimRead(SeqReadFile(data_num));
}
}
for(id = 0, list=seqFontNumTbl; *list != 0; id++, list++) {
if(*list == c) {
data_num = MAKE_DATA_NUM(DATADIR_GAMEMES, id+11);
return HuSprAnimRead(SeqReadFile(data_num));
}
}
for(id = 0, list=seqPunctTbl; *list != 0; id++, list++) {
if(*list == c) {
data_num = MAKE_DATA_NUM(DATADIR_GAMEMES, id+154);
return HuSprAnimRead(SeqReadFile(data_num));
}
}
if(str[1] == 222) {
list = seqFontKanaTbl;
list += 55;
id = 55;
} else if(str[1] == 223) {
list = seqFontKanaTbl;
list += 75;
id = 75;
} else {
list = seqFontKanaTbl;
id = 0;
}
while(*list != 0) {
if(*list == c) {
if(flags & 0x1) {
data_num = MAKE_DATA_NUM(DATADIR_GAMEMES, id+156);
} else {
data_num = MAKE_DATA_NUM(DATADIR_GAMEMES, id+73);
}
return HuSprAnimRead(SeqReadFile(data_num));
}
id++;
list++;
}
return NULL;
}
static float ForceDefine480()
{
return 480.0f;
}
static void SeqPlayStartFX(void);
static int SeqInitMGBasic(SeqWork *work, va_list params)
{
s16 i;
s16 word_grp;
work->work_s16[1] = va_arg(params, int);
if(work->work_s16[1] == 2) {
return SeqInitDraw(work, params);
}
work->type = 0;
work->work_float[0] = 0;
{
s32 word_katakana;
s32 word_flag;
s32 word_ofs;
word_katakana = 0;
if(work->work_s16[1] == 2 && seqLanguage == 0) {
word_katakana = 1;
}
if(word_katakana) {
word_flag = 1;
} else {
word_flag = 0;
}
if(seqLanguage == 0) {
word_ofs = 0;
} else {
word_ofs = 3;
}
word_grp = SeqMakeWord(work, wordMgTbl[work->work_s16[1]+word_ofs], word_flag);
}
HuSprGrpPosSet(work->spr_grp[word_grp], 0.0f, 0.0f);
for(i=0; i<work->work_s16[3]; i++) {
HuSprTPLvlSet(work->spr_grp[word_grp], i, 1.0f);
HuSprPosSet(work->spr_grp[word_grp], i, -100.0f, 240.0f);
}
if(seqPauseF) {
work->type = 2;
HuSprAttrSet(word_grp, 0, SPRITE_ATTR_HIDDEN);
} else {
work->param[0] = 3;
}
return 1;
}
static int SeqUpdateMGBasic(SeqWork *work)
{
s16 idx;
float scale;
if(work->param[0] != 0 && work->type != -1) {
switch(work->param[0]) {
case 2:
if(work->param[1] != -1) {
(void)work; //HACK: to introduce extra branch
} else {
work->type = -1;
work->work_float[0] = 0.0f;
}
work->param[0] = 0;
break;
case 1:
work->time_max = work->param[1];
work->param[0] = 0;
break;
case 3:
work->type = 1;
work->param[0] = 0;
break;
default:
work->param[0] = 0;
break;
}
}
if(work->type == 2) {
return 1;
}
work->time += seqSpeed;
if(work->time >= work->time_max && work->type != -1) {
work->type = -1;
work->work_float[0] = 0.0f;
}
if(work->type != 0) {
switch(work->type) {
case 1:
{
float pos_x;
float time;
s16 i;
if(work->work_s16[1] == 0) {
if(work->time <= 40) {
for(i=0; i<work->work_s16[3]; i++) {
time = work->time-((20/work->work_s16[3])*(work->work_s16[3]-i-1));
if(time < 0 || time > 20.0f) {
continue;
}
pos_x = (work->x-(0.5f*(work->work_s16[3]*56)))+28.0f+(i*56);
if(time == 20.0f) {
HuSprPosSet(work->spr_grp[0], i, pos_x, work->y);
HuSprZRotSet(work->spr_grp[0], i, 0.0f);
} else {
HuSprPosSet(work->spr_grp[0], i, pos_x-(((1.0-sin(((time*4.5f)*M_PI)/180.0))*(work->work_s16[3]*56*2))), work->y);
HuSprZRotSet(work->spr_grp[0], i, (time/20.0f)*390.0f);
}
}
} else {
time = work->time-40;
scale = work->scale_x+(0.5*sin(((time*9.0f)*M_PI)/180.0));
for(i=0; i<work->work_s16[3]; i++) {
pos_x = ((28.0f*scale)+(work->x-(0.5f*(scale*(work->work_s16[3]*56)))))+(scale*(i*56));
HuSprPosSet(work->spr_grp[0], i, pos_x, work->y);
HuSprScaleSet(work->spr_grp[0], i, scale, work->scale_y+sin(((time*9.0f)*M_PI)/180.0));
}
}
if(work->time == 40) {
idx = HuAudFXPlay(36);
work->stat |= 0x10;
}
if(work->time == 60) {
SeqPlayStartFX();
work->stat |= 0x4;
}
if(work->time >= 60) {
work->type = 0;
}
} else {
if(work->time == 1) {
if(work->work_s16[1] == 1) {
HuAudFXPlay(37);
} else {
HuAudFXPlay(40);
}
MGSeqPauseEnableCtrl(0);
work->stat |= 0x10;
}
if(work->time <= 20) {
time = work->time;
scale = work->scale_x+(0.5*sin(((time*9.0f)*M_PI)/180.0));
for(i=0; i<work->work_s16[3]; i++) {
HuSprAttrReset(work->spr_grp[0], i, SPRITE_ATTR_HIDDEN);
pos_x = ((28.0f*scale)+(work->x-(0.5f*(scale*(work->work_s16[3]*56)))))+(scale*(i*56));
HuSprPosSet(work->spr_grp[0], i, pos_x, work->y);
HuSprScaleSet(work->spr_grp[0], i, work->scale_x+sin(((time*9.0f)*M_PI)/180.0), work->scale_y+sin(((time*9.0f)*M_PI)/180.0));
}
if(time == 20.0f) {
for(i=0; i<work->work_s16[3]; i++) {
HuSprAttrReset(work->spr_grp[0], i, SPRITE_ATTR_HIDDEN);
}
}
} else {
if(work->time > 80) {
for(i=0; i<work->work_s16[3]; i++) {
time = (work->time-80)-((20/work->work_s16[3])*(work->work_s16[3]-i-1));
if(time < 0.0f || time > 20.0f) {
continue;
}
pos_x = (28.0f+(work->x-(0.5f*(work->work_s16[3]*56))))+(i*56);
if(time == 20.0f) {
HuSprAttrSet(work->spr_grp[0], i, SPRITE_ATTR_HIDDEN);
} else {
HuSprPosSet(work->spr_grp[0], i, pos_x+((1.0-cos(((time*4.5f)*M_PI)/180.0f))*(work->work_s16[3]*56*2)), work->y);
HuSprZRotSet(work->spr_grp[0], i, (time/20.0f)*390.0f);
}
}
}
}
if(work->time == 110) {
work->stat |= 0x4;
}
if(work->time >= 110) {
work->type = 0;
work->stat |= 8;
}
}
}
break;
case -1:
{
work->work_float[0] += seqSpeed*0.1f;
scale = 1.0f-work->work_float[0];
if(scale <= 0.0f) {
scale = 0.0f;
work->type = 0;
work->stat |= 0x8;
if(work->work_s16[1] == 0) {
MGSeqPauseEnableCtrl(1);
}
}
for(idx=0; idx<work->work_s16[3]; idx++) {
HuSprTPLvlSet(work->spr_grp[0], idx, scale);
}
}
break;
default:
break;
}
}
if(seqDoneF || (work->stat & 0x8)) {
MGSeqSprKill(work);
return 0;
}
return 1;
}
static int SeqInitMGCommon(SeqWork *work, va_list params)
{
s16 i;
float tp_lvl;
s16 j;
s16 word_grp;
work->work_s16[1] = va_arg(params, int);
if(work->work_s16[1] == 2) {
return SeqInitDraw(work, params);
}
work->type = 0;
work->work_float[0] = 0;
tp_lvl = 1.0f;
for(i=0; i<4; i++) {
if(i == 0)
{
s32 word_katakana;
s32 word_flag;
s32 word_ofs;
word_katakana = 0;
if(work->work_s16[1] == 2 && seqLanguage == 0) {
word_katakana = 1;
}
if(word_katakana) {
word_flag = 1;
} else {
word_flag = 0;
}
if(seqLanguage == 0) {
word_ofs = 0;
} else {
word_ofs = 3;
}
word_grp = SeqMakeWord(work, wordMgTbl[work->work_s16[1]+word_ofs], word_flag);
} else {
s16 grp_idx;
s32 new_grp;
for(grp_idx=0; grp_idx<16; grp_idx++) {
if(work->spr_grp[grp_idx] == -1) {
break;
}
}
if(grp_idx == 16) {
new_grp = -1;
} else {
work->spr_grp[grp_idx] = HuSprGrpCopy(work->spr_grp[word_grp]);
new_grp = grp_idx;
}
(void)new_grp;
word_grp = new_grp;
}
HuSprGrpPosSet(work->spr_grp[word_grp], 0.0f, 0.0f);
for(j=0; j<work->work_s16[3]; j++) {
HuSprTPLvlSet(work->spr_grp[word_grp], j, tp_lvl);
HuSprPosSet(work->spr_grp[word_grp], j, -100.0f, 240.0f);
HuSprPriSet(work->spr_grp[word_grp], j, i+5);
HuSprAttrSet(work->spr_grp[word_grp], i, SPRITE_ATTR_BILINEAR);
}
if(i == 0) {
tp_lvl -= 0.5;
} else {
tp_lvl -= 0.1f;
}
}
if(seqPauseF) {
work->type = 2;
HuSprAttrSet(word_grp, 0, SPRITE_ATTR_HIDDEN);
} else {
work->param[0] = 3;
}
return 1;
}
static int SeqInitDraw(SeqWork *work, va_list params)
{
}
static void SeqPlayStartFX(void)
{
}
void MGSeqPauseEnableCtrl(s32 flag)
{
}