diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index fdc0f023..fb415df7 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -863,9 +863,9 @@ PlayEffectSound = .text:0x8004C9D4; // type:function size:0x344 scope:local CharMotionCreate = .text:0x8004CD18; // type:function size:0x1D0 CharMotionSet = .text:0x8004CEE8; // type:function size:0x88 CharMotionKill = .text:0x8004CF70; // type:function size:0x9C -CharModelKill = .text:0x8004D00C; // type:function size:0x2B8 -CharModelKillIndex = .text:0x8004D2C4; // type:function size:0x430 -CharModelKillAll = .text:0x8004D6F4; // type:function size:0x244 +CharMotionClose = .text:0x8004D00C; // type:function size:0x2B8 +CharModelDataClose = .text:0x8004D2C4; // type:function size:0x430 +CharModelKill = .text:0x8004D6F4; // type:function size:0x244 CharModelMotionSet = .text:0x8004D938; // type:function size:0x7C CharModelTexAnimSet = .text:0x8004D9B4; // type:function size:0x17C CharModelTexNameGet = .text:0x8004DB30; // type:function size:0x7C @@ -1221,20 +1221,20 @@ BoardPlayerCopyEyeMat = .text:0x8006CFFC; // type:function size:0x24C BoardPlayerCopyMat = .text:0x8006D248; // type:function size:0xC0 BoardModelInit = .text:0x8006D308; // type:function size:0xF0 BoardModelKillAll = .text:0x8006D3F8; // type:function size:0xA0 -ModelMgrObjFunc = .text:0x8006D498; // type:function size:0x70 scope:local -stubfn_8006D508 = .text:0x8006D508; // type:function size:0x4 +ModelMgrFunc = .text:0x8006D498; // type:function size:0x70 scope:local +BoardModelDummyUpdate = .text:0x8006D508; // type:function size:0x4 BoardModelVisibilityUpdate = .text:0x8006D50C; // type:function size:0xCC -BoardModelShowSetAll = .text:0x8006D5D8; // type:function size:0x90 -BoardModelPosSetAll = .text:0x8006D668; // type:function size:0x70 +BoardModelHideSetAll = .text:0x8006D5D8; // type:function size:0x90 +BoardModelAmbSetAll = .text:0x8006D668; // type:function size:0x70 BoardModelCameraSetAll = .text:0x8006D6D8; // type:function size:0x7C -BoardModelCreateInstance = .text:0x8006D754; // type:function size:0x250 +CreateInstance = .text:0x8006D754; // type:function size:0x250 scope:local BoardModelCreate = .text:0x8006D9A4; // type:function size:0x40 BoardModelCreateCharacter = .text:0x8006D9E4; // type:function size:0x44 BoardModelCreateParam = .text:0x8006DA28; // type:function size:0x168 BoardModelKill = .text:0x8006DB90; // type:function size:0x44 BoardModelIDGet = .text:0x8006DBD4; // type:function size:0x48 fn_8006DC1C = .text:0x8006DC1C; // type:function size:0x60 -BoardModelSetPass = .text:0x8006DC7C; // type:function size:0x74 +BoardModelPassSet = .text:0x8006DC7C; // type:function size:0x74 BoardModelAmbSet = .text:0x8006DCF0; // type:function size:0x68 BoardModelExistCheck = .text:0x8006DD58; // type:function size:0x48 BoardModelExistDupe = .text:0x8006DDA0; // type:function size:0x48 diff --git a/include/game/board/model.h b/include/game/board/model.h new file mode 100644 index 00000000..6b08afc8 --- /dev/null +++ b/include/game/board/model.h @@ -0,0 +1,48 @@ +#ifndef _BOARD_WARP_H +#define _BOARD_WARP_H + +#include "game/hsfman.h" +#include "game/data.h" + +typedef struct board_model_param { + s32 data_num; + struct { + u8 field04_bit0 : 2; + u8 visible : 1; + u8 link : 1; + u8 start_mot : 1; + u8 pause : 1; + }; + s16 unk6; +} BoardModelParam; + +void BoardModelInit(void); +void BoardModelKillAll(void); +void BoardModelDummyUpdate(void); +void BoardModelVisibilityUpdate(void); +void BoardModelHideSetAll(s32 flag); +void BoardModelAmbSetAll(float r, float g, float b); +void BoardModelCameraSetAll(u16 camera); +s16 BoardModelCreate(s32 data_num, s32 *mot_list, s32 link); +s16 BoardModelCreateCharacter(s32 character, s32 data_num, s32 *mot_list, s32 link); +s16 BoardModelCreateParam(BoardModelParam *param, Vec *pos, Vec *rot); +void BoardModelKill(s16 model); +s16 BoardModelIDGet(s16 model); +s32 fn_8006DC1C(s16 model, s32 arg1); +s32 BoardModelPassSet(s16 model, s32 pass); +s32 BoardModelAmbSet(s16 model, float r, float g, float b); +s32 BoardModelExistCheck(s16 model, s32 arg1); +s32 BoardModelExistDupe(s16 model, s32 arg1); +s32 fn_8006DDE8(s16 model, float arg1); +s32 BoardModelMotionStart(s16 model, s32 slot, u32 attr); +s32 BoardModelMotionSpeedSet(s16 model, float speed); +void BoardModelPosSet(s16 model, float x, float y, float z); +void BoardModelPosSetV(s16 model, Vec *pos); +void BoardModelRotSet(s16 model, float x, float y, float z); +void BoardModelRotSetV(s16 model, Vec *rot); +void BoardModelScaleSet(s16 model, float x, float y, float z); +void BoardModelScaleSetV(s16 model, Vec *scale); +void BoardModelVisibilitySet(s16 model, s32 flag); + + +#endif \ No newline at end of file diff --git a/include/game/hsfman.h b/include/game/hsfman.h index 41d26437..e860df75 100644 --- a/include/game/hsfman.h +++ b/include/game/hsfman.h @@ -3,6 +3,8 @@ #include "game/hsfanim.h" #include "game/hsfformat.h" +#include "game/memory.h" +#include "game/data.h" #define Hu3DModelCreateFile(data_id) (Hu3DModelCreate(HuDataSelHeapReadNum((data_id), MEMORY_DEFAULT_NUM, HEAP_DATA))) diff --git a/include/unsplit.h b/include/unsplit.h index fec96abf..b2315bca 100644 --- a/include/unsplit.h +++ b/include/unsplit.h @@ -6,6 +6,10 @@ void MGSeqKillAll(void); void MGSeqPracticeStart(void); -void fn_8004D6F4(s16 arg); +void CharModelClose(s16 character); +void CharModelKill(s16 character); +s16 CharModelCreate(s16 character, s16 lod); +s16 CharMotionCreate(s16 character, s32 data_num); +void CharMotionKill(s16 character, u32 motion); #endif diff --git a/src/game/board/main.c b/src/game/board/main.c index 4dfe0381..21e7885b 100644 --- a/src/game/board/main.c +++ b/src/game/board/main.c @@ -686,7 +686,7 @@ static void CreateBoard(void) BoardBooHouseCreate(); BoardCameraInit(); BoardStatusCreate(); - CharModelKillIndex(-1); + CharModelDataClose(-1); BoardPlayerInit(); if(GWSystem.last5_effect == 2) { BoardSpaceTypeForce(2, 3); diff --git a/src/game/board/model.c b/src/game/board/model.c new file mode 100644 index 00000000..6d91a28c --- /dev/null +++ b/src/game/board/model.c @@ -0,0 +1,552 @@ +#include "game/board/main.h" +#include "game/board/model.h" +#include "game/hsfman.h" +#include "game/hsfmotion.h" +#include "game/memory.h" +#include "game/object.h" +#include "unsplit.h" + +#define BOARD_MODEL_MAX 256 +#define BOARD_MOT_MAX 32 + +typedef struct board_model { + struct { + u8 visible : 1; + u8 visible_old : 1; + u8 field00_bit2 : 1; + u8 field00_bit3 : 1; + u8 field00_bit4 : 1; + }; + s8 mot_count; + s8 character; + u8 alpha; + u8 layer; + u16 camera; + s16 index; + s16 id; + s16 mot_id[BOARD_MOT_MAX]; + s16 curr_mot; + HsfData *data; + HsfData *mot_data[BOARD_MOT_MAX]; + float unk_D4; + s32 data_num; + float mot_start; + float mot_end; + Vec trans; + Vec rot; + Vec scale; +} BoardModel; + +static s16 modelDataNum; +static omObjData *modelMgrObj; +static BoardModel *modelDataList; + +static void ModelMgrFunc(omObjData *object); + +static BoardModel *SearchBoardModel(s16 id); +static void KillBoardModel(BoardModel *model); +static s32 CreateBoardModel(BoardModel *model, s32 data_num, s32 link); +static s32 CreateBoardModelMotion(BoardModel *model, s32 count, s32 *data_num); + +void BoardModelDummyUpdate(void); +void BoardModelVisibilityUpdate(void); + +typedef struct modelmgr_work { + u8 kill : 1; +} ModelMgrWork; + +void BoardModelInit(void) +{ + ModelMgrWork *work; + s32 i; + modelDataList = HuMemDirectMallocNum(HEAP_SYSTEM, BOARD_MODEL_MAX*sizeof(BoardModel), MEMORY_DEFAULT_NUM); + reflectMapNo = 0; + modelDataNum = 0; + memset(modelDataList, 0, BOARD_MODEL_MAX*sizeof(BoardModel)); + for(i=0; ikill = 0; + omSetStatBit(modelMgrObj, OM_STAT_NOPAUSE|0x80); +} + +void BoardModelKillAll(void) +{ + if(modelMgrObj) { + ModelMgrWork *work = OM_GET_WORK_PTR(modelMgrObj, ModelMgrWork); + work->kill = 1; + } + if(modelDataList) { + BoardModel *model; + for(model=modelDataList; model < &modelDataList[BOARD_MODEL_MAX]; model++) { + KillBoardModel(model); + } + if(modelDataList) { + HuMemDirectFree(modelDataList); + modelDataList = NULL; + } + + } +} + +static void ModelMgrFunc(omObjData *object) +{ + ModelMgrWork *work = OM_GET_WORK_PTR(modelMgrObj, ModelMgrWork); + if(work->kill || BoardIsKill()) { + modelMgrObj = NULL; + omDelObjEx(HuPrcCurrentGet(), object); + return; + } + BoardModelDummyUpdate(); + BoardModelVisibilityUpdate(); +} + +void BoardModelDummyUpdate(void) +{ + +} + +void BoardModelVisibilityUpdate(void) +{ + s32 i; + BoardModel *model; + u32 temp[2]; + Vec pos, target; + temp[1] = temp[0] = 0; + BoardCameraPosGet(&pos); + BoardCameraTargetGet(&target); + for(i=0, model = modelDataList; iindex == -1) { + continue; + } + attr = Hu3DModelAttrGet(model->id); + if(!model->visible) { + if(!(attr & 0x1)) { + Hu3DModelAttrSet(model->id, 1); + } + } else { + if(attr & 0x1) { + Hu3DModelAttrReset(model->id, 1); + } + } + } +} + +void BoardModelHideSetAll(s32 flag) +{ + BoardModel *model; + if(!modelDataList) { + return; + } + + for(model=modelDataList; model < &modelDataList[BOARD_MODEL_MAX]; model++) { + if(model->index == -1) { + continue; + } + if(flag) { + model->visible_old = model->visible; + model->visible = 0; + } else { + model->visible = model->visible_old; + } + } +} + +void BoardModelAmbSetAll(float r, float g, float b) +{ + BoardModel *model; + for(model=modelDataList; model < &modelDataList[BOARD_MODEL_MAX]; model++) { + if(model->index == -1) { + continue; + } + BoardModelAmbSet(model->index, r, g, b); + } +} + +void BoardModelCameraSetAll(u16 camera) +{ + BoardModel *model; + for(model=modelDataList; model < &modelDataList[BOARD_MODEL_MAX]; model++) { + if(model->index == -1) { + continue; + } + if(model->character != -1) { + continue; + } + Hu3DModelCameraSet(model->id, camera); + model->camera = camera; + } +} + +static s16 CreateInstance(s32 character, s32 data_num, s32 *mot_list, s32 link, s32 arg4) +{ + BoardModel *model; + s32 i; + model = NULL; + for(i=0; iindex = i+1; + model->character = character; + modelDataNum++; + if(CreateBoardModel(model, data_num, link) == 0) { + s32 count; + count = 0; + if(mot_list) { + for(count=0; mot_list[count] >= 0; count++); + if(count >= BOARD_MOT_MAX) { + count = BOARD_MOT_MAX; + } + } + for(i=0; imot_id[i] = -1; + } + if(CreateBoardModelMotion(model, count, mot_list) == 0) { + model->visible = 1; + model->visible_old = model->visible; + model->field00_bit2 = 0; + model->field00_bit4 = 0; + model->unk_D4 = 100.0f; + model->scale.x = model->scale.y = model->scale.z = 1.0f; + model->curr_mot = 0; + Hu3DModelCameraSet(model->id, 1); + Hu3DModelLayerSet(model->id, 0); + model->field00_bit3 = 0; + model->alpha = 255; + BoardModelPosSet(model->index, 0.0f, 0.0f, 0.0f); + BoardModelRotSet(model->index, 0.0f, 0.0f, 0.0f); + BoardModelScaleSet(model->index, 1.0f, 1.0f, 1.0f); + BoardModelAmbSet(model->index, 1.0f, 1.0f, 1.0f); + return model->index; + } + } + BoardModelKill(model->index); + return -1; +} + +s16 BoardModelCreate(s32 data_num, s32 *mot_list, s32 link) +{ + return CreateInstance(-1, data_num, mot_list, link, 0); +} + +s16 BoardModelCreateCharacter(s32 character, s32 data_num, s32 *mot_list, s32 link) +{ + return CreateInstance(character, data_num, mot_list, link, 0); +} + +s16 BoardModelCreateParam(BoardModelParam *param, Vec *pos, Vec *rot) +{ + float unk_param; + s16 model = BoardModelCreate(param->data_num, NULL, param->link); + if(model == -1) { + return -1; + } + BoardModelMotionStart(model, 0, (param->pause) ? 0x40000001 : 0); + if(!param->start_mot) { + BoardModelMotionSpeedSet(model, 0.0f); + } + BoardModelExistDupe(model, param->field04_bit0); + BoardModelVisibilitySet(model, param->visible); + if(pos) { + BoardModelPosSetV(model, pos); + } + if(rot) { + BoardModelRotSetV(model, rot); + } + OSs16tof32(¶m->unk6, &unk_param); + fn_8006DDE8(model, unk_param); + return model; +} + +void BoardModelKill(s16 model) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(model_ptr) { + KillBoardModel(model_ptr); + } +} + +s16 BoardModelIDGet(s16 model) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + return model_ptr->id; + } +} + +s32 fn_8006DC1C(s16 model, s32 arg1) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + model_ptr->field00_bit3 = arg1; + return 0; + } +} + +s32 BoardModelPassSet(s16 model, s32 pass) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + if(pass != 0) { + Hu3DModelAttrSet(model_ptr->id, 2); + } else { + Hu3DModelAttrReset(model_ptr->id, 2); + } + return 0; + } +} + +s32 BoardModelAmbSet(s16 model, float r, float g, float b) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + Hu3DModelAmbSet(model_ptr->id, r, g, b); + return 0; + } +} + +s32 BoardModelExistCheck(s16 model, s32 arg1) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + return 0; + } +} + +s32 BoardModelExistDupe(s16 model, s32 arg1) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + return 0; + } +} + +s32 fn_8006DDE8(s16 model, float arg1) +{ + BoardModel *model_ptr = SearchBoardModel(model); + if(!model_ptr) { + return -1; + } else { + if(arg1 < 0) { + arg1 = -1; + } + model_ptr->unk_D4 = arg1; + return 0; + } +} + +s32 BoardModelMotionCreate(s16 model, s32 data_num) +{ + BoardModel *model_ptr = SearchBoardModel(model); + s32 i; + if(!model_ptr) { + return -1; + } else { + s16 id; + if(model_ptr->mot_count >= BOARD_MOT_MAX) { + return -1; + } + for(i=1; imot_id[i] == -1) { + break; + } + } + if(model_ptr->character == -1) { + model_ptr->mot_data[i] = HuDataSelHeapReadNum(data_num, MEMORY_DEFAULT_NUM, HEAP_DATA); + if(!model_ptr->mot_data[i]) { + return -1; + } + model = Hu3DJointMotion(model_ptr->id, model_ptr->mot_data[i]); + } else { + model = CharMotionCreate(model_ptr->character, data_num); + CharMotionClose(model_ptr->character); + } + model_ptr->mot_id[i] = model; + model_ptr->mot_count++; + return i; + } +} + +s32 BoardModelMotionKill(s16 model, s32 motion) +{ + BoardModel *model_ptr = SearchBoardModel(model); + s32 i; + if(!model_ptr) { + return -1; + } else { + if(motion >= BOARD_MOT_MAX || motion <= 0) { + return -1; + } + if(motion == model_ptr->curr_mot && model_ptr->curr_mot != 0) { + BoardModelMotionStart(model, 0, 0); + } + if(model_ptr->mot_id[motion] > 0) { + if(model_ptr->character == -1) { + Hu3DMotionKill(model_ptr->mot_id[motion]); + } else { + CharMotionKill(model_ptr->character, model_ptr->mot_id[motion]); + } + model_ptr->mot_id[motion] = -1; + } + model_ptr->mot_data[motion] = NULL; + model_ptr->mot_count--; + return 0; + } +} + +static BoardModel *SearchBoardModel(s16 id) +{ + BoardModel *model; + if(id <= 0 || id > BOARD_MODEL_MAX || !modelDataList || BoardIsKill()) { + return NULL; + } + model = &modelDataList[id-1]; + if(model->index != id) { + return NULL; + } + return model; +} + +static void KillBoardModel(BoardModel *model) +{ + s32 i; + if(model->index == -1) { + return; + } + if(model->character == -1) { + model->mot_id[0] = -1; + if(model->id >= 0) { + Hu3DModelKill(model->id); + model->id = -1; + } + for(i=1; imot_id[i] >= 0) { + if(i != 0) { + Hu3DMotionKill(model->mot_id[i]); + } + model->mot_id[i] = -1; + } + model->mot_data[i] = NULL; + } + model->data = NULL; + model->data_num = 0; + } else { + for(i=0; imot_id[i] = -1; + model->mot_data[i] = NULL; + } + if(model->data) { + if(model->id >= 0) { + model->id = -1; + } + model->data = NULL; + } + CharModelKill(model->character); + model->character = -1; + } + modelDataNum--; + model->index = -1; + model->visible = 0; +} + +static BoardModel *FindLinkModel(s32 data_num) +{ + BoardModel *model; + for(model=modelDataList; model < &modelDataList[BOARD_MODEL_MAX]; model++) { + if(model->data_num == data_num) { + return model; + } + } + return NULL; +} + +static s32 CreateBoardModel(BoardModel *model, s32 data_num, s32 link) +{ + BoardModel *linked_mdl = NULL; + if(link && model->character == -1) { + linked_mdl = FindLinkModel(data_num); + if(linked_mdl) { + model->id = Hu3DModelLink(linked_mdl->id); + model->data = NULL; + model->data_num = 0; + return 0; + } + } + if(model->character == -1) { + model->data = HuDataSelHeapReadNum(data_num, MEMORY_DEFAULT_NUM, HEAP_DATA); + if(!model->data) { + s32 size_data, size_dvd; + size_data = HuMemHeapSizeGet(HEAP_DATA)-HuMemUsedMallocSizeGet(HEAP_DATA); + size_dvd = HuMemHeapSizeGet(HEAP_DVD)-HuMemUsedMallocSizeGet(HEAP_DVD); + return -1; + } + } else { + model->data = NULL; + } + if(model->character == -1) { + model->id = Hu3DModelCreate(model->data); + } else { + model->id = CharModelCreate(model->character, 2); + } + Hu3DModelAttrSet(model->id, 0x4000); + if(model->id < 0) { + return -1; + } else { + model->data_num = data_num; + return 0; + } +} + +static s32 CreateBoardModelMotion(BoardModel *model, s32 count, s32 *data_num) +{ + void *data; + s32 i; + model->mot_id[0] = Hu3DData[model->id].unk_08; + if(!data_num) { + model->mot_count = 1; + return 0; + } + data = NULL; + for(i=0; icharacter == -1) { + data = HuDataSelHeapReadNum(data_num[i], MEMORY_DEFAULT_NUM, HEAP_DATA); + if(!data) { + return -1; + } + index = Hu3DJointMotion(model->id, data); + } else { + index = CharMotionCreate(model->character, data_num[i]); + } + if(index < 0) { + return -1; + } + model->mot_id[i+1] = index; + model->mot_data[i+1] = data; + } + model->mot_count = count+1; + return 0; +} \ No newline at end of file diff --git a/src/game/objmain.c b/src/game/objmain.c index 195ead1a..ce30d3d7 100644 --- a/src/game/objmain.c +++ b/src/game/objmain.c @@ -142,7 +142,7 @@ void omOvlReturnEx(s16 level, s16 arg2) void omOvlKill(s16 arg) { - CharModelKillAll(-1); + CharModelKill(-1); MGSeqKillAll(); Hu3DAllKill(); HuWinAllKill();