#include "game/gamework_data.h" #include "game/flag.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/space.h" #include "game/board/star.h" #include "game/board/tutorial.h" #include "game/hsfman.h" #include "game/data.h" #include "game/sprite.h" #include "game/objsub.h" #include "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 = (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; iflag & 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; ilink_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; ilink_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; ilink_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; ilink_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; ilink_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) { 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((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; itype == from) { space->type = to; } } } void BoardSpaceHide(s32 value) { if(value) { Hu3DModelAttrSet(spaceDrawMdl, 1); } else { Hu3DModelAttrReset(spaceDrawMdl, 1); } } 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; itype == 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; ipos, 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; jlink_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(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(BoardCurrGet() != 7 && BoardCurrGet() != 8) { 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; } }