2232 lines
No EOL
49 KiB
C
2232 lines
No EOL
49 KiB
C
#include "board_unsplit.h"
|
|
#include "game/gamework_data.h"
|
|
#include "math.h"
|
|
#include "game/object.h"
|
|
#include "game/flag.h"
|
|
#include "game/data.h"
|
|
#include "game/wipe.h"
|
|
#include "string.h"
|
|
#include "game/hsfman.h"
|
|
#include "game/hsfdraw.h"
|
|
#include "game/board/battle.h"
|
|
#include "game/board/lottery.h"
|
|
#include "game/board/main.h"
|
|
#include "game/board/model.h"
|
|
#include "game/board/pause.h"
|
|
#include "game/board/player.h"
|
|
#include "game/board/shop.h"
|
|
#include "game/board/space.h"
|
|
#include "game/board/start.h"
|
|
#include "game/board/tutorial.h"
|
|
#include "game/board/ui.h"
|
|
#include "game/pad.h"
|
|
#include "game/msm.h"
|
|
|
|
typedef struct camera_view {
|
|
s16 x_rot;
|
|
s16 zoom;
|
|
s16 fov;
|
|
} CameraView;
|
|
|
|
omObjData *boardMainObj;
|
|
u32 boardRandSeed;
|
|
static omObjData *last5GfxObj;
|
|
static omObjData *confettiObj;
|
|
static omObjData *filterObj;
|
|
BoardTurnStartHook boardTurnStartFunc;
|
|
BoardBowserHook boardBowserHook;
|
|
void (*boardStarShowNextHook)(void);
|
|
void (*boardStarGiveHook)(void);
|
|
BoardFunc boardTurnFunc;
|
|
BoardLightHook boardLightResetHook;
|
|
BoardLightHook boardLightSetHook;
|
|
static BoardFunc destroyFunc;
|
|
static BoardFunc createFunc;
|
|
static s32 cameraUseBackup;
|
|
static omObjData *tauntObj;
|
|
static omObjData *cameraObj;
|
|
Process *boardObjMan;
|
|
Process *boardMainProc;
|
|
|
|
BoardCameraData boardCamera;
|
|
static BoardCameraData cameraBackup;
|
|
|
|
static OverlayID nextOvl = OVL_INVALID;
|
|
|
|
static CameraView camViewTbl[] = {
|
|
{ 0, 0, 25 },
|
|
{ -33, 3200, 25 },
|
|
{ -33, 2100, 25 },
|
|
{ -33, 1800, 25 },
|
|
{ -33, 12640, 25 },
|
|
{ -33, 3200, 25 },
|
|
};
|
|
|
|
|
|
extern void BoardMGSetupPlayClear(void);
|
|
|
|
static void InitBoardFunc(omObjData *object);
|
|
static void ExecBoardFunc(omObjData *object);
|
|
static void KillBoardFunc(omObjData *object);
|
|
static void UpdateCamera(omObjData *object);
|
|
|
|
static void CalcCameraTarget(BoardCameraData *camera);
|
|
static void CalcCameraPos(BoardCameraData *camera);
|
|
|
|
static void MainFunc(void);
|
|
static void DestroyMainFunc(void);
|
|
|
|
static s32 ExecTurnStart(void);
|
|
|
|
static void CreateBoard(void);
|
|
static void DestroyBoard(void);
|
|
|
|
void BoardCommonInit(BoardFunc create, BoardFunc destroy)
|
|
{
|
|
omSysPauseEnable(FALSE);
|
|
if(!_CheckFlag(FLAG_ID_MAKE(1, 0))) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 0));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 1));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 3));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 0));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 2));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 4));
|
|
_ClearFlag(FLAG_ID_MAKE(2, 5));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 6));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 9));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 8));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 10));
|
|
BoardMGSetupPlayClear();
|
|
}
|
|
|
|
nextOvl = OVL_INVALID;
|
|
_SetFlag(FLAG_ID_MAKE(1, 28));
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 16));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 17));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 18));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 19));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 20));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 21));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 23));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 24));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 25));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 27));
|
|
createFunc = create;
|
|
destroyFunc = destroy;
|
|
boardTurnFunc = NULL;
|
|
boardStarShowNextHook = NULL;
|
|
boardBowserHook = NULL;
|
|
boardStarGiveHook = NULL;
|
|
boardTurnStartFunc = NULL;
|
|
boardObjMan = omInitObjMan(64, 8192);
|
|
omSystemKeyCheckSetup(boardObjMan);
|
|
boardMainObj = omAddObjEx(boardObjMan, 0, 0, 0, -1, InitBoardFunc);
|
|
switch(omcurovl) {
|
|
case OVL_W01:
|
|
GWSystem.board = 0;
|
|
break;
|
|
|
|
case OVL_W02:
|
|
GWSystem.board = 1;
|
|
break;
|
|
|
|
case OVL_W03:
|
|
GWSystem.board = 2;
|
|
break;
|
|
|
|
case OVL_W04:
|
|
GWSystem.board = 3;
|
|
break;
|
|
|
|
case OVL_W05:
|
|
GWSystem.board = 4;
|
|
break;
|
|
|
|
case OVL_W06:
|
|
GWSystem.board = 5;
|
|
break;
|
|
|
|
case OVL_W10:
|
|
GWSystem.board = 6;
|
|
break;
|
|
|
|
case OVL_W20:
|
|
GWSystem.board = 7;
|
|
break;
|
|
|
|
case OVL_W21:
|
|
GWSystem.board = 8;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void InitBoardFunc(omObjData *object)
|
|
{
|
|
boardMainProc = HuPrcChildCreate(MainFunc, 8194, 0x6000, 0, boardObjMan);
|
|
HuPrcDestructorSet2(boardMainProc, DestroyMainFunc);
|
|
object->func = ExecBoardFunc;
|
|
}
|
|
|
|
static void ExecBoardFunc(omObjData *object)
|
|
{
|
|
if(!_CheckFlag(FLAG_ID_MAKE(1, 16))) {
|
|
return;
|
|
}
|
|
if(!_CheckFlag(FLAG_ID_MAKE(1, 17))) {
|
|
if(omSysExitReq) {
|
|
BoardKill();
|
|
} else {
|
|
if(BoardPauseReqCheck()) {
|
|
BoardPauseStart();
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
if(boardMainProc) {
|
|
HuPrcKill(boardMainProc);
|
|
}
|
|
object->func = KillBoardFunc;
|
|
}
|
|
}
|
|
|
|
static void KillBoardFunc(omObjData *object)
|
|
{
|
|
if(boardMainProc) {
|
|
return;
|
|
}
|
|
if(WipeStatGet()) {
|
|
return;
|
|
return_alt:
|
|
return;
|
|
} else {
|
|
if(HuARDMACheck()) {
|
|
goto return_alt;
|
|
}
|
|
if(nextOvl != OVL_INVALID) {
|
|
omOvlCallEx(nextOvl, 1, 0, 0);
|
|
} else {
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
BoardTutorialKill();
|
|
BoardTutorialWorkRestore();
|
|
}
|
|
_ClearFlag(FLAG_ID_MAKE(1, 0));
|
|
HuARDirFree(DATADIR_BOARD);
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 27))) {
|
|
omOvlReturnEx(2, 1);
|
|
} else {
|
|
omOvlReturnEx(1, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BoardKill(void)
|
|
{
|
|
_SetFlag(FLAG_ID_MAKE(1, 28));
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
BoardTutorialHookExec(29, 0);
|
|
}
|
|
HuAudFXAllStop();
|
|
if(!BoardStartCheck()) {
|
|
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, -1);
|
|
boardTutorialF = 1;
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
}
|
|
_SetFlag(FLAG_ID_MAKE(1, 17));
|
|
HuPrcKill(boardMainProc);
|
|
DestroyBoard();
|
|
}
|
|
|
|
s32 BoardIsKill(void)
|
|
{
|
|
return (_CheckFlag(FLAG_ID_MAKE(1, 17))) ? 1 : 0;
|
|
}
|
|
|
|
void BoardPauseDisableSet(s32 value)
|
|
{
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 25));
|
|
omSysPauseEnable(FALSE);
|
|
} else {
|
|
if(value) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 25));
|
|
} else {
|
|
_ClearFlag(FLAG_ID_MAKE(1, 25));
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 BoardPauseDisableGet()
|
|
{
|
|
return (_CheckFlag(FLAG_ID_MAKE(1, 25))) ? 1 : 0;
|
|
}
|
|
|
|
void BoardSaveInit(s32 board)
|
|
{
|
|
int i;
|
|
GWSystem.board = board;
|
|
_ClearFlag(FLAG_ID_MAKE(1, 0));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 1));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 5));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 4));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 6));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 2));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 9));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 7));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 8));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 8));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 12));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 3));
|
|
GWSystem.turn = 1;
|
|
GWSystem.star_flag = 0;
|
|
GWSystem.star_pos = 0;
|
|
GWSystem.star_total = 1;
|
|
GWSystem.last5_effect = 0;
|
|
GWSystem.player_curr = -1;
|
|
GWSystem.bowser_loss = 0;
|
|
GWSystem.bowser_event = 0;
|
|
GWSystem.unk_32 = 1;
|
|
GWSystem.mg_next = 0;
|
|
GWSystem.mg_next_type = 0;
|
|
GWSystem.unk_38 = 0;
|
|
GWSystem.block_pos = 0;
|
|
memset(GWSystem.board_data, 0, 32);
|
|
for(i=0; i<4; i++) {
|
|
s32 party_flag;
|
|
BoardPlayerAutoSizeSet(i, 0);
|
|
GWPlayer[i].field00_bit9 = 0;
|
|
GWPlayer[i].color = 0;
|
|
GWPlayer[i].bowser_suit = 0;
|
|
GWPlayer[i].field08_bit3 = 0;
|
|
GWPlayer[i].space_shock = 0;
|
|
GWPlayer[i].field02_bit1 = 0;
|
|
GWPlayer[i].show_next = 1;
|
|
BoardPlayerCoinsSet(i, 0);
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
GWSystem.team = 0;
|
|
}
|
|
GWPlayer[i].blue_count = 0;
|
|
GWPlayer[i].red_count = 0;
|
|
GWPlayer[i].question_count = 0;
|
|
GWPlayer[i].fortune_count = 0;
|
|
GWPlayer[i].bowser_count = 0;
|
|
GWPlayer[i].battle_count = 0;
|
|
GWPlayer[i].mushroom_count = 0;
|
|
GWPlayer[i].warp_count = 0;
|
|
GWPlayer[i].coins_mg = 0;
|
|
GWPlayer[i].coins_total = 0;
|
|
GWPlayer[i].coins_max = 0;
|
|
GWPlayer[i].stars_max = 0;
|
|
GWPlayer[i].coins_battle = 0;
|
|
GWPlayer[i].unk_26 = 0;
|
|
GWPlayer[i].coin_gain = 0;
|
|
GWPlayer[i].items[0] = -1;
|
|
GWPlayer[i].items[1] = -1;
|
|
GWPlayer[i].items[2] = -1;
|
|
if(GWPartyGet() == 0 || _CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
GWStarsSet(i, 0);
|
|
} else {
|
|
GWStarsSet(i, BoardPlayerHandicapGet(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
void BoardStoryConfigSet(s32 mg_list, s32 diff_story)
|
|
{
|
|
GWSystem.party = 0;
|
|
GWSystem.team = 0;
|
|
GWSystem.diff_story = diff_story;
|
|
GWSystem.bonus_star = 0;
|
|
GWSystem.mg_list = mg_list;
|
|
GWPlayer[0].handicap = 0;
|
|
GWPlayer[1].handicap = 0;
|
|
GWPlayer[2].handicap = 0;
|
|
GWPlayer[3].handicap = 0;
|
|
GWSystem.max_turn = 15;
|
|
memset(GWPlayer, 0, 4*sizeof(PlayerState));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 2));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 3));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 4));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 5));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 6));
|
|
_ClearFlag(FLAG_ID_MAKE(0, 7));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 11));
|
|
_SetFlag(FLAG_ID_MAKE(0, 11));
|
|
_SetFlag(FLAG_ID_MAKE(1, 10));
|
|
}
|
|
|
|
void BoardPartyConfigSet(s32 team, s32 bonus_star, s32 mg_list, s32 max_turn, s32 p1_handicap, s32 p2_handicap, s32 p3_handicap, s32 p4_handicap)
|
|
{
|
|
GWSystem.party = 1;
|
|
GWSystem.team = team;
|
|
GWSystem.diff_story = 0;
|
|
GWSystem.bonus_star = bonus_star;
|
|
GWSystem.mg_list = mg_list;
|
|
GWSystem.max_turn = max_turn;
|
|
memset(GWPlayer, 0, 4*sizeof(PlayerState));
|
|
GWPlayer[0].handicap = p1_handicap;
|
|
GWPlayer[1].handicap = p2_handicap;
|
|
GWPlayer[2].handicap = p3_handicap;
|
|
GWPlayer[3].handicap = p4_handicap;
|
|
_ClearFlag(FLAG_ID_MAKE(1, 11));
|
|
_SetFlag(FLAG_ID_MAKE(0, 11));
|
|
_SetFlag(FLAG_ID_MAKE(1, 10));
|
|
}
|
|
|
|
static void DestroyMainFunc(void)
|
|
{
|
|
boardMainProc = NULL;
|
|
}
|
|
|
|
static void MainFunc(void)
|
|
{
|
|
s32 i;
|
|
s32 fade_enable, turn_cont, fade_type;
|
|
fade_enable = 0;
|
|
turn_cont = 0;
|
|
BoardPauseDisableSet(1);
|
|
if(_CheckFlag(FLAG_ID_MAKE(0, 10))) {
|
|
_ClearFlag(FLAG_ID_MAKE(0, 10));
|
|
_SetFlag(FLAG_ID_MAKE(1, 16));
|
|
BoardKill();
|
|
HuPrcSleep(-1);
|
|
}
|
|
_ClearFlag(FLAG_ID_MAKE(0, 10));
|
|
BoardTutorialInit();
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
BoardTutorialWorkSave();
|
|
BoardTutorialPlayerInit();
|
|
GWSystem.mess_speed = 1;
|
|
GWSystem.mess_delay = 32;
|
|
}
|
|
CreateBoard();
|
|
if(!_CheckFlag(FLAG_ID_MAKE(1, 1))) {
|
|
GWSystem.player_curr = -1;
|
|
BoardStartExec();
|
|
GWSystem.player_curr = 0;
|
|
fade_enable = 1;
|
|
_SetFlag(FLAG_ID_MAKE(1, 1));
|
|
} else {
|
|
fade_enable = 0;
|
|
}
|
|
if(ExecTurnStart()) {
|
|
turn_cont = 1;
|
|
}
|
|
if((int)(GWSystem.max_turn-GWSystem.turn) < 5 && GWSystem.player_curr == 0 && !turn_cont) {
|
|
if(!_CheckFlag(FLAG_ID_MAKE(0, 8))) {
|
|
BoardLast5Exec();
|
|
_SetFlag(FLAG_ID_MAKE(0, 8));
|
|
} else {
|
|
BoardLast5GfxInit();
|
|
}
|
|
}
|
|
if(!turn_cont) {
|
|
fade_type = 1;
|
|
} else {
|
|
fade_type = 0;
|
|
}
|
|
_ClearFlag(FLAG_ID_MAKE(1, 28));
|
|
do {
|
|
BoardStatusShowSetAll(1);
|
|
if(GWBoardGet() == 5 && GWSystem.player_curr == 0 && !turn_cont && boardTurnFunc) {
|
|
GWSystem.player_curr = -1;
|
|
boardTurnFunc();
|
|
GWSystem.player_curr = 0;
|
|
}
|
|
BoardMusStartBoard();
|
|
for(i=GWSystem.player_curr; i<4; i++) {
|
|
if(GWBoardGet() == 7 || GWBoardGet() == 8) {
|
|
if((int)(GWSystem.max_turn-GWSystem.turn) < 5 && i == 0 && !turn_cont) {
|
|
BoardLast5GfxInit();
|
|
_SetFlag(FLAG_ID_MAKE(0, 8));
|
|
}
|
|
}
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 6))) {
|
|
BoardPlayerTurnExec(i);
|
|
} else {
|
|
if(!turn_cont) {
|
|
BoardCameraMoveSet(0);
|
|
GWSystem.player_curr = i;
|
|
BoardCameraTargetPlayerSet(i);
|
|
BoardCameraMotionWait();
|
|
{
|
|
Vec pos;
|
|
BoardSpacePosGet(0, GWPlayer[i].space_curr, &pos);
|
|
BoardPlayerPosSetV(i, &pos);
|
|
}
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
if(!fade_enable) {
|
|
if(!fade_type) {
|
|
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_CROSS, 30);
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
} else {
|
|
fade_type = 0;
|
|
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 21);
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
}
|
|
} else {
|
|
fade_enable = 0;
|
|
}
|
|
BoardPlayerTurnExec(i);
|
|
}
|
|
}
|
|
turn_cont = 0;
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
BoardTutorialHookExec(9, 0);
|
|
}
|
|
if(i != 3 || _CheckFlag(FLAG_ID_MAKE(1, 11))) {
|
|
WipeColorSet(255, 255, 255);
|
|
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_CROSS, 1);
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
BoardPlayerMoveAwayStartCurr(GWPlayer[i].space_curr, 1);
|
|
fade_type = 0;
|
|
} else {
|
|
if(GWBoardGet() == 7 || GWBoardGet() == 8) {
|
|
if(GWSystem.turn != GWSystem.max_turn) {
|
|
WipeColorSet(255, 255, 255);
|
|
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_CROSS, 1);
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
BoardPlayerMoveAwayStartCurr(GWPlayer[i].space_curr, 1);
|
|
fade_type = 0;
|
|
}
|
|
} else {
|
|
WipeColorSet(0, 0, 0);
|
|
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 21);
|
|
while(WipeStatGet()) {
|
|
HuPrcVSleep();
|
|
}
|
|
}
|
|
}
|
|
BoardPlayerPostTurnHookExec(i);
|
|
}
|
|
if(GWBoardGet() == 7 || GWBoardGet() == 8) {
|
|
GWSystem.player_curr = 0;
|
|
if(BoardTurnNext()) {
|
|
BoardAudSeqFadeOut(0, 500);
|
|
BoardKill();
|
|
HuPrcEnd();
|
|
HuPrcSleep(-1);
|
|
}
|
|
} else {
|
|
_SetFlag(FLAG_ID_MAKE(1, 28));
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
BoardPauseDisableSet(1);
|
|
_ClearFlag(FLAG_ID_MAKE(1, 9));
|
|
if(_CheckFlag(FLAG_ID_MAKE(2, 0)) || _CheckFlag(FLAG_ID_MAKE(1, 11)) ) {
|
|
for(i=0; i<4; i++) {
|
|
GWPlayer[i].color = 0;
|
|
}
|
|
GWSystem.player_curr = (GWSystem.player_curr+1)&3;
|
|
} else {
|
|
BoardMGSetupExec();
|
|
HuPrcSleep(-1);
|
|
}
|
|
}
|
|
} while(1);
|
|
}
|
|
|
|
s32 BoardTurnNext(void)
|
|
{
|
|
s32 i;
|
|
for(i=0; i<4; i++) {
|
|
GWPlayer[i].color = 0;
|
|
}
|
|
GWSystem.turn++;
|
|
if(GWSystem.turn > GWSystem.max_turn) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static s32 ExecTurnStart(void)
|
|
{
|
|
s32 player;
|
|
s32 space;
|
|
if(!BoardStartCheck()) {
|
|
return 0;
|
|
}
|
|
player = GWSystem.player_curr;
|
|
space = GWPlayer[player].space_curr;
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 5))) {
|
|
BoardFortuneExec(player, space);
|
|
_ClearFlag(FLAG_ID_MAKE(1, 5));
|
|
} else if(_CheckFlag(FLAG_ID_MAKE(1, 4))) {
|
|
BoardMusStartBoard();
|
|
BoardBattleExec(player, space);
|
|
_ClearFlag(FLAG_ID_MAKE(1, 4));
|
|
} else if(_CheckFlag(FLAG_ID_MAKE(1, 3))) {
|
|
BoardBowserExec(player, space);
|
|
_ClearFlag(FLAG_ID_MAKE(1, 3));
|
|
} else if(_CheckFlag(FLAG_ID_MAKE(1, 2))) {
|
|
s32 turn_end = 0;
|
|
BoardCameraMoveSet(0);
|
|
BoardCameraViewSet(2);
|
|
BoardCameraMotionWait();
|
|
turn_end = BoardTurnNext();
|
|
if(turn_end) {
|
|
BoardKill();
|
|
HuPrcEnd();
|
|
}
|
|
_ClearFlag(FLAG_ID_MAKE(1, 2));
|
|
return 0;
|
|
} else if(_CheckFlag(FLAG_ID_MAKE(1, 6))) {
|
|
boardTurnStartFunc(player, space);
|
|
return 1;
|
|
}
|
|
BoardPlayerZoomRestore(player);
|
|
return 1;
|
|
}
|
|
|
|
void BoardNextOvlSet(OverlayID overlay)
|
|
{
|
|
nextOvl = overlay;
|
|
BoardAudSeqFadeOut(0, 1000);
|
|
BoardKill();
|
|
}
|
|
|
|
s32 BoardStartCheck(void)
|
|
{
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 2)) || _CheckFlag(FLAG_ID_MAKE(1, 3)) || _CheckFlag(FLAG_ID_MAKE(1, 4)) || _CheckFlag(FLAG_ID_MAKE(1, 5)) || _CheckFlag(FLAG_ID_MAKE(1, 6))) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void CreateBoard(void)
|
|
{
|
|
s32 guest_status;
|
|
int mess_speed;
|
|
s32 clear_flags;
|
|
s32 reset_unk32;
|
|
|
|
GWSystem.mg_next = -1;
|
|
if(!GWGameStat.field10E_bit5) {
|
|
s32 type_temp;
|
|
if(GWMGListGet() == 2) {
|
|
GWSystem.mg_list = 0;
|
|
}
|
|
}
|
|
mess_speed = GWMessSpeedGet();
|
|
GWSystem.mess_speed = mess_speed;
|
|
switch(mess_speed) {
|
|
case 0:
|
|
GWSystem.mess_delay = 16;
|
|
break;
|
|
|
|
case 2:
|
|
GWSystem.mess_delay = 48;
|
|
break;
|
|
|
|
default:
|
|
GWSystem.mess_delay = 32;
|
|
break;
|
|
}
|
|
if((int)GWSystem.explain_mg != 0) {
|
|
_SetFlag(FLAG_ID_MAKE(0, 11));
|
|
} else {
|
|
_ClearFlag(FLAG_ID_MAKE(0, 11));
|
|
}
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 2)) || _CheckFlag(FLAG_ID_MAKE(1, 3)) || _CheckFlag(FLAG_ID_MAKE(1, 4)) || _CheckFlag(FLAG_ID_MAKE(1, 5)) || _CheckFlag(FLAG_ID_MAKE(1, 6))) {
|
|
clear_flags = 1;
|
|
} else {
|
|
clear_flags = 0;
|
|
}
|
|
if(!clear_flags) {
|
|
_ClearFlag(FLAG_ID_MAKE(1, 2));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 3));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 4));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 5));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 6));
|
|
}
|
|
_ClearFlag(FLAG_ID_MAKE(1, 8));
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 2)) || _CheckFlag(FLAG_ID_MAKE(1, 3)) || _CheckFlag(FLAG_ID_MAKE(1, 4)) || _CheckFlag(FLAG_ID_MAKE(1, 5)) || _CheckFlag(FLAG_ID_MAKE(1, 6))) {
|
|
reset_unk32 = 1;
|
|
} else {
|
|
reset_unk32 = 0;
|
|
}
|
|
if(!reset_unk32) {
|
|
GWSystem.unk_32 = 1;
|
|
}
|
|
guest_status = BoardDataDirReadAsync(DATADIR_BGUEST);
|
|
if(guest_status != -1) {
|
|
BoardDataAsyncWait(guest_status);
|
|
}
|
|
BoardAudSeqClear();
|
|
BoardModelInit();
|
|
BoardRandInit();
|
|
BoardWinInit();
|
|
BoardPlayerModelInit();
|
|
createFunc();
|
|
BoardLightSetExec();
|
|
BoardLotteryInit();
|
|
BoardShopInit();
|
|
BoardBooHouseCreate();
|
|
BoardCameraInit();
|
|
BoardStatusCreate();
|
|
CharModelDataClose(-1);
|
|
BoardPlayerInit();
|
|
if(GWSystem.last5_effect == 2) {
|
|
BoardSpaceTypeForce(2, 3);
|
|
}
|
|
if(GWSystem.last5_effect == 3) {
|
|
BoardSpaceTypeForce(2, 7);
|
|
}
|
|
BoardCameraMoveSet(0);
|
|
BoardCameraTargetPlayerSet(0);
|
|
BoardCameraViewSet(2);
|
|
BoardCameraMotionWait();
|
|
BoardTauntInit();
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
HuDataDirClose(DATADIR_BKOOPASUIT);
|
|
HuDataDirClose(DATADIR_BBATTLE);
|
|
HuDataDirClose(DATADIR_BKOOPA);
|
|
HuDataDirClose(DATADIR_BKUJIYA);
|
|
HuDataDirClose(DATADIR_BYOKODORI);
|
|
HuDataDirClose(DATADIR_BPAUSE);
|
|
HuDataDirClose(DATADIR_BLAST5);
|
|
HuDataDirClose(DATADIR_EFFECT);
|
|
_SetFlag(FLAG_ID_MAKE(1, 16));
|
|
}
|
|
|
|
static void DestroyBoard(void)
|
|
{
|
|
s32 dir_table[] = {
|
|
DATADIR_W01,
|
|
DATADIR_W02,
|
|
DATADIR_W03,
|
|
DATADIR_W04,
|
|
DATADIR_W05,
|
|
DATADIR_W06,
|
|
DATADIR_W10,
|
|
DATADIR_W20,
|
|
DATADIR_W21
|
|
};
|
|
BoardTauntKill();
|
|
BoardAudSeqFadeOutAll();
|
|
HuAudAllStop();
|
|
BoardRollKill();
|
|
BoardStatusKill();
|
|
BoardBooHouseKill();
|
|
BoardShopKill();
|
|
BoardLotteryKill();
|
|
BoardSpaceDestroy();
|
|
BoardPlayerModelKill();
|
|
if(destroyFunc) {
|
|
destroyFunc();
|
|
}
|
|
BoardModelKillAll();
|
|
BoardWinKillAll();
|
|
HuDataDirClose(dir_table[GWBoardGet()]);
|
|
HuDataDirClose(DATADIR_EFFECT);
|
|
HuDataDirClose(DATADIR_BGUEST);
|
|
HuDataDirClose(DATADIR_BKOOPASUIT);
|
|
HuDataDirClose(DATADIR_BBATTLE);
|
|
HuDataDirClose(DATADIR_BKOOPA);
|
|
HuDataDirClose(DATADIR_BKUJIYA);
|
|
HuDataDirClose(DATADIR_BYOKODORI);
|
|
HuDataDirClose(DATADIR_BOARD);
|
|
createFunc = destroyFunc = NULL;
|
|
}
|
|
|
|
void BoardLightHookSet(BoardLightHook set, BoardLightHook reset)
|
|
{
|
|
boardLightSetHook = set;
|
|
boardLightResetHook = reset;
|
|
}
|
|
|
|
void BoardLightSetExec(void)
|
|
{
|
|
Hu3DBGColorSet(0, 0, 0);
|
|
if(boardLightSetHook) {
|
|
boardLightSetHook();
|
|
}
|
|
}
|
|
|
|
void BoardLightResetExec(void)
|
|
{
|
|
if(boardLightResetHook) {
|
|
boardLightResetHook();
|
|
}
|
|
Hu3DBGColorSet(0, 0, 0);
|
|
Hu3DFogClear();
|
|
Hu3DReflectNoSet(0);
|
|
}
|
|
|
|
static BoardCameraData *BoardCameraGet(void)
|
|
{
|
|
return &boardCamera;
|
|
}
|
|
|
|
void BoardCameraBackup(void)
|
|
{
|
|
cameraUseBackup = TRUE;
|
|
memcpy(&cameraBackup, &boardCamera, sizeof(BoardCameraData));
|
|
}
|
|
|
|
void BoardCameraRestore(void)
|
|
{
|
|
if(cameraUseBackup) {
|
|
memcpy(&boardCamera, &cameraBackup, sizeof(BoardCameraData));
|
|
cameraUseBackup = FALSE;
|
|
}
|
|
}
|
|
|
|
void BoardCameraScissorSet(s32 x, s32 y, s32 w, s32 h)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
Hu3DCameraScissorSet(camera->mask, x, y, w, h);
|
|
}
|
|
|
|
void BoardCameraViewSet(s32 type)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
BoardFocusData *focus;
|
|
float size;
|
|
if(!cameraObj) {
|
|
return;
|
|
}
|
|
focus = &camera->focus;
|
|
if(type == 0) {
|
|
focus->view_type = 0;
|
|
return;
|
|
}
|
|
OSs16tof32(&camViewTbl[type].fov, &focus->fov_end);
|
|
focus->fov_start = camera->fov;
|
|
OSs16tof32(&camViewTbl[type].zoom, &focus->zoom_end);
|
|
focus->zoom_start = camera->zoom;
|
|
OSs16tof32(&camViewTbl[type].x_rot, &focus->rot_end.x);
|
|
focus->rot_end.y = 0;
|
|
focus->rot_end.z = 0;
|
|
focus->rot_start = camera->rot;
|
|
focus->target_start = camera->target;
|
|
if(BoardPlayerSizeGet(GWSystem.player_curr) == 2 || GWPlayer[GWSystem.player_curr].bowser_suit) {
|
|
focus->zoom_end += 400.0f;
|
|
size = 2.5f;
|
|
} else {
|
|
size = 1.0f;
|
|
}
|
|
BoardCameraTargetModelSet(BoardPlayerModelGetCurr());
|
|
BoardPlayerPosGet(GWSystem.player_curr, &focus->target_end);
|
|
BoardCameraOffsetSet(0.0f, 100.0f*size, 0.0f);
|
|
focus->target_end.y += 100.0f*size;
|
|
_SetFlag(FLAG_ID_MAKE(1, 21));
|
|
focus->view_type = type;
|
|
focus->time = 0;
|
|
if(camera->moving) {
|
|
focus->max_time = 21;
|
|
} else {
|
|
focus->max_time = 1;
|
|
}
|
|
}
|
|
|
|
s32 BoardCameraPosGet(Vec *dst)
|
|
{
|
|
BoardCameraData *camera;
|
|
if(!dst) {
|
|
return -1;
|
|
}
|
|
camera = &boardCamera;
|
|
*dst = camera->pos;
|
|
return 0;
|
|
}
|
|
|
|
s32 BoardCameraTargetGet(Vec *dst)
|
|
{
|
|
BoardCameraData *camera;
|
|
if(!dst) {
|
|
return -1;
|
|
}
|
|
camera = &boardCamera;
|
|
*dst = camera->target;
|
|
return 0;
|
|
}
|
|
|
|
s32 BoardCameraRotGet(Vec *dst)
|
|
{
|
|
BoardCameraData *camera;
|
|
if(!dst) {
|
|
return -1;
|
|
}
|
|
camera = &boardCamera;
|
|
*dst = camera->rot;
|
|
return 0;
|
|
}
|
|
|
|
float BoardCameraZoomGet()
|
|
{
|
|
BoardCameraData *camera;
|
|
camera = &boardCamera;
|
|
return camera->zoom;
|
|
}
|
|
|
|
s32 BoardCameraDirGet(Vec *dst)
|
|
{
|
|
BoardCameraData *camera;
|
|
if(!dst) {
|
|
return -1;
|
|
}
|
|
camera = &boardCamera;
|
|
if(!camera) {
|
|
return -1;
|
|
}
|
|
VECSubtract(&camera->target, &camera->pos, dst);
|
|
if(dst->x != 0 || dst->y != 0 || dst->z != 0) {
|
|
VECNormalize(dst, dst);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 BoardCameraPointDirGet(Vec *point, Vec *dst)
|
|
{
|
|
BoardCameraData *camera;
|
|
if(!dst || !point) {
|
|
return -1;
|
|
}
|
|
camera = &boardCamera;
|
|
if(!camera) {
|
|
return -1;
|
|
}
|
|
VECSubtract(point, &camera->pos, dst);
|
|
if(dst->x != 0 || dst->y != 0 || dst->z != 0) {
|
|
VECNormalize(dst, dst);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void BoardCameraMaskSet(u16 mask)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->mask = mask;
|
|
}
|
|
|
|
void BoardCameraMoveSet(s32 move)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
if(!move) {
|
|
camera->moving = 0;
|
|
} else {
|
|
camera->moving = 1;
|
|
}
|
|
}
|
|
|
|
void BoardCameraOffsetSet(float x, float y, float z)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->offset.x = x;
|
|
camera->offset.y = y;
|
|
camera->offset.z = z;
|
|
}
|
|
|
|
void BoardCameraTargetPlayerSet(s32 player)
|
|
{
|
|
PlayerState *player_ptr = BoardPlayerGet(player);
|
|
if(!player_ptr) {
|
|
BoardCameraTargetModelSet(-1);
|
|
return;
|
|
}
|
|
BoardCameraTargetModelSet(BoardPlayerModelGet(player));
|
|
BoardCameraOffsetSet(0, 100, 0);
|
|
}
|
|
|
|
void BoardCameraTargetModelSet(s16 model)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->target_mdl = model;
|
|
camera->target_space = -1;
|
|
camera->offset.x = camera->offset.y = camera->offset.z = 0;
|
|
}
|
|
|
|
void BoardCameraTargetSpaceSet(s32 space)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->target_mdl = -1;
|
|
camera->target_space = space;
|
|
camera->offset.x = camera->offset.y = camera->offset.z = 0;
|
|
}
|
|
|
|
void BoardCameraPosCalcFuncSet(BoardCameraPosCalcFunc func)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->pos_calc = func;
|
|
}
|
|
|
|
void BoardCameraQuakeSet(s32 duration, float strength)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera) {
|
|
return;
|
|
}
|
|
camera->quaking = 1;
|
|
camera->quake_strength = strength;
|
|
camera->quake_timer = duration;
|
|
}
|
|
|
|
void BoardCameraQuakeReset()
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->quaking = 0;
|
|
camera->quake_strength = 0;
|
|
camera->quake_timer = 0;
|
|
}
|
|
|
|
void BoardCameraTargetSet(float x, float y, float z)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->target.x = x;
|
|
camera->target.y = y;
|
|
camera->target.z = z;
|
|
}
|
|
|
|
void BoardCameraPosSet(float x, float y, float z)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->pos.x = x;
|
|
camera->pos.y = y;
|
|
camera->pos.z = z;
|
|
}
|
|
|
|
void BoardCameraXRotZoomSet(float zoom, float x_rot)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->zoom = zoom;
|
|
camera->rot.x = x_rot;
|
|
}
|
|
|
|
void BoardCameraZoomSet(float zoom)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->zoom = zoom;
|
|
}
|
|
|
|
void BoardCameraRotSet(float x, float y)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->rot.x = x;
|
|
camera->rot.y = y;
|
|
}
|
|
|
|
void BoardCameraNearFarSet(float near, float far)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->near = near;
|
|
camera->far = far;
|
|
}
|
|
|
|
void BoardCameraNearFarGet(float *near, float *far)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(near) {
|
|
*near = camera->near;
|
|
}
|
|
if(far) {
|
|
*far = camera->far;
|
|
}
|
|
}
|
|
|
|
void BoardCameraMotionStart(s16 model_target, Vec *rot_target, float zoom_target, float fov_target)
|
|
{
|
|
BoardCameraMotionStartEx(model_target, rot_target, 0, zoom_target, fov_target, 21);
|
|
}
|
|
|
|
void BoardCameraMotionStartEx(s16 model_target, Vec *rot_target, Vec *offset_end, float zoom_target, float fov_target, s16 max_time)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
BoardFocusData *focus;
|
|
if(!cameraObj) {
|
|
return;
|
|
}
|
|
focus = &camera->focus;
|
|
focus->fov_start = camera->fov;
|
|
focus->zoom_start = camera->zoom;
|
|
focus->rot_start = camera->rot;
|
|
focus->target_start = camera->target;
|
|
if(fov_target == -1) {
|
|
focus->fov_end = focus->fov_start;
|
|
} else {
|
|
focus->fov_end = fov_target;
|
|
}
|
|
if(zoom_target == -1) {
|
|
focus->zoom_end = focus->zoom_start;
|
|
} else {
|
|
focus->zoom_end = zoom_target;
|
|
}
|
|
if(!rot_target) {
|
|
focus->rot_end = focus->rot_start;
|
|
} else {
|
|
focus->rot_end = *rot_target;
|
|
}
|
|
if(model_target == -1) {
|
|
focus->target_end = focus->target_start;
|
|
} else {
|
|
BoardCameraTargetModelSet(model_target);
|
|
BoardModelPosGet(model_target, &focus->target_end);
|
|
}
|
|
if(offset_end) {
|
|
BoardCameraOffsetSet(offset_end->x, offset_end->y, offset_end->z);
|
|
VECAdd(offset_end, &focus->target_end, &focus->target_end);
|
|
}
|
|
_SetFlag(FLAG_ID_MAKE(1, 21));
|
|
focus->view_type = 5;
|
|
focus->time = 0;
|
|
if(max_time < 0) {
|
|
max_time = 1;
|
|
}
|
|
focus->max_time = max_time;
|
|
}
|
|
|
|
void BoardCameraFovSet(float fov)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
camera->fov = fov;
|
|
}
|
|
|
|
s32 BoardCameraCullCheck(Vec *point, float radius)
|
|
{
|
|
Vec dir;
|
|
Vec pos;
|
|
float dist;
|
|
float dot;
|
|
BoardCameraData *camera = &boardCamera;
|
|
if(!camera->hide_all) {
|
|
return 0;
|
|
}
|
|
BoardCameraDirGet(&dir);
|
|
VECSubtract(point, &camera->pos, &pos);
|
|
dist = sqrtf((pos.x*pos.x)+(pos.y*pos.y)+(pos.z*pos.z));
|
|
if(25000 < dist-(radius*2.0f)) {
|
|
return 0;
|
|
}
|
|
BoardCameraPointDirGet(point, &pos);
|
|
dot = VECDotProduct(&dir, &pos);
|
|
if(BOARD_FABS(dot) < cos((camera->fov*M_PI)/180)) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
s32 BoardCameraMotionIsDone(void)
|
|
{
|
|
return (_CheckFlag(FLAG_ID_MAKE(1, 21))) ? 0 : 1;
|
|
}
|
|
|
|
void BoardCameraMotionWait(void)
|
|
{
|
|
while(!BoardCameraMotionIsDone()) {
|
|
HuPrcVSleep();
|
|
}
|
|
HuPrcVSleep();
|
|
}
|
|
|
|
void BoardCameraInit(void)
|
|
{
|
|
BoardCameraData *camera;
|
|
cameraUseBackup = FALSE;
|
|
memset(&cameraBackup, 0, sizeof(BoardCameraData));
|
|
memset(&boardCamera, 0, sizeof(BoardCameraData));
|
|
camera = &boardCamera;
|
|
camera->fov = 25;
|
|
camera->near = 100;
|
|
camera->far = 13000;
|
|
camera->aspect = 1.2;
|
|
camera->viewport_x = 0;
|
|
camera->viewport_y = 0;
|
|
camera->viewport_h = 480;
|
|
camera->viewport_w = 640;
|
|
camera->viewport_near = 0;
|
|
camera->viewport_far = 1;
|
|
camera->up.y = 1;
|
|
camera->moving = 0;
|
|
camera->quaking = 0;
|
|
camera->quake_timer = 0;
|
|
camera->pos.x = 0;
|
|
camera->pos.y = 5000;
|
|
camera->pos.z = 5000;
|
|
camera->offset.x = 0;
|
|
camera->offset.y = 0;
|
|
camera->offset.z = 0;
|
|
camera->pos_calc = NULL;
|
|
BoardSpaceFlagPosGet(0, 0x80000000, &camera->target);
|
|
camera->rot.x = camViewTbl[1].x_rot;
|
|
camera->zoom = camViewTbl[1].zoom;
|
|
camera->hide_all = 1;
|
|
camera->mask = 1;
|
|
Hu3DCameraCreate(1);
|
|
Hu3DCameraScissorSet(1, camera->viewport_x, camera->viewport_y, camera->viewport_w, camera->viewport_h);
|
|
Hu3DCameraScissorSet(2, 0, 0, 0, 0);
|
|
Hu3DCameraPerspectiveSet(2, -1, 100, 13000, 1.2);
|
|
cameraObj = omAddObjEx(boardObjMan, 32258, 0, 0, -1, UpdateCamera);
|
|
}
|
|
|
|
static inline void CalcCameraView(void)
|
|
{
|
|
BoardCameraData *camera = &boardCamera;
|
|
CalcCameraTarget(camera);
|
|
CalcCameraPos(camera);
|
|
}
|
|
|
|
static void UpdateCamera(omObjData *object)
|
|
{
|
|
BoardCameraData *camera;
|
|
Vec *target;
|
|
float x, y, z;
|
|
if(BoardIsKill()) {
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
return;
|
|
}
|
|
CalcCameraView();
|
|
camera = &boardCamera;
|
|
Hu3DCameraPerspectiveSet(camera->mask, camera->fov, camera->near, camera->far, camera->aspect);
|
|
Hu3DCameraViewportSet(camera->mask, camera->viewport_x, camera->viewport_y, camera->viewport_w, camera->viewport_h, camera->viewport_near, camera->viewport_far);
|
|
target = &camera->target;
|
|
if(camera->pos_calc) {
|
|
camera->pos_calc(camera);
|
|
} else {
|
|
|
|
x = camera->rot.x;
|
|
y = camera->rot.y;
|
|
camera->pos.x = target->x+(sin((y*M_PI)/180.0)*cos((x*M_PI)/180.0)*camera->zoom);
|
|
camera->pos.y = target->y+(-sin((x*M_PI)/180.0)*camera->zoom);
|
|
camera->pos.z = target->z+(cos((y*M_PI)/180.0)*cos((x*M_PI)/180.0)*camera->zoom);
|
|
camera->up.x = sin((y*M_PI)/180.0)*sin((x*M_PI)/180.0);
|
|
camera->up.y = cos((x*M_PI)/180.0);
|
|
camera->up.z = cos((y*M_PI)/180.0)*sin((x*M_PI)/180.0);
|
|
if(camera->quaking) {
|
|
x = BoardRandFloat();
|
|
y = BoardRandFloat();
|
|
z = BoardRandFloat();
|
|
camera->pos.x += (x-0.5f)*camera->quake_strength;
|
|
camera->pos.y += (y-0.5f)*camera->quake_strength;
|
|
camera->pos.z += (z-0.5f)*camera->quake_strength;
|
|
if(--camera->quake_timer <= 0) {
|
|
camera->quaking = 0;
|
|
camera->quake_timer = 0;
|
|
camera->quake_strength = 0;
|
|
}
|
|
}
|
|
}
|
|
Hu3DCameraPosSetV(camera->mask, &camera->pos, &camera->up, target);
|
|
}
|
|
|
|
static void CalcCameraTarget(BoardCameraData *camera)
|
|
{
|
|
Vec offset;
|
|
Vec pos = { 0, 0, 0 };
|
|
BoardFocusData *focus = &camera->focus;
|
|
if(camera->target_mdl != -1) {
|
|
BoardModelPosGet(camera->target_mdl, &pos);
|
|
} else {
|
|
if(camera->target_space != -1) {
|
|
BoardSpacePosGet(0, camera->target_space, &pos);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
VECAdd(&camera->offset, &pos, &pos);
|
|
VECSubtract(&pos, &camera->target, &offset);
|
|
if(camera->moving) {
|
|
VECScale(&offset, &offset, 0.15f);
|
|
}
|
|
VECAdd(&offset, &camera->target, &camera->target);
|
|
}
|
|
|
|
#define CAM_LERP(t, x1, x2, out) \
|
|
{ \
|
|
float result; \
|
|
float offset; \
|
|
float unit_scale; \
|
|
float lerp_t; \
|
|
lerp_x2 = x2; \
|
|
lerp_x1 = x1; \
|
|
lerp_t = t; \
|
|
if(lerp_t2 == lerp_t1) { \
|
|
result = lerp_x2; \
|
|
} else { \
|
|
unit_scale = (lerp_x1-lerp_x2)/((float)lerp_t1-(float)lerp_t2); \
|
|
offset = lerp_x2-(unit_scale*lerp_t2); \
|
|
result = offset+(unit_scale*lerp_t); \
|
|
} \
|
|
out = result; \
|
|
}
|
|
|
|
#define CAM_LERP_VEC(t, x1, x2, out) \
|
|
CAM_LERP(t, (x1).x, (x2).x, (out).x) \
|
|
CAM_LERP(t, (x1).y, (x2).y, (out).y) \
|
|
CAM_LERP(t, (x1).z, (x2).z, (out).z)
|
|
|
|
static void CalcCameraPos(BoardCameraData *camera)
|
|
{
|
|
|
|
volatile unsigned int lerp_t1, lerp_t2;
|
|
volatile float lerp_x1, lerp_x2;
|
|
float time;
|
|
|
|
BoardFocusData *focus = &camera->focus;
|
|
if(focus->time > focus->max_time) {
|
|
focus->view_type = 0;
|
|
_ClearFlag(FLAG_ID_MAKE(1, 21));
|
|
return;
|
|
}
|
|
OSs16tof32(&focus->time, &time);
|
|
focus->time++;
|
|
lerp_t2 = focus->max_time;
|
|
lerp_t1 = 0;
|
|
CAM_LERP(time, focus->zoom_start, focus->zoom_end, camera->zoom)
|
|
CAM_LERP_VEC(time, focus->rot_start, focus->rot_end, camera->rot)
|
|
CAM_LERP(time, focus->fov_start, focus->fov_end, camera->fov)
|
|
CAM_LERP_VEC(time, focus->target_start, focus->target_end, camera->target)
|
|
}
|
|
|
|
void BoardMGDoneFlagSet(s32 flag)
|
|
{
|
|
if(flag) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 20));
|
|
} else {
|
|
_ClearFlag(FLAG_ID_MAKE(1, 20));
|
|
}
|
|
}
|
|
|
|
s32 BoardMGDoneFlagGet()
|
|
{
|
|
return (_CheckFlag(FLAG_ID_MAKE(1, 20))) ? 1 : 0;
|
|
}
|
|
|
|
void BoardMGExit(void)
|
|
{
|
|
s32 player = GWSystem.player_curr;
|
|
BoardPlayerMoveToAsync(player, GWPlayer[GWSystem.player_curr].space_curr);
|
|
BoardCameraTargetPlayerSet(player);
|
|
BoardCameraMoveSet(1);
|
|
BoardCameraViewSet(1);
|
|
_ClearFlag(FLAG_ID_MAKE(1, 19));
|
|
}
|
|
|
|
static void KillBoardMG(omObjData *object)
|
|
{
|
|
if(!BoardMGDoneFlagGet()) {
|
|
BoardEventFlagReset();
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
}
|
|
}
|
|
|
|
static void ExecBoardMG(omObjData *object)
|
|
{
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 19))) {
|
|
return;
|
|
}
|
|
if(GWPlayer[GWSystem.player_curr].moving == 0) {
|
|
BoardPlayerMotionShiftSet(GWSystem.player_curr, 1, 0.0f, 10.0f, 0x40000001);
|
|
if(!_CheckFlag(FLAG_ID_MAKE(1, 21))) {
|
|
_SetFlag(FLAG_ID_MAKE(1, 20));
|
|
object->func = KillBoardMG;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BoardMGCreate(s32 arg0)
|
|
{
|
|
_SetFlag(FLAG_ID_MAKE(1, 19));
|
|
_ClearFlag(FLAG_ID_MAKE(1, 20));
|
|
GWSystem.unk_38 = arg0;
|
|
omAddObjEx(boardObjMan, 0x201, 0, 0, -1, ExecBoardMG);
|
|
BoardEventFlagSet();
|
|
BoardSpaceWalkMiniEventExec();
|
|
}
|
|
|
|
void BoardEventFlagSet(void)
|
|
{
|
|
_SetFlag(FLAG_ID_MAKE(1, 18));
|
|
}
|
|
|
|
void BoardEventFlagReset(void)
|
|
{
|
|
_ClearFlag(FLAG_ID_MAKE(1, 18));
|
|
}
|
|
|
|
s32 BoardEventFlagGet(void)
|
|
{
|
|
return _CheckFlag(FLAG_ID_MAKE(1, 18)) ? 1 : 0;
|
|
}
|
|
|
|
void BoardMTXCalcLookAt(Mtx dest, Vec *eye, Vec *up, Vec *target)
|
|
{
|
|
Vec f, u, s;
|
|
f.x = eye->x-target->x;
|
|
f.y = eye->y-target->y;
|
|
f.z = eye->z-target->z;
|
|
VECNormalize(&f, &f);
|
|
VECCrossProduct(up, &f, &u);
|
|
VECNormalize(&u, &u);
|
|
VECCrossProduct(&f, &u, &s);
|
|
dest[0][0] = u.x;
|
|
dest[0][1] = u.y;
|
|
dest[0][2] = u.z;
|
|
dest[0][3] = 0;
|
|
dest[1][0] = s.x;
|
|
dest[1][1] = s.y;
|
|
dest[1][2] = s.z;
|
|
dest[1][3] = 0;
|
|
dest[2][0] = f.x;
|
|
dest[2][1] = f.y;
|
|
dest[2][2] = f.z;
|
|
dest[2][3] = 0;
|
|
}
|
|
|
|
float BoardArcSin(float value)
|
|
{
|
|
float result;
|
|
s32 sign;
|
|
if(value < 0) {
|
|
sign = 1;
|
|
value = BOARD_FABS(value);
|
|
} else {
|
|
sign = 0;
|
|
}
|
|
if(value > 1.0f) {
|
|
return 0;
|
|
}
|
|
if(value <= (float)(M_PI/2)) {
|
|
result = atanf(value/(float)sqrtf(1-(value*value)));
|
|
} else {
|
|
result = ((float)M_PI/2.0f)-atanf((float)sqrtf(1-(value*value))/value);
|
|
}
|
|
if(sign) {
|
|
result = BOARD_FABS(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
float BoardArcCos(float value)
|
|
{
|
|
if(BOARD_FABS(value) > 1) {
|
|
return 0;
|
|
}
|
|
return ((float)M_PI/2.0f)-BoardArcSin(value);
|
|
}
|
|
|
|
void BoardRandInit(void)
|
|
{
|
|
boardRandSeed = OSGetTime();
|
|
}
|
|
|
|
u32 BoardRand(void)
|
|
{
|
|
boardRandSeed = (boardRandSeed*0x19660D)+(0x3C6EF35F);
|
|
return boardRandSeed;
|
|
}
|
|
|
|
u32 BoardRandMod(u32 value)
|
|
{
|
|
return (BoardRand() & 0x7FFFFFFF)%value;
|
|
}
|
|
|
|
float BoardRandFloat(void)
|
|
{
|
|
float value;
|
|
*((u32 *)&value) = (BoardRand() & 0x7FFFFF)|0x3F800000;
|
|
return value-1.0f;
|
|
}
|
|
|
|
float BoardVecDistXZCalc(Vec *vec1, Vec *vec2)
|
|
{
|
|
float x = vec1->x-vec2->x;
|
|
float z = vec1->z-vec2->z;
|
|
return sqrtf((x*x)+(z*z));
|
|
}
|
|
|
|
s32 BoardVecMaxDistXZCheck(Vec *vec1, Vec *vec2, float max_dist)
|
|
{
|
|
float z = vec1->z-vec2->z;
|
|
float x = vec1->x-vec2->x;
|
|
float dist = sqrtf((x*x)+(z*z));
|
|
if(dist <= max_dist) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void BoardDAngleCalcVec(Vec *vec1)
|
|
{
|
|
int i;
|
|
float *data = (float *)(&vec1->x);
|
|
for(i=0; i<3; i++) {
|
|
while(*data > 180.0f) {
|
|
*data -= 360.0f;
|
|
}
|
|
while(*data < -180.0f) {
|
|
*data += 360.0f;
|
|
}
|
|
data++;
|
|
}
|
|
}
|
|
|
|
float BoardDAngleCalc(float value)
|
|
{
|
|
while(value > 180.0f) {
|
|
value -= 360.0f;
|
|
}
|
|
while(value < -180.0f) {
|
|
value += 360.0f;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
s32 BoardDAngleCalcRange(float *value, float min, float range)
|
|
{
|
|
float diff = min-(*value);
|
|
if(diff >= 180.0f) {
|
|
min -= 360.0f;
|
|
}
|
|
if(diff <= -180.0f) {
|
|
min += 360.0f;
|
|
}
|
|
if(min > *value) {
|
|
*value += range;
|
|
if(*value >= min) {
|
|
*value = BoardDAngleCalc(min);
|
|
return 1;
|
|
}
|
|
} else {
|
|
*value -= range;
|
|
if(*value <= min) {
|
|
*value = BoardDAngleCalc(min);
|
|
return 1;
|
|
}
|
|
}
|
|
*value = BoardDAngleCalc(*value);
|
|
return 0;
|
|
}
|
|
|
|
s32 BoardVecMinDistCheck(Vec *vec1, Vec *vec2, float min_dist)
|
|
{
|
|
Vec temp;
|
|
Mtx temp_mtx;
|
|
VECSubtract(vec1, vec2, &temp);
|
|
if(VECSquareMag(&temp) >= (min_dist*min_dist)) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
typedef struct filter_work {
|
|
struct {
|
|
u8 kill : 1;
|
|
u8 paused : 1;
|
|
};
|
|
u8 max_alpha;
|
|
s16 time;
|
|
s16 len;
|
|
s16 model;
|
|
GXColor color;
|
|
float speed;
|
|
} FilterWork;
|
|
|
|
static void UpdateFilter(omObjData *object);
|
|
static void DrawFilter(ModelData *model, Mtx matrix);
|
|
|
|
void BoardFilterFadeOut(s16 len)
|
|
{
|
|
FilterWork *work;
|
|
float speed;
|
|
if(!filterObj) {
|
|
return;
|
|
}
|
|
if(len <= 0) {
|
|
len = 1;
|
|
}
|
|
work = OM_GET_WORK_PTR(filterObj, FilterWork);
|
|
work->len = len;
|
|
OSs16tof32(&len, &speed);
|
|
work->speed = -(work->color.a)/speed;
|
|
work->paused = 0;
|
|
work->time = work->len;
|
|
}
|
|
|
|
void BoardFilterFadeInit(s16 len, u8 max_alpha)
|
|
{
|
|
FilterWork *work;
|
|
if(filterObj) {
|
|
work = OM_GET_WORK_PTR(filterObj, FilterWork);
|
|
work->kill = 1;
|
|
while(filterObj) {
|
|
HuPrcVSleep();
|
|
}
|
|
}
|
|
filterObj = omAddObjEx(boardObjMan, 32000, 0, 0, -1, UpdateFilter);
|
|
omSetStatBit(filterObj, OM_STAT_NOPAUSE|0x80);
|
|
if(len <= 0) {
|
|
len = 1;
|
|
}
|
|
work = OM_GET_WORK_PTR(filterObj, FilterWork);
|
|
work->kill = 0;
|
|
work->paused = 0;
|
|
work->color.r = 0;
|
|
work->color.g = 0;
|
|
work->color.b = 0;
|
|
work->color.a = 0;
|
|
work->max_alpha = max_alpha;
|
|
work->speed = (float)(max_alpha-work->color.a)/(float)len;
|
|
work->time = len;
|
|
work->len = len;
|
|
work->model = Hu3DHookFuncCreate(DrawFilter);
|
|
Hu3DModelLayerSet(work->model, 1);
|
|
}
|
|
|
|
s32 BoardFilterFadePauseCheck(void)
|
|
{
|
|
FilterWork *work;
|
|
if(!filterObj) {
|
|
return 1;
|
|
}
|
|
work = OM_GET_WORK_PTR(filterObj, FilterWork);
|
|
return (work->paused) ? 1 : 0;
|
|
}
|
|
|
|
s32 BoardFilterFadeCheck(void)
|
|
{
|
|
return (filterObj != NULL) ? 0 : 1;
|
|
}
|
|
|
|
static void UpdateFilter(omObjData *object)
|
|
{
|
|
float alpha;
|
|
FilterWork *work = OM_GET_WORK_PTR(object, FilterWork);
|
|
if(work->kill || BoardIsKill()) {
|
|
if(work->model != -1) {
|
|
Hu3DModelKill(work->model);
|
|
}
|
|
filterObj = NULL;
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
return;
|
|
}
|
|
if(work->paused) {
|
|
return;
|
|
}
|
|
OSu8tof32(&work->color.a, &alpha);
|
|
alpha += work->speed;
|
|
OSf32tou8(&alpha, &work->color.a);
|
|
if(work->time > 0) {
|
|
work->time--;
|
|
return;
|
|
}
|
|
if(work->speed > 0) {
|
|
work->paused = 1;
|
|
work->color.a = work->max_alpha;
|
|
} else {
|
|
work->kill = 1;
|
|
}
|
|
}
|
|
|
|
static void DrawFilter(ModelData *model, Mtx matrix)
|
|
{
|
|
static GXColor colorN = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
Mtx44 proj;
|
|
Mtx modelview;
|
|
|
|
float x1, x2, y1, y2;
|
|
FilterWork *work;
|
|
if(!filterObj) {
|
|
return;
|
|
}
|
|
work = OM_GET_WORK_PTR(filterObj, FilterWork);
|
|
x1 = 0.0f;
|
|
x2 = 640.0f;
|
|
y1 = 0.0f;
|
|
y2 = 480.0f;
|
|
MTXOrtho(proj, y1, y2, x1, x2, 0, 10);
|
|
GXSetProjection(proj, GX_ORTHOGRAPHIC);
|
|
MTXIdentity(modelview);
|
|
GXLoadPosMtxImm(modelview, GX_PNMTX0);
|
|
GXSetCurrentMtx(GX_PNMTX0);
|
|
GXSetViewport(0, 0, x2, 1.0f+y2, 0, 1);
|
|
GXSetScissor(0, 0, x2, 1.0f+y2);
|
|
GXClearVtxDesc();
|
|
GXSetChanMatColor(GX_COLOR0A0, work->color);
|
|
GXSetNumChans(1);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE);
|
|
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
|
GXSetNumTexGens(0);
|
|
GXSetNumTevStages(1);
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_U16, 0);
|
|
GXSetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE);
|
|
GXSetAlphaUpdate(GX_FALSE);
|
|
GXSetColorUpdate(GX_TRUE);
|
|
GXSetAlphaCompare(GX_GEQUAL, 1, GX_AOP_AND, GX_GEQUAL, 1);
|
|
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GXPosition2u16(x1, y1);
|
|
GXPosition2u16(x2, y1);
|
|
GXPosition2u16(x2, y2);
|
|
GXPosition2u16(x1, y2);
|
|
GXEnd();
|
|
GXSetChanMatColor(GX_COLOR0A0, colorN);
|
|
|
|
}
|
|
|
|
typedef struct confetti_particle {
|
|
s16 time;
|
|
u8 alpha;
|
|
u8 light_col;
|
|
Vec pos;
|
|
Vec rot;
|
|
Vec pos_vel;
|
|
Vec rot_vel;
|
|
} ConfettiParticle;
|
|
|
|
typedef struct confetti_work {
|
|
struct {
|
|
u8 kill : 1;
|
|
u8 paused : 1;
|
|
};
|
|
s8 spawn_speed;
|
|
s8 time;
|
|
s8 delay;
|
|
s16 count;
|
|
s16 gfx_mdl;
|
|
s16 draw_mdl;
|
|
ConfettiParticle *data;
|
|
} ConfettiWork;
|
|
|
|
static void UpdateConfetti(omObjData *object);
|
|
static void SpawnConfetti(omObjData *object);
|
|
static void MoveConfetti(omObjData *object);
|
|
static void DrawConfetti(ModelData *model, Mtx matrix);
|
|
|
|
|
|
void BoardConfettiCreate(Vec *pos, s16 count, float range)
|
|
{
|
|
omObjData *object;
|
|
ConfettiWork *work;
|
|
if(confettiObj) {
|
|
BoardConfettiStop();
|
|
HuPrcSleep(17);
|
|
}
|
|
object = omAddObjEx(boardObjMan, 257, 0, 0, -1, UpdateConfetti);
|
|
confettiObj = object;
|
|
work = OM_GET_WORK_PTR(object, ConfettiWork);
|
|
work->kill = 0;
|
|
work->paused = 0;
|
|
work->count = count;
|
|
work->spawn_speed = 1;
|
|
work->time = 0;
|
|
work->delay = 10;
|
|
work->draw_mdl = Hu3DHookFuncCreate(DrawConfetti);
|
|
work->data = HuMemDirectMallocNum(HEAP_SYSTEM, work->count*sizeof(ConfettiParticle), MEMORY_DEFAULT_NUM);
|
|
object->trans.x = pos->x;
|
|
object->trans.y = pos->y;
|
|
object->trans.z = pos->z;
|
|
object->rot.x = range;
|
|
work->gfx_mdl = BoardModelCreate(DATA_MAKE_NUM(DATADIR_BOARD, 7), NULL, 0);
|
|
BoardModelLayerSet(work->gfx_mdl, 2);
|
|
BoardModelVisibilitySet(work->gfx_mdl, 0);
|
|
{
|
|
ConfettiParticle *particle;
|
|
s32 i;
|
|
particle = work->data;
|
|
for(i=0; i<work->count; i++, particle++) {
|
|
particle->time = -1;
|
|
}
|
|
}
|
|
HuAudFXPlay(774);
|
|
}
|
|
|
|
void BoardConfettiKill(void)
|
|
{
|
|
if(confettiObj) {
|
|
OM_GET_WORK_PTR(confettiObj, ConfettiWork)->kill = 1;
|
|
}
|
|
}
|
|
|
|
void BoardConfettiStop(void)
|
|
{
|
|
if(confettiObj) {
|
|
s32 i;
|
|
ConfettiParticle *particle;
|
|
ConfettiWork *work = OM_GET_WORK_PTR(confettiObj, ConfettiWork);
|
|
work->paused = 1;
|
|
particle = work->data;
|
|
for(i=0; i<work->count; i++, particle++) {
|
|
if(particle->time != -1) {
|
|
if(particle->time > 16) {
|
|
particle->time = 16;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void UpdateConfetti(omObjData *object)
|
|
{
|
|
ConfettiWork *work = OM_GET_WORK_PTR(object, ConfettiWork);
|
|
if(work->kill || BoardIsKill()) {
|
|
BoardModelKill(work->gfx_mdl);
|
|
Hu3DModelKill(work->draw_mdl);
|
|
HuMemDirectFree(work->data);
|
|
confettiObj = NULL;
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
} else {
|
|
SpawnConfetti(object);
|
|
MoveConfetti(object);
|
|
}
|
|
}
|
|
|
|
static void SpawnConfetti(omObjData *object)
|
|
{
|
|
ConfettiWork *work = OM_GET_WORK_PTR(object, ConfettiWork);
|
|
int i;
|
|
if(work->paused) {
|
|
return;
|
|
}
|
|
if(work->spawn_speed < 5) {
|
|
if(work->time++ > work->delay) {
|
|
work->time = 0;
|
|
work->spawn_speed++;
|
|
}
|
|
}
|
|
for(i=0; i<work->spawn_speed; i++) {
|
|
ConfettiParticle *particle;
|
|
float angle;
|
|
int j;
|
|
particle = work->data;
|
|
for(j=0; j<work->count; j++, particle++) {
|
|
if(particle->time == -1) {
|
|
break;
|
|
}
|
|
}
|
|
if(j == work->count) {
|
|
break;
|
|
}
|
|
particle->time = BoardRandMod(60)+120;
|
|
angle = BoardRandFloat()*360.0f;
|
|
particle->pos.x = (sin((angle*M_PI)/180.0)*object->rot.x)+object->trans.x;
|
|
particle->pos.y = object->trans.y;
|
|
particle->pos.z = (cos((angle*M_PI)/180.0)*object->rot.x)+object->trans.z;
|
|
particle->pos_vel.x = 2.0f*(BoardRandFloat()-0.5f);
|
|
particle->pos_vel.y = (-98.00001f/15.0f)*BoardRandFloat();
|
|
particle->pos_vel.z = 2.0f*(BoardRandFloat()-0.5f);
|
|
particle->rot_vel.x = 8.0f+((BoardRandFloat()-0.5f)*20.0f);
|
|
particle->rot_vel.y = 8.0f+((BoardRandFloat()-0.5f)*20.0f);
|
|
particle->rot_vel.z = 8.0f+((BoardRandFloat()-0.5f)*20.0f);
|
|
particle->rot.x = 0;
|
|
particle->rot.y = 0;
|
|
particle->rot.z = 0;
|
|
particle->alpha = 255;
|
|
particle->light_col = BoardRandMod(6);
|
|
}
|
|
}
|
|
|
|
static void MoveConfetti(omObjData *object)
|
|
{
|
|
ConfettiWork *work = OM_GET_WORK_PTR(object, ConfettiWork);
|
|
int i;
|
|
int existF;
|
|
ConfettiParticle *particle;
|
|
|
|
existF = 0;
|
|
particle = work->data;
|
|
|
|
for(i=0; i<work->count; i++, particle++) {
|
|
if(particle->time == -1) {
|
|
continue;
|
|
}
|
|
if(particle->time <= 0) {
|
|
particle->time = -1;
|
|
continue;
|
|
}
|
|
particle->time--;
|
|
particle->pos.x += particle->pos_vel.x;
|
|
particle->pos.y += particle->pos_vel.y;
|
|
particle->pos.z += particle->pos_vel.z;
|
|
particle->rot.x += particle->rot_vel.x;
|
|
particle->rot.y += particle->rot_vel.y;
|
|
particle->rot.z += particle->rot_vel.z;
|
|
if(particle->time < 16) {
|
|
if(particle->alpha >= 15) {
|
|
particle->alpha -= 15;
|
|
} else {
|
|
particle->alpha = 0;
|
|
}
|
|
}
|
|
if(!existF) {
|
|
existF = 1;
|
|
}
|
|
}
|
|
if(existF == 0 && work->paused) {
|
|
work->kill = 1;
|
|
}
|
|
}
|
|
|
|
static Vec confettiLightTbl[6] = {
|
|
{ 0.1, 0.4, 1 },
|
|
{ 0.2, 1, 0.1 },
|
|
{ 0.3, 1, 1 },
|
|
{ 1, 0.2, 0.1 },
|
|
{ 1, 0.2, 0.8 },
|
|
{ 1, 8, 0.3 }
|
|
};
|
|
|
|
static void DrawConfetti(ModelData *model, Mtx matrix)
|
|
{
|
|
if(!confettiObj || BoardIsKill()) {
|
|
return;
|
|
} else {
|
|
ConfettiWork *work = OM_GET_WORK_PTR(confettiObj, ConfettiWork);
|
|
ModelData *model = &Hu3DData[work->gfx_mdl];
|
|
ConfettiParticle *particle;
|
|
int i;
|
|
if(!model->hsfData) {
|
|
return;
|
|
}
|
|
particle = work->data;
|
|
for(i=0; i<work->count; i++, particle++) {
|
|
Mtx result, temp;
|
|
float r, g, b, a;
|
|
if(particle->time == -1) {
|
|
continue;
|
|
}
|
|
MTXRotDeg(temp, 'z', particle->rot.z);
|
|
MTXRotDeg(result, 'x', particle->rot.x);
|
|
MTXConcat(temp, result, result);
|
|
MTXRotDeg(temp, 'y', particle->rot.y);
|
|
MTXConcat(temp, result, result);
|
|
MTXTrans(temp, particle->pos.x, particle->pos.y, particle->pos.z);
|
|
MTXConcat(temp, result, result);
|
|
MTXConcat(matrix, result, result);
|
|
r = confettiLightTbl[particle->light_col].x;
|
|
g = confettiLightTbl[particle->light_col].y;
|
|
b = confettiLightTbl[particle->light_col].z;
|
|
OSu8tof32(&particle->alpha, &a);
|
|
a = a*(1.0f/255.0f);
|
|
Hu3DModelTPLvlSet(BoardModelIDGet(work->gfx_mdl), a);
|
|
Hu3DModelAmbSet(BoardModelIDGet(work->gfx_mdl), r, g, b);
|
|
Hu3DModelObjDraw(BoardModelIDGet(work->gfx_mdl), "grid2", result);
|
|
}
|
|
}
|
|
}
|
|
|
|
typedef struct last5_gfx_work {
|
|
struct {
|
|
u8 kill : 1;
|
|
u8 state : 3;
|
|
u8 is_last : 1;
|
|
u8 : 4;
|
|
};
|
|
u8 stop_time;
|
|
s16 time;
|
|
s16 group;
|
|
s16 sprites[3];
|
|
} Last5GfxWork;
|
|
|
|
static s32 last5GfxSprTbl[3] = {
|
|
DATA_MAKE_NUM(DATADIR_BOARD, 95),
|
|
DATA_MAKE_NUM(DATADIR_BOARD, 97),
|
|
DATA_MAKE_NUM(DATADIR_BOARD, 96),
|
|
};
|
|
|
|
static float last5GfxPosTbl[2][3][2] = {
|
|
{
|
|
{ -80, 0 },
|
|
{ 0, 0 },
|
|
{ 80, 0 }
|
|
},
|
|
{
|
|
{ -52, 0 },
|
|
{ 0, 0 },
|
|
{ 52, 0 }
|
|
}
|
|
};
|
|
|
|
static void UpdateLast5Gfx(omObjData *object);
|
|
|
|
void BoardLast5GfxInit(void)
|
|
{
|
|
Last5GfxWork *work;
|
|
omObjData *object;
|
|
s32 turn_remain;
|
|
s32 lastF;
|
|
turn_remain = GWSystem.max_turn-GWSystem.turn;
|
|
if(turn_remain > 4 || turn_remain < 0) {
|
|
return;
|
|
} else {
|
|
s32 i;
|
|
turn_remain = 4-turn_remain;
|
|
object = omAddObjEx(boardObjMan, 0, 0, 0, -1, UpdateLast5Gfx);
|
|
last5GfxObj = object;
|
|
work = OM_GET_WORK_PTR(object, Last5GfxWork);
|
|
work->kill = 0;
|
|
work->stop_time = 0;
|
|
work->time = 0;
|
|
work->group = HuSprGrpCreate(3);
|
|
if((s32)(GWSystem.max_turn-GWSystem.turn) == 0) {
|
|
work->is_last = 1;
|
|
lastF = 1;
|
|
} else {
|
|
work->is_last = 0;
|
|
lastF = 0;
|
|
}
|
|
for(i=0; i<3; i++) {
|
|
s32 prio;
|
|
s32 spr_file;
|
|
|
|
if(i == 1) {
|
|
prio = 1000;
|
|
} else {
|
|
prio = 1400;
|
|
}
|
|
spr_file = last5GfxSprTbl[i];
|
|
if(i == 2 && work->is_last && GWLanguageGet() != 0) {
|
|
spr_file = DATA_MAKE_NUM(DATADIR_BOARD, 98);
|
|
}
|
|
BoardSpriteCreate(spr_file, prio, NULL, &work->sprites[i]);
|
|
HuSprGrpMemberSet(work->group, i, work->sprites[i]);
|
|
HuSprAttrSet(work->group, i, HUSPR_ATTR_LINEAR);
|
|
HuSprPosSet(work->group, i, last5GfxPosTbl[lastF][i][0], last5GfxPosTbl[lastF][i][1]);
|
|
}
|
|
if(!work->is_last) {
|
|
HuSprite *sprite = &HuSprData[HuSprGrpData[work->group].members[1]];
|
|
HuSprBankSet(work->group, 1, 0);
|
|
sprite->frame = turn_remain;
|
|
} else {
|
|
HuSprAttrSet(work->group, 1, HUSPR_ATTR_DISPOFF);
|
|
}
|
|
HuSprAttrSet(work->group, 1, HUSPR_ATTR_NOANIM);
|
|
object->trans.x = 0.0f;
|
|
HuSprGrpTPLvlSet(work->group, object->trans.x);
|
|
HuSprGrpPosSet(work->group, 288, 72);
|
|
HuAudFXPlay(838);
|
|
work->time = 0;
|
|
}
|
|
}
|
|
|
|
static void UpdateLast5Gfx(omObjData *object)
|
|
{
|
|
Last5GfxWork *work = OM_GET_WORK_PTR(object, Last5GfxWork);
|
|
if(work->kill || BoardIsKill()) {
|
|
HuSprGrpKill(work->group);
|
|
last5GfxObj = NULL;
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
return;
|
|
}
|
|
if(work->stop_time != 0) {
|
|
work->stop_time--;
|
|
return;
|
|
}
|
|
switch(work->state) {
|
|
case 0:
|
|
object->trans.x += 1.0f/30.0f;
|
|
if(object->trans.x > 1.0f) {
|
|
object->trans.x = 1.0f;
|
|
work->state = 1;
|
|
}
|
|
HuSprGrpTPLvlSet(work->group, object->trans.x);
|
|
break;
|
|
|
|
case 1:
|
|
if(work->time >= 720) {
|
|
work->state = 2;
|
|
work->stop_time = 90;
|
|
if(work->is_last) {
|
|
HuSprGrpScaleSet(work->group, 1.0f, 1.0f);
|
|
} else {
|
|
HuSprScaleSet(work->group, 1, 1.0f, 1.0f);
|
|
}
|
|
} else {
|
|
s16 angle;
|
|
angle = work->time%180;
|
|
OSs16tof32(&angle, &object->trans.y);
|
|
object->trans.y = sin((object->trans.y*M_PI)/180.0)+0.5;
|
|
if(work->is_last) {
|
|
HuSprGrpScaleSet(work->group, object->trans.y, object->trans.y);
|
|
} else {
|
|
HuSprScaleSet(work->group, 1, object->trans.y, object->trans.y);
|
|
}
|
|
work->time += 9;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
object->trans.x -= 1.0f/30.0f;
|
|
if(object->trans.x < 0.0f) {
|
|
object->trans.x = 0.0f;
|
|
work->kill = 1;
|
|
}
|
|
HuSprGrpTPLvlSet(work->group, object->trans.x);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BoardLast5GfxShowSet(s32 show)
|
|
{
|
|
s32 i;
|
|
Last5GfxWork *work;
|
|
if(!last5GfxObj) {
|
|
return;
|
|
}
|
|
|
|
work = OM_GET_WORK_PTR(last5GfxObj, Last5GfxWork);
|
|
for(i=0; i<3; i++) {
|
|
if(show) {
|
|
HuSprAttrReset(work->group, i, HUSPR_ATTR_DISPOFF);
|
|
} else {
|
|
HuSprAttrSet(work->group, i, HUSPR_ATTR_DISPOFF);
|
|
}
|
|
if(work->is_last) {
|
|
HuSprAttrSet(work->group, 1, HUSPR_ATTR_DISPOFF);
|
|
}
|
|
}
|
|
}
|
|
|
|
static s32 tauntActiveFXTbl[4] = { -1, -1, -1, -1 };
|
|
static s32 tauntFXTbl[8] = {
|
|
294,
|
|
358,
|
|
422,
|
|
486,
|
|
550,
|
|
614,
|
|
678,
|
|
742
|
|
};
|
|
|
|
typedef struct taunt_work {
|
|
u8 kill : 1;
|
|
} TauntWork;
|
|
|
|
static void TauntUpdate(omObjData *object);
|
|
|
|
void BoardTauntInit(void)
|
|
{
|
|
int i;
|
|
tauntObj = omAddObjEx(boardObjMan, 32258, 0, 0, -1, TauntUpdate);
|
|
for(i=0; i<4; i++) {
|
|
tauntActiveFXTbl[i] = -1;
|
|
}
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
}
|
|
|
|
void BoardTauntKill(void)
|
|
{
|
|
TauntWork *work;
|
|
if(!tauntObj) {
|
|
return;
|
|
}
|
|
work = OM_GET_WORK_PTR(tauntObj, TauntWork);
|
|
work->kill = 1;
|
|
_SetFlag(FLAG_ID_MAKE(1, 14));
|
|
}
|
|
|
|
static void TauntUpdate(omObjData *object)
|
|
{
|
|
int i;
|
|
s32 port;
|
|
s32 character;
|
|
TauntWork *work;
|
|
work = OM_GET_WORK_PTR(object, TauntWork);
|
|
if(work->kill || BoardIsKill()) {
|
|
for(i=0; i<4; i++) {
|
|
if(tauntActiveFXTbl[i] >= 0) {
|
|
HuAudFXStop(tauntActiveFXTbl[i]);
|
|
tauntActiveFXTbl[i] = -1;
|
|
}
|
|
}
|
|
tauntObj = NULL;
|
|
omDelObjEx(HuPrcCurrentGet(), object);
|
|
return;
|
|
}
|
|
for(i=0; i<4; i++) {
|
|
if(tauntActiveFXTbl[i] >= 0 && HuAudFXStatusGet(tauntActiveFXTbl[i]) == 0) {
|
|
tauntActiveFXTbl[i] = -1;
|
|
}
|
|
}
|
|
if(BoardPauseActiveCheck()) {
|
|
return;
|
|
}
|
|
if(_CheckFlag(FLAG_ID_MAKE(1, 14))) {
|
|
return;
|
|
}
|
|
if(WipeStatGet() != 0) {
|
|
return;
|
|
}
|
|
if(GWSystem.player_curr == -1) {
|
|
return;
|
|
}
|
|
for(i=0; i<4; i++) {
|
|
|
|
if(i == GWSystem.player_curr || GWPlayer[i].com) {
|
|
continue;
|
|
}
|
|
port = GWPlayer[i].port & 0x3;
|
|
character = GWPlayer[i].character & 0x7;
|
|
if(tauntActiveFXTbl[port] >= 0) {
|
|
UnkMsmStruct_01 param;
|
|
float vol, pan;
|
|
vol = (64.0f*(HuPadSubStkX[port]/59.0f))+64.0f;
|
|
pan = 8191.0f*(HuPadSubStkY[port]/59.0f);
|
|
memset(¶m, 0, sizeof(UnkMsmStruct_01));
|
|
param.unk00 = 6;
|
|
OSf32tos8(&vol, ¶m.unk05);
|
|
OSf32tos16(&pan, ¶m.unk06);
|
|
msmSeSetParam(tauntActiveFXTbl[port], ¶m);
|
|
} else {
|
|
if(HuPadBtnDown[port] & PAD_TRIGGER_L) {
|
|
tauntActiveFXTbl[port] = HuAudFXPlay(tauntFXTbl[character]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 BoardDataDirReadAsync(s32 data_num)
|
|
{
|
|
s32 status = HuDataDirReadAsync(data_num);
|
|
return status;
|
|
}
|
|
|
|
void BoardDataAsyncWait(s32 status)
|
|
{
|
|
if(status == -1) {
|
|
return;
|
|
}
|
|
while(!HuDataGetAsyncStat(status)) {
|
|
HuPrcVSleep();
|
|
}
|
|
} |