mirror of
https://github.com/pmret/papermario.git
synced 2024-10-18 10:42:43 +02:00
1589a30e26
* leftover work * remaining API_CALLABLE --------- Co-authored-by: HailSanta <Hail2Santa@gmail.com>
828 lines
33 KiB
C
828 lines
33 KiB
C
#include "common.h"
|
|
#include "entity.h"
|
|
|
|
EntityModelScript D_8014C260 = {
|
|
ems_End
|
|
ems_End
|
|
};
|
|
Lights1 D_8014C268 = gdSPDefLights1(255, 255, 255, 0, 0, 0, 0, 0, 0);
|
|
|
|
SHIFT_BSS EntityModelList gWorldEntityModelList;
|
|
SHIFT_BSS EntityModelList gBattleEntityModelList;
|
|
SHIFT_BSS EntityModelList* gCurrentEntityModelList;
|
|
SHIFT_BSS s32 gEntityModelCount;
|
|
|
|
SHIFT_BSS s32 D_80154374;
|
|
SHIFT_BSS s32 entity_fog_enabled;
|
|
SHIFT_BSS s32 entity_fog_red;
|
|
SHIFT_BSS s32 entity_fog_green;
|
|
SHIFT_BSS s32 entity_fog_blue;
|
|
SHIFT_BSS s32 entity_fog_alpha;
|
|
SHIFT_BSS s32 entity_fog_dist_min;
|
|
SHIFT_BSS s32 entity_fog_dist_max;
|
|
|
|
extern Gfx Gfx_RM1_SURFACE_OPA[];
|
|
extern Gfx Gfx_RM1_DECAL_OPA[];
|
|
extern Gfx Gfx_RM1_INTERSECTING_OPA[];
|
|
extern Gfx Gfx_RM1_ALPHATEST[];
|
|
extern Gfx Gfx_RM1_SURFACE_XLU[];
|
|
extern Gfx Gfx_RM1_DECAL_XLU[];
|
|
extern Gfx Gfx_RM1_INTERSECTING_XLU[];
|
|
extern Gfx Gfx_RM1_ALPHATEST_ONESIDED[];
|
|
extern Gfx Gfx_RM1_SURFACE_XLU_NO_AA[];
|
|
extern Gfx Gfx_RM1_DECAL_XLU_NO_AA[];
|
|
extern Gfx Gfx_RM1_PASS_THROUGH[];
|
|
extern Gfx Gfx_RM1_SURFACE_OPA_NO_ZB[];
|
|
extern Gfx Gfx_RM1_ALPHATEST_NO_ZB[];
|
|
extern Gfx Gfx_RM1_SURFACE_XLU_NO_ZB[];
|
|
extern Gfx Gfx_RM1_CLOUD_NO_ZCMP[];
|
|
extern Gfx Gfx_RM3_SURFACE_OPA[];
|
|
extern Gfx Gfx_RM3_DECAL_OPA[];
|
|
extern Gfx Gfx_RM3_INTERSECTING_OPA[];
|
|
extern Gfx Gfx_RM3_ALPHATEST[];
|
|
extern Gfx Gfx_RM3_SURFACE_XLU[];
|
|
extern Gfx Gfx_RM3_DECAL_XLU[];
|
|
extern Gfx Gfx_RM3_INTERSECTING_XLU[];
|
|
|
|
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;
|
|
}
|
|
|
|
gEntityModelCount = 0;
|
|
entity_fog_enabled = 0;
|
|
entity_fog_red = 10;
|
|
entity_fog_green = 10;
|
|
entity_fog_blue = 10;
|
|
entity_fog_alpha = 10;
|
|
entity_fog_dist_min = 800;
|
|
entity_fog_dist_max = 1000;
|
|
}
|
|
|
|
void init_entity_models(void) {
|
|
s32 i;
|
|
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentEntityModelList = &gWorldEntityModelList;
|
|
} else {
|
|
gCurrentEntityModelList = &gBattleEntityModelList;
|
|
}
|
|
|
|
gEntityModelCount = 0;
|
|
entity_fog_enabled = 0;
|
|
entity_fog_red = 10;
|
|
entity_fog_green = 10;
|
|
entity_fog_blue = 10;
|
|
entity_fog_alpha = 10;
|
|
entity_fog_dist_min = 800;
|
|
entity_fog_dist_max = 1000;
|
|
}
|
|
|
|
s32 load_entity_model(EntityModelScript* cmdList) {
|
|
EntityModel* newEntityModel;
|
|
s32* entityModelCount;
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_ENTITY_MODELS; i++) {
|
|
if ((*gCurrentEntityModelList)[i] == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i < MAX_ENTITY_MODELS);
|
|
|
|
(*gCurrentEntityModelList)[i] = newEntityModel = heap_malloc(sizeof(*newEntityModel));
|
|
entityModelCount = &gEntityModelCount;
|
|
(*entityModelCount)++;
|
|
|
|
ASSERT(newEntityModel != NULL);
|
|
|
|
newEntityModel->flags = (ENTITY_MODEL_FLAG_CAM0 | ENTITY_MODEL_FLAG_CAM1 | ENTITY_MODEL_FLAG_CAM2 | ENTITY_MODEL_FLAG_ENABLED);
|
|
newEntityModel->renderMode = 1;
|
|
newEntityModel->gfx.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_BIT;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
s32 ALT_load_entity_model(EntityModelScript* cmdList) {
|
|
EntityModel* newEntityModel;
|
|
SpriteRasterInfo* imageData;
|
|
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(*newEntityModel));
|
|
entityModelCount = &gEntityModelCount;
|
|
(*entityModelCount)++;
|
|
}
|
|
|
|
ASSERT(newEntityModel != NULL);
|
|
|
|
newEntityModel->gfx.imageData = imageData = heap_malloc(sizeof(*imageData));
|
|
ASSERT(imageData != NULL);
|
|
|
|
newEntityModel->flags = (ENTITY_MODEL_FLAG_CAM0 | ENTITY_MODEL_FLAG_CAM1 | ENTITY_MODEL_FLAG_CAM2 | ENTITY_MODEL_FLAG_ENABLED | ENTITY_MODEL_FLAG_USE_IMAGE);
|
|
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_BIT;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void exec_entity_model_commandlist(s32 idx) {
|
|
EntityModel* entityModel;
|
|
|
|
if (!gGameStatusPtr->isBattle || (idx & BATTLE_ENTITY_ID_BIT)) {
|
|
idx &= ~BATTLE_ENTITY_ID_BIT;
|
|
entityModel = (*gCurrentEntityModelList)[idx];
|
|
if (entityModel != NULL && (entityModel->flags)) {
|
|
if (!(entityModel->flags & ENTITY_MODEL_FLAG_HIDDEN)) {
|
|
if (!(entityModel->flags & ENTITY_MODEL_FLAG_DISABLE_SCRIPT)) {
|
|
entityModel->flags &= ~ENTITY_MODEL_FLAG_100;
|
|
entityModel->nextFrameTime -= entityModel->timeScale;
|
|
if (entityModel->nextFrameTime <= 0.0f) {
|
|
while (step_entity_model_commandlist(entityModel));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 step_entity_model_commandlist(EntityModel* entityModel) {
|
|
SpriteRasterInfo* imageData;
|
|
|
|
u32* curPos = *entityModel->cmdListReadPos;
|
|
switch (*curPos++) {
|
|
case ENTITY_MODEL_SCRIPT_OP_End: // kill model
|
|
free_entity_model_by_ref(entityModel);
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_Draw: // set display list ptr
|
|
entityModel->nextFrameTime = (f32) *curPos++;
|
|
entityModel->gfx.displayList = (Gfx*) *curPos++;
|
|
entityModel->cmdListReadPos = (EntityModelScript*) curPos;
|
|
break;
|
|
case ENTITY_MODEL_SCRIPT_OP_Restart: // restore saved position
|
|
entityModel->cmdListReadPos = entityModel->cmdListSavedPos;
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_Loop: // set saved position
|
|
entityModel->cmdListReadPos = entityModel->cmdListSavedPos = (EntityModelScript*) curPos;
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_SetRenderMode: // set render mode
|
|
entityModel->renderMode = *curPos++;
|
|
entityModel->cmdListReadPos = (EntityModelScript*) curPos;
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_SetFlags: // set flags
|
|
entityModel->flags |= *curPos++;
|
|
entityModel->cmdListReadPos = (EntityModelScript*) curPos;
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_ClearFlags: // clear flags
|
|
entityModel->flags &= ~*curPos++;
|
|
entityModel->cmdListReadPos = (EntityModelScript*) curPos;
|
|
return 1;
|
|
case ENTITY_MODEL_SCRIPT_OP_DrawImage: // set image data
|
|
imageData = entityModel->gfx.imageData;
|
|
entityModel->nextFrameTime = *curPos++;
|
|
imageData->raster = (u8*)*curPos++;
|
|
imageData->defaultPal = (PAL_PTR) *curPos++;
|
|
imageData->width = *curPos++;
|
|
imageData->height = *curPos++;
|
|
entityModel->cmdListReadPos = (EntityModelScript*) 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;
|
|
}
|
|
|
|
void appendGfx_entity_model(EntityModel* model) {
|
|
Matrix4f mtx;
|
|
Matrix4f mtx2;
|
|
ImgFXTexture ifxImg;
|
|
Matrix4f imgfxMtx;
|
|
|
|
gDisplayContext->matrixStack[gMatrixListPos] = model->transform;
|
|
gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_USE_IMAGE)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_10000)) {
|
|
gDPPipeSync(gMainGfxPos++);
|
|
gDPSetRenderMode(gMainGfxPos++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
|
|
gDPSetPrimColor(gMainGfxPos++, 0, 0, 255, 255, 255, 255);
|
|
gDPSetCombineMode(gMainGfxPos++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
gDPSetAlphaCompare(gMainGfxPos++, G_AC_NONE);
|
|
gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE);
|
|
|
|
switch (entity_fog_enabled && !(model->flags & ENTITY_MODEL_FLAG_FOG_DISABLED)) {
|
|
case FALSE:
|
|
switch (model->renderMode) {
|
|
case RENDER_MODE_SURFACE_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_OPA);
|
|
break;
|
|
case RENDER_MODE_DECAL_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_OPA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_OPA);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_LAYER1:
|
|
case RENDER_MODE_SURFACE_XLU_LAYER2:
|
|
case RENDER_MODE_SURFACE_XLU_LAYER3:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_NO_AA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU_NO_AA);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU:
|
|
case RENDER_MODE_DECAL_XLU_AHEAD:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_XLU);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU_NO_AA:
|
|
case RENDER_MODE_SHADOW:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_XLU_NO_AA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_XLU);
|
|
break;
|
|
case RENDER_MODE_PASS_THROUGH:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_PASS_THROUGH);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST_ONESIDED:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST_ONESIDED);
|
|
break;
|
|
case RENDER_MODE_SURFACE_OPA_NO_ZB:
|
|
case RENDER_MODE_SURFACE_OPA_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_OPA_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST_NO_ZB:
|
|
case RENDER_MODE_ALPHATEST_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_NO_ZB:
|
|
case RENDER_MODE_SURFACE_XLU_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_CLOUD_NO_ZCMP:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_CLOUD_NO_ZCMP);
|
|
break;
|
|
}
|
|
break;
|
|
case TRUE:
|
|
switch (model->renderMode) {
|
|
case RENDER_MODE_SURFACE_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_OPA);
|
|
break;
|
|
case RENDER_MODE_DECAL_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_OPA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_OPA);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_ALPHATEST);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_LAYER1:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_XLU);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_XLU);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_XLU);
|
|
break;
|
|
}
|
|
gDPSetFogColor(gMainGfxPos++, entity_fog_red, entity_fog_green, entity_fog_blue, entity_fog_alpha);
|
|
gSPFogPosition(gMainGfxPos++, entity_fog_dist_min, entity_fog_dist_max);
|
|
break;
|
|
}
|
|
gSPClearGeometryMode(gMainGfxPos++, G_LIGHTING);
|
|
if (!entity_fog_enabled || (model->flags & ENTITY_MODEL_FLAG_FOG_DISABLED)) {
|
|
gDPSetCombineMode(gMainGfxPos++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
|
} else {
|
|
gDPSetCombineMode(gMainGfxPos++, PM_CC_42, PM_CC2_MULTIPLY_SHADE);
|
|
}
|
|
}
|
|
if (model->vertexArray != NULL) {
|
|
gSPSegment(gMainGfxPos++, D_80154374, VIRTUAL_TO_PHYSICAL(model->vertexArray));
|
|
}
|
|
gDPPipeSync(gMainGfxPos++);
|
|
|
|
if (model->fpSetupGfxCallback != NULL) {
|
|
model->fpSetupGfxCallback(model->setupGfxCallbackArg0);
|
|
}
|
|
gDPPipeSync(gMainGfxPos++);
|
|
|
|
gSPDisplayList(gMainGfxPos++, model->gfx.displayList);
|
|
gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
|
|
gDPPipeSync(gMainGfxPos++);
|
|
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_REFLECT)) {
|
|
return;
|
|
}
|
|
|
|
guMtxL2F(mtx, &model->transform);
|
|
make_entity_model_mtx_flipZ(mtx2);
|
|
guMtxCatF(mtx, mtx2, mtx);
|
|
guMtxF2L(mtx, &model->transform);
|
|
gDisplayContext->matrixStack[gMatrixListPos] = model->transform;
|
|
gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(gMainGfxPos++, model->gfx.displayList);
|
|
} else {
|
|
SpriteRasterInfo* imageData;
|
|
|
|
gDPPipeSync(gMainGfxPos++);
|
|
gSPClearGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH);
|
|
gSPSetGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH);
|
|
gSPSetLights1(gMainGfxPos++, D_8014C268);
|
|
gSPTexture(gMainGfxPos++, -1, -1, 0, G_TX_RENDERTILE, G_ON);
|
|
gDPSetAlphaCompare(gMainGfxPos++, G_AC_NONE);
|
|
gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE);
|
|
|
|
imageData = model->gfx.imageData;
|
|
ifxImg.raster = imageData->raster;
|
|
ifxImg.palette = imageData->defaultPal;
|
|
ifxImg.width = imageData->width;
|
|
ifxImg.height = imageData->height;
|
|
ifxImg.xOffset = -imageData->width / 2;
|
|
ifxImg.yOffset = imageData->height / 2;
|
|
ifxImg.alpha = 255;
|
|
guMtxL2F(imgfxMtx, &model->transform);
|
|
imgfx_appendGfx_component(0, &ifxImg, 0, imgfxMtx);
|
|
}
|
|
|
|
gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
|
|
gDPPipeSync(gMainGfxPos++);
|
|
}
|
|
|
|
|
|
void draw_entity_model_A(s32 modelIdx, Mtx* transformMtx) {
|
|
EntityModel* model;
|
|
RenderTask rt;
|
|
RenderTask* rtPtr = &rt;
|
|
Camera* camera = &gCameras[gCurrentCamID];
|
|
Matrix4f mtx;
|
|
f32 x, y, z, w;
|
|
f32 inX, inY, inZ;
|
|
|
|
if ((!gGameStatusPtr->isBattle) || (modelIdx & BATTLE_ENTITY_ID_BIT)) {
|
|
modelIdx &= ~BATTLE_ENTITY_ID_BIT;
|
|
model = (*gCurrentEntityModelList)[modelIdx];
|
|
|
|
if (model != NULL) {
|
|
if (model->flags != 0) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_100)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_HIDDEN)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_40) && (model->flags & (1 << gCurrentCamID))) {
|
|
model->transform = *transformMtx;
|
|
model->vertexArray = NULL;
|
|
guMtxL2F(mtx, transformMtx);
|
|
inX = mtx[3][0];
|
|
inY = mtx[3][1];
|
|
inZ = mtx[3][2];
|
|
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &w);
|
|
rtPtr->renderMode = model->renderMode;
|
|
rtPtr->appendGfxArg = model;
|
|
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;
|
|
rtPtr->dist = ((u32)(model->flags & 0xF000) >> 8) + inZ;
|
|
queue_render_task(rtPtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_entity_model_B(s32 modelIdx, Mtx* transformMtx, s32 vertexSegment, Vec3s* vertexArray) {
|
|
EntityModel* model;
|
|
RenderTask rt;
|
|
RenderTask* rtPtr = &rt;
|
|
Camera* camera = &gCameras[gCurrentCamID];
|
|
Matrix4f mtx;
|
|
f32 x, y, z, w;
|
|
f32 inX, inY, inZ;
|
|
|
|
if ((!gGameStatusPtr->isBattle) || (modelIdx & BATTLE_ENTITY_ID_BIT)) {
|
|
modelIdx &= ~BATTLE_ENTITY_ID_BIT;
|
|
model = (*gCurrentEntityModelList)[modelIdx];
|
|
|
|
if (model != NULL) {
|
|
if (model->flags != 0) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_100)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_HIDDEN)) {
|
|
if (model->flags & (1 << gCurrentCamID)) {
|
|
model->transform = *transformMtx;
|
|
D_80154374 = vertexSegment;
|
|
model->vertexArray = vertexArray;
|
|
guMtxL2F(mtx, transformMtx);
|
|
inX = mtx[3][0];
|
|
inY = mtx[3][1];
|
|
inZ = mtx[3][2];
|
|
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &w);
|
|
rtPtr->renderMode = model->renderMode;
|
|
rtPtr->appendGfxArg = model;
|
|
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;
|
|
rtPtr->dist = ((u32)(model->flags & 0xF000) >> 8) + inZ;
|
|
queue_render_task(rtPtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_entity_model_C(s32 modelIdx, Mtx* transformMtx) {
|
|
EntityModel* model;
|
|
RenderTask rt;
|
|
RenderTask* rtPtr = &rt;
|
|
|
|
if ((!gGameStatusPtr->isBattle) || (modelIdx & BATTLE_ENTITY_ID_BIT)) {
|
|
modelIdx &= ~BATTLE_ENTITY_ID_BIT;
|
|
model = (*gCurrentEntityModelList)[modelIdx];
|
|
|
|
if (model != NULL) {
|
|
if (model->flags != 0) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_100)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_HIDDEN)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_40) && (model->flags & (1 << gCurrentCamID))) {
|
|
model->flags |= ENTITY_MODEL_FLAG_REFLECT;
|
|
model->transform = *transformMtx;
|
|
model->vertexArray = NULL;
|
|
rtPtr->renderMode = model->renderMode;
|
|
rtPtr->appendGfxArg = model;
|
|
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;
|
|
rtPtr->dist = (u32)(model->flags & 0xF000) >> 8;
|
|
queue_render_task(rtPtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_entity_model_D(s32 modelIdx, Mtx* transformMtx, s32 arg2, Vec3s* vertexArray) {
|
|
EntityModel* model;
|
|
RenderTask rt;
|
|
RenderTask* rtPtr = &rt;
|
|
|
|
if ((!gGameStatusPtr->isBattle) || (modelIdx & BATTLE_ENTITY_ID_BIT)) {
|
|
modelIdx &= ~BATTLE_ENTITY_ID_BIT;
|
|
model = (*gCurrentEntityModelList)[modelIdx];
|
|
|
|
if (model != NULL) {
|
|
if (model->flags != 0) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_100)) {
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_HIDDEN)) {
|
|
if (model->flags & (1 << gCurrentCamID)) {
|
|
model->flags |= ENTITY_MODEL_FLAG_REFLECT;
|
|
model->transform = *transformMtx;
|
|
D_80154374 = arg2;
|
|
model->vertexArray = vertexArray;
|
|
rtPtr->renderMode = model->renderMode;
|
|
rtPtr->appendGfxArg = model;
|
|
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;
|
|
rtPtr->dist = (u32)(model->flags & 0xF000) >> 8;
|
|
queue_render_task(rtPtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_entity_model_E(s32 modelIdx, Mtx* transformMtx) {
|
|
EntityModel* model = (*gCurrentEntityModelList)[modelIdx & ~BATTLE_ENTITY_ID_BIT];
|
|
Matrix4f mtx;
|
|
Matrix4f mtx2;
|
|
ImgFXTexture ifxImg;
|
|
Matrix4f imgfxMtx;
|
|
|
|
if (model == NULL) {
|
|
return;
|
|
}
|
|
if (model->flags == 0) {
|
|
return;
|
|
}
|
|
if (model->flags & ENTITY_MODEL_FLAG_100) {
|
|
return;
|
|
}
|
|
if (model->flags & ENTITY_MODEL_FLAG_HIDDEN) {
|
|
return;
|
|
}
|
|
if (model->flags & ENTITY_MODEL_FLAG_40) {
|
|
return;
|
|
}
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_CAM3)) {
|
|
return;
|
|
}
|
|
|
|
model->transform = *transformMtx;
|
|
model->vertexArray = NULL;
|
|
gDisplayContext->matrixStack[gMatrixListPos] = model->transform;
|
|
gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_USE_IMAGE)) {
|
|
switch (entity_fog_enabled && !(model->flags & ENTITY_MODEL_FLAG_FOG_DISABLED)) {
|
|
case FALSE:
|
|
switch (model->renderMode) {
|
|
case RENDER_MODE_SURFACE_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_OPA);
|
|
break;
|
|
case RENDER_MODE_DECAL_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_OPA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_OPA);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_LAYER1:
|
|
case RENDER_MODE_SURFACE_XLU_LAYER2:
|
|
case RENDER_MODE_SURFACE_XLU_LAYER3:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_NO_AA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU_NO_AA);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU:
|
|
case RENDER_MODE_DECAL_XLU_AHEAD:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_XLU);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU_NO_AA:
|
|
case RENDER_MODE_SHADOW:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_XLU_NO_AA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_XLU);
|
|
break;
|
|
case RENDER_MODE_PASS_THROUGH:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_PASS_THROUGH);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST_ONESIDED:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST_ONESIDED);
|
|
break;
|
|
case RENDER_MODE_SURFACE_OPA_NO_ZB:
|
|
case RENDER_MODE_SURFACE_OPA_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_OPA_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST_NO_ZB:
|
|
case RENDER_MODE_ALPHATEST_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_NO_ZB:
|
|
case RENDER_MODE_SURFACE_XLU_NO_ZB_BEHIND:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU_NO_ZB);
|
|
break;
|
|
case RENDER_MODE_CLOUD_NO_ZCMP:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM1_CLOUD_NO_ZCMP);
|
|
break;
|
|
}
|
|
break;
|
|
case TRUE:
|
|
switch (model->renderMode) {
|
|
case RENDER_MODE_SURFACE_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_OPA);
|
|
break;
|
|
case RENDER_MODE_DECAL_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_OPA);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_OPA:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_OPA);
|
|
break;
|
|
case RENDER_MODE_ALPHATEST:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_ALPHATEST);
|
|
break;
|
|
case RENDER_MODE_SURFACE_XLU_LAYER1:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_XLU);
|
|
break;
|
|
case RENDER_MODE_DECAL_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_XLU);
|
|
break;
|
|
case RENDER_MODE_INTERSECTING_XLU:
|
|
gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_XLU);
|
|
break;
|
|
}
|
|
gDPSetFogColor(gMainGfxPos++, entity_fog_red, entity_fog_green, entity_fog_blue, entity_fog_alpha);
|
|
gSPFogPosition(gMainGfxPos++, entity_fog_dist_min, entity_fog_dist_max);
|
|
break;
|
|
}
|
|
gSPClearGeometryMode(gMainGfxPos++, G_LIGHTING);
|
|
if (!entity_fog_enabled || (model->flags & ENTITY_MODEL_FLAG_FOG_DISABLED)) {
|
|
gDPSetCombineMode(gMainGfxPos++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
|
} else {
|
|
gDPSetCombineMode(gMainGfxPos++, PM_CC_42, PM_CC2_MULTIPLY_SHADE);
|
|
}
|
|
if (model->vertexArray != NULL) {
|
|
gSPSegment(gMainGfxPos++, D_80154374, VIRTUAL_TO_PHYSICAL(model->vertexArray));
|
|
}
|
|
gSPDisplayList(gMainGfxPos++, model->gfx.displayList);
|
|
gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
|
|
gDPPipeSync(gMainGfxPos++);
|
|
if (!(model->flags & ENTITY_MODEL_FLAG_REFLECT)) {
|
|
return;
|
|
}
|
|
|
|
guMtxL2F(mtx, &model->transform);
|
|
make_entity_model_mtx_flipZ(mtx2);
|
|
guMtxCatF(mtx, mtx2, mtx);
|
|
guMtxF2L(mtx, &model->transform);
|
|
gDisplayContext->matrixStack[gMatrixListPos] = model->transform;
|
|
gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(gMainGfxPos++, model->gfx.displayList);
|
|
} else {
|
|
SpriteRasterInfo* imageData;
|
|
|
|
gDPPipeSync(gMainGfxPos++);
|
|
gSPClearGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH);
|
|
gSPSetGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH);
|
|
gSPSetLights1(gMainGfxPos++, D_8014C268);
|
|
gSPTexture(gMainGfxPos++, -1, -1, 0, G_TX_RENDERTILE, G_ON);
|
|
gDPSetAlphaCompare(gMainGfxPos++, G_AC_NONE);
|
|
gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE);
|
|
|
|
imageData = model->gfx.imageData;
|
|
ifxImg.raster = imageData->raster;
|
|
ifxImg.palette = imageData->defaultPal;
|
|
ifxImg.width = imageData->width;
|
|
ifxImg.height = imageData->height;
|
|
ifxImg.xOffset = -imageData->width / 2;
|
|
ifxImg.yOffset = imageData->height / 2;
|
|
ifxImg.alpha = 255;
|
|
guMtxL2F(imgfxMtx, &model->transform);
|
|
imgfx_appendGfx_component(0, &ifxImg, 0, imgfxMtx);
|
|
}
|
|
|
|
gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
|
|
gDPPipeSync(gMainGfxPos++);
|
|
}
|
|
|
|
void set_entity_model_render_command_list(s32 idx, EntityModelScript* cmdList) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_BIT];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
if (cmdList == NULL) {
|
|
cmdList = &D_8014C260;
|
|
}
|
|
entityModel->cmdListReadPos = cmdList;
|
|
entityModel->cmdListSavedPos = cmdList;
|
|
entityModel->nextFrameTime = 1.0f;
|
|
entityModel->timeScale = 1.0f;
|
|
}
|
|
}
|
|
|
|
EntityModel* get_entity_model(s32 listIndex) {
|
|
return (*gCurrentEntityModelList)[listIndex & ~BATTLE_ENTITY_ID_BIT];
|
|
}
|
|
|
|
void free_entity_model_by_index(s32 idx) {
|
|
s32 index = idx & ~BATTLE_ENTITY_ID_BIT;
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[index];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
if (entityModel->flags & ENTITY_MODEL_FLAG_USE_IMAGE) {
|
|
heap_free(entityModel->gfx.imageData);
|
|
}
|
|
{
|
|
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_BIT];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
entityModel->flags |= newFlags;
|
|
}
|
|
}
|
|
|
|
void clear_entity_model_flags(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_BIT];
|
|
|
|
if (entityModel != NULL && entityModel->flags) {
|
|
entityModel->flags &= ~newFlags;
|
|
}
|
|
}
|
|
|
|
void bind_entity_model_setupGfx(s32 idx, void* setupGfxCallbackArg0, void (*fpSetupGfxCallback)(void*)) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_BIT];
|
|
|
|
entityModel->fpSetupGfxCallback = fpSetupGfxCallback;
|
|
entityModel->setupGfxCallbackArg0 = setupGfxCallbackArg0;
|
|
}
|
|
|
|
void func_80122F8C(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_BIT];
|
|
|
|
entityModel->flags |= newFlags;
|
|
}
|
|
|
|
void func_80122FB8(s32 idx, s32 newFlags) {
|
|
EntityModel* entityModel = (*gCurrentEntityModelList)[idx & ~BATTLE_ENTITY_ID_BIT];
|
|
|
|
entityModel->flags = (entityModel->flags & ~(ENTITY_MODEL_FLAG_CAM0 | ENTITY_MODEL_FLAG_CAM1 | ENTITY_MODEL_FLAG_CAM2 | ENTITY_MODEL_FLAG_CAM3)) | 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;
|
|
}
|