diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index cd0f3d05..c6bc04f5 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -4847,7 +4847,8 @@ fcoltbl = .data:0x80122140; // type:object size:0x40 scope:local align:32 lbl_80122180 = .data:0x80122180; // type:object size:0x1F data:string lbl_8012219F = .data:0x8012219F; // type:object size:0x31 lbl_801221D0 = .data:0x801221D0; // type:object size:0x12 -bitSizeTbl = .data:0x801221E2; // type:object size:0x10E scope:local +bitSizeTbl = .data:0x801221E2; // type:object size:0x16 scope:local +lbl_801221F8 = .data:0x801221F8; // type:object size:0xF8 scope:local jumptable_801222F0 = .data:0x801222F0; // type:object size:0x2C scope:local jumptable_80122320 = .data:0x80122320; // type:object size:0x28 scope:local jumptable_80122348 = .data:0x80122348; // type:object size:0x2C scope:local @@ -5289,7 +5290,7 @@ lbl_8013C514 = .data:0x8013C514; // type:object size:0x34 jumptable_8013C5B4 = .data:0x8013C5B4; // type:object size:0x40 scope:local jumptable_8013C5F4 = .data:0x8013C5F4; // type:object size:0x34 scope:local jumptable_8013C628 = .data:0x8013C628; // type:object size:0x34 scope:local -ErrorTable = .data:0x8013C660; // type:object size:0x48 data:4byte scope:local +ErrorTable = .data:0x8013C660; // type:object size:0x48 scope:local data:4byte @36 = .data:0x8013C6A8; // type:object size:0x1A scope:local data:string timing = .data:0x8013C718; // type:object size:0x130 scope:local taps = .data:0x8013C848; // type:object size:0x32 scope:local @@ -6011,9 +6012,9 @@ procfunc = .sbss:0x801D3B38; // type:object size:0x4 data:4byte processcnt = .sbss:0x801D3B3C; // type:object size:0x2 scope:local data:2byte processcur = .sbss:0x801D3B40; // type:object size:0x4 scope:local data:4byte processtop = .sbss:0x801D3B44; // type:object size:0x4 scope:local data:4byte -HuSprPauseF = .sbss:0x801D3B48; // type:object size:0x4 data:4byte -HuSprOrderNo = .sbss:0x801D3B4C; // type:object size:0x2 data:2byte -HuSprOrderNum = .sbss:0x801D3B4E; // type:object size:0x2 data:2byte +HuSprPauseF = .sbss:0x801D3B48; // type:object size:0x4 scope:local data:4byte +HuSprOrderNo = .sbss:0x801D3B4C; // type:object size:0x2 scope:local data:2byte +HuSprOrderNum = .sbss:0x801D3B4E; // type:object size:0x2 scope:local data:2byte bmpCCIdx = .sbss:0x801D3B50; // type:object size:0x8 data:2byte MaterialTop = .sbss:0x801D3B58; // type:object size:0x4 data:4byte AttributeTop = .sbss:0x801D3B5C; // type:object size:0x4 data:4byte @@ -6045,14 +6046,14 @@ matChgCnt = .sbss:0x801D3BBE; // type:object size:0x2 scope:local data:2byte DLFirstF = .sbss:0x801D3BC0; // type:object size:0x4 scope:local data:4byte modelObjNum = .sbss:0x801D3BC4; // type:object size:0x2 data:2byte modelMeshNum = .sbss:0x801D3BC6; // type:object size:0x2 data:2byte -totalTexCacheCnted = .sbss:0x801D3BC8; // type:object size:0x4 scope:local data:4byte -totalTexCacheCnt = .sbss:0x801D3BCC; // type:object size:0x4 scope:local data:4byte -totalTexCnted = .sbss:0x801D3BD0; // type:object size:0x4 scope:local data:4byte -totalTexCnt = .sbss:0x801D3BD4; // type:object size:0x4 scope:local data:4byte -totalMatCnted = .sbss:0x801D3BD8; // type:object size:0x4 scope:local data:4byte -totalMatCnt = .sbss:0x801D3BDC; // type:object size:0x4 scope:local data:4byte +totalTexCacheCnted = .sbss:0x801D3BC8; // type:object size:0x4 data:4byte +totalTexCacheCnt = .sbss:0x801D3BCC; // type:object size:0x4 data:4byte +totalTexCnted = .sbss:0x801D3BD0; // type:object size:0x4 data:4byte +totalTexCnt = .sbss:0x801D3BD4; // type:object size:0x4 data:4byte +totalMatCnted = .sbss:0x801D3BD8; // type:object size:0x4 data:4byte +totalMatCnt = .sbss:0x801D3BDC; // type:object size:0x4 data:4byte totalPolyCnted = .sbss:0x801D3BE0; // type:object size:0x4 data:4byte -totalPolyCnt = .sbss:0x801D3BE4; // type:object size:0x4 scope:local data:4byte +totalPolyCnt = .sbss:0x801D3BE4; // type:object size:0x4 data:4byte hookIdx = .sbss:0x801D3BE8; // type:object size:0x2 scope:local data:2byte kColorIdx = .sbss:0x801D3BEC; // type:object size:0x4 scope:local data:4byte kColor = .sbss:0x801D3BF0; // type:object size:0x4 scope:local data:byte diff --git a/configure.py b/configure.py index 19295e97..838ed8dd 100755 --- a/configure.py +++ b/configure.py @@ -243,7 +243,7 @@ config.libs = [ Object(Matching, "game/memory.c"), Object(Matching, "game/printfunc.c"), Object(Matching, "game/process.c"), - Object(NonMatching, "game/sprman.c"), + Object(Matching, "game/sprman.c"), Object(NonMatching, "game/sprput.c"), Object(NonMatching, "game/hsfload.c"), Object(NonMatching, "game/hsfdraw.c"), diff --git a/include/common_structs.h b/include/common_structs.h index 1525241d..b57b78d6 100644 --- a/include/common_structs.h +++ b/include/common_structs.h @@ -4,6 +4,8 @@ #include "types.h" #include "common_enums.h" #include "dolphin/dvd.h" +#include "dolphin/mtx/GeoTypes.h" +#include "dolphin/gx/GXEnum.h" typedef struct om_ovl_his_data { OverlayID overlay; @@ -157,4 +159,119 @@ typedef struct om_obj_data { void *data; } omObjData; +typedef struct anim_time_data { + s16 pat; + s16 time; + s16 shiftX; + s16 shiftY; + s16 flip; + s16 pad; +} AnimFrameData; + +typedef struct anim_bank_data { + s16 timeNum; + AnimFrameData *frame; +} AnimBankData; + +typedef struct anim_layer_data { + u8 alpha; + u8 flip; + s16 bmpNo; + s16 startX; + s16 startY; + s16 sizeX; + s16 sizeY; + s16 shiftX; + s16 shiftY; + s16 vtx[8]; +} AnimLayerData; + +typedef struct anim_pat_data { + s16 layerNum; + s16 centerX; + s16 centerY; + s16 sizeX; + s16 sizeY; + AnimLayerData *layer; +} AnimPatData; + +typedef struct anim_bmp_data { + u8 pixSize; + u8 dataFmt; + s16 palNum; + s16 sizeX; + s16 sizeY; + u32 dataSize; + void *palData; + void *data; +} AnimBmpData; + +typedef struct anim_data { + s16 bankNum; + s16 patNum; + s16 bmpNum; + s16 useNum; + AnimBankData *bank; + AnimPatData *pat; + AnimBmpData *bmp; +} AnimData; + +typedef struct sprite_data { + char r; + char g; + char b; + char draw_no; + short frame; + short bank; + short attr; + short dirty_flag; + short prio; + float time; + float x; + float y; + float rot; + float scale_x; + float scale_y; + float speed; + float alpha; + GXTexWrapMode wrap_s; + GXTexWrapMode wrap_t; + short tex_scale_x; + short tex_scale_y; + Mtx *group_mtx; + union { + AnimData *data; + void (*func)(struct sprite_data *sprite); + }; + AnimPatData *pat_data; + AnimFrameData *frame_data; + short work[4]; + AnimData *bg; + short bg_bank; + short scissor_x; + short scissor_y; + short scissor_w; + short scissor_h; +} SpriteData; + +typedef struct sprite_group_data { + short num_members; + float x; + float y; + float rot; + float scale_x; + float scale_y; + float center_x; + float center_y; + s16 *members; + Mtx mtx; +} SpriteGroupData; + +typedef struct sprite_order_data { + u16 group; + u16 sprite; + u16 prio; + u16 next; +} SpriteOrderData; + #endif diff --git a/src/game/sprman.c b/src/game/sprman.c new file mode 100644 index 00000000..d17a637f --- /dev/null +++ b/src/game/sprman.c @@ -0,0 +1,261 @@ +#include "common.h" +#include "dolphin/mtx.h" + +SpriteData HuSprData[384]; +SpriteGroupData HuSprGrpData[256]; +static SpriteOrderData HuSprOrder[384*2]; + + +static s16 HuSprOrderNum; +static s16 HuSprOrderNo; +static BOOL HuSprPauseF; + +void HuSprGrpKill(s16 i); +void HuSprKill(s16 i); + +void HuSprDisp(SpriteData *sprite); +SpriteData *HuSprCall(); + +static void HuSprOrderEntry(s16 group, s16 sprite); + +extern u32 minimumVcount; + +void mtxTransCat(Mtx matrix, float x, float y, int z); //Last argument should be a float + +void HuSprInit(void) +{ + s16 i; + SpriteData *sprite; + SpriteGroupData *group; + for(sprite = &HuSprData[1], i=1; i<384; i++, sprite++) { + sprite->data = NULL; + } + for(group = HuSprGrpData, i=0; i<256; i++, group++) { + group->num_members = 0; + } + sprite = &HuSprData[0]; + sprite->prio = 0; + sprite->data = (void *)1; + HuSprPauseF = FALSE; +} + +void HuSprClose(void) +{ + s16 i; + SpriteGroupData *group; + SpriteData *sprite; + + for(group = HuSprGrpData, i=0; i<256; i++, group++) { + if(group->num_members != 0) { + HuSprGrpKill(i); + } + } + for(sprite = &HuSprData[1], i=1; i<384; i++, sprite++) { + if(sprite->data) { + HuSprKill(i); + } + } + HuSprPauseF = FALSE; +} + +void HuSprExec(s16 draw_no) +{ + SpriteData *sprite; + while(sprite = HuSprCall()) { + if(!(sprite->attr & 0x4) && sprite->draw_no == draw_no) { + HuSprDisp(sprite); + } + } +} + +void HuSprBegin(void) +{ + Mtx temp, rot; + s16 i, j; + Vec axis = {0, 0, 1}; + SpriteGroupData *group; + group = HuSprGrpData; + HuSprOrderNum = 1; + HuSprOrder[0].next = 0; + HuSprOrder[0].prio = -1; + for(i=0; i<256; i++, group++) { + if(group->num_members != 0) { + MTXTrans(temp, group->center_x*group->scale_x, group->center_y*group->scale_y, 0.0f); + MTXRotAxisDeg(rot, &axis, group->rot); + MTXConcat(rot, temp, group->mtx); + MTXScale(temp, group->scale_x, group->scale_y, 1.0f); + MTXConcat(group->mtx, temp, group->mtx); + mtxTransCat(group->mtx, group->x, group->y, 0); + for(j=0; jnum_members; j++) { + if(group->members[j] != -1) { + HuSprOrderEntry(i, group->members[j]); + } + } + } + } + HuSprOrderNo = 0; +} + +static void HuSprOrderEntry(s16 group, s16 sprite) +{ + SpriteOrderData *order = &HuSprOrder[HuSprOrderNum]; + s16 prio = HuSprData[sprite].prio; + s16 prev, next; + if(HuSprOrderNum >= 384*2) { + OSReport("Order Max Over!\n"); + return; + } + next = HuSprOrder[0].next; + for(prev = 0; next != 0; prev = next, next = HuSprOrder[next].next) { + if(HuSprOrder[next].prio < prio) { + break; + } + } + order->next = HuSprOrder[prev].next; + HuSprOrder[prev].next = HuSprOrderNum; + order->prio = prio; + order->group = group; + order->sprite = sprite; + HuSprOrderNum++; +} + +SpriteData *HuSprCall(void) +{ + HuSprOrderNo = HuSprOrder[HuSprOrderNo].next; + if(HuSprOrderNo != 0) { + SpriteOrderData *order = &HuSprOrder[HuSprOrderNo]; + SpriteData *sprite = &HuSprData[order->sprite]; + sprite->group_mtx = &HuSprGrpData[order->group].mtx; + if(sprite->attr & 0x10) { + return sprite; + } + sprite->frame_data = &sprite->data->bank[sprite->bank].frame[sprite->frame]; + sprite->pat_data = &sprite->data->pat[sprite->frame_data->pat]; + return sprite; + } else { + return NULL; + } +} + +void HuSprFinish(void) +{ + AnimData *anim; + AnimBankData *bank; + AnimFrameData *frame; + SpriteData *sprite; + s16 i; + s16 j; + s16 wrap; + s16 dir; + + + for(sprite = &HuSprData[1], i=1; i<384; i++, sprite++) { + if(sprite->data && !(sprite->attr & 0x10)) { + if(!HuSprPauseF || (sprite->attr & 0x20)) { + anim = sprite->data; + bank = &anim->bank[sprite->bank]; + frame = &bank->frame[sprite->frame]; + wrap = (sprite->attr & 0x2) ? 0 : 1; + if(!(sprite->attr & 0x1)) { + dir = (sprite->attr & 0x40) ? -1 : 1; + for(j=0; j<(int)sprite->speed*minimumVcount; j++) { + sprite->time += dir; + if(sprite->time >= frame->time) { + sprite->frame++; + sprite->time -= frame->time; + if(sprite->frame >= bank->timeNum || frame[1].time == -1) { + if(wrap) { + sprite->frame = 0; + } else { + sprite->frame = bank->timeNum-1; + } + } + frame = &bank->frame[sprite->frame]; + } else if(sprite->time < 0) { + sprite->frame--; + if(sprite->frame < 0) { + if(wrap) { + sprite->frame = bank->timeNum-1; + } else { + sprite->frame = 0; + } + } + frame = &bank->frame[sprite->frame]; + sprite->time += frame->time; + } + } + sprite->time += (sprite->speed*(float)minimumVcount)-j; + if(sprite->time >= frame->time) { + sprite->frame++; + sprite->time -= frame->time; + if(sprite->frame >= bank->timeNum || frame[1].time == -1) { + if(wrap) { + sprite->frame = 0; + } else { + sprite->frame = bank->timeNum-1; + } + } + frame = &bank->frame[sprite->frame]; + } else if(sprite->time < 0) { + sprite->frame--; + if(sprite->frame < 0) { + if(wrap) { + sprite->frame = bank->timeNum-1; + } else { + sprite->frame = 0; + } + } + frame = &bank->frame[sprite->frame]; + sprite->time += frame->time; + } + } + sprite->dirty_flag = 0; + } + } + } +} + +void HuSprPauseSet(BOOL value) +{ + HuSprPauseF = value; +} + +AnimData *HuSprAnimRead(void *data) +{ + s16 i; + AnimBmpData *bmp; + AnimBankData *bank; + AnimPatData *pat; + + + AnimData *anim = (AnimData *)data; + if((u32)anim->bank & 0xFFFF0000) { + anim->useNum++; + return anim; + } + bank = (AnimBankData *)((u32)anim->bank+(u32)data); + anim->bank = bank; + pat = (AnimPatData *)((u32)anim->pat+(u32)data); + anim->pat = pat; + bmp = (AnimBmpData *)((u32)anim->bmp+(u32)data); + anim->bmp = bmp; + for(i=0; ibankNum; i++, bank++) { + bank->frame = (AnimFrameData *)((u32)bank->frame+(u32)data); + } + for(i=0; ipatNum; i++, pat++) { + pat->layer = (AnimLayerData *)((u32)pat->layer+(u32)data); + } + for(i=0; ibmpNum; i++, bmp++) { + bmp->palData = (void *)((u32)bmp->palData+(u32)data); + bmp->data = (void *)((u32)bmp->data+(u32)data); + } + anim->useNum = 0; + return anim; +} + +void HuSprAnimLock(AnimData *anim) +{ + anim->useNum++; +} + +static s16 bitSizeTbl[11] = { 32, 24, 16, 8, 4, 10, 8, 8, 4, 8, 4 };