/******************/ /*** Actor Bank ***/ /******************/ #include "system\global.h" #include "mem\memory.h" #include "fileio\fileio.h" #include "utils\utils.h" #include "utils\pak.h" #include "gfx\prim.h" #include "gfx\actor.h" #include /*****************************************************************************/ int ShadowXOfs=32; int ShadowYOfs=32; /*****************************************************************************/ CActorPool::ACTOR_TYPE CActorPool::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 }; /*****************************************************************************/ 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); for (H=0; HAnimList=(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); } // FixUp FrameList DAVE_DBGMSG("Anims %i\n",Spr->FrameCount); for (i=0; iFrameCount; i++) { sSpriteFrame *ThisFrame=&Spr->FrameList[i]; ThisFrame->PAKSpr=(u8*) MakePtr(Spr,(int)ThisFrame->PAKSpr); } // Store it int Idx=FindFreeActor(); ASSERT(Idx!=-1); sActorPool &ThisActor=ActorPool[Idx]; ThisActor.Filename=Filename; ThisActor.SpriteBank=Spr; ThisActor.RefCount=1; ThisActor.Clut=LoadPalette(ThisActor,Idx); return(Idx); } /*****************************************************************************/ #define DYN_PALW 64 #define DYN_PALH 1 #define DYN_PALX 512 #define DYN_PALY 511 u16 CActorPool::LoadPalette(sActorPool &ThisActor,int Idx) { RECT R; int X=Idx&31; int Y=Idx%31; 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; iMaxW,_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; u16 ThisFrame=ThisAnim->Anim[Frame]; return(SpriteBank->FrameList+ThisFrame); } /*****************************************************************************/ int ActorOT=10; POLY_FT4 *CActorGfx::Render(DVECTOR &Pos,int Anim,int Frame,bool XFlip,bool YFlip,bool Shadow) { sSpriteFrame *FrameGfx=GetFrame(Anim,Frame); PAK_doUnpak(UnpackBuffer,FrameGfx->PAKSpr); // Gfx 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); setRGB0(Ft4,128,128,128); Ft4->tpage=TPage; Ft4->clut=Clut; AddPrimToList(Ft4,ActorOT); if (Shadow) { POLY_FT4 *sFt4=GetPrimFT4(); *sFt4=*Ft4; sFt4->x0-=ShadowXOfs; sFt4->x1-=ShadowXOfs; sFt4->y0+=ShadowYOfs; sFt4->y1+=ShadowYOfs; setSemiTrans(sFt4,1); setRGB0(sFt4,0,0,0); AddPrimToList(sFt4,ActorOT); } return(Ft4); } /*****************************************************************************/ void CActorGfx::SetUpFT4(POLY_FT4 *Ft4,sSpriteFrame *Frame,int X,int Y,bool XFlip,bool YFlip) { u8 W=Frame->W; u8 H=Frame->H; if (XFlip) { X-=Frame->XOfs; X-=W; Ft4->u0=U+W-1; Ft4->u1=U;//-1; Ft4->u2=U+W-1; Ft4->u3=U;//-1; } else { X+=Frame->XOfs; Ft4->u0=U; Ft4->u1=U+W; Ft4->u2=U; Ft4->u3=U+W; } if (YFlip) { Y-=Frame->YOfs; Y-=H; Ft4->v0=V+H-1; Ft4->v1=V+H-1; Ft4->v2=V;//-1; Ft4->v3=V;//-1; } else { Y+=Frame->YOfs; Ft4->v0=V; Ft4->v1=V; Ft4->v2=V+H; Ft4->v3=V+H; } setXYWH(Ft4,X,Y,W,H); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ sModel *CModelGfx::ModelTable; sTri *CModelGfx::ModelTriList; sQuad *CModelGfx::ModelQuadList; sVtx *CModelGfx::ModelVtxList; /*****************************************************************************/ void CModelGfx::SetData(sModel *Table,sTri *TList,sQuad *QList,sVtx *VList) { ModelTable=Table; ModelTriList=TList; ModelQuadList=QList; ModelVtxList=VList; } /*****************************************************************************/ void CModelGfx::SetModel(int Type) { Model=&CModelGfx::ModelTable[Type]; } /*****************************************************************************/ int DX=1; int DY=1; int PXOfs=-16; int PYOfs=-6; void CModelGfx::Render(DVECTOR &Pos) { #define BLOCK_MULT 16 u8 *PrimPtr=GetPrimPtr(); POLY_FT3 *TPrimPtr=(POLY_FT3*)PrimPtr; sVtx *P0,*P1,*P2; u32 T0,T1,T2; s32 ClipZ; sOT *ThisOT; DVECTOR MapXY; VECTOR RenderPos; int TriCount=Model->TriCount; sTri *TList=&ModelTriList[Model->TriStart]; MapXY.vx=Pos.vx>>4; MapXY.vy=Pos.vy>>4; int ShiftX=(Pos.vx & 15); int ShiftY=(Pos.vy & 15); RenderPos.vx=(PXOfs*16)+((MapXY.vx*16)+ShiftX); RenderPos.vy=(PYOfs*16)+((MapXY.vy*16)+ShiftY); CMX_SetTransMtxXY(&RenderPos); while (TriCount--) { P0=&ModelVtxList[TList->P0]; P1=&ModelVtxList[TList->P1]; P2=&ModelVtxList[TList->P2]; gte_ldv3(P0,P1,P2); setPolyFT3(TPrimPtr); setShadeTex(TPrimPtr,1); setlen(TPrimPtr, GPU_PolyFT3Tag); gte_rtpt_b(); T0=*(u32*)&TList->uv0; // Get UV0 & TPage T1=*(u32*)&TList->uv1; // Get UV1 & Clut T2=*(u16*)&TList->uv2; // Get UV2 *(u32*)&TPrimPtr->u0=T0; // Set UV0 *(u32*)&TPrimPtr->u1=T1; // Set UV1 *(u16*)&TPrimPtr->u2=T2; // Set UV2 if (TList->OTOfs>MAX_OT-1) TList->OTOfs=MAX_OT-1; ThisOT=OtPtr+TList->OTOfs; 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) { addPrim(ThisOT,TPrimPtr); TPrimPtr++; } } SetPrimPtr((u8*)TPrimPtr); }