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; FontBank *CGameScene::s_genericFont;
MATRIX CGameScene::CamMtx; 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; int s_globalLevelSelectThing=0;
@ -103,14 +147,8 @@ const s32 Scale = (512<<12)/(256);
void CGameScene::init() void CGameScene::init()
{ {
// Setup Constant Camera Matrix // Setup Constant Camera Matrix
// SetIdentNoTrans(&CamMtx); SetIdentTrans(&CamMtx,0,0,RenderZ);
// CamMtx.t[2]=ZPos;
// AspectCorrectCamera();
// SetRotMatrix(&CamMtx);
// SetTransMatrix(&CamMtx);
SetGeomScreen(RenderZ); SetGeomScreen(RenderZ);
CamMtx.t[2]=RenderZ;
SetTransMatrix(&CamMtx); SetTransMatrix(&CamMtx);
s_genericFont=new ("CGameScene::Init") FontBank(); s_genericFont=new ("CGameScene::Init") FontBank();
@ -127,8 +165,8 @@ void CGameScene::init()
CFader::setFadingIn(); CFader::setFadingIn();
initLevel(); initLevel();
}
}
/*****************************************************************************/ /*****************************************************************************/
// This is a seperate funtion ( and virtual ) so that we can overload it for // This is a seperate funtion ( and virtual ) so that we can overload it for
// the demo mode (pkg) // the demo mode (pkg)
@ -164,6 +202,12 @@ void CGameScene::render()
m_pauseMenu->render(); m_pauseMenu->render();
CConversation::render(); CConversation::render();
CThingManager::renderAllThings(); CThingManager::renderAllThings();
SetIdentTrans(&CamMtx,0,0,RenderZ);
SetGeomScreen(RenderZ);
SetRotMatrix(&CamMtx);
SetTransMatrix(&CamMtx);
Level.render(); Level.render();
} }
@ -265,10 +309,10 @@ void CGameScene::initLevel()
for ( actorNum = 0 ; actorNum < Level.getActorCount() ; actorNum++ ) for ( actorNum = 0 ; actorNum < Level.getActorCount() ; actorNum++ )
{ {
sThingActor *ThisActor=actorList[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 ) switch ( actorType )
{ {
case CActorPool::ACTOR_ENEMY_NPC: case CGameScene::ACTOR_ENEMY_NPC:
{ {
CNpcEnemy *enemy; CNpcEnemy *enemy;
enemy=CNpcEnemy::Create(ThisActor); 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 // Song is loaded/dumped by the level, and played from here. This just gives some
// better timing over when it starts (pkg) // better timing over when it starts (pkg)
CSoundMediator::playSong(); CSoundMediator::playSong();
CActorPool::SetUpCache();
printf("InitLevelDone\n"); printf("InitLevelDone\n");
} }

View file

@ -21,6 +21,13 @@ class CGameScene : public CScene
public: public:
CGameScene() {;} CGameScene() {;}
virtual ~CGameScene() {;} virtual ~CGameScene() {;}
enum ACTOR_TYPE
{
ACTOR_PLAYER = 0,
ACTOR_FRIEND_NPC = 1,
ACTOR_ENEMY_NPC,
ACTOR_UNKNOWN,
};
void init(); void init();
@ -35,10 +42,12 @@ virtual int canPause();
CPlayer *getPlayer(); CPlayer *getPlayer();
void sendEvent( GAME_EVENT evt, class CThing *sourceThing ); void sendEvent( GAME_EVENT evt, class CThing *sourceThing );
static void setReadyToExit() {s_readyToExit=true;} static void setReadyToExit() {s_readyToExit=true;}
static void levelFinished() {s_levelFinished=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: protected:
void initLevel(); void initLevel();
@ -47,13 +56,15 @@ protected:
void AspectCorrectCamera(); void AspectCorrectCamera();
CLevel Level; CLevel Level;
class CPauseMenu *m_pauseMenu; class CPauseMenu *m_pauseMenu;
class CPlayer *m_player; class CPlayer *m_player;
static FontBank *s_genericFont; static FontBank *s_genericFont;
static MATRIX CamMtx; static MATRIX CamMtx;
static int s_readyToExit; static int s_readyToExit;
static int s_levelFinished; static int s_levelFinished;
static ACTOR_TYPE actorType[];
}; };

View file

@ -13,125 +13,233 @@
#include <dstructs.h> #include <dstructs.h>
/*****************************************************************************/ /*****************************************************************************/
int ShadowXOfs=32; CActorCache CActorPool::Cache;
int ShadowYOfs=32; sActorPool *CActorPool::ActorList,*CActorPool::LastActor;
u8 CActorGfx::UnpackBuffer[CActorCache::MAX_ACTOR_SIZE];
/*****************************************************************************/ /*****************************************************************************/
/*** Cache *******************************************************************/
CActorPool::ACTOR_TYPE CActorPool::actorType[39] = /*****************************************************************************/
CActorCache::CActorCache()
{ {
ACTOR_PLAYER, //SpongeBob=0 for (int i=0;i<CACHE_TYPE_MAX; i++)
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 X=0; X<DYN_SLOTW; X++) SlotList[i].NodeList.List=0;
{
Cache[X][Y].W=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 (Size<= 16) return(16);
if (SX+SW>DYN_SLOTW) return(false); if (Size<= 32) return(32);
if (SY+SH>DYN_SLOTH) return(false); if (Size<= 64) return(64);
if ((SX&3)==3 && SW>1) return(false); if (Size<=128) return(128);
if (Size<=256) return(256);
ASSERT(!"SPRITE SIZE NOT SUPPORTED");
for (H=0; H<SH; H++) return(-1);
{ }
for (W=0; W<SW; W++)
{ /*****************************************************************************/
if (Cache[SX+W][SY+H].W) return(false); 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 SlotList[Slot].RefCount++;
for (H=0; H<SH; H++)
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; // printf("Slot %i: (%i) %i %i=%i\n",i,SlotList[i].RefCount,SlotList[i].Width,SlotList[i].Height,SlotList[i].FrameCount);
Cache[SX+W][SY+H].H=SH; 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() void CActorPool::Init()
{ {
int i; Cache.Reset();
for (i=0; i<MAX_ACTORS; i++) ActorList=0;
{ LastActor=0;
ActorPool[i].SpriteBank=0;
}
CActorGfx::ResetCache();
} }
/*****************************************************************************/ /*****************************************************************************/
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 i;
int TotalFrames=0;
sSpriteAnimBank *Spr=(sSpriteAnimBank*)CFileIO::loadFile(Filename); sSpriteAnimBank *Spr=(sSpriteAnimBank*)CFileIO::loadFile(Filename);
// printf("Add Actor %i\n",(int)Filename);
Spr->AnimList=(sSpriteAnim*) MakePtr(Spr,(int)Spr->AnimList); Spr->AnimList=(sSpriteAnim*) MakePtr(Spr,(int)Spr->AnimList);
Spr->FrameList=(sSpriteFrame*) MakePtr(Spr,(int)Spr->FrameList); Spr->FrameList=(sSpriteFrame*) MakePtr(Spr,(int)Spr->FrameList);
Spr->Palette=(u8*) MakePtr(Spr,(int)Spr->Palette); Spr->Palette=(u8*) MakePtr(Spr,(int)Spr->Palette);
// FixUp AnimList // FixUp AnimList
DAVE_DBGMSG("Anims %i\n",Spr->AnimCount);
for (i=0; i<Spr->AnimCount; i++) for (i=0; i<Spr->AnimCount; i++)
{ {
sSpriteAnim *ThisAnim=&Spr->AnimList[i]; sSpriteAnim *ThisAnim=&Spr->AnimList[i];
ThisAnim->Anim=(u16*) MakePtr(Spr,(int)ThisAnim->Anim); ThisAnim->Anim=(u16*) MakePtr(Spr,(int)ThisAnim->Anim);
TotalFrames+=ThisAnim->FrameCount;
} }
// FixUp FrameList // FixUp FrameList
DAVE_DBGMSG("Anims %i\n",Spr->FrameCount);
for (i=0; i<Spr->FrameCount; i++) for (i=0; i<Spr->FrameCount; i++)
{ {
sSpriteFrame *ThisFrame=&Spr->FrameList[i]; sSpriteFrame *ThisFrame=&Spr->FrameList[i];
@ -194,79 +358,32 @@ sSpriteAnimBank *Spr=(sSpriteAnimBank*)CFileIO::loadFile(Filename);
} }
// Store it // Store it
int Idx=FindFreeActor(); sActorPool *NewActor;
ASSERT(Idx!=-1);
sActorPool &ThisActor=ActorPool[Idx]; NewActor=new ("ActorPool") sActorPool();
NewActor->Filename=Filename;
NewActor->ActorGfx=Spr;
AddActor(NewActor);
ThisActor.Filename=Filename; return(NewActor);
ThisActor.SpriteBank=Spr;
ThisActor.RefCount=1;
ThisActor.Clut=LoadPalette(ThisActor,Idx);
return(Idx);
} }
/*****************************************************************************/ /*****************************************************************************/
#define DYN_PALW 64 void CActorPool::AddActor(sActorPool *NewActor)
#define DYN_PALH 1
#define DYN_PALX 512
#define DYN_PALY 511
u16 CActorPool::LoadPalette(sActorPool &ThisActor,int Idx)
{ {
RECT R; // Insert into list
int X=Idx&31;
int Y=Idx%31;
R.x=DYN_PALX+(Idx*DYN_PALW); if (!LastActor)
R.y=DYN_PALY-Y; { // Empty List
R.w=DYN_PALW; ActorList=NewActor;
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);
} }
else
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++)
{ {
if (ActorPool[i].SpriteBank && ActorPool[i].Filename!=ACTORS_SPONGEBOB_SBK) LastActor->Next=NewActor;
{
if (ActorPool[i].SpriteBank) MemFree(ActorPool[i].SpriteBank);
ActorPool[i].SpriteBank=0;
} }
} NewActor->Next=0;
printf("DumpActorsDone\n"); 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) sSpriteFrame *CActorGfx::GetFrame(int Anim,int Frame)
{ {
sSpriteAnim *ThisAnim=SpriteBank->AnimList+Anim;
sSpriteAnim *ThisAnim=PoolEntry->ActorGfx->AnimList+Anim;
u16 ThisFrame=ThisAnim->Anim[Frame]; 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; int ActorOT=10;
POLY_FT4 *CActorGfx::Render(DVECTOR &Pos,int Anim,int Frame,bool XFlip,bool YFlip,bool Shadow) POLY_FT4 *CActorGfx::Render(DVECTOR &Pos,int Anim,int Frame,bool XFlip,bool YFlip,bool Shadow)
{ {
sSpriteFrame *FrameGfx=GetFrame(Anim,Frame); 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); 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; Ft4=GetPrimFT4();
Rect.x=TexX; SetUpFT4(Ft4,FrameGfx,ThisNode,Pos.vx,Pos.vy,XFlip,YFlip);
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);
setRGB0(Ft4,128,128,128); setRGB0(Ft4,128,128,128);
Ft4->tpage=TPage; Ft4->tpage=ThisNode->TPage;
Ft4->clut=Clut; Ft4->clut=PoolEntry->ActorGfx->Clut;
AddPrimToList(Ft4,ActorOT); AddPrimToList(Ft4,ActorOT);
if (Shadow) 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 W=Frame->W;
u8 H=Frame->H; u8 H=Frame->H;
u8 U=Node->U;
u8 V=Node->V;
if (XFlip) if (XFlip)
{ {
@ -387,9 +507,9 @@ u8 H=Frame->H;
{ {
X+=Frame->XOfs; X+=Frame->XOfs;
Ft4->u0=U; Ft4->u0=U;
Ft4->u1=U+W; Ft4->u1=U+W-1;
Ft4->u2=U; Ft4->u2=U;
Ft4->u3=U+W; Ft4->u3=U+W-1;
} }
@ -489,12 +609,6 @@ int ShiftY=(Pos.vy & 15);
TList++; TList++;
gte_nclip_b(); gte_nclip_b();
gte_stsxy3_ft3(TPrimPtr); gte_stsxy3_ft3(TPrimPtr);
// if (TriCount==1)
// {
// printf("%i,%i\n",TPrimPtr->x0,TPrimPtr->y0);
//
// }
gte_stopz(&ClipZ); gte_stopz(&ClipZ);
if (ClipZ<=0) if (ClipZ<=0)
{ {

View file

@ -12,120 +12,152 @@
#include <biglump.h> #include <biglump.h>
#endif #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 struct sActorPool
{ {
FileEquate Filename; FileEquate Filename;
sSpriteAnimBank *SpriteBank; sSpriteAnimBank *ActorGfx;
u16 RefCount; int CacheSlot;
u16 Clut; sNodeList *CachePool;
sNodeList ThisCache;
sActorPool *Next;
}; };
/*****************************************************************************/ /*****************************************************************************/
class CSlotCache class CActorCache
{ {
public: public:
enum enum
{ {
DYN_W =64, TPAGE_W =256,
DYN_H =64, TPAGE_H =256-4,
DYN_TPAGEW =4*256,
DYN_TPAGEH =1*256, CACHE_X =512+256,
DYN_SLOTW =(DYN_TPAGEW/DYN_W), CACHE_Y =256,
DYN_SLOTH =(DYN_TPAGEH/DYN_H), CACHE_W =4,
DYN_SLOTX =512+256, CACHE_H =1,
DYN_SLOTY =256,
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: 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 CActorGfx;
class CActorPool class CActorPool
{ {
public: 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 Init();
static void Reset();
static void SetUpCache();
static void AddActor(FileEquate Filename) {GetActor(Filename);} static void AddActor(FileEquate Filename) {GetActor(Filename);}
static CActorGfx *GetActor(FileEquate Filename); static CActorGfx *GetActor(FileEquate Filename);
static void DumpActors();
static ACTOR_TYPE getActorType( int actorNum ) {return actorType[actorNum];}
protected: protected:
static int FindActorInPool(FileEquate Filename); static sActorPool *FindActor(FileEquate Filename);
static int FindFreeActor(); static sActorPool *LoadActor(FileEquate Filename);
static int LoadActor(FileEquate Filename); static void AddActor(sActorPool *ThisActor);
static u16 LoadPalette(sActorPool &ThisActor,int Idx);
static sActorPool ActorPool[];
static ACTOR_TYPE actorType[];
static CActorCache Cache;
static sActorPool *ActorList,*LastActor;
}; };
/*****************************************************************************/ /*****************************************************************************/
class CActorGfx class CActorGfx
{ {
public: public:
CActorGfx(); enum
virtual ~CActorGfx(); {
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); 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: 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); sSpriteFrame *GetFrame(int Anim,int Frame);
sSpriteAnimBank *SpriteBank; sActorPool *PoolEntry;
// RECT DrawRect;
u16 Clut;
u16 TPage,TexX,TexY;
u8 U,V;
static CSlotCache SlotCache;
static u8 UnpackBuffer[CActorPool::MAX_ACTOR_SIZE];
static u8 UnpackBuffer[CActorCache::MAX_ACTOR_SIZE];
}; };
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
class CModelGfx class CModelGfx
{ {

View file

@ -122,7 +122,7 @@ void CLevel::init(int LevelNo)
// Load it // Load it
sLvlTab *lvlTab=&LvlTable[LevelNo]; sLvlTab *lvlTab=&LvlTable[LevelNo];
CActorGfx::ResetCache(); CActorPool::Reset();
CSoundMediator::setSong((CSoundMediator::SONGID)lvlTab->songId); CSoundMediator::setSong((CSoundMediator::SONGID)lvlTab->songId);
DisplayLoadingScreen(lvlTab); DisplayLoadingScreen(lvlTab);
@ -345,7 +345,7 @@ void CLevel::shutdown()
if (PlatformList) MemFree(PlatformList); if (PlatformList) MemFree(PlatformList);
MemFree(LevelHdr); MemFree(LevelHdr);
CActorPool::DumpActors(); CActorPool::Reset();
TPFree(m_levelTPage); TPFree(m_levelTPage);
} }