/*========================================================================= SPRSET.CPP Author: Gary Liddon @ Fareham Created: Project: TPW Parkgrab Purpose: Object that reads in all the frames for sprites processes them into tpages and spits it all out to disk Copyright (c) 1998 G R Liddon ===========================================================================*/ /*---------------------------------------------------------------------- Includes -------- */ /* Std Lib ------- */ #include #include #include /* Glib ---- */ #include #include #include #include #include /* Local ----- */ #include "sprset.h" #include "cross.h" /*---------------------------------------------------------------------- Tyepdefs && Defines ------------------- */ using namespace std; /*---------------------------------------------------------------------- Structure defintions -------------------- */ /*---------------------------------------------------------------------- Function Prototypes ------------------- */ /*---------------------------------------------------------------------- Vars ---- */ /*---------------------------------------------------------------------- Data ---- */ static const char BadFileChars[] = { '+', '-', '*', '/', '\\', '#', ',', '.', '(', ')', '!', '"', '£', '$', '%', '^', '&', '=', '#', ':', ';', '<', '>', '?', '@', '{', '}', '[', ']', '¬', }; static const int nbBadFileChars = (sizeof(BadFileChars) / sizeof(char)); /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ GString ReplaceBadFileChars(GString s) { GString out; const char *textin = (const char*)s; char *textout = new char[s.Len()+1]; memset(textout, 0, s.Len()+1); int i, p; p=0; for (i=0; i (*PalIt).GetNumOfCols()) (*PalIt)=ThisPal; PalIndex=PalIt-AllSprPals.begin(); } } /* If Palindex == -1 then we couldn't find the palette we wanted so add this one to the pool */ if (PalIndex==-1) { AllSprPals.resize(AllSprPals.size()+1); SprPal & ThisSprPal=AllSprPals[AllSprPals.size()-1]; PalIndex=AllSprPals.size()-1; ThisSprPal=ThisPal; ThisSprPal.SetPlusColZero((*it).GetPlusColZero()); ThisSprPal.SetZeroColZero((*it).GetZeroColZero()); ThisSprPal.SetName((*it).GetName()); } /* Set the sprframe to have the write pal index */ (*it).SetPalIndex(PalIndex); AllSprPals[PalIndex].SetPalIndex(PalIndex); } cout<<"Found "<SaveAs16ColLbm(FileName); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ #include void SprSet::WriteReport(char const * File) { const int DirLen=1024; char Dir[DirLen+1]; GString CurrDir; CurrDir=getcwd(Dir,DirLen); CurrDir.Upper(); CurrDir=CurrDir+"\\"; GString OutFileName(File); OutFileName.Lower(); Gofstream Out; Out.open(OutFileName,ios::out); if (Out) { Out<<"File\tTPage\tClut\tu\tv\tw\th\tRotated"<GetActualName(); u=Frm.GetTPRect().X; v=Frm.GetTPRect().Y; w=Frm.GetWidth(); h=Frm.GetHeight(); RelName=GFName::makerelative(CurrDir,Name,Dir); Out<<(char const *)RelName<<"\t$"<PlotFrame(AllSprFrames[f]); for (f=0;fPlotPal(AllSprPals[f]); /* struct SpriteBankHdr { u16 NumOfSprites; u16 NumOfTPages; u16 TpageStart; u16 WidthInTpages; u16 HeightInTpages; u16 NumOfSpareBoxes; }; */ Gofstream Out(Gofstream::LITTLE_ENDIAN); GString OutFileName(File); OutFileName.Lower(); Out.open(OutFileName,ios::out|ios::binary); TPRectVec spareVRAM; MyVram.getUnusedSpace(spareVRAM); if (Out) { int FrameCount=AllSprFrames.size(); if (m_AnimatedHeadersOnly) { FrameCount=0; for (f=0;fsetDoCompress(m_compressTpages); Vi->Write(Out); } Out.close(); } else Error(ERR_FATAL,"Error wring file %s",(char const *)OutFileName); WriteHeaderFile(GetHeaderFileName(File)); } GString SprSet::GetHeaderFileName(char const * File) { GString HeaderFileName; if (IncOutFile == "") { GFName HeaderFile(File); HeaderFile.Ext("h"); HeaderFileName=HeaderFile.FullName(); } else HeaderFileName=IncOutFile; HeaderFileName.Lower(); return(HeaderFileName); } void SprSet::WriteHeaderFile(char const * HName) { ofstream HOut; int f; GFName HeaderFile(HName); GString OFileDefine; OFileDefine="__SPR_"; OFileDefine+=HeaderFile.File(); OFileDefine+="_H__"; OFileDefine.Upper(); GString HeaderFileName(HeaderFile.FullName()); HeaderFileName.Lower(); HOut.open(HeaderFileName,ios::out); if (HOut) { HOut<<"#ifndef "<<(char const *)OFileDefine< CopySprPals; /* Make a copy of the palettes */ CopySprPals=AllSprPals; std::sort(CopySprPals.begin(),CopySprPals.end()); /* Sort em according to how many cols */ for (f=0;f AllocRects; AllocRects.resize(AllSprFrames.size()); std::vector oldTypes; oldTypes.resize(AllSprFrames.size()); for (f=0;fgetAllocateAs16Bit()) oldTypes[f]=AllocRects[f].convertTo16Bit(); } /* Allocate int VRAM */ if(Vr.AllocVRAM(AllocRects,false,true,true)) { /* Now go back through all the sprite frames and tell them where they are going to sit in VRAM */ for (f=0;fgetAllocateAs16Bit()) AllocRects[f].convertFrom16Bit(oldTypes[AllocRects[f].GetId()]); AllSprFrames[AllocRects[f].GetId()].SetVRAMPos(AllocRects[f]); } } else { Error(ERR_FATAL,"Couldn't fit frames into VRAM"); } /* Go through and tell all pals and frames what the base tpage is */ for (f=0;fWriteInTpageChunks(out); } else Error(ERR_FATAL,"Error opening raw file %s",file); } /*---------------------------------------------------------------------- Function: Purpose: Write out sprs and pals to a sprite file (not a VRAM block) Params: Returns: ---------------------------------------------------------------------- */ void SprSet::WriteSprFile(char const * Name) { std::vector SprOffsets; std::vector PalOffsets; ProcessPals(); Gofstream SpriteOut(Gofstream::LITTLE_ENDIAN); GString SpriteOutName(Name); SpriteOutName.Lower(); SpriteOut.open(SpriteOutName,ios::binary|ios::out|ios::trunc); if (SpriteOut) { int NumOfSprs; int NumOfPals; int PalOffsetTable; int SprOffsetTable; /* struct SPR_RAM_HDR { int NumOfPals; int NumOfSprs; int PalOffsets[NumOfPals]; int SprOfffsets[NumOfSprs]; RAM_FRAME_HDR Frames[NumOfSprs]; Pals Pals[NumOfPals]; Data [NumOfSprs] } */ NumOfSprs=AllSprFrames.size(); NumOfPals=AllSprPals.size(); SpriteOut.Put32(NumOfPals); SpriteOut.Put32(NumOfSprs); SprOffsets.resize(NumOfSprs); PalOffsets.resize(NumOfPals); PalOffsetTable=SpriteOut.tellp(); SpriteOut.seekp(sizeof(u32)*NumOfPals,ios::cur); SprOffsetTable=SpriteOut.tellp(); SpriteOut.seekp(sizeof(u32)*NumOfSprs,ios::cur); int f; for (f=0;f MaxSize) NewWidth=MaxSize; if (NewHeight > MaxSize) NewHeight=MaxSize; if (NewWidth != GetWidth() || NewHeight != GetHeight()) { cout<<"Reducing frame "<GetActualFileName()<GetActualFileName()< 254 || Height > 254) { Error(ERR_FATAL,"Images only allowed to 254x254, this is %dx%d : %s",Width,Height,MyFileInfo.GetActualFileName()); } } struct fRGBA { void Set(float _R,float _G,float _B,float _A) {R=_R;G=_G;B=_B;A=_A;} float R,G,B,A; }; void SprFrame::ResizeAndReduce(Frame & Frm,int TargCols,float XPerc,float YPerc,bool ZeroSeeThrough) { std::vector FullColNewScreen; std::vector DestBytePic; std::vector Bitmap; u8 Pal[256*3]; u8 * Dest; int f; Bitmap.resize(Frm.GetWidth()*Frm.GetHeight()*4); Frm.MakeRGBA(&Bitmap[0],ZeroSeeThrough); int Width,Height; Width=Frm.GetWidth(); Height=Frm.GetHeight(); int NewWidth=float(Width)*XPerc; int NewHeight=float(Height)*YPerc; if (!(Dest=new u8[NewWidth*NewHeight])) GObject::Error(ERM_OUTOFMEM); FullColNewScreen.resize(NewWidth*NewHeight); DestBytePic.resize(NewWidth*NewHeight*3); /* Now Super Sample it down */ const int Samples=8; int DestW=NewWidth; int DestH=NewHeight; float YMul=float(Height)/DestH; float XMul=float(Width)/DestW; for (int dy=0;dy1.0f) R=1.0f; if (G>1.0f) B=1.0f; if (B>1.0f) B=1.0f; int DestIndex=(dy*NewWidth+dx); FullColNewScreen[DestIndex].Set(R,G,B,A); } } /* Convert Back to RGBA into a dest byte picture */ const float Bound=0.5f; for (f=0;f Bound) { DestBytePic[f*3+0]=R*255; DestBytePic[f*3+1]=G*255; DestBytePic[f*3+2]=B*255; } else { DestBytePic[f*3+0]=0; DestBytePic[f*3+1]=0; DestBytePic[f*3+2]=0; } } /* Now reduce colours */ Palette NewPal; if (ZeroSeeThrough) { int Cols=TargCols-1; tquant(&DestBytePic[0],Dest,Pal,Cols,NewWidth*NewHeight); for (f=0;f Bound) Dest[f]=Dest[f]+1; else Dest[f]=0; } for (f=1;f Body; Frame NewFrame; NewFrame=*this; Rect OriginalRect; OriginalRect=NewFrame; OriginalRect.X=0; OriginalRect.Y=0; OriginalRect.W=GU_AlignVal(OriginalRect.W,AlignPixels); NewFrame.Crop(OriginalRect); int nfW,nfH,nfLineWidthBytes,nfAreaBytes; nfW=NewFrame.GetWidth(); nfH=NewFrame.GetHeight(); nfLineWidthBytes=GU_AlignVal(nfW,2)/2; nfAreaBytes=nfLineWidthBytes*nfH; Body.resize(nfAreaBytes); for (int y=0;y OutPal; MakePSXPal(OutPal); Out.Put32(OutPal.size()); for (int f=0;f>3; G=Col.GetG()>>3; B=Col.GetB()>>3; return((R&0x1f)<<0)|((G&0x1f)<<5)|((B&0x1f)<<10); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void SprPal::MakePSXPal(std::vector & OutWords) const { int NumOfCols; int f; NumOfCols=(*this).GetNumOfCols(); OutWords.resize(NumOfCols); if (GetZeroColZero() || GetPlusColZero()) { OutWords[0]=0; for (f=1;f