1100 lines
No EOL
26 KiB
C
1100 lines
No EOL
26 KiB
C
#include "game/gamework_data.h"
|
|
#include "game/flag.h"
|
|
#include "game/board/main.h"
|
|
#include "game/board/player.h"
|
|
#include "game/board/space.h"
|
|
#include "game/hsfman.h"
|
|
#include "game/data.h"
|
|
#include "game/sprite.h"
|
|
|
|
#include "math.h"
|
|
#include "string.h"
|
|
|
|
extern void omVibrate(s16, s16, s16, s16);
|
|
|
|
|
|
extern s16 BoardStarHostMdlGet(void);
|
|
extern void BoardModelPosSetV(s16 model, Vec *pos);
|
|
extern s16 BoardModelCreate(s32 file, s32 *data, s32 arg3);
|
|
extern s16 BoardModelIDGet(s16 model);
|
|
|
|
static BoardSpace spaceData[2][256];
|
|
s16 boardSpaceStarTbl[8];
|
|
static GXTexObj spaceHiliteTex;
|
|
static GXTexObj spaceTex;
|
|
|
|
static s8 spaceImgIdx[12] = {
|
|
0, 1, 2, 7,
|
|
6, 5, 3, 4,
|
|
9, 10, 11, 0
|
|
};
|
|
|
|
static s8 spaceHiliteImgIdx[12] = {
|
|
-1, 0, 1, 1,
|
|
2, 2, 2, 2,
|
|
-1, 3, -1, -1
|
|
};
|
|
|
|
static s16 spaceCnt[2];
|
|
static u32 spaceAttr[2];
|
|
static void *spaceTexData;
|
|
static void *spaceHiliteTexData;
|
|
static GXTexFmt spaceTexFmt;
|
|
static GXTexFmt spaceHiliteTexFmt;
|
|
s16 lbl_801D3FC4[4];
|
|
static BoardSpaceEventFunc landEventFunc;
|
|
static BoardSpaceEventFunc walkMiniEventFunc;
|
|
static BoardSpaceEventFunc walkEventFunc;
|
|
static s32 spaceDrawCnt;
|
|
static s16 spaceDrawF;
|
|
|
|
static s16 spaceDrawMdl = -1;
|
|
static s16 starPlatMdl = -1;
|
|
|
|
static s32 ExecPipeSpace(s32 player, s32 space);
|
|
|
|
extern s8 boardTutorialBlockF;
|
|
extern s32 boardTutorialBlockPos;
|
|
|
|
|
|
void BoardSpaceWalkEventFuncSet(BoardSpaceEventFunc func)
|
|
{
|
|
walkEventFunc = func;
|
|
}
|
|
|
|
void BoardSpaceWalkMiniEventFuncSet(BoardSpaceEventFunc func)
|
|
{
|
|
walkMiniEventFunc = func;
|
|
}
|
|
|
|
void BoardSpaceLandEventFuncSet(BoardSpaceEventFunc func)
|
|
{
|
|
landEventFunc = func;
|
|
}
|
|
|
|
s32 BoardSpaceWalkEventExec(void)
|
|
{
|
|
s32 ret = -1;
|
|
if(walkEventFunc) {
|
|
ret = walkEventFunc();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
s32 BoardSpaceWalkMiniEventExec(void)
|
|
{
|
|
s32 ret = -1;
|
|
if(walkMiniEventFunc) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 8));
|
|
ret = walkMiniEventFunc();
|
|
_ClearFlag(FLAG_ID_MAKE(1, 8));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
s32 BoardSpaceCountGet(s32 layer)
|
|
{
|
|
return spaceCnt[layer];
|
|
}
|
|
|
|
BoardSpace *BoardSpaceGet(s32 layer, s32 index)
|
|
{
|
|
if(index <= 0 || index > spaceCnt[layer]) {
|
|
return NULL;
|
|
} else {
|
|
return &spaceData[layer][index-1];
|
|
}
|
|
}
|
|
|
|
void BoardSpaceAttrSet(s32 layer, u32 attr)
|
|
{
|
|
spaceAttr[layer] |= attr;
|
|
}
|
|
|
|
void BoardSpaceAttrReset(s32 layer, u32 attr)
|
|
{
|
|
spaceAttr[layer] &= ~attr;
|
|
}
|
|
|
|
u32 BoardSpaceFlagGet(s32 layer, s32 index)
|
|
{
|
|
if(index <= 0 || index > spaceCnt[layer]) {
|
|
return 0;
|
|
} else {
|
|
return spaceData[layer][index-1].flag;
|
|
}
|
|
}
|
|
|
|
s32 BoardSpaceTypeGet(s32 layer, s32 index)
|
|
{
|
|
if(index <= 0 || index > spaceCnt[layer]) {
|
|
return 0;
|
|
} else {
|
|
return spaceData[layer][index-1].type;
|
|
}
|
|
}
|
|
|
|
void BoardSpaceTypeSet(s32 layer, s32 index, s32 type)
|
|
{
|
|
if(index <= 0 || index > spaceCnt[layer]) {
|
|
return;
|
|
} else {
|
|
spaceData[layer][index-1].type = type;
|
|
}
|
|
}
|
|
|
|
s32 BoardSpacePosGet(s32 layer, s32 index, Vec *pos)
|
|
{
|
|
BoardSpace *space = BoardSpaceGet(layer, index);
|
|
if(!space) {
|
|
return -1;
|
|
} else {
|
|
*pos = space->pos;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void BoardSpaceCornerPosGet(s32 index, s32 corner, Vec *pos)
|
|
{
|
|
Vec corner_ofs;
|
|
Vec rot;
|
|
s8 corner_pos[4][2] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
|
|
BoardSpaceRotGet(0, index, &rot);
|
|
BoardSpacePosGet(0, index, pos);
|
|
corner_ofs.x = corner_pos[corner][0]*80.0f;
|
|
corner_ofs.y = 0;
|
|
corner_ofs.z = corner_pos[corner][1]*80.0f;
|
|
corner_ofs.x = (cos((M_PI*rot.z)/180)*corner_ofs.x)+(sin((M_PI*rot.z)/180)*corner_ofs.y);
|
|
corner_ofs.y = (cos((M_PI*rot.x)/180)*cos((M_PI*rot.z)/180)*corner_ofs.y)
|
|
+(sin((M_PI*rot.z)/180)*corner_ofs.x)
|
|
+(sin((M_PI*-rot.x)/180)*corner_ofs.z);
|
|
corner_ofs.z = (sin((M_PI*rot.x)/180)*corner_ofs.y)+(cos((M_PI*rot.x)/180)*corner_ofs.z);
|
|
pos->x += corner_ofs.x;
|
|
pos->y += corner_ofs.y;
|
|
pos->z += corner_ofs.z;
|
|
}
|
|
|
|
s32 BoardSpaceRotGet(s32 layer, s32 index, Vec *rot)
|
|
{
|
|
BoardSpace *space = BoardSpaceGet(layer, index);
|
|
if(!space) {
|
|
return -1;
|
|
} else {
|
|
*rot = space->rot;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
s32 BoardSpaceFlagSearch(s32 layer, u32 flag)
|
|
{
|
|
s32 i;
|
|
for(i=0; i<spaceCnt[layer]; i++) {
|
|
BoardSpace *space = &spaceData[layer][i];
|
|
if((space->flag & flag) == flag) {
|
|
return space-(&spaceData[layer][0])+1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
s32 BoardSpaceFlagPosGet(s32 layer, u32 flag, Vec *pos)
|
|
{
|
|
s32 space = BoardSpaceFlagSearch(layer, flag);
|
|
if(space == -1) {
|
|
return -1;
|
|
}
|
|
if(pos) {
|
|
BoardSpacePosGet(layer, space, pos);
|
|
}
|
|
return space;
|
|
}
|
|
|
|
s32 BoardSpaceLinkFlagSearch(s32 layer, s32 index, u32 flag)
|
|
{
|
|
BoardSpace *link_space;
|
|
BoardSpace *space = BoardSpaceGet(layer, index);
|
|
s32 i;
|
|
if(!space) {
|
|
return -1;
|
|
}
|
|
for(i=0; i<space->link_cnt; i++) {
|
|
link_space = BoardSpaceGet(layer, space->link[i]);
|
|
if(link_space->flag & flag) {
|
|
return link_space-&spaceData[layer][0]+1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
s32 BoardSpaceLinkTypeListGet(s32 layer, s32 index, s32 type, s16 *list)
|
|
{
|
|
s32 count;
|
|
BoardSpace *space = BoardSpaceGet(layer, index);
|
|
s32 i;
|
|
if(!space) {
|
|
return -1;
|
|
}
|
|
for(count=i=0; i<space->link_cnt; i++) {
|
|
BoardSpace *link_space = BoardSpaceGet(layer, space->link[i]);
|
|
if(link_space->type == type && count < BOARD_SPACE_LINKMAX) {
|
|
list[count] = link_space-&spaceData[layer][0]+1;
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
s32 BoardSpaceLinkTargetListGet(s32 layer, s32 target, s16 *list)
|
|
{
|
|
s32 i, j;
|
|
s32 count;
|
|
BoardSpace *space;
|
|
memset(list, 0, BOARD_SPACE_LINKMAX*sizeof(s16));
|
|
space = &spaceData[layer][0];
|
|
for(count=i=0; i<spaceCnt[layer]; i++, space++) {
|
|
for(j=0; j<space->link_cnt; j++) {
|
|
if(space->link[j] == target && count < BOARD_SPACE_LINKMAX) {
|
|
list[count++] = space-&spaceData[layer][0]+1;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
s32 BoardSpaceLinkTypeSearch(s32 layer, s32 target, u16 type)
|
|
{
|
|
s32 i;
|
|
BoardSpace *space = BoardSpaceGet(layer, target);
|
|
if(!space) {
|
|
return -1;
|
|
}
|
|
for(i=0; i<space->link_cnt; i++) {
|
|
BoardSpace *link_space = BoardSpaceGet(layer, space->link[i]);
|
|
if(link_space->type == type) {
|
|
return space->link[i];
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
s32 BoardSpaceLinkTransformGet(s32 flag, Vec *pos, Vec *rot, Vec *scale)
|
|
{
|
|
s32 i;
|
|
s32 space_flag = BoardSpaceFlagSearch(0, flag);
|
|
BoardSpace *space = BoardSpaceGet(0, space_flag);
|
|
|
|
for(i=0; i<space->link_cnt; i++) {
|
|
BoardSpace *link_space = BoardSpaceGet(0, space->link[i]);
|
|
BoardSpace *src_space;
|
|
if(!(link_space->flag & 0x2000000)) {
|
|
continue;
|
|
}
|
|
src_space = BoardSpaceGet(0, link_space->link[0]);
|
|
if(pos) {
|
|
*pos = src_space->pos;
|
|
}
|
|
if(rot) {
|
|
*rot = src_space->rot;
|
|
}
|
|
if(scale) {
|
|
*scale = src_space->scale;
|
|
}
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void BoardSpaceHostSet(s32 space)
|
|
{
|
|
s16 host_space;
|
|
Vec pos;
|
|
BoardSpace *space_plat;
|
|
BoardSpaceTypeSet(0, space, 8);
|
|
host_space = BoardSpaceLinkFlagSearch(0, space, 0x04000000);
|
|
BoardSpacePosGet(0, host_space, &pos);
|
|
BoardModelPosSetV(BoardStarHostMdlGet(), &pos);
|
|
}
|
|
|
|
static inline s16 StarPlatGetMdl(void)
|
|
{
|
|
return starPlatMdl;
|
|
}
|
|
|
|
static inline s32 BoardStarSpaceTypeGet(s16 index)
|
|
{
|
|
return BoardSpaceTypeGet(0, BoardSpaceStarGet(index));
|
|
}
|
|
|
|
void BoardSpaceStarSetIndex(s32 index)
|
|
{
|
|
Vec pos;
|
|
Vec rot;
|
|
s16 space;
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 1))) {
|
|
BoardSpaceTypeSet(0, boardSpaceStarTbl[GWSystem.star_pos], 1);
|
|
}
|
|
GWSystem.star_pos = index & 0x7;
|
|
BoardSpaceHostSet(BoardSpaceStarGetCurr());
|
|
space = BoardSpaceLinkFlagSearch(0, BoardSpaceStarGetCurr(), 0x04000000);
|
|
BoardSpacePosGet(0, space, &pos);
|
|
BoardModelPosSetV(StarPlatGetMdl(), &pos);
|
|
BoardSpaceRotGet(0, space, &rot);
|
|
BoardModelRotYSet(StarPlatGetMdl(), rot.y);
|
|
BoardModelVisibilitySet(StarPlatGetMdl(), 1);
|
|
}
|
|
|
|
s32 BoardSpaceStarGetNext(void)
|
|
{
|
|
s16 random_pos;
|
|
s16 star_total;
|
|
s16 star_pos;
|
|
star_total = GWSystem.star_total;
|
|
star_pos = GWSystem.star_pos;
|
|
if(BoardCurrGet() == 5) {
|
|
s16 i;
|
|
s32 count;
|
|
s32 last_free;
|
|
last_free = -1;
|
|
for(count=i=0; i<8; i++) {
|
|
if((1 << i) & GWSystem.star_flag) {
|
|
count++;
|
|
} else {
|
|
last_free = i;
|
|
}
|
|
}
|
|
if(count == 7) {
|
|
if(BoardSpaceTypeGet(0, BoardSpaceStarGet(last_free)) == 10) {
|
|
GWSystem.star_flag = 0;
|
|
}
|
|
}
|
|
}
|
|
begin:
|
|
random_pos = BoardRandMod(8);
|
|
if(star_pos == random_pos || BoardStarSpaceTypeGet(random_pos) == 10) {
|
|
goto begin;
|
|
}
|
|
switch(GWSystem.board) {
|
|
case 0:
|
|
if(star_total >= 2) {
|
|
break;
|
|
}
|
|
if(random_pos != 6 && random_pos != 7) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
|
|
case 1:
|
|
if(star_total >= 2) {
|
|
break;
|
|
}
|
|
if(random_pos != 6 && random_pos != 7) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
|
|
case 2:
|
|
if(star_total == 1) {
|
|
if(random_pos < 3 || random_pos > 5) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
} else {
|
|
if(star_total != 2) {
|
|
break;
|
|
}
|
|
if(random_pos != 3 && random_pos != 4) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
}
|
|
|
|
case 3:
|
|
if(star_total == 1) {
|
|
if(random_pos < 5 || random_pos > 7) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
} else {
|
|
if(star_total != 2) {
|
|
break;
|
|
}
|
|
if(random_pos == 5) {
|
|
goto begin;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 4:
|
|
if(star_total == 1) {
|
|
if(random_pos <= 1 || random_pos >= 4) {
|
|
goto begin;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
if(star_total == 1) {
|
|
if(random_pos == 1 || random_pos == 4 || random_pos == 5) {
|
|
goto begin;
|
|
}
|
|
}
|
|
if(star_total != 2) {
|
|
break;
|
|
}
|
|
if(random_pos == 5) {
|
|
goto begin;
|
|
}
|
|
}
|
|
if((1 << random_pos) & GWSystem.star_flag) {
|
|
goto begin;
|
|
}
|
|
return random_pos;
|
|
}
|
|
|
|
s32 BoardSpaceStarGetRandom(s32 excl_pos)
|
|
{
|
|
s8 new_pos;
|
|
int i;
|
|
for(i=0; i<1024; i++) {
|
|
new_pos = BoardRandMod(8);
|
|
if(new_pos == GWSystem.star_pos) {
|
|
continue;
|
|
}
|
|
if(GWSystem.turn == 1 && new_pos <= 2) {
|
|
continue;
|
|
}
|
|
if(new_pos != excl_pos) {
|
|
break;
|
|
}
|
|
}
|
|
return new_pos;
|
|
}
|
|
|
|
void BoardSpaceStarMove(void)
|
|
{
|
|
u8 star_total;
|
|
s16 star_pos;
|
|
s16 star_next;
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 1))) {
|
|
star_pos = GWSystem.star_pos;
|
|
GWSystem.star_flag |= (u8)(1 << star_pos);
|
|
if(GWSystem.star_flag == 0xFF) {
|
|
GWSystem.star_flag = 0;
|
|
}
|
|
if(GWSystem.star_total >= 99) {
|
|
star_total = 99;
|
|
GWSystem.star_total = star_total;
|
|
} else {
|
|
star_total = GWSystem.star_total++;
|
|
}
|
|
}
|
|
star_next = BoardSpaceStarGetNext();
|
|
BoardSpaceStarSetIndex(star_next);
|
|
}
|
|
|
|
s32 BoardSpaceStarGet(s32 index)
|
|
{
|
|
return boardSpaceStarTbl[index & 0x7];
|
|
}
|
|
|
|
s32 BoardSpaceStarGetCurr(void)
|
|
{
|
|
return BoardSpaceStarGet(GWSystem.star_pos);
|
|
}
|
|
|
|
s32 BoardSpaceStarCheck(s32 index)
|
|
{
|
|
s32 ret;
|
|
BoardSpace *space = BoardSpaceGet(0, index);
|
|
BoardSpace *star_space;
|
|
if(BoardCurrGet() == 7 || BoardCurrGet() == 8) {
|
|
ret = 0;
|
|
goto end;
|
|
}
|
|
star_space = BoardSpaceGet(0, boardSpaceStarTbl[GWSystem.star_pos]);
|
|
if(space == star_space) {
|
|
ret = 1;
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
end:
|
|
return ret;
|
|
}
|
|
|
|
void BoardSpaceLandExec(s32 player, s32 space)
|
|
{
|
|
BoardSpace *space_ptr = BoardSpaceGet(0, space);
|
|
switch(space_ptr->type) {
|
|
case 1:
|
|
GWPlayer[player].blue_count++;
|
|
if(GWPlayer[player].blue_count > 99) {
|
|
GWPlayer[player].blue_count = 99;
|
|
}
|
|
BoardLandBlueExec(player, space);
|
|
break;
|
|
|
|
case 2:
|
|
GWPlayer[player].red_count++;
|
|
if(GWPlayer[player].red_count > 99) {
|
|
GWPlayer[player].red_count = 99;
|
|
}
|
|
BoardLandRedExec(player, space);
|
|
break;
|
|
|
|
case 3:
|
|
GWPlayer[player].bowser_count++;
|
|
if(GWPlayer[player].bowser_count > 99) {
|
|
GWPlayer[player].bowser_count = 99;
|
|
}
|
|
BoardBowserExec(player, space);
|
|
break;
|
|
|
|
case 4:
|
|
GWPlayer[player].mushroom_count++;
|
|
if(GWPlayer[player].mushroom_count > 99) {
|
|
GWPlayer[player].mushroom_count = 99;
|
|
}
|
|
BoardMushroomExec(player, space);
|
|
break;
|
|
|
|
case 5:
|
|
GWPlayer[player].battle_count++;
|
|
if(GWPlayer[player].battle_count > 99) {
|
|
GWPlayer[player].battle_count = 99;
|
|
}
|
|
BoardBattleExec(player, space);
|
|
break;
|
|
|
|
case 6:
|
|
GWPlayer[player].question_count++;
|
|
if(GWPlayer[player].question_count > 99) {
|
|
GWPlayer[player].question_count = 99;
|
|
}
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
HuAudFXPlay(842);
|
|
BoardCameraViewSet(2);
|
|
BoardPlayerMotBlendSet(player, 0, 15);
|
|
while(!BoardPlayerMotBlendCheck(player)) {
|
|
HuPrcVSleep();
|
|
}
|
|
BoardCameraMotionWait();
|
|
BoardTutorialHookExec(16, 0);
|
|
} else {
|
|
if(landEventFunc) {
|
|
HuAudFXPlay(842);
|
|
omVibrate(player, 12, 4, 2);
|
|
landEventFunc();
|
|
}
|
|
}
|
|
GWPlayer[player].color = 3;
|
|
break;
|
|
|
|
case 7:
|
|
GWPlayer[player].fortune_count++;
|
|
if(GWPlayer[player].fortune_count > 99) {
|
|
GWPlayer[player].fortune_count = 99;
|
|
}
|
|
BoardFortuneExec(player, space);
|
|
break;
|
|
|
|
case 9:
|
|
GWPlayer[player].warp_count++;
|
|
if(GWPlayer[player].warp_count > 99) {
|
|
GWPlayer[player].warp_count = 99;
|
|
}
|
|
BoardWarpExec(player, space);
|
|
break;
|
|
|
|
case 8:
|
|
BoardStarExec(player, space);
|
|
break;
|
|
}
|
|
}
|
|
|
|
s32 BoardSpaceWalkExec(s32 player, s32 space)
|
|
{
|
|
s32 is_star;
|
|
BoardSpace *space_ptr;
|
|
BoardSpace *star_space;
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
space_ptr = BoardSpaceGet(0, space);
|
|
if(space_ptr->flag & 0x180000) {
|
|
BoardTutorialHookExec(25, 0);
|
|
}
|
|
}
|
|
if(BoardPlayerSizeGet(player) == 2 || GWPlayer[player].bowser_suit) {
|
|
return 0;
|
|
}
|
|
space_ptr = BoardSpaceGet(0, space);
|
|
if(BoardCurrGet() == 7 || BoardCurrGet() == 8) {
|
|
is_star = 0;
|
|
} else {
|
|
star_space = BoardSpaceGet(0, boardSpaceStarTbl[GWSystem.star_pos]);
|
|
if(space_ptr == star_space) {
|
|
is_star = 1;
|
|
} else {
|
|
is_star = 0;
|
|
}
|
|
}
|
|
if(is_star) {
|
|
BoardStarExec(player, space);
|
|
return 1;
|
|
}
|
|
if(space_ptr->flag & 0x600000) {
|
|
u16 mg_param = GWSystem.unk_38;
|
|
if(BoardPlayerSizeGet(player) == 1) {
|
|
BoardRotateDiceNumbers(player);
|
|
BoardMGCreate(mg_param);
|
|
}
|
|
return 1;
|
|
}
|
|
if(space_ptr->flag & 0x180000) {
|
|
BoardShopExec(player, space);
|
|
return 1;
|
|
}
|
|
if(space_ptr->flag & 0x08000000) {
|
|
BoardBooHouseExec(player, space);
|
|
return 1;
|
|
}
|
|
if(space_ptr->flag & 0x10000000) {
|
|
BoardLotteryExec();
|
|
return 1;
|
|
}
|
|
if(space_ptr->flag & 0x20000000) {
|
|
ExecPipeSpace(player, space);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 BoardSpaceBlockExec(s32 player, s32 space)
|
|
{
|
|
s32 event_exec;
|
|
BoardSpace *space_ptr;
|
|
event_exec = 0;
|
|
if(BoardPlayerSizeGet(player) == 2 || GWPlayer[player].bowser_suit) {
|
|
return 0;
|
|
}
|
|
space_ptr = BoardSpaceGet(0, space);
|
|
event_exec = 0;
|
|
if(space == GWSystem.block_pos) {
|
|
event_exec = 1;
|
|
}
|
|
if((int)GWSystem.bonus_star == 0 && BoardPartyFlagGet() == 1 && !_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
event_exec = 0;
|
|
}
|
|
if(BoardCurrGet() == 7 || BoardCurrGet() == 8) {
|
|
event_exec = 0;
|
|
}
|
|
if(event_exec) {
|
|
BoardBlockExec(player, space);
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
BoardBlockExec(player, space);
|
|
}
|
|
BoardSpaceBlockPosSet();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static s32 ExecPipeSpace(s32 player, s32 space)
|
|
{
|
|
Vec pos_link;
|
|
Vec pos;
|
|
Vec dir;
|
|
float radius, y_vel;
|
|
s32 mot_disable;
|
|
BoardSpace *space_ptr;
|
|
mot_disable = 0;
|
|
if(BoardPlayerSizeGet(player) != 1) {
|
|
return 0;
|
|
}
|
|
BoardPlayerPosGet(player, &pos);
|
|
pos.y += 200.0f;
|
|
space_ptr = BoardSpaceGet(0, space);
|
|
BoardSpacePosGet(0, space_ptr->link[0], &pos_link);
|
|
VECSubtract(&pos_link, &pos, &dir);
|
|
VECNormalize(&dir, &dir);
|
|
BoardPlayerRotYSet(player, 90-((atan2(dir.z, dir.x)/M_PI)*180));
|
|
radius = 0.75f*BoardVecDistXZCalc(&pos_link, &pos);
|
|
BoardPlayerMotionStart(player, 4, 0);
|
|
y_vel = 0;
|
|
while(1) {
|
|
if(BoardVecDistXZCalc(&pos_link, &pos) < 2) {
|
|
break;
|
|
}
|
|
pos.x += (dir.x*radius)/60.0f;
|
|
pos.z += (dir.z*radius)/60.0f;
|
|
if(pos.y <= pos_link.y) {
|
|
pos.y = pos_link.y;
|
|
if(!mot_disable) {
|
|
BoardPlayerMotionShiftSet(player, 3, 0, 4, 0x40000001);
|
|
break;
|
|
}
|
|
} else {
|
|
pos.y += 10.0f+(-((1/2399.99f)+(1/50.0f))*y_vel*y_vel);
|
|
y_vel += 1.0f;
|
|
}
|
|
BoardPlayerPosSetV(player, &pos);
|
|
HuPrcVSleep();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void BoardSpaceTypeForce(u16 from, u16 to)
|
|
{
|
|
s32 i;
|
|
for(i=0; i<spaceCnt[0]; i++) {
|
|
BoardSpace *space = &spaceData[0][i];
|
|
if(space->type == from) {
|
|
space->type = to;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BoardSpaceHide(s32 value)
|
|
{
|
|
if(value) {
|
|
Hu3DModelAttrSet(spaceDrawMdl, 1);
|
|
} else {
|
|
Hu3DModelAttrReset(spaceDrawMdl, 1);
|
|
}
|
|
}
|
|
|
|
//Some stack allocation issues. code around BoardPlayerGetCurr is incorrect too
|
|
static void DrawSpaces(ModelData *model, Mtx matrix)
|
|
{
|
|
s32 i;
|
|
|
|
Vec player_pos;
|
|
Vec target;
|
|
Vec pos;
|
|
|
|
Mtx lookat, final, rot_x, rot_y, rot_z, scale;
|
|
Mtx44 proj;
|
|
BoardCameraData *camera;
|
|
if(!spaceDrawF) {
|
|
return;
|
|
}
|
|
spaceDrawCnt = 0;
|
|
camera = &boardCamera;
|
|
BoardCameraPosGet(&pos);
|
|
BoardCameraTargetGet(&target);
|
|
MTXPerspective(proj, camera->fov, camera->aspect, camera->near, camera->far);
|
|
GXSetProjection(proj, GX_PERSPECTIVE);
|
|
MTXLookAt(lookat, &pos, &camera->up, &target);
|
|
GXSetViewport(camera->viewport_x, camera->viewport_y, camera->viewport_w, camera->viewport_h, camera->viewport_near, camera->viewport_far);
|
|
GXSetScissor(camera->viewport_x, camera->viewport_y, camera->viewport_w, camera->viewport_h);
|
|
{
|
|
GXColor color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
BoardSpace *space_curr;
|
|
BoardSpace *space_hilite;
|
|
PlayerState *player;
|
|
PlayerState *player_temp;
|
|
s16 player_mdl;
|
|
float y_dist;
|
|
s32 space_img;
|
|
u16 space_type;
|
|
float uv_x, uv_y, uv_size;
|
|
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
|
GXInvalidateTexAll();
|
|
GXLoadTexObj(&spaceTex, GX_TEXMAP0);
|
|
GXSetNumTexGens(1);
|
|
GXSetNumTevStages(1);
|
|
GXSetTevColor(GX_TEVREG0, color);
|
|
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
|
|
GXSetNumChans(1);
|
|
GXSetChanAmbColor(GX_COLOR0A0, color);
|
|
GXSetChanMatColor(GX_COLOR0A0, color);
|
|
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 1, GX_DF_CLAMP, GX_AF_SPOT);
|
|
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
|
GXSetAlphaCompare(GX_GEQUAL, 1, GX_AOP_AND, GX_GEQUAL, 1);
|
|
GXSetCullMode(GX_CULL_BACK);
|
|
player = player_temp = BoardPlayerGetCurr();
|
|
BoardPlayerPosGet(GWSystem.player_curr, &player_pos);
|
|
player_mdl = BoardModelIDGet(BoardPlayerModelGetCurr());
|
|
space_curr = &spaceData[0][0];
|
|
space_hilite = NULL;
|
|
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
for(i=0; i<spaceCnt[0]; i++, space_curr++) {
|
|
if(space_curr->type == 0) {
|
|
continue;
|
|
}
|
|
if(!BoardCameraCullCheck(&space_curr->pos, 200.0f) || (space_curr->flag & spaceAttr[0])) {
|
|
continue;
|
|
}
|
|
if(!space_hilite) {
|
|
if(player_pos.x > space_curr->pos.x-100.0f
|
|
&& player_pos.z > space_curr->pos.z-100.0f
|
|
&& player_pos.x < space_curr->pos.x+100.0f
|
|
&& player_pos.z < space_curr->pos.z+100.0f) {
|
|
if(player_pos.y-space_curr->pos.y < 0.0f) {
|
|
y_dist = -(player_pos.y-space_curr->pos.y);
|
|
} else {
|
|
y_dist = player_pos.y-space_curr->pos.y;
|
|
}
|
|
if(y_dist < 10.0f) {
|
|
space_hilite = space_curr;
|
|
}
|
|
}
|
|
}
|
|
space_type = space_curr->type;
|
|
space_img = spaceImgIdx[space_type]-1;
|
|
uv_x = (float)(space_img%4)/4.0f;
|
|
uv_y = (float)(space_img/4)/4.0f;
|
|
uv_size = 63.0f/256.0f;
|
|
MTXRotRad(rot_z, 'z', MTXDegToRad(space_curr->rot.y));
|
|
MTXRotRad(rot_y, 'y', MTXDegToRad(space_curr->rot.z));
|
|
MTXRotRad(rot_x, 'x', MTXDegToRad(space_curr->rot.x+90.0f));
|
|
MTXTrans(final, space_curr->pos.x, 3.0f+space_curr->pos.y, space_curr->pos.z);
|
|
MTXConcat(rot_x, rot_y, rot_y);
|
|
MTXConcat(rot_y, rot_z, rot_z);
|
|
MTXConcat(final, rot_z, final);
|
|
MTXConcat(lookat, final, final);
|
|
GXLoadPosMtxImm(final, GX_PNMTX0);
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GXPosition3f32(-100, -100, 0);
|
|
GXTexCoord2f32(uv_x, uv_y);
|
|
GXPosition3f32(100, -100, 0);
|
|
GXTexCoord2f32(uv_x+uv_size, uv_y);
|
|
GXPosition3f32(100, 100, 0);
|
|
GXTexCoord2f32(uv_x+uv_size, uv_y+uv_size+(1.5f/256.0f));
|
|
GXPosition3f32(-100, 100, 0);
|
|
GXTexCoord2f32(uv_x, uv_y+uv_size+(1.5f/256.0f));
|
|
GXEnd();
|
|
spaceDrawCnt++;
|
|
}
|
|
if(space_hilite) {
|
|
space_curr = space_hilite;
|
|
space_type = space_curr->type;
|
|
if(player->show_next && space_type != 0 && (space_img = spaceHiliteImgIdx[space_type]) >= 0) {
|
|
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_FALSE);
|
|
GXLoadTexObj(&spaceHiliteTex, GX_TEXMAP0);
|
|
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_NOOP);
|
|
uv_x = (float)(space_img%4)/4.0f;
|
|
uv_y = (float)(space_img/4)/4.0f;
|
|
uv_size = 63.0f/256.0f;
|
|
MTXScale(scale, 1.5f, 1.5f, 1.5f);
|
|
MTXRotRad(rot_z, 'z', MTXDegToRad(space_curr->rot.y));
|
|
MTXRotRad(rot_y, 'y', MTXDegToRad(space_curr->rot.z));
|
|
MTXRotRad(rot_x, 'x', MTXDegToRad(space_curr->rot.x+90.0f));
|
|
MTXTrans(final, space_curr->pos.x, 3.5f+space_curr->pos.y, space_curr->pos.z);
|
|
MTXConcat(scale, rot_x, rot_x);
|
|
MTXConcat(rot_x, rot_y, rot_y);
|
|
MTXConcat(rot_y, rot_z, rot_z);
|
|
MTXConcat(final, rot_z, final);
|
|
MTXConcat(lookat, final, final);
|
|
GXLoadPosMtxImm(final, GX_PNMTX0);
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GXPosition3f32(-100, -100, 0);
|
|
GXTexCoord2f32(uv_x, uv_y);
|
|
GXPosition3f32(100, -100, 0);
|
|
GXTexCoord2f32(uv_x+uv_size, uv_y);
|
|
GXPosition3f32(100, 100, 0);
|
|
GXTexCoord2f32(uv_x+uv_size, uv_y+uv_size);
|
|
GXPosition3f32(-100, 100, 0);
|
|
GXTexCoord2f32(uv_x, uv_y+uv_size);
|
|
GXEnd();
|
|
spaceDrawCnt++;
|
|
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
|
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
return;
|
|
}
|
|
}
|
|
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
}
|
|
|
|
}
|
|
|
|
s32 BoardSpaceRead(s32 layer, s32 data_num)
|
|
{
|
|
int j;
|
|
int i;
|
|
BoardSpace *space;
|
|
u8 *data;
|
|
s32 star_idx;
|
|
u8 *data_base;
|
|
data_base = data = HuDataSelHeapReadNum(data_num, MEMORY_DEFAULT_NUM, HEAP_DATA);
|
|
spaceCnt[layer] = *(u32 *)data;
|
|
data += sizeof(u32);
|
|
space = &spaceData[layer][0];
|
|
for(i=0; i<spaceCnt[layer]; i++, space++) {
|
|
memcpy(&space->pos, data, sizeof(Vec));
|
|
data += sizeof(Vec);
|
|
memcpy(&space->rot, data, sizeof(Vec));
|
|
data += sizeof(Vec);
|
|
memcpy(&space->scale, data, sizeof(Vec));
|
|
data += sizeof(Vec);
|
|
space->flag = *(u32 *)data;
|
|
data += sizeof(u32);
|
|
space->type = *(u16 *)data;
|
|
data += sizeof(u16);
|
|
space->link_cnt = *(u16 *)data;
|
|
data += sizeof(u16);
|
|
for(j=0; j<space->link_cnt; j++) {
|
|
space->link[j] = (*(u16 *)data)+1;
|
|
data += sizeof(u16);
|
|
}
|
|
if(space->type == 8) {
|
|
|
|
space->type = 1;
|
|
star_idx = (space->flag & 0x70000) >> 16;
|
|
boardSpaceStarTbl[star_idx] = i+1;
|
|
}
|
|
}
|
|
HuDataClose(data_base);
|
|
return 0;
|
|
}
|
|
|
|
void BoardSpaceCameraSet(u16 mask)
|
|
{
|
|
Hu3DModelCameraSet(spaceDrawMdl, mask);
|
|
}
|
|
|
|
void BoardSpaceBlockPosSet(void)
|
|
{
|
|
BoardSpace *space;
|
|
s32 block_pos;
|
|
begin:
|
|
if(boardTutorialBlockF) {
|
|
GWSystem.block_pos = boardTutorialBlockPos;
|
|
return;
|
|
}
|
|
block_pos = BoardRandMod(spaceCnt[0])+1;
|
|
if(block_pos == GWSystem.block_pos) {
|
|
goto begin;
|
|
}
|
|
space = BoardSpaceGet(0, block_pos);
|
|
if(space->type != 1) {
|
|
goto begin;
|
|
}
|
|
GWSystem.block_pos = block_pos;
|
|
}
|
|
|
|
void BoardSpaceInit(s32 data_num)
|
|
{
|
|
s32 board;
|
|
BoardJunctionMaskZero();
|
|
memset(spaceData, 0, sizeof(spaceData));
|
|
memset(spaceAttr, 0, sizeof(spaceAttr));
|
|
lbl_801D3FC4[0] = lbl_801D3FC4[1] = lbl_801D3FC4[2] = lbl_801D3FC4[3] = -1;
|
|
spaceDrawF = 0;
|
|
board = BoardCurrGet();
|
|
{
|
|
AnimBmpData *bmp;
|
|
AnimData *data;
|
|
void *data_base;
|
|
s32 size;
|
|
data = data_base = HuDataSelHeapReadNum(MAKE_DATA_NUM(DATADIR_BOARD, 29), MEMORY_DEFAULT_NUM, HEAP_DATA);
|
|
data->bmp = (void *)((u32)data_base+(u32)data->bmp);
|
|
data->pat = (void *)((u32)data_base+(u32)data->pat);
|
|
data->bank = (void *)((u32)data_base+(u32)data->bank);
|
|
bmp = data->bmp;
|
|
size = bmp->sizeX;
|
|
spaceHiliteTexFmt = -1;
|
|
switch(bmp->dataFmt) {
|
|
case SPRITE_BMP_RGBA8:
|
|
spaceHiliteTexFmt = GX_TF_RGBA8;
|
|
break;
|
|
|
|
case SPRITE_BMP_RGB5A3_DUPE:
|
|
spaceHiliteTexFmt = GX_TF_RGB5A3;
|
|
break;
|
|
|
|
case SPRITE_BMP_CMPR:
|
|
spaceHiliteTexFmt = GX_TF_CMPR;
|
|
break;
|
|
}
|
|
spaceHiliteTexData = HuMemDirectMallocNum(HEAP_SYSTEM, bmp->dataSize, MEMORY_DEFAULT_NUM);
|
|
bmp->data = (void *)((u32)bmp->data+(u32)data_base);
|
|
memcpy(spaceHiliteTexData, bmp->data, bmp->dataSize);
|
|
HuDataClose(data_base);
|
|
GXInitTexObj(&spaceHiliteTex, spaceHiliteTexData, size, size, spaceHiliteTexFmt, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
GXInitTexObjLOD(&spaceHiliteTex, GX_LINEAR, GX_LINEAR, 0, 0, 0, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
|
}
|
|
{
|
|
AnimBmpData *bmp;
|
|
AnimData *data;
|
|
void *data_base;
|
|
s32 size;
|
|
data = data_base = HuDataSelHeapReadNum(MAKE_DATA_NUM(DATADIR_BOARD, 28), MEMORY_DEFAULT_NUM, HEAP_DATA);
|
|
data->bmp = (void *)((u32)data_base+(u32)data->bmp);
|
|
data->pat = (void *)((u32)data_base+(u32)data->pat);
|
|
data->bank = (void *)((u32)data_base+(u32)data->bank);
|
|
bmp = data->bmp;
|
|
size = bmp->sizeX;
|
|
spaceTexFmt = -1;
|
|
switch(bmp->dataFmt) {
|
|
case SPRITE_BMP_RGBA8:
|
|
spaceTexFmt = GX_TF_RGBA8;
|
|
break;
|
|
|
|
case SPRITE_BMP_RGB5A3_DUPE:
|
|
spaceTexFmt = GX_TF_RGB5A3;
|
|
break;
|
|
|
|
case SPRITE_BMP_CMPR:
|
|
spaceTexFmt = GX_TF_CMPR;
|
|
break;
|
|
}
|
|
spaceTexData = HuMemDirectMallocNum(HEAP_SYSTEM, bmp->dataSize, MEMORY_DEFAULT_NUM);
|
|
bmp->data = (void *)((u32)bmp->data+(u32)data_base);
|
|
memcpy(spaceTexData, bmp->data, bmp->dataSize);
|
|
HuDataClose(data_base);
|
|
GXInitTexObj(&spaceTex, spaceTexData, size, size, spaceTexFmt, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
GXInitTexObjLOD(&spaceTex, GX_LINEAR, GX_LINEAR, 0, 0, 0, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
|
}
|
|
BoardSpaceRead(0, data_num);
|
|
spaceDrawMdl = Hu3DHookFuncCreate(DrawSpaces);
|
|
if(!BoardStartCheck() && !_CheckFlag(FLAG_ID_MAKE(1, 1))) {
|
|
BoardSpaceBlockPosSet();
|
|
GWSystem.star_total = 0;
|
|
GWSystem.star_flag = 0;
|
|
}
|
|
if(BoardCurrGet() != 7 && BoardCurrGet() != 8) {
|
|
starPlatMdl = BoardModelCreate(MAKE_DATA_NUM(DATADIR_BOARD, 6), NULL, 0);
|
|
BoardModelMotionStart(starPlatMdl, 0, 0x40000001);
|
|
BoardModelVisibilitySet(starPlatMdl, 0);
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 1))) {
|
|
Vec pos;
|
|
Vec rot;
|
|
s16 space;
|
|
BoardModelVisibilitySet(starPlatMdl, 1);
|
|
GWSystem.star_flag |= (u8)(1 << GWSystem.star_pos);
|
|
BoardSpaceTypeSet(0, boardSpaceStarTbl[GWSystem.star_pos], 8);
|
|
{
|
|
int space;
|
|
BoardSpace *space_plat;
|
|
space = BoardSpaceLinkFlagSearch(0, BoardSpaceStarGetCurr(), 0x04000000);
|
|
BoardSpacePosGet(0, space, &pos);
|
|
BoardModelPosSetV(StarPlatGetMdl(), &pos);
|
|
BoardSpaceRotGet(0, space, &rot);
|
|
BoardModelRotYSet(StarPlatGetMdl(), rot.y);
|
|
}
|
|
}
|
|
}
|
|
spaceDrawF = 1;
|
|
}
|
|
|
|
void BoardSpaceDestroy(void)
|
|
{
|
|
if(spaceDrawMdl >= 0) {
|
|
Hu3DModelKill(spaceDrawMdl);
|
|
spaceDrawMdl = -1;
|
|
}
|
|
if(spaceHiliteTexData) {
|
|
HuMemDirectFree(spaceHiliteTexData);
|
|
spaceHiliteTexData = NULL;
|
|
}
|
|
if(spaceTexData) {
|
|
HuMemDirectFree(spaceTexData);
|
|
spaceTexData = NULL;
|
|
}
|
|
} |