mirror of https://github.com/pmret/papermario.git
535 lines
16 KiB
C
535 lines
16 KiB
C
#include "common.h"
|
|
|
|
s32 D_8014C260[] = { 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFF00 };
|
|
|
|
s32 D_8014C270[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
|
|
|
extern EntityModelList gWorldEntityModelList;
|
|
extern EntityModelList gBattleEntityModelList;
|
|
extern EntityModelList* gCurrentEntityModelList;
|
|
extern s32 gEntityModelCount;
|
|
extern s32 entity_fog_enabled;
|
|
extern s32 entity_fog_red;
|
|
extern s32 entity_fog_green;
|
|
extern s32 entity_fog_blue;
|
|
extern s32 entity_fog_alpha;
|
|
extern s32 entity_fog_dist_min;
|
|
extern s32 entity_fog_dist_max;
|
|
|
|
s32 step_entity_model_commandlist(EntityModel* entityModel);
|
|
void free_entity_model_by_ref(EntityModel* entityModel);
|
|
|
|
void clear_entity_models(void) {
|
|
s32 i;
|
|
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentEntityModelList = &gWorldEntityModelList;
|
|
} else {
|
|
gCurrentEntityModelList = &gBattleEntityModelList;
|
|
}
|
|
|
|
for (i = 0; i < MAX_ENTITY_MODELS; i++) {
|
|
(*gCurrentEntityModelList)[i] = NULL;
|
|
}
|
|
|
|
entity_fog_red = 10;
|
|
entity_fog_green = 10;
|
|
entity_fog_blue = 10;
|
|
entity_fog_alpha = 10;
|
|
entity_fog_dist_min = 800;
|
|
gEntityModelCount = 0;
|
|
entity_fog_enabled = 0;
|
|
entity_fog_dist_max = 1000;
|
|
}
|
|
|
|
void init_entity_models(void) {
|
|
s32 i;
|
|
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentEntityModelList = &gWorldEntityModelList;
|
|
} else {
|
|
gCurrentEntityModelList = &gBattleEntityModelList;
|
|
}
|
|
|
|
entity_fog_red = 10;
|
|
entity_fog_green = 10;
|
|
entity_fog_blue = 10;
|
|
entity_fog_alpha = 10;
|
|
entity_fog_dist_min = 800;
|
|
gEntityModelCount = 0;
|
|
entity_fog_enabled = 0;
|
|
entity_fog_dist_max = 1000;
|
|
}
|
|
|
|
s32 load_entity_model(s32* cmdList) {
|
|
EntityModel* newEntityModel;
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_ENTITY_MODELS; i++) {
|
|
if ((*gCurrentEntityModelList)[i] == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_ENTITY_MODELS);
|
|
|
|
{
|
|
s32* entityModelCount;
|
|
(*gCurrentEntityModelList)[i] = newEntityModel = heap_malloc(sizeof(EntityModel));
|
|
entityModelCount = &gEntityModelCount;
|
|
(*entityModelCount)++;
|
|
}
|
|
ASSERT(newEntityModel != NULL);
|
|
|
|
newEntityModel->flags = (ENTITY_MODEL_FLAGS_1 | ENTITY_MODEL_FLAGS_2 | ENTITY_MODEL_FLAGS_4 | ENTITY_MODEL_FLAGS_10);
|
|
newEntityModel->renderMode = 1;
|
|
newEntityModel->displayList = NULL;
|
|
newEntityModel->cmdListReadPos = cmdList;
|
|
newEntityModel->nextFrameTime = 1.0f;
|
|
newEntityModel->timeScale = 1.0f;
|
|
if (cmdList == NULL) {
|
|
newEntityModel->cmdListReadPos = D_8014C260;
|
|
}
|
|
newEntityModel->vertexArray = NULL;
|
|
newEntityModel->fpSetupGfxCallback = NULL;
|
|
newEntityModel->cmdListSavedPos = newEntityModel->cmdListReadPos;
|
|
|
|
if (gGameStatusPtr->isBattle) {
|
|
i |= BATTLE_ENTITY_ID_MASK;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
s32 ALT_load_entity_model(s32* cmdList) {
|
|
EntityModel* newEntityModel;
|
|
Gfx* newDisplayList;
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_ENTITY_MODELS; i++) {
|
|
if ((*gCurrentEntityModelList)[i] == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_ENTITY_MODELS);
|
|
|
|
{
|
|
s32* entityModelCount;
|
|
(*gCurrentEntityModelList)[i] = newEntityModel = heap_malloc(sizeof(EntityModel));
|
|
entityModelCount = &gEntityModelCount;
|
|
(*entityModelCount)++;
|
|
}
|
|
|
|
ASSERT(newEntityModel != NULL);
|
|
|
|
newEntityModel->displayList = newDisplayList = heap_malloc(sizeof(Gfx) * 2);
|
|
ASSERT(newDisplayList != NULL);
|
|
|
|
newEntityModel->flags = (ENTITY_MODEL_FLAGS_1 | ENTITY_MODEL_FLAGS_2 | ENTITY_MODEL_FLAGS_4 | ENTITY_MODEL_FLAGS_10 | ENTITY_MODEL_FLAGS_400);
|
|
newEntityModel->renderMode = 1;
|
|
newEntityModel->cmdListReadPos = cmdList;
|
|
newEntityModel->nextFrameTime = 1.0f;
|
|
newEntityModel->timeScale = 1.0f;
|
|
if (cmdList == NULL) {
|
|
newEntityModel->cmdListReadPos = D_8014C260;
|
|
}
|
|
newEntityModel->vertexArray = NULL;
|
|
newEntityModel->fpSetupGfxCallback = NULL;
|
|
newEntityModel->cmdListSavedPos = newEntityModel->cmdListReadPos;
|
|
|
|
if (gGameStatusPtr->isBattle) {
|
|
i |= BATTLE_ENTITY_ID_MASK;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void exec_entity_model_commandlist(s32 idx) {
|
|
EntityModel* entityModel;
|
|
void* temp_v0_2;
|
|
|
|
if (!gGameStatusPtr->isBattle || (idx & BATTLE_ENTITY_ID_MASK)) {
|
|
idx &= ~BATTLE_ENTITY_ID_MASK;
|
|
entityModel = (*gCurrentEntityModelList)[idx];
|
|
if (entityModel != NULL && (entityModel->flags)) {
|
|
if (!(entityModel->flags & ENTITY_MODEL_FLAGS_20)) {
|
|
if (!(entityModel->flags & ENTITY_MODEL_FLAGS_20000)) {
|
|
entityModel->flags &= ~ENTITY_MODEL_FLAGS_100;
|
|
entityModel->nextFrameTime -= entityModel->timeScale;
|
|
if (entityModel->nextFrameTime <= 0.0f) {
|
|
while (step_entity_model_commandlist(entityModel));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 step_entity_model_commandlist(EntityModel* entityModel) {
|
|
Gfx* displayList;
|
|
|
|
u32* curPos = entityModel->cmdListReadPos;
|
|
switch (*curPos++) {
|
|
case 0: // kill model
|
|
free_entity_model_by_ref(entityModel);
|
|
return 1;
|
|
case 1: // set display list ptr
|
|
entityModel->nextFrameTime = (f32) *curPos++;
|
|
entityModel->displayList = (Gfx*) *curPos++;
|
|
entityModel->cmdListReadPos = curPos;
|
|
break;
|
|
case 2: // restore saved position
|
|
entityModel->cmdListReadPos = entityModel->cmdListSavedPos;
|
|
return 1;
|
|
case 3: // set saved position
|
|
entityModel->cmdListReadPos = entityModel->cmdListSavedPos = curPos;
|
|
return 1;
|
|
case 4: // set render mode
|
|
entityModel->renderMode = *curPos++;
|
|
entityModel->cmdListReadPos = curPos;
|
|
return 1;
|
|
case 5: // set flags
|
|
entityModel->flags |= *curPos++;
|
|
entityModel->cmdListReadPos = curPos;
|
|
return 1;
|
|
case 6: // clear flags
|
|
entityModel->flags &= ~*curPos++;
|
|
entityModel->cmdListReadPos = curPos;
|
|
return 1;
|
|
case 7: // populate display list
|
|
displayList = entityModel->displayList;
|
|
entityModel->nextFrameTime = *curPos++;
|
|
displayList[0].words.w0 = *curPos++;
|
|
displayList[0].words.w1 = *curPos++;
|
|
displayList[1].words.w0 = *curPos++;
|
|
displayList[1].words.w1 = *curPos++;
|
|
entityModel->cmdListReadPos = curPos;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void make_entity_model_mtx_flipZ(Matrix4f mtx) {
|
|
guMtxIdentF(mtx);
|
|
mtx[0][0] = 1.0f;
|
|
mtx[1][1] = 1.0f;
|
|
mtx[2][2] = -1.0f;
|
|
mtx[3][3] = 1.0f;
|
|
}
|
|
|
|
INCLUDE_ASM(s32, "entity", appendGfx_entity_model);
|
|
|
|
INCLUDE_ASM(s32, "entity", draw_entity_model_A);
|
|
|
|
INCLUDE_ASM(s32, "entity", draw_entity_model_B);
|
|
|
|
INCLUDE_ASM(s32, "entity", draw_entity_model_C);
|
|
|
|
INCLUDE_ASM(s32, "entity", draw_entity_model_D);
|
|
|
|
INCLUDE_ASM(s32, "entity", draw_entity_model_E);
|
|
|
|
void set_entity_model_render_command_list(s32 idx, u32* commandList) {
|
|
u32* phi_a1;
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
phi_a1 = commandList;
|
|
if (commandList == NULL) {
|
|
phi_a1 = D_8014C260;
|
|
}
|
|
entityModel->cmdListReadPos = phi_a1;
|
|
entityModel->cmdListSavedPos = phi_a1;
|
|
entityModel->nextFrameTime = 1.0f;
|
|
entityModel->timeScale = 1.0f;
|
|
}
|
|
}
|
|
|
|
EntityModel* get_entity_model(s32 listIndex) {
|
|
return (*gCurrentEntityModelList)[listIndex & ~BATTLE_ENTITY_ID_MASK];
|
|
}
|
|
|
|
void free_entity_model_by_index(s32 idx) {
|
|
s32 index = idx & ~BATTLE_ENTITY_ID_MASK;
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[index];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
if (entityModel->flags & ENTITY_MODEL_FLAGS_400) {
|
|
heap_free(entityModel->displayList);
|
|
}
|
|
{
|
|
s32* modelCount = &gEntityModelCount;
|
|
heap_free((*gCurrentEntityModelList)[index]);
|
|
(*gCurrentEntityModelList)[index] = NULL;
|
|
(*modelCount)--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void free_entity_model_by_ref(EntityModel* entityModel) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_ENTITY_MODELS; i++) {
|
|
if ((*gCurrentEntityModelList)[i] == entityModel) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < MAX_ENTITY_MODELS) {
|
|
free_entity_model_by_index(i);
|
|
}
|
|
}
|
|
|
|
void set_entity_model_flags(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
entityModel->flags |= newFlags;
|
|
}
|
|
}
|
|
|
|
void clear_entity_model_flags(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
entityModel->flags &= ~newFlags;
|
|
}
|
|
}
|
|
|
|
void bind_entity_model_setupGfx(s32 idx, s32 setupGfxCallbackArg0, UNK_FUN_PTR(fpSetupGfxCallback)) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
entityModel->fpSetupGfxCallback = fpSetupGfxCallback;
|
|
entityModel->setupGfxCallbackArg0 = setupGfxCallbackArg0;
|
|
}
|
|
|
|
void func_80122F8C(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
entityModel->flags |= newFlags;
|
|
}
|
|
|
|
void func_80122FB8(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
|
|
entityModel->flags = (entityModel->flags & ~(ENTITY_MODEL_FLAGS_1 | ENTITY_MODEL_FLAGS_2 | ENTITY_MODEL_FLAGS_4 | ENTITY_MODEL_FLAGS_8)) | newFlags;
|
|
}
|
|
|
|
void enable_entity_fog(void) {
|
|
entity_fog_enabled = 1;
|
|
}
|
|
|
|
void disable_entity_fog(void) {
|
|
entity_fog_enabled = 0;
|
|
}
|
|
|
|
void set_entity_fog_dist(s32 min, s32 max) {
|
|
entity_fog_dist_min = min;
|
|
entity_fog_dist_max = max;
|
|
}
|
|
|
|
void set_entity_fog_color(s32 r, s32 g, s32 b, s32 a) {
|
|
entity_fog_red = r;
|
|
entity_fog_green = g;
|
|
entity_fog_blue = b;
|
|
entity_fog_alpha = a;
|
|
}
|
|
|
|
s32 is_entity_fog_enabled(void) {
|
|
return entity_fog_enabled;
|
|
}
|
|
|
|
void get_entity_fog_distance(s32* start, s32* end) {
|
|
*start = entity_fog_dist_min;
|
|
*end = entity_fog_dist_max;
|
|
}
|
|
|
|
void get_entity_fog_color(s32* r, s32* g, s32* b, s32* a) {
|
|
*r = entity_fog_red;
|
|
*g = entity_fog_green;
|
|
*b = entity_fog_blue;
|
|
*a = entity_fog_alpha;
|
|
}
|
|
|
|
void stub_generic_entity_delegate(void) {
|
|
}
|
|
|
|
void clear_generic_entity_list(void) {
|
|
s32 i;
|
|
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentDynamicEntityListPtr = &gWorldDynamicEntityList;
|
|
} else {
|
|
gCurrentDynamicEntityListPtr = &gBattleDynamicEntityList;
|
|
}
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
(*gCurrentDynamicEntityListPtr)[i] = NULL;
|
|
}
|
|
}
|
|
|
|
void init_generic_entity_list(void) {
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentDynamicEntityListPtr = &gWorldDynamicEntityList;
|
|
} else {
|
|
gCurrentDynamicEntityListPtr = &gBattleDynamicEntityList;
|
|
}
|
|
}
|
|
|
|
s32 create_generic_entity_world(void (*updateFunc)(Evt*, s32), void (*drawFunc)(Evt*, s32)) {
|
|
s32 i;
|
|
DynamicEntity* newDynEntity;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* dynEntity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (dynEntity == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_DYNAMIC_ENTITIES);
|
|
|
|
(*gCurrentDynamicEntityListPtr)[i] = newDynEntity = heap_malloc(sizeof(DynamicEntity));
|
|
ASSERT(newDynEntity != NULL);
|
|
|
|
newDynEntity->flags = ENTITY_FLAGS_HIDDEN | ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1;
|
|
newDynEntity->update = updateFunc;
|
|
if (updateFunc == NULL) {
|
|
newDynEntity->update = &stub_generic_entity_delegate;
|
|
}
|
|
newDynEntity->draw = drawFunc;
|
|
if (drawFunc == NULL) {
|
|
newDynEntity->draw = &stub_generic_entity_delegate;
|
|
}
|
|
|
|
if (gGameStatusPtr->isBattle) {
|
|
i |= BATTLE_ENTITY_ID_MASK;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
s32 create_generic_entity_frontUI(void (*updateFunc)(void), void (*drawFunc)(void)) {
|
|
s32 i;
|
|
DynamicEntity* newDynEntity;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* dynEntity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (dynEntity == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_DYNAMIC_ENTITIES);
|
|
|
|
(*gCurrentDynamicEntityListPtr)[i] = newDynEntity = heap_malloc(sizeof(DynamicEntity));
|
|
ASSERT(newDynEntity != NULL);
|
|
|
|
newDynEntity->flags = ENTITY_FLAGS_HIDDEN | ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1 | ENTITY_FLAGS_HAS_DYNAMIC_SHADOW;
|
|
newDynEntity->update = updateFunc;
|
|
if (updateFunc == NULL) {
|
|
newDynEntity->update = &stub_generic_entity_delegate;
|
|
}
|
|
newDynEntity->draw = drawFunc;
|
|
if (drawFunc == NULL) {
|
|
newDynEntity->draw = &stub_generic_entity_delegate;
|
|
}
|
|
|
|
if (gGameStatusPtr->isBattle) {
|
|
i |= BATTLE_ENTITY_ID_MASK;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
s32 create_generic_entity_backUI(void (*updateFunc)(void), void (*drawFunc)(void)) {
|
|
s32 i;
|
|
DynamicEntity* newDynEntity;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* dynEntity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (dynEntity == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_DYNAMIC_ENTITIES);
|
|
|
|
(*gCurrentDynamicEntityListPtr)[i] = newDynEntity = heap_malloc(sizeof(DynamicEntity));
|
|
ASSERT(newDynEntity != NULL);
|
|
|
|
newDynEntity->flags = ENTITY_FLAGS_HIDDEN | ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1 | ENTITY_FLAGS_HAS_ANIMATED_MODEL;
|
|
newDynEntity->update = updateFunc;
|
|
if (updateFunc == NULL) {
|
|
newDynEntity->update = &stub_generic_entity_delegate;
|
|
}
|
|
newDynEntity->draw = drawFunc;
|
|
if (drawFunc == NULL) {
|
|
newDynEntity->draw = &stub_generic_entity_delegate;
|
|
}
|
|
|
|
if (gGameStatusPtr->isBattle) {
|
|
i |= BATTLE_ENTITY_ID_MASK;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void update_generic_entities(void) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* entity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (entity != NULL) {
|
|
entity->flags &= ~ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1;
|
|
entity->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
void render_generic_entities_world(void) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* entity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (entity != NULL && !(entity->flags & ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1)) {
|
|
if (!(entity->flags & ENTITY_FLAGS_HAS_DYNAMIC_SHADOW)) {
|
|
entity->draw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void render_generic_entities_frontUI(void) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* entity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (entity != NULL && !(entity->flags & ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1)) {
|
|
if (entity->flags & ENTITY_FLAGS_HAS_DYNAMIC_SHADOW) {
|
|
entity->draw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void render_generic_entities_backUI(void) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_DYNAMIC_ENTITIES; i++) {
|
|
DynamicEntity* entity = (*gCurrentDynamicEntityListPtr)[i];
|
|
if (entity != NULL && !(entity->flags & ENTITY_FLAGS_DRAW_IF_CLOSE_HIDE_MODE1)) {
|
|
if (entity->flags & ENTITY_FLAGS_HAS_ANIMATED_MODEL) {
|
|
entity->draw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void free_generic_entity(s32 idx) {
|
|
if (!gGameStatusPtr->isBattle || (idx & BATTLE_ENTITY_ID_MASK)) {
|
|
DynamicEntityList** curDynEntityList = &gCurrentDynamicEntityListPtr;
|
|
|
|
idx &= ~BATTLE_ENTITY_ID_MASK;
|
|
if ((**curDynEntityList)[idx] != NULL) {
|
|
heap_free((**curDynEntityList)[idx]);
|
|
(**curDynEntityList)[idx] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
DynamicEntity* get_generic_entity(s32 idx) {
|
|
return (*gCurrentDynamicEntityListPtr)[idx & ~BATTLE_ENTITY_ID_MASK];
|
|
}
|