diff --git a/source/game/game.cpp b/source/game/game.cpp index 2446e002d..f93803bba 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -77,6 +77,50 @@ int RenderZ=256; FontBank *CGameScene::s_genericFont; MATRIX CGameScene::CamMtx; +/*****************************************************************************/ +CGameScene::ACTOR_TYPE CGameScene::actorType[39] = +{ + ACTOR_PLAYER, //SpongeBob=0 + ACTOR_FRIEND_NPC, //BarnacleBoy=1 + ACTOR_FRIEND_NPC, //Gary=2 + ACTOR_FRIEND_NPC, //Krusty=3 + ACTOR_FRIEND_NPC, //MermaidMan=4 + ACTOR_FRIEND_NPC, //Patrick=5 + ACTOR_FRIEND_NPC, //Sandy=6 + ACTOR_FRIEND_NPC, //Squidward=7 + ACTOR_FRIEND_NPC, //Plankton=8 + ACTOR_UNKNOWN, + ACTOR_ENEMY_NPC, //SmallJellyfish-Level1=10 + ACTOR_ENEMY_NPC, //SmallJellyfish-Level2=11 + ACTOR_ENEMY_NPC, //Motherjellyfish=12 + ACTOR_ENEMY_NPC, //Anenome-Level1=13 + ACTOR_ENEMY_NPC, //SpikeyAnenome=14 + ACTOR_ENEMY_NPC, //Anenome-Level3=15 + ACTOR_ENEMY_NPC, //BabyOctopus=16 + ACTOR_ENEMY_NPC, //Ballblob=17 + ACTOR_ENEMY_NPC, //Boogermonster=18 + ACTOR_ENEMY_NPC, //Caterpillar=19 + ACTOR_ENEMY_NPC, //Clam-Level1=20 + ACTOR_ENEMY_NPC, //Clam-Level2=21 + ACTOR_ENEMY_NPC, //Eyeball=22 + ACTOR_ENEMY_NPC, //Flamingskull=23 + ACTOR_ENEMY_NPC, //FlyingDutchman=24 + ACTOR_ENEMY_NPC, //Ghost=25 + ACTOR_ENEMY_NPC, //GiantWorm=26 + ACTOR_ENEMY_NPC, //HermitCrab=27 + ACTOR_ENEMY_NPC, //IronDogFish=28 + ACTOR_ENEMY_NPC, //PuffaFish=29 + ACTOR_ENEMY_NPC, //SeaSnake=30 + ACTOR_ENEMY_NPC, //Sharkman=31 + ACTOR_ENEMY_NPC, //SharkSub=32 + ACTOR_ENEMY_NPC, //Skeletalfish=33 + ACTOR_ENEMY_NPC, //SpiderCrab=34 + ACTOR_ENEMY_NPC, //Squiddart=35 + ACTOR_ENEMY_NPC, //Stomper=36 + ACTOR_ENEMY_NPC, //DustDevil=37 + ACTOR_ENEMY_NPC, //SiderCrabSpawner=38 +}; + /*****************************************************************************/ int s_globalLevelSelectThing=0; @@ -103,15 +147,9 @@ const s32 Scale = (512<<12)/(256); void CGameScene::init() { // Setup Constant Camera Matrix -// SetIdentNoTrans(&CamMtx); -// CamMtx.t[2]=ZPos; -// AspectCorrectCamera(); -// SetRotMatrix(&CamMtx); -// SetTransMatrix(&CamMtx); - + SetIdentTrans(&CamMtx,0,0,RenderZ); SetGeomScreen(RenderZ); - CamMtx.t[2]=RenderZ; - SetTransMatrix(&CamMtx); + SetTransMatrix(&CamMtx); s_genericFont=new ("CGameScene::Init") FontBank(); s_genericFont->initialise( &standardFont ); @@ -127,8 +165,8 @@ void CGameScene::init() CFader::setFadingIn(); initLevel(); -} +} /*****************************************************************************/ // This is a seperate funtion ( and virtual ) so that we can overload it for // the demo mode (pkg) @@ -164,6 +202,12 @@ void CGameScene::render() m_pauseMenu->render(); CConversation::render(); CThingManager::renderAllThings(); + + SetIdentTrans(&CamMtx,0,0,RenderZ); + SetGeomScreen(RenderZ); + SetRotMatrix(&CamMtx); + SetTransMatrix(&CamMtx); + Level.render(); } @@ -265,10 +309,10 @@ void CGameScene::initLevel() for ( actorNum = 0 ; actorNum < Level.getActorCount() ; actorNum++ ) { sThingActor *ThisActor=actorList[actorNum]; - CActorPool::ACTOR_TYPE actorType = CActorPool::getActorType( actorList[actorNum]->Type ); + CGameScene::ACTOR_TYPE actorType = CGameScene::getActorType( actorList[actorNum]->Type ); switch ( actorType ) { - case CActorPool::ACTOR_ENEMY_NPC: + case CGameScene::ACTOR_ENEMY_NPC: { CNpcEnemy *enemy; enemy=CNpcEnemy::Create(ThisActor); @@ -300,8 +344,8 @@ void CGameScene::initLevel() // Song is loaded/dumped by the level, and played from here. This just gives some // better timing over when it starts (pkg) CSoundMediator::playSong(); + CActorPool::SetUpCache(); printf("InitLevelDone\n"); - } diff --git a/source/game/game.h b/source/game/game.h index 0bcd3b841..17afd104e 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -21,6 +21,13 @@ class CGameScene : public CScene public: CGameScene() {;} virtual ~CGameScene() {;} + enum ACTOR_TYPE + { + ACTOR_PLAYER = 0, + ACTOR_FRIEND_NPC = 1, + ACTOR_ENEMY_NPC, + ACTOR_UNKNOWN, + }; void init(); @@ -35,10 +42,12 @@ virtual int canPause(); CPlayer *getPlayer(); void sendEvent( GAME_EVENT evt, class CThing *sourceThing ); - static void setReadyToExit() {s_readyToExit=true;} - static void levelFinished() {s_levelFinished=true;} +static void setReadyToExit() {s_readyToExit=true;} +static void levelFinished() {s_levelFinished=true;} - static MATRIX &GetCamMtx() {return(CamMtx);} +// static MATRIX &GetCamMtx() {return(CamMtx);} +static ACTOR_TYPE getActorType( int actorNum ) {return actorType[actorNum];} + protected: void initLevel(); @@ -46,14 +55,16 @@ protected: void AspectCorrectCamera(); - CLevel Level; - class CPauseMenu *m_pauseMenu; - class CPlayer *m_player; - static FontBank *s_genericFont; - static MATRIX CamMtx; + CLevel Level; +class CPauseMenu *m_pauseMenu; +class CPlayer *m_player; +static FontBank *s_genericFont; +static MATRIX CamMtx; - static int s_readyToExit; - static int s_levelFinished; +static int s_readyToExit; +static int s_levelFinished; + +static ACTOR_TYPE actorType[]; }; diff --git a/source/gfx/actor.cpp b/source/gfx/actor.cpp index bcd66892a..fbc1067a2 100644 --- a/source/gfx/actor.cpp +++ b/source/gfx/actor.cpp @@ -13,125 +13,233 @@ #include /*****************************************************************************/ -int ShadowXOfs=32; -int ShadowYOfs=32; +CActorCache CActorPool::Cache; +sActorPool *CActorPool::ActorList,*CActorPool::LastActor; + +u8 CActorGfx::UnpackBuffer[CActorCache::MAX_ACTOR_SIZE]; /*****************************************************************************/ - -CActorPool::ACTOR_TYPE CActorPool::actorType[39] = +/*** Cache *******************************************************************/ +/*****************************************************************************/ +CActorCache::CActorCache() { - ACTOR_PLAYER, //SpongeBob=0 - ACTOR_FRIEND_NPC, //BarnacleBoy=1 - ACTOR_FRIEND_NPC, //Gary=2 - ACTOR_FRIEND_NPC, //Krusty=3 - ACTOR_FRIEND_NPC, //MermaidMan=4 - ACTOR_FRIEND_NPC, //Patrick=5 - ACTOR_FRIEND_NPC, //Sandy=6 - ACTOR_FRIEND_NPC, //Squidward=7 - ACTOR_FRIEND_NPC, //Plankton=8 - ACTOR_UNKNOWN, - ACTOR_ENEMY_NPC, //SmallJellyfish-Level1=10 - ACTOR_ENEMY_NPC, //SmallJellyfish-Level2=11 - ACTOR_ENEMY_NPC, //Motherjellyfish=12 - ACTOR_ENEMY_NPC, //Anenome-Level1=13 - ACTOR_ENEMY_NPC, //SpikeyAnenome=14 - ACTOR_ENEMY_NPC, //Anenome-Level3=15 - ACTOR_ENEMY_NPC, //BabyOctopus=16 - ACTOR_ENEMY_NPC, //Ballblob=17 - ACTOR_ENEMY_NPC, //Boogermonster=18 - ACTOR_ENEMY_NPC, //Caterpillar=19 - ACTOR_ENEMY_NPC, //Clam-Level1=20 - ACTOR_ENEMY_NPC, //Clam-Level2=21 - ACTOR_ENEMY_NPC, //Eyeball=22 - ACTOR_ENEMY_NPC, //Flamingskull=23 - ACTOR_ENEMY_NPC, //FlyingDutchman=24 - ACTOR_ENEMY_NPC, //Ghost=25 - ACTOR_ENEMY_NPC, //GiantWorm=26 - ACTOR_ENEMY_NPC, //HermitCrab=27 - ACTOR_ENEMY_NPC, //IronDogFish=28 - ACTOR_ENEMY_NPC, //PuffaFish=29 - ACTOR_ENEMY_NPC, //SeaSnake=30 - ACTOR_ENEMY_NPC, //Sharkman=31 - ACTOR_ENEMY_NPC, //SharkSub=32 - ACTOR_ENEMY_NPC, //Skeletalfish=33 - ACTOR_ENEMY_NPC, //SpiderCrab=34 - ACTOR_ENEMY_NPC, //Squiddart=35 - ACTOR_ENEMY_NPC, //Stomper=36 - ACTOR_ENEMY_NPC, //DustDevil=37 - ACTOR_ENEMY_NPC, //SiderCrabSpawner=38 -}; - -/*****************************************************************************/ -sActorPool CActorPool::ActorPool[MAX_ACTORS]; - -CSlotCache CActorGfx::SlotCache; -u8 CActorGfx::UnpackBuffer[CActorPool::MAX_ACTOR_SIZE]; - -/*****************************************************************************/ -/*** Slot Cache **************************************************************/ -/*****************************************************************************/ -void CSlotCache::Init() -{ - for (int Y=0; YDYN_SLOTW) return(false); - if (SY+SH>DYN_SLOTH) return(false); - if ((SX&3)==3 && SW>1) return(false); + if (Size<= 16) return(16); + if (Size<= 32) return(32); + if (Size<= 64) return(64); + if (Size<=128) return(128); + if (Size<=256) return(256); + ASSERT(!"SPRITE SIZE NOT SUPPORTED"); - for (H=0; HList; +sPoolNode *Next=Node->Next; + + Root->List=Node->Next; + Next->Prev=0; + Node->Next=0; + return(Node); +} + +/*****************************************************************************/ +void CActorCache::RemoveNode(sPoolNode *Node,sNodeList *Root) +{ +sPoolNode *Prev=Node->Prev; +sPoolNode *Next=Node->Next; + + if (Prev) + { // Not Head Node + Prev->Next=Node->Next; + } + if (Next) + { // Not Tail Node + Next->Prev=Node->Prev; + } +} + +/*****************************************************************************/ +// Add node to end of list +void CActorCache::AddNode(sPoolNode *Node,sNodeList *Root) +{ +sPoolNode *Prev=Root->LastNode; +sPoolNode *Next=0; + + if (Prev) + { // Not Head Node + Prev->Next=Node; + } + else + { + Root->List=Node; + } + + Node->Prev=Prev; + Node->Next=0; + Root->LastNode=Node; +} + +/*****************************************************************************/ +int CActorCache::ReserveSlot(int W,int H,int FrameCount) +{ +int Slot=GetSlot(W,H); + SlotList[Slot].FrameCount+=FrameCount; + return(Slot); +} + +/*****************************************************************************/ +void CActorCache::AllocCache() +{ +int TPW=CACHE_W/SlotCount; + + for (int i=0; iWidth; +int H=(TPAGE_H)/ThisSlot->Height; +int Total=W*H; +sPoolNode *List; + +// Init List - return(true); + List=(sPoolNode*)MemAlloc(Total*sizeof(sPoolNode),"CacheNodeList"); + +// Create List Entries + for (int Y=0; YWidth); + int V=Y*ThisSlot->Height; + int TexX=CACHE_X+CurrentTPX+(U>>2); + int TexY=CACHE_Y+V; + + List->Actor=0; + List->TexX=TexX; + List->TexY=TexY; + List->U=U&255; + List->V=V&255; + List->TPage=getTPage(0,0,TexX,TexX); + AddNode(List,&ThisSlot->NodeList); + List++; + } + } + + CurrentTPX+=(TPW*TPAGE_W)>>2; +} + +/*****************************************************************************/ +void CActorCache::Reset() +{ +// Free and init lists + for (int i=0;iFilename==ACTORS_SPONGEBOB_SBK) + { + R.x=512; + R.y=511; + } + else + { + R.x=CACHE_PALX+(CurrentPalette*CACHE_PALW); + R.y=CACHE_PALY-Y; + } + + R.w=CACHE_PALW; + R.h=CACHE_PALH; + DrawSync(0); + LoadImage( &R, (u32*)Actor->ActorGfx->Palette); + + Actor->ActorGfx->Clut=getClut(R.x,R.y); + CurrentPalette++; } /*****************************************************************************/ @@ -139,54 +247,110 @@ int W,H; /*****************************************************************************/ void CActorPool::Init() { -int i; - for (i=0; iNext; + if (List->Filename!=ACTORS_SPONGEBOB_SBK) + { + MemFree(List->ActorGfx); + delete List; + } + else + { + List->Next=0; + } + List=Next; + } + Cache.Reset(); } /*****************************************************************************/ -int CActorPool::FindFreeActor() +void CActorPool::SetUpCache() { - for (int i=0; iCachePool=Cache.GetSlotList(List->CacheSlot); + List->ThisCache.List=0; + List->ThisCache.LastNode=0; + List=List->Next; + } } /*****************************************************************************/ -int CActorPool::LoadActor(FileEquate Filename) +sActorPool *CActorPool::FindActor(FileEquate Filename) +{ +sActorPool *List=ActorList; + + while (List) + { + if (List->ActorGfx && List->Filename==Filename) return(List); + List=List->Next; + } + return(0); +} + +/*****************************************************************************/ +CActorGfx *CActorPool::GetActor(FileEquate Filename) +{ +sActorPool *ThisActor; +CActorGfx *NewActor; +int TotalFrames=0; +bool NewFlag=false; +// Find Actor in Pool + ThisActor=FindActor(Filename); + if (!ThisActor) + { + ThisActor=LoadActor(Filename); + NewFlag=true; + } + + NewActor=new ("CActorGfx") CActorGfx(ThisActor); + if (NewFlag) + { + TotalFrames=NewActor->GetTotalFrameCount(); + } + + ThisActor->CacheSlot=Cache.ReserveSlot(ThisActor->ActorGfx->MaxW,ThisActor->ActorGfx->MaxH,TotalFrames); + + return(NewActor); +} + +/*****************************************************************************/ +sActorPool *CActorPool::LoadActor(FileEquate Filename) { int i; +int TotalFrames=0; sSpriteAnimBank *Spr=(sSpriteAnimBank*)CFileIO::loadFile(Filename); +// printf("Add Actor %i\n",(int)Filename); Spr->AnimList=(sSpriteAnim*) MakePtr(Spr,(int)Spr->AnimList); Spr->FrameList=(sSpriteFrame*) MakePtr(Spr,(int)Spr->FrameList); Spr->Palette=(u8*) MakePtr(Spr,(int)Spr->Palette); // FixUp AnimList - DAVE_DBGMSG("Anims %i\n",Spr->AnimCount); for (i=0; iAnimCount; i++) { sSpriteAnim *ThisAnim=&Spr->AnimList[i]; ThisAnim->Anim=(u16*) MakePtr(Spr,(int)ThisAnim->Anim); + TotalFrames+=ThisAnim->FrameCount; } + // FixUp FrameList - DAVE_DBGMSG("Anims %i\n",Spr->FrameCount); for (i=0; iFrameCount; i++) { sSpriteFrame *ThisFrame=&Spr->FrameList[i]; @@ -194,79 +358,32 @@ sSpriteAnimBank *Spr=(sSpriteAnimBank*)CFileIO::loadFile(Filename); } // Store it -int Idx=FindFreeActor(); - ASSERT(Idx!=-1); +sActorPool *NewActor; -sActorPool &ThisActor=ActorPool[Idx]; + NewActor=new ("ActorPool") sActorPool(); + NewActor->Filename=Filename; + NewActor->ActorGfx=Spr; + AddActor(NewActor); - ThisActor.Filename=Filename; - ThisActor.SpriteBank=Spr; - ThisActor.RefCount=1; - ThisActor.Clut=LoadPalette(ThisActor,Idx); - - return(Idx); + return(NewActor); } /*****************************************************************************/ -#define DYN_PALW 64 -#define DYN_PALH 1 -#define DYN_PALX 512 -#define DYN_PALY 511 - -u16 CActorPool::LoadPalette(sActorPool &ThisActor,int Idx) +void CActorPool::AddActor(sActorPool *NewActor) { -RECT R; -int X=Idx&31; -int Y=Idx%31; +// Insert into list - R.x=DYN_PALX+(Idx*DYN_PALW); - R.y=DYN_PALY-Y; - R.w=DYN_PALW; - R.h=DYN_PALH; -// DrawSync(0); - LoadImage( &R, (u32*)ThisActor.SpriteBank->Palette); - -int Clut=getClut(R.x,R.y); - return(Clut); -} - -/*****************************************************************************/ -CActorGfx *CActorPool::GetActor(FileEquate Filename) -{ -CActorGfx *Actor; -int Idx; - -// Find Actor in Pool - Idx=FindActorInPool(Filename); - if (Idx==-1) - { - Idx=LoadActor(Filename); - } - -sActorPool &ThisActor=ActorPool[Idx]; - Actor=new ("CActorGfx") CActorGfx; - Actor->SetData(Filename,ThisActor.SpriteBank,ThisActor.Clut); - ThisActor.RefCount++; - return(Actor); -} - -/*****************************************************************************/ -/*** Dump ********************************************************************/ -/*****************************************************************************/ -// Dumps all apart from spongeybob -void CActorPool::DumpActors() -{ - printf("DumpActors\n"); - for (int i=0; iNext=NewActor; + } + NewActor->Next=0; + Cache.LoadPalette(NewActor); + LastActor=NewActor; } /*****************************************************************************/ @@ -275,8 +392,10 @@ void CActorPool::DumpActors() /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ -CActorGfx::CActorGfx() +/*****************************************************************************/ +CActorGfx::CActorGfx(sActorPool *ThisActor) { + PoolEntry=ThisActor; } /*****************************************************************************/ @@ -284,71 +403,70 @@ CActorGfx::~CActorGfx() { } -/*****************************************************************************/ -void CActorGfx::SetData(FileEquate Filename,sSpriteAnimBank *_SpriteBank,u16 _Clut) -{ - SpriteBank=_SpriteBank; - Clut=_Clut; - - if (Filename!=ACTORS_SPONGEBOB_SBK) - { - bool SlotStatus=SlotCache.FindSlot(_SpriteBank->MaxW,_SpriteBank->MaxH,TexX,TexY,U,V); - ASSERT(SlotStatus); - } - else - { - TexX=512; - TexY=256; - U=0; - V=0; - } - TPage=getTPage(0,0,TexX,TexY); -} - -/*****************************************************************************/ -void CActorGfx::ResetCache() -{ -RECT R; - SlotCache.Init(); - R.x=512; - R.y=256; - R.w=512; - R.h=250; - ClearImage(&R,0,255,0); -} - /*****************************************************************************/ sSpriteFrame *CActorGfx::GetFrame(int Anim,int Frame) { -sSpriteAnim *ThisAnim=SpriteBank->AnimList+Anim; + +sSpriteAnim *ThisAnim=PoolEntry->ActorGfx->AnimList+Anim; u16 ThisFrame=ThisAnim->Anim[Frame]; - return(SpriteBank->FrameList+ThisFrame); + return(PoolEntry->ActorGfx->FrameList+ThisFrame); } /*****************************************************************************/ +int CActorGfx::GetTotalFrameCount() +{ +int Total=0; + for (int Anim=0; AnimActorGfx->AnimCount; Anim++) + { + sSpriteAnim *ThisAnim=PoolEntry->ActorGfx->AnimList+Anim; + Total+=ThisAnim->FrameCount; + } + return(Total); +} + +/*****************************************************************************/ int ActorOT=10; + POLY_FT4 *CActorGfx::Render(DVECTOR &Pos,int Anim,int Frame,bool XFlip,bool YFlip,bool Shadow) { sSpriteFrame *FrameGfx=GetFrame(Anim,Frame); +sPoolNode *ThisNode;; +POLY_FT4 *Ft4; - PAK_doUnpak(UnpackBuffer,FrameGfx->PAKSpr); -// Gfx +// Is cached? +// if(this->PoolEntry->Filename==ACTORS_SPONGEBOB_SBK) return(0); -RECT Rect; - Rect.x=TexX; - Rect.y=TexY; - Rect.w=FrameGfx->W/4; - Rect.h=FrameGfx->H; + ThisNode=PoolEntry->ThisCache.List; + while (ThisNode) + { + if (ThisNode->Anim==Anim && ThisNode->Frame==Frame) break; + ThisNode=ThisNode->Next; + } - LoadImage( &Rect, (u32*)UnpackBuffer); + if (!ThisNode) + { // Not cached frame + ThisNode=CActorCache::RemoveHeadNode(PoolEntry->CachePool); + CActorCache::AddNode(ThisNode,&PoolEntry->ThisCache); + RECT R; -POLY_FT4 *Ft4=GetPrimFT4(); - SetUpFT4(Ft4,FrameGfx,Pos.vx,Pos.vy,XFlip,YFlip); + ThisNode->Anim=Anim; + ThisNode->Frame=Frame; + + PAK_doUnpak(UnpackBuffer,FrameGfx->PAKSpr); + R.x=ThisNode->TexX; + R.y=ThisNode->TexY; + R.w=FrameGfx->W>>2; // div 4 cos 16 color + R.h=FrameGfx->H; + LoadImage( &R, (u32*)UnpackBuffer); + } + + Ft4=GetPrimFT4(); + SetUpFT4(Ft4,FrameGfx,ThisNode,Pos.vx,Pos.vy,XFlip,YFlip); setRGB0(Ft4,128,128,128); - Ft4->tpage=TPage; - Ft4->clut=Clut; + Ft4->tpage=ThisNode->TPage; + Ft4->clut=PoolEntry->ActorGfx->Clut; AddPrimToList(Ft4,ActorOT); if (Shadow) @@ -368,10 +486,12 @@ POLY_FT4 *Ft4=GetPrimFT4(); } /*****************************************************************************/ -void CActorGfx::SetUpFT4(POLY_FT4 *Ft4,sSpriteFrame *Frame,int X,int Y,bool XFlip,bool YFlip) +void CActorGfx::SetUpFT4(POLY_FT4 *Ft4,sSpriteFrame *Frame,sPoolNode *Node,int X,int Y,bool XFlip,bool YFlip) { u8 W=Frame->W; u8 H=Frame->H; +u8 U=Node->U; +u8 V=Node->V; if (XFlip) { @@ -387,9 +507,9 @@ u8 H=Frame->H; { X+=Frame->XOfs; Ft4->u0=U; - Ft4->u1=U+W; + Ft4->u1=U+W-1; Ft4->u2=U; - Ft4->u3=U+W; + Ft4->u3=U+W-1; } @@ -489,12 +609,6 @@ int ShiftY=(Pos.vy & 15); TList++; gte_nclip_b(); gte_stsxy3_ft3(TPrimPtr); -// if (TriCount==1) -// { -// printf("%i,%i\n",TPrimPtr->x0,TPrimPtr->y0); -// -// } - gte_stopz(&ClipZ); if (ClipZ<=0) { diff --git a/source/gfx/actor.h b/source/gfx/actor.h index 72cb04caa..4d772f142 100644 --- a/source/gfx/actor.h +++ b/source/gfx/actor.h @@ -12,120 +12,152 @@ #include #endif -struct sSlot +/*****************************************************************************/ +// Pack together Actor anim & frame for quicker check later +struct sPoolNode { - u16 W,H; + u16 Actor; + u16 Anim; + u16 Frame; + u16 TPage; + u16 TexX,TexY; + u8 U,V; + sPoolNode *Prev,*Next; +}; + +struct sNodeList +{ + sPoolNode *List; + sPoolNode *LastNode; +}; + +struct sPoolSlot +{ + u16 Width,Height; + u16 RefCount; + u16 FrameCount; + sNodeList NodeList; }; /*****************************************************************************/ struct sActorPool { FileEquate Filename; - sSpriteAnimBank *SpriteBank; - u16 RefCount; - u16 Clut; + sSpriteAnimBank *ActorGfx; + int CacheSlot; + sNodeList *CachePool; + sNodeList ThisCache; + sActorPool *Next; }; /*****************************************************************************/ -class CSlotCache +class CActorCache { public: enum { - DYN_W =64, - DYN_H =64, - DYN_TPAGEW =4*256, - DYN_TPAGEH =1*256, - DYN_SLOTW =(DYN_TPAGEW/DYN_W), - DYN_SLOTH =(DYN_TPAGEH/DYN_H), - DYN_SLOTX =512+256, - DYN_SLOTY =256, + TPAGE_W =256, + TPAGE_H =256-4, + + CACHE_X =512+256, + CACHE_Y =256, + CACHE_W =4, + CACHE_H =1, + + CACHE_PALX =CACHE_X, + CACHE_PALY =511, + CACHE_PALW =64, + CACHE_PALH =1, + + CACHE_TABLE_W =(TPAGE_W*CACHE_W)/32, + CACHE_TABLE_H =(TPAGE_H*CACHE_H)/32, + + CACHE_TYPE_MAX =8, + + MAX_ACTOR_W =128, + MAX_ACTOR_H =128, + MAX_ACTOR_SIZE =MAX_ACTOR_W*MAX_ACTOR_H, }; - CSlotCache(){}; - ~CSlotCache(){}; + CActorCache(); + ~CActorCache(); + + int ReserveSlot(int W,int H,int FrameCount); + void AllocCache(); + void Reset(); + void LoadPalette(sActorPool *NewActor); + sNodeList *GetSlotList(int Slot) {return(&SlotList[Slot].NodeList);} + +static sPoolNode *RemoveHeadNode(sNodeList *Root); +static void RemoveNode(sPoolNode *Node,sNodeList *Root); +static void AddNode(sPoolNode *Node,sNodeList *Root); - void Init(); - bool FindSlot(int SprW,int SprH,u16 &TexX,u16 &TexY,u8 &u,u8 &v); protected: - bool TakeSlot(int SX,int SY,int SW,int SH); + int GetSlot(int W,int H); + void InitCache(int Type,int Count); + int GetSizeType(int Size); - sSlot Cache[DYN_SLOTW][DYN_SLOTH]; + u8 SlotTable[CACHE_TABLE_W][CACHE_TABLE_H]; + sPoolSlot SlotList[CACHE_TYPE_MAX]; + + int CurrentTPX; + int CurrentPalette; + int SlotCount; }; + /*****************************************************************************/ class CActorGfx; class CActorPool { public: - enum - { - MAX_ACTORS =64, - MAX_ACTOR_SIZE= 128*128, - }; - - enum ACTOR_TYPE - { - ACTOR_PLAYER = 0, - ACTOR_FRIEND_NPC = 1, - ACTOR_ENEMY_NPC, - ACTOR_UNKNOWN, - }; static void Init(); +static void Reset(); +static void SetUpCache(); static void AddActor(FileEquate Filename) {GetActor(Filename);} static CActorGfx *GetActor(FileEquate Filename); -static void DumpActors(); - - -static ACTOR_TYPE getActorType( int actorNum ) {return actorType[actorNum];} protected: -static int FindActorInPool(FileEquate Filename); -static int FindFreeActor(); -static int LoadActor(FileEquate Filename); -static u16 LoadPalette(sActorPool &ThisActor,int Idx); - - -static sActorPool ActorPool[]; - -static ACTOR_TYPE actorType[]; +static sActorPool *FindActor(FileEquate Filename); +static sActorPool *LoadActor(FileEquate Filename); +static void AddActor(sActorPool *ThisActor); +static CActorCache Cache; +static sActorPool *ActorList,*LastActor; }; /*****************************************************************************/ class CActorGfx { public: - CActorGfx(); + enum + { + ShadowXOfs =32, + ShadowYOfs =32, + + }; + + CActorGfx(sActorPool *ThisActor); virtual ~CActorGfx(); - void SetData(FileEquate Filename,sSpriteAnimBank *_SpriteBank,u16 _Clut); -static void ResetCache(); - - POLY_FT4 *Render(DVECTOR &Pos,int Anim,int Frame,bool FlipX=false,bool FlipY=false,bool Shadow=false); - - int getFrameCount(int Anim) {return(SpriteBank->AnimList[Anim].FrameCount);} + POLY_FT4 *Render(DVECTOR &Pos,int Anim,int Frame,bool FlipX=false,bool FlipY=false,bool Shadow=false); + int getFrameCount(int Anim) {return(PoolEntry->ActorGfx->AnimList[Anim].FrameCount);} + int GetTotalFrameCount(); protected: - void SetUpFT4(POLY_FT4 *Ft4,sSpriteFrame *ThisFrame,int X,int Y,bool XFlip,bool YFlip); + void SetUpFT4(POLY_FT4 *Ft4,sSpriteFrame *Frame,sPoolNode *Node,int X,int Y,bool XFlip,bool YFlip); sSpriteFrame *GetFrame(int Anim,int Frame); - sSpriteAnimBank *SpriteBank; - -// RECT DrawRect; - u16 Clut; - u16 TPage,TexX,TexY; - u8 U,V; - -static CSlotCache SlotCache; -static u8 UnpackBuffer[CActorPool::MAX_ACTOR_SIZE]; - + sActorPool *PoolEntry; +static u8 UnpackBuffer[CActorCache::MAX_ACTOR_SIZE]; }; +/*****************************************************************************/ +/*****************************************************************************/ /*****************************************************************************/ class CModelGfx { diff --git a/source/level/level.cpp b/source/level/level.cpp index 60d9a0043..fd4569ecf 100644 --- a/source/level/level.cpp +++ b/source/level/level.cpp @@ -122,7 +122,7 @@ void CLevel::init(int LevelNo) // Load it sLvlTab *lvlTab=&LvlTable[LevelNo]; - CActorGfx::ResetCache(); + CActorPool::Reset(); CSoundMediator::setSong((CSoundMediator::SONGID)lvlTab->songId); DisplayLoadingScreen(lvlTab); @@ -345,7 +345,7 @@ void CLevel::shutdown() if (PlatformList) MemFree(PlatformList); MemFree(LevelHdr); - CActorPool::DumpActors(); + CActorPool::Reset(); TPFree(m_levelTPage); }