/**********************/ /*** PSX Vram Stuff ***/ /**********************/ #include "System\global.h" #include "Gfx\TPage.h" #include "Gfx\AnimTex.h" #include "Gfx\Prim.h" #include "System\vid.h" #include "FileIO/FileIO.h" #include "Mem\Memory.h" #include "utils\utils.h" enum TPAGE_ENUMS { TPAGE_HALF0 = 0, TPAGE_HALF1 = 1, TPAGE_FULL = 0, TPAGE_DYN_START = (24), TPAGE_DYN_END = (26), MAX_TPAGES = 32, }; //#define INVALIDATE_CACHE 1 const int TPRawW=64; const int TPRawH=256; struct sAnimTexInfo { int Frame; sFrameHdr FrameHdr; }; struct sTPageInfo { s16 RefCount; FileEquate TPageName; s16 XOfs,YOfs; u16 AnimTexCount; sAnimTexInfo AnimTexFrame[TPAGE_MAX_ANIM_TEX]; }; struct sTPageCache { sTPageInfo Info[2]; }; static sTPageCache s_TPCache[MAX_TPAGES]; // Theory!! // Filenames stored so IF tpage is set to load, AND is found within table (free or not) then use that // Will only work if people are good with the tpage allocation (due to no checks on width) // Will write a InvalidDate routine /*****************************************************************************/ void TPInit() { // Likes to be a multiple of 65536, dunno why, Im shit like that for (int i=0; i15)*TPRawH,64,128); Invalidate=1; #endif s_TPCache[desc.tpage].Info[desc.Half].RefCount--; if (!s_TPCache[desc.tpage].Info[desc.Half].RefCount) { if (Invalidate) s_TPCache[desc.tpage].Info[desc.Half].TPageName=(FileEquate)0; if (desc.Half==0 && s_TPCache[desc.tpage].Info[1].RefCount==-1) // Check for full tpage { s_TPCache[desc.tpage].Info[1].RefCount=0; #if defined(INVALIDATE_CACHE) R.h=256; #endif } CAnimTex::DumpThisTPage(s_TPCache[desc.tpage].Info[desc.Half].TPageName); #if defined(INVALIDATE_CACHE) R.y+=desc.Half*128; ClearImage(&R,0,255,0); #endif } } /*****************************************************************************/ void IsTPageInCache(FileEquate Filename,int &TPage,int &Half) { TPage=0; for (int Loop=0; LoopTPageStart; Half=0; if (TPage>=TPAGE_DYN_START && TPage<=TPAGE_DYN_END) // Its a dynamic TPage! { // Find spare VRam if (TPHdr->TPageHeightInPixels <= 128) // Half TPage { // Find spare half while(s_TPCache[TPage].Info[0].RefCount && s_TPCache[TPage].Info[1].RefCount) { TPage++; ASSERT(TPage <= TPAGE_DYN_END);// ASSERT(!"VRAM FULL"); } if (!s_TPCache[TPage].Info[0].RefCount) Half = TPAGE_HALF0; else Half=TPAGE_HALF1; } else { // Full TPage while(s_TPCache[TPage].Info[0].RefCount || s_TPCache[TPage].Info[1].RefCount) { TPage++; if (TPage >= MAX_TPAGES) ASSERT(!"VRAM FULL"); } Half = TPAGE_FULL; s_TPCache[TPage].Info[1].TPageName=(FileEquate)0; s_TPCache[TPage].Info[1].RefCount=-1; // lock 2nd half } } sTPageInfo *Cache=&s_TPCache[TPage].Info[Half]; Cache->RefCount++; Cache->TPageName=Filename; Cache->XOfs=TPage-TPHdr->TPageStart; Cache->YOfs=Half*128; Cache->AnimTexCount=0; return(Cache); } /*****************************************************************************/ void TPLoadVRam(sTPageHdr *TPHdr, int TPage, int Half, u32 *VRamData) { RECT Rect; // Read and DMA TP to VRam Rect.x=(TPage%16)*TPRawW; Rect.y=((TPage>>4)*TPRawH)+(Half*128); Rect.w=TPHdr->TPageWidth*TPRawW; Rect.h=TPHdr->TPageHeightInPixels; DrawSync( 0 ); LoadImage( &Rect, VRamData); } /*****************************************************************************/ void AddAnimTexToList(sTPageInfo *Cache,sFrameHdr *FramePtr,int Frm,int TPage,int Half) { MCmemcpy(&Cache->AnimTexFrame[Cache->AnimTexCount].FrameHdr,FramePtr,sizeof(sFrameHdr)); Cache->AnimTexFrame[Cache->AnimTexCount].Frame=Frm; Cache->AnimTexCount++; } /*****************************************************************************/ TPAGE_DESC TPLoadTex(FileEquate Filename) { TPAGE_DESC Desc; sTPageHdr *TPHdr; sFrameHdr *FramePtr; u32 *VRAMData; int TPage,Half; sTPageInfo *Cache; // Is it already loaded in TCache? IsTPageInCache(Filename,TPage,Half); if (TPage) // Is in cache, no need to load it again :o) { // DBG_MSG2("TPLoadTex Cached (%i,%i)",TPage,Half); s_TPCache[TPage].Info[Half].RefCount++; Cache=&s_TPCache[TPage].Info[Half]; } else { // Better load it then // DBG_MSG0("TPLoadTex"); TPHdr=(sTPageHdr*)CFileIO::loadFile(Filename,"TPLoadTEX"); ASSERT(!TPHdr->NumOfSpareBoxes); FramePtr=(sFrameHdr*) MakePtr(TPHdr,sizeof(sTPageHdr)); VRAMData=(u32*) MakePtr(FramePtr,TPHdr->NoOfFrames*sizeof(sFrameHdr)); Cache=FindSpareTPage(Filename,TPage,Half,TPHdr); for (int Frm=0;FrmNoOfFrames; Frm++) // Add Animated Texture references { if (FramePtr->Cycle) AddAnimTexToList(Cache,FramePtr,Frm,TPage,Half); FramePtr++; } TPLoadVRam(TPHdr, TPage,Half,VRAMData); MemFree(TPHdr); } // If first instance, add animated textures if (Cache->RefCount==1) { sAnimTexInfo *ATexPtr=Cache->AnimTexFrame; for (int Frm=0; FrmAnimTexCount; Frm++) CAnimTex::AddAnimTex(&ATexPtr[Frm].FrameHdr,ATexPtr[Frm].Frame,Filename); } Desc.Half= Half; Desc.tpage = TPage; Desc.xoffset = Cache->XOfs; Desc.yoffset = Cache->YOfs; return (Desc); } /*****************************************************************************/ // These are NEVER dynamic, but need to store the frame headers // Plus, this should only happen at system startup now :o) TPAGE_DESC TPLoadTexWithHeaders(FileEquate Filename, sFrameHdr **hdrs ) { TPAGE_DESC Desc; sTPageHdr TPHdr; sFrameHdr *FramePtr; u32 *VRAMData; int TPage,Half=0; sTPageInfo *Cache; int ReadLeft; // Is it already loaded in TCache? IsTPageInCache(Filename,TPage,Half); if (TPage) // Found one!! { // DBG_MSG2("TPLoadTexWithHeaders Cached (%i,%i)",TPage,Half); s_TPCache[TPage].Info[Half].RefCount++; Cache=&s_TPCache[TPage].Info[Half]; // Reload headers (PKG) CFileIO::OpenFile(Filename); CFileIO::ReadFile((void*)&TPHdr,sizeof(sTPageHdr)); *hdrs=(sFrameHdr*)MemAlloc(sizeof(sFrameHdr)*TPHdr.NoOfFrames,"TpFh(from cache)"); ReadLeft=CFileIO::GetReadLeft(); FramePtr=(sFrameHdr*)MemAlloc(ReadLeft,"TPLoadTemp"); CFileIO::ReadFile(FramePtr,ReadLeft); CFileIO::CloseFile(); MCmemcpy(*hdrs,FramePtr,TPHdr.NoOfFrames*sizeof(sFrameHdr)); MemFree(FramePtr); } else { // DBG_MSG0("TPLoadTexWithHeaders"); CFileIO::OpenFile(Filename); // Load Main Header CFileIO::ReadFile((void*)&TPHdr,sizeof(sTPageHdr)); ASSERT(!TPHdr.NumOfSpareBoxes); TPage=TPHdr.TPageStart; // Load Rest *hdrs=(sFrameHdr*)MemAlloc(sizeof(sFrameHdr)*TPHdr.NoOfFrames,"TpFh"); ReadLeft=CFileIO::GetReadLeft(); FramePtr=(sFrameHdr*)MemAlloc(ReadLeft,"TPLoadTemp"); CFileIO::ReadFile(FramePtr,ReadLeft); CFileIO::CloseFile(); VRAMData=(u32*) MakePtr(FramePtr,TPHdr.NoOfFrames*sizeof(sFrameHdr)); MCmemcpy(*hdrs,FramePtr,TPHdr.NoOfFrames*sizeof(sFrameHdr)); TPLoadVRam(&TPHdr, TPage,Half,VRAMData); Cache=&s_TPCache[TPage].Info[Half]; MemFree(FramePtr); FramePtr=*hdrs; for (int Frm=0;FrmCycle) AddAnimTexToList(Cache,FramePtr++,Frm,TPage,Half); } Cache->RefCount=1; Cache->TPageName=Filename; Cache->XOfs=0; Cache->YOfs=0; Cache->AnimTexCount=0; s_TPCache[TPage].Info[1].RefCount=-1; } // If first instance, add animated textures if (Cache->RefCount==1) { sAnimTexInfo *ATexPtr=Cache->AnimTexFrame; for (int Frm=0; FrmAnimTexCount; Frm++) CAnimTex::AddAnimTex(&ATexPtr[Frm].FrameHdr,ATexPtr[Frm].Frame,Filename); } Desc.Half= Half; Desc.tpage = TPage; Desc.xoffset = Cache->XOfs; Desc.yoffset = Cache->YOfs; return (Desc); }