This commit is contained in:
Daveo 2001-04-25 16:41:16 +00:00
parent 2f6c1ebd68
commit 60de8af07c
5 changed files with 534 additions and 333 deletions

View File

@ -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,14 +147,8 @@ 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);
s_genericFont=new ("CGameScene::Init") FontBank();
@ -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");
}

View File

@ -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 ACTOR_TYPE getActorType( int actorNum ) {return actorType[actorNum];}
static MATRIX &GetCamMtx() {return(CamMtx);}
protected:
void initLevel();
@ -47,13 +56,15 @@ protected:
void AspectCorrectCamera();
CLevel Level;
class CPauseMenu *m_pauseMenu;
class CPlayer *m_player;
static FontBank *s_genericFont;
static MATRIX CamMtx;
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[];
};

View File

@ -13,125 +13,233 @@
#include <dstructs.h>
/*****************************************************************************/
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; Y<DYN_SLOTH; Y++)
for (int i=0;i<CACHE_TYPE_MAX; i++)
{
for (int X=0; X<DYN_SLOTW; X++)
{
Cache[X][Y].W=0;
}
SlotList[i].NodeList.List=0;
}
}
/*****************************************************************************/
bool CSlotCache::FindSlot(int SprW,int SprH,u16 &TexX,u16 &TexY,u8 &u,u8 &v)
CActorCache::~CActorCache()
{
int W=(SprW+(DYN_W-1))/DYN_W;
int H=(SprH+(DYN_H-1))/DYN_H;
for (int Y=0; Y<DYN_SLOTH; Y++)
{
for (int X=0; X<DYN_SLOTW; X++)
{
if (TakeSlot(X,Y,W,H))
{
printf("TakeSlot %i %i\n",X,Y);
TexX=DYN_SLOTX+(X*DYN_W/4);
TexY=DYN_SLOTY+(Y*DYN_H);
u=(X&3)*64;
v=(Y&3)*64;
return(true);
}
}
}
return(false);
}
/*****************************************************************************/
bool CSlotCache::TakeSlot(int SX,int SY,int SW,int SH)
int CActorCache::GetSizeType(int Size)
{
int W,H;
if (SX+SW>DYN_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; H<SH; H++)
{
for (W=0; W<SW; W++)
{
if (Cache[SX+W][SY+H].W) return(false);
return(-1);
}
/*****************************************************************************/
int CActorCache::GetSlot(int W,int H)
{
int i;
int Slot=0;
W=GetSizeType(W);
H=GetSizeType(H);
for (i=0; i<SlotCount && !Slot; i++)
{ // Slot exist?
if (SlotList[i].Width==W && SlotList[i].Height==H) Slot=i;
}
if (!Slot)
{ // Use New Slot
ASSERT(SlotCount!=CACHE_TYPE_MAX);
Slot=SlotCount;
SlotList[Slot].Width=W;
SlotList[Slot].Height=H;
SlotCount++;
}
// Slot good
for (H=0; H<SH; H++)
SlotList[Slot].RefCount++;
return(Slot);
}
/*****************************************************************************/
sPoolNode *CActorCache::RemoveHeadNode(sNodeList *Root)
{
sPoolNode *Node=Root->List;
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
{
for (W=0; W<SW; W++)
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; i<SlotCount; i++)
{
Cache[SX+W][SY+H].W=SW;
Cache[SX+W][SY+H].H=SH;
// printf("Slot %i: (%i) %i %i=%i\n",i,SlotList[i].RefCount,SlotList[i].Width,SlotList[i].Height,SlotList[i].FrameCount);
InitCache(i,TPW);
}
}
/*****************************************************************************/
// This needs improving to 'grab' free areas left from bigger grabs (YIKES!)
void CActorCache::InitCache(int Slot,int TPW)
{
sPoolSlot *ThisSlot=&SlotList[Slot];
int W=(TPW*(TPAGE_W))/ThisSlot->Width;
int H=(TPAGE_H)/ThisSlot->Height;
int Total=W*H;
sPoolNode *List;
// Init List
List=(sPoolNode*)MemAlloc(Total*sizeof(sPoolNode),"CacheNodeList");
// Create List Entries
for (int Y=0; Y<H; Y++)
{
for (int X=0; X<W; X++)
{
int U=(X*ThisSlot->Width);
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++;
}
}
return(true);
CurrentTPX+=(TPW*TPAGE_W)>>2;
}
/*****************************************************************************/
void CActorCache::Reset()
{
// Free and init lists
for (int i=0;i<CACHE_TYPE_MAX; i++)
{
if (SlotList[i].NodeList.List) MemFree(SlotList[i].NodeList.List);
SlotList[i].NodeList.List=0;
SlotList[i].NodeList.LastNode=0;
SlotList[i].RefCount=0;
SlotList[i].FrameCount=0;
SlotList[i].Width=0;
SlotList[i].Height=0;
}
// Init VRam Table
for (int Y=0; Y<CACHE_TABLE_H; Y++)
{
for (int X=0; X<CACHE_TABLE_W; X++)
{
SlotTable[X][Y]=0;
}
}
CurrentTPX=0;
CurrentPalette=0;
SlotCount=0;
// Clear VRam
RECT R={512,256,512,250};
ClearImage(&R,0,255,0);
}
/*****************************************************************************/
void CActorCache::LoadPalette(sActorPool *Actor)
{
RECT R;
int X=CurrentPalette%(((CACHE_W*TPAGE_W)/CACHE_PALW));
int Y=CurrentPalette/(((CACHE_W*TPAGE_W)/CACHE_PALW)-1);
// Cheap bodge at mo
if (Actor->Filename==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; i<MAX_ACTORS; i++)
{
ActorPool[i].SpriteBank=0;
}
CActorGfx::ResetCache();
Cache.Reset();
ActorList=0;
LastActor=0;
}
/*****************************************************************************/
int CActorPool::FindActorInPool(FileEquate Filename)
void CActorPool::Reset()
{
for (int i=0; i<MAX_ACTORS; i++)
sActorPool *List=ActorList;
while (List)
{
if (ActorPool[i].SpriteBank && ActorPool[i].Filename==Filename) return(i);
sActorPool *Next=List->Next;
if (List->Filename!=ACTORS_SPONGEBOB_SBK)
{
MemFree(List->ActorGfx);
delete List;
}
return(-1);
else
{
List->Next=0;
}
List=Next;
}
Cache.Reset();
}
/*****************************************************************************/
int CActorPool::FindFreeActor()
void CActorPool::SetUpCache()
{
for (int i=0; i<MAX_ACTORS; i++)
Cache.AllocCache();
// SetUp Actors
sActorPool *List=ActorList;
while (List)
{
if (ActorPool[i].SpriteBank==0) return(i);
List->CachePool=Cache.GetSlotList(List->CacheSlot);
List->ThisCache.List=0;
List->ThisCache.LastNode=0;
List=List->Next;
}
return(-1);
}
/*****************************************************************************/
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; i<Spr->AnimCount; 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; i<Spr->FrameCount; 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);
if (!LastActor)
{ // Empty List
ActorList=NewActor;
}
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; i<MAX_ACTORS; i++)
else
{
if (ActorPool[i].SpriteBank && ActorPool[i].Filename!=ACTORS_SPONGEBOB_SBK)
{
if (ActorPool[i].SpriteBank) MemFree(ActorPool[i].SpriteBank);
ActorPool[i].SpriteBank=0;
LastActor->Next=NewActor;
}
}
printf("DumpActorsDone\n");
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; Anim<PoolEntry->ActorGfx->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;
// Is cached?
// if(this->PoolEntry->Filename==ACTORS_SPONGEBOB_SBK) return(0);
ThisNode=PoolEntry->ThisCache.List;
while (ThisNode)
{
if (ThisNode->Anim==Anim && ThisNode->Frame==Frame) break;
ThisNode=ThisNode->Next;
}
if (!ThisNode)
{ // Not cached frame
ThisNode=CActorCache::RemoveHeadNode(PoolEntry->CachePool);
CActorCache::AddNode(ThisNode,&PoolEntry->ThisCache);
RECT R;
ThisNode->Anim=Anim;
ThisNode->Frame=Frame;
PAK_doUnpak(UnpackBuffer,FrameGfx->PAKSpr);
// Gfx
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);
}
RECT Rect;
Rect.x=TexX;
Rect.y=TexY;
Rect.w=FrameGfx->W/4;
Rect.h=FrameGfx->H;
LoadImage( &Rect, (u32*)UnpackBuffer);
POLY_FT4 *Ft4=GetPrimFT4();
SetUpFT4(Ft4,FrameGfx,Pos.vx,Pos.vy,XFlip,YFlip);
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)
{

View File

@ -12,120 +12,152 @@
#include <biglump.h>
#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();
virtual ~CActorGfx();
enum
{
ShadowXOfs =32,
ShadowYOfs =32,
void SetData(FileEquate Filename,sSpriteAnimBank *_SpriteBank,u16 _Clut);
static void ResetCache();
};
CActorGfx(sActorPool *ThisActor);
virtual ~CActorGfx();
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);}
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
{

View File

@ -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);
}