1114 lines
32 KiB
C
1114 lines
32 KiB
C
#include "game/board/space.h"
|
|
#include "game/board/battle.h"
|
|
#include "game/board/lottery.h"
|
|
#include "game/board/main.h"
|
|
#include "game/board/model.h"
|
|
#include "game/board/player.h"
|
|
#include "game/board/shop.h"
|
|
#include "game/board/star.h"
|
|
#include "game/board/tutorial.h"
|
|
#include "game/data.h"
|
|
#include "game/flag.h"
|
|
#include "game/gamework_data.h"
|
|
#include "game/hsfman.h"
|
|
#include "game/objsub.h"
|
|
#include "game/sprite.h"
|
|
|
|
#include "ext_math.h"
|
|
#include "string.h"
|
|
|
|
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);
|
|
|
|
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 = (cosd(rot.z) * corner_ofs.x) + (sind(rot.z) * corner_ofs.y);
|
|
corner_ofs.y = (cosd(rot.x) * cosd(rot.z) * corner_ofs.y) + (sind(rot.z) * corner_ofs.x)
|
|
+ (sind(-rot.x) * corner_ofs.z);
|
|
corner_ofs.z = (sind(rot.x) * corner_ofs.y) + (cosd(rot.x) * 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 (GWBoardGet() == BOARD_ID_MAIN6) {
|
|
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 BOARD_ID_MAIN1:
|
|
if (star_total >= 2) {
|
|
break;
|
|
}
|
|
if (random_pos != 6 && random_pos != 7) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
|
|
case BOARD_ID_MAIN2:
|
|
if (star_total >= 2) {
|
|
break;
|
|
}
|
|
if (random_pos != 6 && random_pos != 7) {
|
|
break;
|
|
}
|
|
goto begin;
|
|
|
|
case BOARD_ID_MAIN3:
|
|
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 BOARD_ID_MAIN4:
|
|
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 BOARD_ID_MAIN5:
|
|
if (star_total == 1) {
|
|
if (random_pos <= 1 || random_pos >= 4) {
|
|
goto begin;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BOARD_ID_MAIN6:
|
|
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 (GWBoardGet() == BOARD_ID_EXTRA1 || GWBoardGet() == BOARD_ID_EXTRA2) {
|
|
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)
|
|
{
|
|
#define BLUE_SPACE 1
|
|
#define RED_SPACE 2
|
|
#define BOWSER_SPACE 3
|
|
#define MUSHROOM_SPACE 4
|
|
#define BATTLE_SPACE 5
|
|
#define HAPPENING_SPACE 6
|
|
#define FORTUNE_SPACE 7
|
|
#define STAR_SPACE 8
|
|
#define WARP_SPACE 9
|
|
|
|
BoardSpace *space_ptr = BoardSpaceGet(0, space);
|
|
switch (space_ptr->type) {
|
|
case BLUE_SPACE:
|
|
GWPlayer[player].blue_count++;
|
|
if (GWPlayer[player].blue_count > 99) {
|
|
GWPlayer[player].blue_count = 99;
|
|
}
|
|
BoardLandBlueExec(player, space);
|
|
break;
|
|
|
|
case RED_SPACE:
|
|
GWPlayer[player].red_count++;
|
|
if (GWPlayer[player].red_count > 99) {
|
|
GWPlayer[player].red_count = 99;
|
|
}
|
|
BoardLandRedExec(player, space);
|
|
break;
|
|
|
|
case BOWSER_SPACE:
|
|
GWPlayer[player].bowser_count++;
|
|
if (GWPlayer[player].bowser_count > 99) {
|
|
GWPlayer[player].bowser_count = 99;
|
|
}
|
|
BoardBowserExec(player, space);
|
|
break;
|
|
|
|
case MUSHROOM_SPACE:
|
|
GWPlayer[player].mushroom_count++;
|
|
if (GWPlayer[player].mushroom_count > 99) {
|
|
GWPlayer[player].mushroom_count = 99;
|
|
}
|
|
BoardMushroomExec(player, space);
|
|
break;
|
|
|
|
case BATTLE_SPACE:
|
|
GWPlayer[player].battle_count++;
|
|
if (GWPlayer[player].battle_count > 99) {
|
|
GWPlayer[player].battle_count = 99;
|
|
}
|
|
BoardBattleExec(player, space);
|
|
break;
|
|
|
|
case HAPPENING_SPACE:
|
|
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 FORTUNE_SPACE:
|
|
GWPlayer[player].fortune_count++;
|
|
if (GWPlayer[player].fortune_count > 99) {
|
|
GWPlayer[player].fortune_count = 99;
|
|
}
|
|
BoardFortuneExec(player, space);
|
|
break;
|
|
|
|
case WARP_SPACE:
|
|
GWPlayer[player].warp_count++;
|
|
if (GWPlayer[player].warp_count > 99) {
|
|
GWPlayer[player].warp_count = 99;
|
|
}
|
|
BoardWarpExec(player, space);
|
|
break;
|
|
|
|
case STAR_SPACE:
|
|
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 (GWBoardGet() == BOARD_ID_EXTRA1 || GWBoardGet() == BOARD_ID_EXTRA2) {
|
|
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) {
|
|
s32 mg_param = GWSystem.unk_38;
|
|
if (BoardPlayerSizeGet(player) == 1) {
|
|
BoardPlayerIdleSet(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 (!GWBonusStarGet() && GWPartyGet() == 1 && !_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
event_exec = 0;
|
|
}
|
|
if (GWBoardGet() == BOARD_ID_EXTRA1 || GWBoardGet() == BOARD_ID_EXTRA2) {
|
|
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 - atan2d(dir.z, dir.x));
|
|
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, HU3D_MOTATTR_LOOP);
|
|
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, HU3D_ATTR_DISPOFF);
|
|
}
|
|
else {
|
|
Hu3DModelAttrReset(spaceDrawMdl, HU3D_ATTR_DISPOFF);
|
|
}
|
|
}
|
|
|
|
static inline void InitGXSpace()
|
|
{
|
|
GXColor color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
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);
|
|
}
|
|
|
|
// 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);
|
|
{
|
|
BoardSpace *space_curr;
|
|
BoardSpace *space_hilite;
|
|
PlayerState *player;
|
|
s16 player_mdl;
|
|
float y_dist;
|
|
s32 space_img;
|
|
u16 space_type;
|
|
float uv_x, uv_y, uv_size;
|
|
InitGXSpace();
|
|
|
|
player = BoardPlayerGet(GWSystem.player_curr);
|
|
BoardPlayerPosGet(GWSystem.player_curr, &player_pos);
|
|
player_mdl = BoardModelIDGet(BoardPlayerModelGet(GWSystem.player_curr));
|
|
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 = GWBoardGet();
|
|
{
|
|
AnimBmpData *bmp;
|
|
AnimData *data;
|
|
void *data_base;
|
|
s32 size;
|
|
data = data_base = HuDataSelHeapReadNum(DATA_MAKE_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 ANIM_BMP_RGBA8:
|
|
spaceHiliteTexFmt = GX_TF_RGBA8;
|
|
break;
|
|
|
|
case ANIM_BMP_RGB5A3_DUPE:
|
|
spaceHiliteTexFmt = GX_TF_RGB5A3;
|
|
break;
|
|
|
|
case ANIM_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(DATA_MAKE_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 ANIM_BMP_RGBA8:
|
|
spaceTexFmt = GX_TF_RGBA8;
|
|
break;
|
|
|
|
case ANIM_BMP_RGB5A3_DUPE:
|
|
spaceTexFmt = GX_TF_RGB5A3;
|
|
break;
|
|
|
|
case ANIM_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 (GWBoardGet() != BOARD_ID_EXTRA1 && GWBoardGet() != BOARD_ID_EXTRA2) {
|
|
starPlatMdl = BoardModelCreate(DATA_MAKE_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;
|
|
}
|
|
}
|