/*========================================================================= FILENAME.CPP Author: Gary Liddon @ Created: Project: Purpose: Copyright (c) 1998 G R Liddon ===========================================================================*/ /*---------------------------------------------------------------------- Includes -------- */ /* Std Lib ------- */ /* Glib ---- */ #include "pak.h" /* Local ----- */ #include "vimage.h" /*---------------------------------------------------------------------- Tyepdefs && Defines ------------------- */ using namespace std; /*---------------------------------------------------------------------- Structure defintions -------------------- */ /*---------------------------------------------------------------------- Function Prototypes ------------------- */ /*---------------------------------------------------------------------- Vars ---- */ /*---------------------------------------------------------------------- Data ---- */ /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ VRAMImage::VRAMImage(int NewWidthInTpages,int NewHeightInPixels) : VRAMData(NULL) { WidthInTpages=NewWidthInTpages; HeightInPixels=NewHeightInPixels; HeightInTPages=NewHeightInPixels / 256; if (!HeightInTPages) { aTPageHeight = 128; HeightInTPages = 1; } else { aTPageHeight = HeightInTPages * 256; } TPageSizeInBytes = 128 * aTPageHeight; WidthInBytes=WidthInTpages*128; VramAreaBytes=WidthInBytes * HeightInPixels; VRAMData=new u8[VramAreaBytes]; lbmData = new u8[WidthInTpages*256*HeightInPixels]; if (!lbmData) Error(ERM_OUTOFMEM); if (!VRAMData) Error(ERM_OUTOFMEM); memset(VRAMData,0,VramAreaBytes); m_doCompress=false; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ VRAMImage::~VRAMImage(void) { if (lbmData) delete lbmData; if (VRAMData) delete VRAMData; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::getTpData(unsigned int tp,std::vector<u8> & dest) const { const int TPAGES_IN_ALL =WidthInTpages * HeightInTPages; if (tp >= TPAGES_IN_ALL) Error(ERR_FATAL,"illegal tpage number"); int tpX,tpY; u8 const * srcTpData; dest.resize(TPageSizeInBytes); tpX=(tp%WidthInTpages)*128; tpY=(tp/WidthInTpages)*aTPageHeight; srcTpData=&VRAMData[tpX+tpY*WidthInBytes]; for (int x=0;x<128;x++) for (int y=0;y<aTPageHeight;y++) dest[x+y*128]=srcTpData[x+y*WidthInBytes]; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CompressMem(char const * CmdLine,std::vector<u8> & Body) { try { GString Com; char TmpName[100]; char CompTmpName[100]; tmpnam(TmpName); tmpnam(CompTmpName); GString ComStr(CmdLine); ComStr.Replace("%1",TmpName); ComStr.Replace("%2",CompTmpName); ofstream Out; Out.open(TmpName,ios::binary|ios::trunc); if (Out) { int CompSize; Out.write((char const *)&Body[0],Body.size()); Out.close(); cout<<(char const *)ComStr<<"from "<<CmdLine<<endl; system(ComStr); CompSize=FileSize(CompTmpName); Body.resize(CompSize); ifstream In; In.open(CompTmpName,ios::binary); if (In) { In.read((char *)&Body[0],CompSize); In.close(); } else throw("Can't open compressed out file"); } else throw("Can't open uncompressed out file"); remove(TmpName); remove(CompTmpName); } catch (const char * Err) { GObject::Error(ERR_FATAL,"%s im CompressMem",Err); } } void VRAMImage::WriteInTpageChunks(ofstream & str) { const int TPAGES_IN_ALL =WidthInTpages * HeightInTPages; vector<u8> tpageData; tpageData.resize(TPageSizeInBytes); for (int f=0;f<TPAGES_IN_ALL;f++) { getTpData(f,tpageData); str.write((char*)&tpageData[0],TPageSizeInBytes); } } void VRAMImage::Write(ofstream & Str) { if (m_doCompress) { printf("Packing TPage\n"); const int TPAGES_IN_ALL =WidthInTpages * HeightInTPages; const int NUM_OF_WINDOWS = TPAGES_IN_ALL*4; vector<u8> tpageData; vector<u8> dataToWrite; tpageData.resize(TPageSizeInBytes); dataToWrite.resize(TPageSizeInBytes); for (int f=0;f<NUM_OF_WINDOWS;f++) { int dataWriteSize; const u8 * srcData; if ((f&3) == 0) getTpData(f/4,tpageData); srcData=&tpageData[(f%4)*128*64]; if (f != 0) { vector<u8> myData; myData.resize(128*64); memcpy(&myData[0],srcData,128*64); #ifdef __USE_LZNP__ CompressMem("lznp %1 %2",myData); dataWriteSize=myData.size(); memcpy(&dataToWrite[0],&myData[0],dataWriteSize); #else dataWriteSize=PAK_findPakSize(&myData[0],128*64); PAK_doPak(&dataToWrite[0],&myData[0],128*64); #endif } else { dataWriteSize=128*64; memcpy(&dataToWrite[0],srcData,128*64); } for (int a=0;a<16;a++) printf("%i, ",(int)dataToWrite[a]); printf("\n"); Str.write((char *)(&dataToWrite[0]),dataWriteSize); } } else Str.write((char *)(VRAMData),VramAreaBytes); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::PlotPal(SprPal const & PalToPlot) { TPRect Tp=PalToPlot.GetTPRect(); int W=WidthInTpages*256; W/=2; u16 * Addr=(u16 *)&VRAMData[Tp.Y*W+Tp.X/2]; std::vector<u16> OutWords; PalToPlot.MakePSXPal(OutWords); int f; for (f=0;f<OutWords.size();f++) Addr[f]=OutWords[f]; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::PlotFrame(SprFrame const & FrameToPlot) { SprFrame::BDEPTH ThisDepth; ThisDepth=FrameToPlot.GetBitDepth(); switch(ThisDepth) { case SprFrame::BITS_4: PlotFrame4(FrameToPlot); break; case SprFrame::BITS_8: PlotFrame8(FrameToPlot); break; }; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::SaveAs16ColLbm(const char * Name) { Palette GazPalette; GazPalette[0].SetR(0); GazPalette[0].SetG(0); GazPalette[0].SetB(255); int W=WidthInTpages*256; int H=HeightInPixels; Frame ThisFr; for (int f=1;f<15;f++) { int Col=f*17; GazPalette[1+f].SetR(Col); GazPalette[1+f].SetG(Col); GazPalette[1+f].SetB(Col); } for (int y=0;y<H;y++) for (int x=0;x<W;x++) { if ((x&1)) lbmData[x+y*W]=(VRAMData[ (y*(W/2))+(x/2)]&0xf0) >> 4; else lbmData[x+y*W]=VRAMData[(y*(W/2))+(x/2)]&0x0f; } ThisFr.SetFrame(lbmData,W,H,GazPalette); ThisFr.SaveLbm(Name); // cout<<"Written "<<Name<<endl; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::PlotFrame4(SprFrame const & Fr) { TPRect Tp=Fr.GetTPRect(); int W=WidthInTpages*256; W=W/2; /* we're plotting nibbles */ if (!Tp.GetRotate()) { for (int y=Tp.Y;y<Tp.Y+Tp.H;y++) for (int x=Tp.X;x<Tp.X+Tp.W;x++) { int FrX=x-Tp.X; int FrY=y-Tp.Y; u8 ScrNib=Fr.SeeData()[FrY*Tp.W+FrX]&0xf; u8 * PixAddr=&VRAMData[y*W+x/2]; if ((x&1)) { *PixAddr&=0x0f; *PixAddr|=ScrNib<<4; } else { *PixAddr&=0xf0; *PixAddr|=ScrNib; } } } else { for (int y=Tp.Y;y<Tp.Y+Tp.H;y++) for (int x=Tp.X;x<Tp.X+Tp.W;x++) { int FrX=x-Tp.X; int FrY=y-Tp.Y; u8 ScrNib=Fr.SeeData()[FrX*Tp.H+(Tp.H-FrY-1)]&0xf; u8 * PixAddr=&VRAMData[y*W+x/2]; if ((x&1)) { *PixAddr&=0x0f; *PixAddr|=ScrNib<<4; } else { *PixAddr&=0xf0; *PixAddr|=ScrNib; } } } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void VRAMImage::PlotFrame8(SprFrame const & Fr) { const TPRect & Tp=Fr.GetTPRect(); int W=WidthInTpages*256; W/=2; u8 * Addr=&VRAMData[Tp.Y*W+Tp.X/2]; if (!Fr.IsRotated()) { for (int y=0;y<Fr.GetHeight();y++) for (int x=0;x<Fr.GetWidth();x++) Addr[y*W+x]=Fr.SeeData()[x+y*Fr.GetWidth()]; } else { for (int y=0;y<Fr.GetWidth();y++) for (int x=0;x<Fr.GetHeight();x++) Addr[y*W+x]=Fr.SeeData()[x*Fr.GetWidth()+(Fr.GetWidth()-y-1)]; } } /*=========================================================================== end */