marioparty4/src/game/sprput.c
gamemasterplc 504e565727 Clean Up Sprite Constant Labeling
Also improved struct labeling.
2024-03-10 22:36:14 -05:00

254 lines
No EOL
10 KiB
C

#include "game/sprite.h"
#include "game/hsfman.h"
#include "game/init.h"
#include "dolphin/mtx.h"
#include "dolphin/gx.h"
#include "dolphin/vi.h"
static void *bmpNoCC[8];
static short HuSprLayerDrawNo[8];
static short bmpCCIdx;
void mtxTransCat(Mtx matrix, float x, float y, float z);
static void HuSprLayerHook(short layer);
void HuSprDispInit(void)
{
Mtx44 proj;
short i;
for(i=0; i<8; i++) {
bmpNoCC[i] = NULL;
}
bmpCCIdx = 0;
GXInvalidateTexAll();
MTXOrtho(proj, 0, 480, 0, 576, 0, 10);
GXSetProjection(proj, GX_ORTHOGRAPHIC);
if(RenderMode->field_rendering) {
GXSetViewportJitter(0, 0, 640, 480, 0, 1, VIGetNextField());
} else {
GXSetViewport(0, 0, 640, 480, 0, 1);
}
GXSetScissor(0, 0, 640, 480);
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);
GXSetCullMode(GX_CULL_NONE);
GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
}
void HuSprDisp(HuSprite *sprite)
{
short i;
AnimData *anim = sprite->data;
AnimPatData *pat = sprite->pat_data;
Vec axis = {0, 0, 1};
Mtx modelview, rot;
short color_sum;
HuSprFunc func;
GXSetScissor(sprite->scissor_x, sprite->scissor_y, sprite->scissor_w, sprite->scissor_h);
if(sprite->attr & HUSPR_ATTR_FUNC) {
if(sprite->func) {
func = sprite->func;
func(sprite);
HuSprDispInit();
}
} else {
AnimLayerData *layer;
AnimBmpData *bg_bmp;
GXColor color;
GXSetNumTexGens(1);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
color.r = color.g = color.b = color.a = 255;
GXSetChanAmbColor(GX_COLOR0A0, color);
GXSetChanMatColor(GX_COLOR0A0, color);
color.r = sprite->r;
color.g = sprite->g;
color.b = sprite->b;
color.a = sprite->a;
color_sum = color.r+color.g+color.b+color.a;
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_C0, GX_CC_CPREV, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP, GX_AF_SPOT);
if(sprite->attr & HUSPR_ATTR_ADDCOL) {
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_NOOP);
} else if(sprite->attr & HUSPR_ATTR_INVCOL) {
GXSetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_INVDSTCLR, GX_LO_NOOP);
} else {
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
}
if(sprite->bg) {
AnimPatData *bg_pat;
AnimFrameData *bg_frame;
bg_frame = sprite->bg->bank[sprite->bg_bank].frame;
bg_pat = &sprite->bg->pat[bg_frame->pat];
layer = bg_pat->layer;
bg_bmp = &sprite->bg->bmp[layer->bmpNo];
HuSprTexLoad(sprite->bg, layer->bmpNo, 1, GX_CLAMP, GX_CLAMP, GX_NEAR);
GXSetNumIndStages(1);
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, bg_bmp->sizeX*16, bg_bmp->sizeY*16);
GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_16, GX_ITS_16);
GXSetTevIndTile(GX_TEVSTAGE0, GX_INDTEXSTAGE0, 16, 16, 16, 16, GX_ITF_4, GX_ITM_0, GX_ITB_NONE, GX_ITBA_OFF);
}
GXSetAlphaCompare(GX_GEQUAL, 1, GX_AOP_AND, GX_GEQUAL, 1);
GXSetZCompLoc(GX_FALSE);
if(0 != sprite->z_rot) {
MTXRotAxisDeg(rot, &axis, sprite->z_rot);
MTXScale(modelview, sprite->scale_x, sprite->scale_y, 1.0f);
MTXConcat(rot, modelview, modelview);
} else {
MTXScale(modelview, sprite->scale_x, sprite->scale_y, 1.0f);
}
mtxTransCat(modelview, sprite->x, sprite->y, 0);
MTXConcat(*sprite->group_mtx, modelview, modelview);
GXLoadPosMtxImm(modelview, GX_PNMTX0);
for(i=pat->layerNum-1; i>=0; i--) {
float pos[4][2];
float texcoord_x1, texcoord_y1, texcoord_x2, texcoord_y2;
AnimBmpData *bmp;
layer = &pat->layer[i];
bmp = &anim->bmp[layer->bmpNo];
if(!bmp) {
continue;
}
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
HuSprTexLoad(anim, layer->bmpNo, 0, sprite->wrap_s, sprite->wrap_t, (sprite->attr & HUSPR_ATTR_LINEAR) ? GX_LINEAR : GX_NEAR);
if(layer->alpha != 255 || color_sum != 255*4) {
color.a = (u16)(sprite->a*layer->alpha) >> 8;
GXSetTevColor(GX_TEVSTAGE1, color);
GXSetNumTevStages(2);
} else {
GXSetNumTevStages(1);
}
if(!sprite->bg) {
pos[0][0] = layer->vtx[0]-pat->centerX;
pos[0][1] = layer->vtx[1]-pat->centerY;
pos[1][0] = layer->vtx[2]-pat->centerX;
pos[1][1] = layer->vtx[3]-pat->centerY;
pos[2][0] = layer->vtx[4]-pat->centerX;
pos[2][1] = layer->vtx[5]-pat->centerY;
pos[3][0] = layer->vtx[6]-pat->centerX;
pos[3][1] = layer->vtx[7]-pat->centerY;
if(layer->flip & ANIM_LAYER_FLIPX) {
texcoord_x2 = layer->startX/(float)bmp->sizeX;
texcoord_x1 = (layer->startX+layer->sizeX)/(float)bmp->sizeX;
} else {
texcoord_x1 = layer->startX/(float)bmp->sizeX;
texcoord_x2 = (layer->startX+layer->sizeX)/(float)bmp->sizeX;
}
if(layer->flip & ANIM_LAYER_FLIPY) {
texcoord_y2 = layer->startY/(float)bmp->sizeY;
texcoord_y1 = (layer->startY+layer->sizeY)/(float)bmp->sizeY;
} else {
texcoord_y1 = layer->startY/(float)bmp->sizeY;
texcoord_y2 = (layer->startY+layer->sizeY)/(float)bmp->sizeY;
}
} else {
pos[0][0] = pos[3][0] = -(bg_bmp->sizeX*16)/2;
pos[0][1] = pos[1][1] = -(bg_bmp->sizeY*16)/2;
pos[2][0] = pos[1][0] = pos[0][0]+(bg_bmp->sizeX*16);
pos[2][1] = pos[3][1] = pos[0][1]+(bg_bmp->sizeY*16);
texcoord_x1 = texcoord_y1 = 1.0/(bg_bmp->sizeX*16);
texcoord_x2 = texcoord_y2 = 1.0f;
}
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition3f32(pos[0][0], pos[0][1], 0);
GXTexCoord2f32(texcoord_x1*sprite->tex_scale_x, texcoord_y1*sprite->tex_scale_y);
GXPosition3f32(pos[1][0], pos[1][1], 0);
GXTexCoord2f32(texcoord_x2*sprite->tex_scale_x, texcoord_y1*sprite->tex_scale_y);
GXPosition3f32(pos[2][0], pos[2][1], 0);
GXTexCoord2f32(texcoord_x2*sprite->tex_scale_x, texcoord_y2*sprite->tex_scale_y);
GXPosition3f32(pos[3][0], pos[3][1], 0);
GXTexCoord2f32(texcoord_x1*sprite->tex_scale_x, texcoord_y2*sprite->tex_scale_y);
GXEnd();
}
if(sprite->bg) {
GXSetNumIndStages(0);
GXSetTevDirect(GX_TEVSTAGE0);
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_FALSE, 0, 0);
}
}
}
void HuSprTexLoad(AnimData *anim, short bmp, short slot, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXTexFilter filter)
{
GXTexObj tex_obj;
GXTlutObj tlut_obj;
AnimBmpData *bmp_ptr = &anim->bmp[bmp];
short sizeX = bmp_ptr->sizeX;
short sizeY = bmp_ptr->sizeY;
switch(bmp_ptr->dataFmt & ANIM_BMP_FMTMASK) {
case ANIM_BMP_RGBA8:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_RGBA8, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_RGB5A3:
case ANIM_BMP_RGB5A3_DUPE:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_RGB5A3, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_C8:
GXInitTlutObj(&tlut_obj, bmp_ptr->palData, GX_TL_RGB5A3, bmp_ptr->palNum);
GXLoadTlut(&tlut_obj, slot);
GXInitTexObjCI(&tex_obj,bmp_ptr->data, sizeX, sizeY, GX_TF_C8, wrap_s, wrap_t, GX_FALSE, slot);
break;
case ANIM_BMP_C4:
GXInitTlutObj(&tlut_obj, bmp_ptr->palData, GX_TL_RGB5A3, bmp_ptr->palNum);
GXLoadTlut(&tlut_obj, slot);
GXInitTexObjCI(&tex_obj,bmp_ptr->data, sizeX, sizeY, GX_TF_C4, wrap_s, wrap_t, GX_FALSE, slot);
break;
case ANIM_BMP_IA8:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_IA8, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_IA4:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_IA4, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_I8:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_I8, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_I4:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_I4, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_A8:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_CTF_A8, wrap_s, wrap_t, GX_FALSE);
break;
case ANIM_BMP_CMPR:
GXInitTexObj(&tex_obj, bmp_ptr->data, sizeX, sizeY, GX_TF_CMPR, wrap_s, wrap_t, GX_FALSE);
break;
default:
break;
}
GXInitTexObjLOD(&tex_obj, filter, filter, 0, 0, 0, GX_FALSE, GX_FALSE, GX_ANISO_1);
GXLoadTexObj(&tex_obj, slot);
}
void HuSprExecLayerSet(short draw_no, short layer)
{
HuSprLayerDrawNo[layer] = draw_no;
Hu3DLayerHookSet(layer, HuSprLayerHook);
}
static void HuSprLayerHook(short layer)
{
HuSprDispInit();
HuSprExec(HuSprLayerDrawNo[layer]);
}