2000-12-02 19:55:49 +01:00
|
|
|
/*=========================================================================
|
|
|
|
|
|
|
|
FILENAME.CPP
|
|
|
|
|
|
|
|
Author: Gary Liddon @
|
|
|
|
Created:
|
|
|
|
Project:
|
|
|
|
Purpose:
|
|
|
|
|
|
|
|
Copyright (c) 1997 Climax Development Ltd
|
|
|
|
|
|
|
|
===========================================================================*/
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Includes
|
|
|
|
-------- */
|
|
|
|
|
|
|
|
/* Std Lib
|
|
|
|
------- */
|
|
|
|
#include <algorithm>
|
|
|
|
#include "conio.h"
|
|
|
|
|
|
|
|
/* Glib
|
|
|
|
---- */
|
|
|
|
#include "gutils.h"
|
|
|
|
|
|
|
|
/* Local
|
|
|
|
----- */
|
|
|
|
#include "tpage.h"
|
|
|
|
#include "grect.h"
|
|
|
|
|
|
|
|
/* Graphics
|
|
|
|
-------- */
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Tyepdefs && Defines
|
|
|
|
------------------- */
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Structure defintions
|
|
|
|
-------------------- */
|
|
|
|
struct TPInfo
|
|
|
|
{
|
|
|
|
int XAlign;
|
|
|
|
int TpWidth;
|
|
|
|
int BorderX;
|
|
|
|
int BorderY;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Information about where I can place this frame in the Tpage
|
|
|
|
----------------------------------------------------------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Vars
|
|
|
|
---- */
|
2000-12-06 20:29:40 +01:00
|
|
|
// changed by dave to get the pixel border back
|
2000-12-02 19:55:49 +01:00
|
|
|
static TPInfo const InfStruct[TP_NUM_OF_TP_TYPES]=
|
|
|
|
{
|
2000-12-06 20:29:40 +01:00
|
|
|
{1,256,0,0}, // TP_4
|
|
|
|
{2,512,0,0}, // TP_8
|
|
|
|
{4,256,0,0}, // TP_16
|
|
|
|
{0,0,0,0}, // TP_SCREEN
|
|
|
|
{16*4,1024*4,0,0}, // TP_PAL
|
2000-12-02 19:55:49 +01:00
|
|
|
};
|
2000-12-06 20:29:40 +01:00
|
|
|
/*
|
|
|
|
static TPInfo const InfStruct[TP_NUM_OF_TP_TYPES]=
|
|
|
|
{
|
|
|
|
{1,256,1,1}, // TP_4
|
|
|
|
{2,512,2,1}, // TP_8
|
|
|
|
{4,256,4,1}, // TP_16
|
|
|
|
{0,0,0,0}, // TP_SCREEN
|
|
|
|
{16*4,1024*4,0,0}, // TP_PAL
|
|
|
|
};
|
|
|
|
*/
|
2000-12-02 19:55:49 +01:00
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function Prototypes
|
|
|
|
------------------- */
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Vars
|
|
|
|
---- */
|
|
|
|
int TPRect::W2Alloc=1;
|
|
|
|
int TPRect::H2Alloc=1;
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Data
|
|
|
|
---- */
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function:
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
VRAM::VRAM(int nTpWidth,int nTpHeightInPixels)
|
|
|
|
{
|
|
|
|
Big2Little=false;
|
|
|
|
RotateEveryEmpty=false;
|
|
|
|
|
|
|
|
|
|
|
|
TpWidth=-1;
|
|
|
|
TpHeightInPixels=-1;
|
|
|
|
|
|
|
|
Clear(nTpWidth,nTpHeightInPixels);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VRAM::Clear(int nTpWidth,int nTpHeightInPixels)
|
|
|
|
{
|
|
|
|
if (nTpWidth >= 0 )
|
|
|
|
TpWidth=nTpWidth;
|
|
|
|
|
|
|
|
if (nTpHeightInPixels >= 0)
|
|
|
|
TpHeightInPixels=nTpHeightInPixels;
|
|
|
|
|
|
|
|
InitEmpty(0,0,TpWidth*256,TpHeightInPixels);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: void VRAM::InitEmpty(void)
|
|
|
|
Purpose: Initialise the VRAM as empty
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
void VRAM::InitEmpty(int vX,int vY,int nW,int nH)
|
|
|
|
{
|
|
|
|
const int Width16=256;
|
|
|
|
const int Height16=256;
|
|
|
|
|
|
|
|
W=nW;
|
|
|
|
H=nH;
|
|
|
|
X=vX;
|
|
|
|
Y=vY;
|
|
|
|
|
|
|
|
VRAMWidthPages=W/Width16;
|
|
|
|
VRAMHeightPages=H/Height16;
|
|
|
|
|
|
|
|
if (!VRAMHeightPages)
|
|
|
|
{
|
|
|
|
VRAMHeightPages = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
NumOfTPages=VRAMWidthPages*VRAMHeightPages;
|
|
|
|
|
|
|
|
VecOfPages.resize(NumOfTPages,TPRectList());
|
|
|
|
|
|
|
|
Unused.reserve(4000);
|
|
|
|
Used.reserve(2000);
|
|
|
|
|
|
|
|
Unused.resize(0);
|
|
|
|
Used.resize(0);
|
|
|
|
|
|
|
|
for (int f=0;f<NumOfTPages;f++)
|
|
|
|
VecOfPages[f].resize(0);
|
|
|
|
|
|
|
|
for (int y=0;y<VRAMHeightPages;y++)
|
|
|
|
for (int x=0;x<VRAMWidthPages;x++)
|
|
|
|
AddEmpty((x*Width16)+vX,(y*Height16)+vY,Width16,Height16);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: bool TryNFit(TPRectList & TpList)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
bool VRAM::TryNFit(TPRectList & TpList,TPRect & ThisRect)
|
|
|
|
{
|
|
|
|
bool Done=false;
|
|
|
|
|
|
|
|
TPRectList::iterator f;
|
|
|
|
|
|
|
|
|
|
|
|
for (f=TpList.begin();f!=TpList.end();f++)
|
|
|
|
{
|
|
|
|
TPRect & BlankRect = *f;
|
|
|
|
|
|
|
|
if (TryRect(BlankRect,ThisRect))
|
|
|
|
return(true);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (RotateEveryEmpty && CanRotate(ThisRect))
|
|
|
|
{
|
|
|
|
ThisRect.SetRotate(!ThisRect.GetRotate());
|
|
|
|
|
|
|
|
if (TryRect(BlankRect,ThisRect))
|
|
|
|
return(true);
|
|
|
|
else
|
|
|
|
ThisRect.SetRotate(!ThisRect.GetRotate());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VRAM::PosFromTPrect(TPRect & ThisRect,POS_INFO & Pi)
|
|
|
|
{
|
|
|
|
TPInfo const * Tpi;
|
|
|
|
int WorkingWidth;
|
|
|
|
|
|
|
|
Tpi=&InfStruct[ThisRect.TypeOfPage];
|
|
|
|
Pi.XAlign=Tpi->XAlign;
|
|
|
|
|
|
|
|
WorkingWidth=GU_AlignVal(ThisRect.W,Pi.XAlign);
|
|
|
|
|
|
|
|
Pi.MinX=Tpi->BorderX;
|
|
|
|
Pi.MinY=Tpi->BorderY;
|
|
|
|
Pi.MaxX=W-Tpi->BorderX-WorkingWidth;
|
|
|
|
Pi.MaxY=H-Tpi->BorderY-ThisRect.H;
|
|
|
|
|
|
|
|
Pi.TpWidthPix=Tpi->TpWidth;
|
|
|
|
|
|
|
|
Pi.MinXTp=Tpi->BorderX;
|
|
|
|
Pi.MaxXTp=Tpi->TpWidth-Tpi->BorderX-WorkingWidth;
|
|
|
|
|
|
|
|
Pi.MinYTp=Tpi->BorderY;
|
|
|
|
Pi.MaxYTp=(256-Tpi->BorderY)-ThisRect.H;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VRAM::TryRect(TPRect & BlankRect,TPRect & ThisRect)
|
|
|
|
{
|
|
|
|
POS_INFO Pi;
|
|
|
|
PosFromTPrect(ThisRect,Pi);
|
|
|
|
|
|
|
|
int MinTpX=Pi.MinXTp+(BlankRect.X/Pi.TpWidthPix)*Pi.TpWidthPix;
|
|
|
|
int MaxTpX=Pi.MaxXTp+(BlankRect.X/Pi.TpWidthPix)*Pi.TpWidthPix;
|
|
|
|
int MinTpY=Pi.MinYTp+(BlankRect.Y/256)*256;
|
|
|
|
int MaxTpY=Pi.MaxYTp+(BlankRect.Y/256)*256;
|
|
|
|
|
|
|
|
/* Move to avoid edges of the map */
|
|
|
|
int MinX = MinTpX > Pi.MinX ? MinTpX : Pi.MinX;
|
|
|
|
int MaxX = MaxTpX < Pi.MaxX ? MaxTpX : Pi.MaxX;
|
|
|
|
int MinY = MinTpY > Pi.MinY ? MinTpY : Pi.MinY;
|
|
|
|
int MaxY = MaxTpY < Pi.MaxY ? MaxTpY : Pi.MaxY;
|
|
|
|
|
|
|
|
int ThisX=GU_AlignVal(BlankRect.X,Pi.XAlign);
|
|
|
|
int ThisY=BlankRect.Y;
|
|
|
|
|
|
|
|
if (ThisX<MinX)
|
|
|
|
ThisX=MinX;
|
|
|
|
|
|
|
|
if (ThisX>MaxX)
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
if (ThisY<MinY)
|
|
|
|
ThisY=MinY;
|
|
|
|
|
|
|
|
if (ThisY>MaxY)
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
ThisRect.SetXY(ThisX,ThisY);
|
|
|
|
|
|
|
|
if (!InColisionWithUsed(ThisRect))
|
|
|
|
{
|
|
|
|
RemovedFromUnused(ThisRect);
|
|
|
|
AddToUsed(ThisRect);
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: TPRect VRAM::AllocVRAM(TPageType nType,int nW,int nH,bool Rotated)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
class Predicate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool operator()(TPRect const & R1,TPRect const & R2) const
|
|
|
|
{
|
|
|
|
u32 R1Val=(R1.H<<16)|(R1.W);
|
|
|
|
u32 R2Val=(R2.H<<16)|(R2.W);
|
|
|
|
return (R1Val<R2Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Predicate2
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool operator()(TPRect const & R1,TPRect const & R2) const
|
|
|
|
{
|
|
|
|
u32 R1Val=(R1.H<<16)|(R1.W);
|
|
|
|
u32 R2Val=(R2.H<<16)|(R2.W);
|
|
|
|
return (R1Val>R2Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: TPRect VRAM::AllocVRAM(TpRectVec & RectVec)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
bool VRAM::AllocVRAM(TPRectVec & RectVec,bool nRotateEveryEmpty,bool nBig2Little,bool nWiderThanHigher)
|
|
|
|
{
|
|
|
|
int f;
|
|
|
|
|
|
|
|
RotateEveryEmpty=nRotateEveryEmpty;
|
|
|
|
Big2Little=nBig2Little;
|
|
|
|
WiderThanHigher=nWiderThanHigher;
|
|
|
|
|
|
|
|
if (WiderThanHigher)
|
|
|
|
{
|
|
|
|
for (f=0;f<RectVec.size();f++)
|
|
|
|
{
|
|
|
|
if ((RectVec[f].H > RectVec[f].W) && CanRotate(RectVec[f]))
|
|
|
|
RectVec[f].SetRotate(!RectVec[f].GetRotate());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Big2Little)
|
|
|
|
std::sort(RectVec.begin(),RectVec.end(),Predicate());
|
|
|
|
else
|
|
|
|
std::sort(RectVec.begin(),RectVec.end(),Predicate2());
|
|
|
|
|
|
|
|
bool AllocedEverything=true;
|
|
|
|
|
|
|
|
for (f=0;f<RectVec.size();f++)
|
|
|
|
{
|
|
|
|
if (!AllocVRAM(RectVec[f]))
|
|
|
|
{
|
|
|
|
AllocedEverything=false;
|
|
|
|
cout<<"Couldn't alloc "<<RectVec[f].W<<","<<RectVec[f].H<<endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(AllocedEverything);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: void VRAM::AllocVRAM(TPageType nType,int nW,int nH)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
bool VRAM::AllocVRAM(TPRect & OriginalRect)
|
|
|
|
{
|
|
|
|
bool Done;
|
|
|
|
TPRect ThisRect;
|
|
|
|
|
|
|
|
ThisRect=OriginalRect;
|
|
|
|
|
|
|
|
Done=false;
|
|
|
|
|
|
|
|
for (int Page=0;Page<NumOfTPages && !Done;Page++)
|
|
|
|
{
|
|
|
|
VecOfPages[Page].sort();
|
|
|
|
|
|
|
|
TPRect::SetAllocWH(ThisRect.W,ThisRect.H);
|
|
|
|
|
|
|
|
if (!TryNFit(VecOfPages[Page],ThisRect))
|
|
|
|
{
|
|
|
|
if (CanRotate(ThisRect))
|
|
|
|
{
|
|
|
|
ThisRect.SetRotate(!ThisRect.GetRotate());
|
|
|
|
|
|
|
|
VecOfPages[Page].sort();
|
|
|
|
TPRect::SetAllocWH(ThisRect.W,ThisRect.H);
|
|
|
|
|
|
|
|
if (!TryNFit(VecOfPages[Page],ThisRect))
|
|
|
|
ThisRect.SetRotate(!ThisRect.GetRotate());
|
|
|
|
else
|
|
|
|
Done=true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Done=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Done)
|
|
|
|
{
|
|
|
|
OriginalRect=ThisRect;
|
|
|
|
OriginalRect.SetAlloced(true);
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OriginalRect.SetAlloced(false);
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function:
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
bool VRAM::CanRotate(TPRect & ThisRect)
|
|
|
|
{
|
|
|
|
if (ThisRect.GetDontRotate())
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
switch (ThisRect.TypeOfPage)
|
|
|
|
{
|
|
|
|
case TP_PAL:
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
case TP_4:
|
|
|
|
case TP_8:
|
|
|
|
case TP_16:
|
|
|
|
return(true);
|
|
|
|
|
|
|
|
case TP_SCREEN:
|
|
|
|
case TP_NUM_OF_TP_TYPES:
|
|
|
|
default:
|
|
|
|
Error(ERR_FATAL,"Not catered for");
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: void VRAM::AllocVRAM(TPageType nType,int nW,int nH)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
void VRAM::RectFromTpRect(Rect & R,TPRect const & ThisRect)
|
|
|
|
{
|
|
|
|
R.W=ThisRect.W;
|
|
|
|
R.H=ThisRect.H;
|
|
|
|
R.X=ThisRect.X;
|
|
|
|
R.Y=ThisRect.Y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VRAM::RemovedFromUnused(TPRect const & ThisRect)
|
|
|
|
{
|
|
|
|
RectVec Result;
|
|
|
|
Rect NewRect;
|
|
|
|
int f;
|
|
|
|
|
|
|
|
RectFromTpRect(NewRect,ThisRect);
|
|
|
|
|
|
|
|
int ColidedWith=0;
|
|
|
|
|
|
|
|
for ( f=0;f<Unused.size();f++)
|
|
|
|
{
|
|
|
|
Rect UnusedRect;
|
|
|
|
|
|
|
|
RectFromTpRect(UnusedRect,Unused[f]);
|
|
|
|
|
|
|
|
if (UnusedRect.IsColiding(ThisRect) )
|
|
|
|
{
|
|
|
|
CutRect(UnusedRect,ThisRect,Result);
|
|
|
|
ColidedWith++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Result.push_back(UnusedRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
Unused.resize(0);
|
|
|
|
|
|
|
|
for (f=0;f<NumOfTPages;f++)
|
|
|
|
VecOfPages[f].resize(0);
|
|
|
|
|
|
|
|
for (f=0;f<Result.size();f++)
|
|
|
|
AddEmpty(Result[f].X,Result[f].Y,Result[f].W,Result[f].H);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VRAM::AddEmpty(int x,int y,int w,int h)
|
|
|
|
{
|
|
|
|
Unused.resize(Unused.size()+1);
|
|
|
|
|
|
|
|
TPRect & ThisRect=(Unused[Unused.size()-1]);
|
|
|
|
|
|
|
|
ThisRect.TypeOfPage=TP_4;
|
|
|
|
ThisRect.W=w;
|
|
|
|
ThisRect.H=h;
|
|
|
|
ThisRect.X=x;
|
|
|
|
ThisRect.Y=y;
|
|
|
|
|
|
|
|
int TpNum=(x/256)+((y/256)*VRAMWidthPages);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VecOfPages[TpNum].insert(VecOfPages[TpNum].end(),ThisRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VRAM::AddToUsed(TPRect const & ThisRect)
|
|
|
|
{
|
|
|
|
|
|
|
|
Used.push_back(ThisRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool VRAM::InColisionWithUsed(TPRect const & R)
|
|
|
|
{
|
|
|
|
for (int f=0;f<Used.size();f++)
|
|
|
|
{
|
|
|
|
if (R.IsColiding(Used[f]))
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: bool VRAM::CheckValidAlloc(TPageType nType,int nW,int nH)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
bool VRAM::CheckValidAlloc(TPageType nType,int nW,int nH)
|
|
|
|
{
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: int VRAM::GetMaxWidthTp(TPageType nType)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
int VRAM::GetMaxWidthTp(TPageType nType)
|
|
|
|
{
|
|
|
|
int RetVal;
|
|
|
|
|
|
|
|
switch (nType)
|
|
|
|
{
|
|
|
|
case TP_4:
|
|
|
|
RetVal=1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_8:
|
|
|
|
RetVal=2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_16:
|
|
|
|
RetVal=4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_SCREEN:
|
|
|
|
RetVal=256;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
RetVal=-1;
|
|
|
|
Error(ERR_FATAL,"Illegal tpage type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(RetVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function: int VRAM::GetXAlign(TPageType nType)
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
int VRAM::GetXAlign(TPageType nType)
|
|
|
|
{
|
|
|
|
int RetVal;
|
|
|
|
|
|
|
|
switch (nType)
|
|
|
|
{
|
|
|
|
case TP_4:
|
|
|
|
RetVal=1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_8:
|
|
|
|
RetVal=2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_16:
|
|
|
|
RetVal=4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_PAL:
|
|
|
|
RetVal=16*4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_SCREEN:
|
|
|
|
RetVal=4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
RetVal=-1;
|
|
|
|
Error(ERR_FATAL,"Illegal tpage type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(RetVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function:
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function:
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
TPRect & VRAM::NewItem(TPRectVec & TPRects)
|
|
|
|
{
|
|
|
|
TPRects.resize(TPRects.size()+1);
|
|
|
|
return(TPRects[TPRects.size()-1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
|
|
Function:
|
|
|
|
Purpose:
|
|
|
|
Params:
|
|
|
|
Returns:
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
TPRect::TPRect(void)
|
|
|
|
{
|
|
|
|
InitRect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::InitRect(void)
|
|
|
|
{
|
|
|
|
X=0;
|
|
|
|
Y=0;
|
|
|
|
W=0;
|
|
|
|
H=0;
|
|
|
|
TypeOfPage=TP_4;
|
|
|
|
Rotated=false;
|
|
|
|
Alloced=false;
|
|
|
|
DontRotate=false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TPRect::TPRect(TPageType nType,int nW,int nH)
|
|
|
|
{
|
|
|
|
int WidthMul;
|
|
|
|
|
|
|
|
InitRect();
|
|
|
|
|
|
|
|
WidthMul=GetWidthMul(nType);
|
|
|
|
|
|
|
|
W=nW*WidthMul;
|
|
|
|
H=nH;
|
|
|
|
TypeOfPage=nType;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TPRect::GetWidthMul(TPageType nType)
|
|
|
|
{
|
|
|
|
int WidthMul;
|
|
|
|
|
|
|
|
switch (nType)
|
|
|
|
{
|
|
|
|
case TP_4:
|
|
|
|
WidthMul=1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_8:
|
|
|
|
WidthMul=2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_16:
|
|
|
|
case TP_SCREEN:
|
|
|
|
case TP_PAL:
|
|
|
|
WidthMul=4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_NUM_OF_TP_TYPES:
|
|
|
|
default:
|
|
|
|
Error(ERR_FATAL,"Can't alloc type TP_NUM_OF_TP_TYPES");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return (WidthMul);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::Set(TPageType nType,int nX,int nY,int nW,int nH)
|
|
|
|
{
|
|
|
|
TypeOfPage=nType;
|
|
|
|
X=nX;
|
|
|
|
Y=nY;
|
|
|
|
W=nW*GetWidthMul(nType);
|
|
|
|
H=nH;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::SetXY(int nX,int nY)
|
|
|
|
{
|
|
|
|
X=nX;
|
|
|
|
Y=nY;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 TPRect::GetId(void) const
|
|
|
|
{
|
|
|
|
int Colis=0;
|
|
|
|
|
|
|
|
int PageNum=(X/256)+((Y/256)*16);
|
|
|
|
|
|
|
|
if ((X/256) != ((X+W2Alloc-1)/256))
|
|
|
|
Colis|=1;
|
|
|
|
|
|
|
|
if ((Y/256) != ((Y+H2Alloc-1)/256))
|
|
|
|
Colis|=2;
|
|
|
|
|
|
|
|
return ((Colis<<24)|(PageNum<<16)|((Y&0xff)<<8)|(X&0xff));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TPRect::SetRotate(bool Rot)
|
|
|
|
{
|
|
|
|
bool RetBool=Rotated;
|
|
|
|
|
|
|
|
if (Rot != RetBool)
|
|
|
|
{
|
|
|
|
W/=GetWidthMul(TypeOfPage);
|
|
|
|
int Temp=W;
|
|
|
|
W=H;
|
|
|
|
H=Temp;
|
|
|
|
W*=GetWidthMul(TypeOfPage);
|
|
|
|
}
|
|
|
|
|
|
|
|
Rotated=Rot;
|
|
|
|
return(RetBool);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void VRAM::getUnusedSpace(TPRectVec & unusedBoxes)
|
|
|
|
{
|
|
|
|
int vX=X;
|
|
|
|
int vY=Y;
|
|
|
|
const int Width16=256;
|
|
|
|
const int Height16=256;
|
|
|
|
|
|
|
|
for (int y=0;y<VRAMHeightPages;y++)
|
|
|
|
for (int x=0;x<VRAMWidthPages;x++)
|
|
|
|
{
|
|
|
|
TPRect thisRect;
|
|
|
|
bool foundRect;
|
|
|
|
|
|
|
|
foundRect=false;
|
|
|
|
|
|
|
|
for (int f=1;f<255 && !foundRect;f++)
|
|
|
|
{
|
|
|
|
int boxBaseY;
|
|
|
|
int boxHeight;
|
|
|
|
|
|
|
|
boxBaseY=f;
|
|
|
|
boxHeight=255-f;
|
|
|
|
|
|
|
|
thisRect.X=(x*Width16)+vX;
|
|
|
|
thisRect.Y=(y*Height16)+vY+boxBaseY;
|
|
|
|
thisRect.W=Width16;
|
|
|
|
thisRect.H=boxHeight;
|
|
|
|
|
|
|
|
if (!InColisionWithUsed(thisRect))
|
|
|
|
foundRect=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (foundRect)
|
|
|
|
unusedBoxes.push_back(thisRect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int VRAM::GetNumOfUsedPages()
|
|
|
|
{
|
|
|
|
int Used=0;
|
|
|
|
int vX=X;
|
|
|
|
int vY=Y;
|
|
|
|
const int Width16=256;
|
|
|
|
const int Height16=256;
|
|
|
|
|
|
|
|
for (int y=0;y<VRAMHeightPages;y++)
|
|
|
|
for (int x=0;x<VRAMWidthPages;x++)
|
|
|
|
{
|
|
|
|
TPRect ThisRect;
|
|
|
|
ThisRect.X=(x*Width16)+vX;
|
|
|
|
ThisRect.Y=(y*Height16)+vY;
|
|
|
|
ThisRect.W=Width16;
|
|
|
|
ThisRect.H=Height16;
|
|
|
|
|
|
|
|
if (InColisionWithUsed(ThisRect))
|
|
|
|
Used++;
|
|
|
|
}
|
|
|
|
return(Used);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TPRect::IsAlloced(void) const
|
|
|
|
{
|
|
|
|
return(Alloced);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::SetAlloced(bool nAlloced)
|
|
|
|
{
|
|
|
|
Alloced=nAlloced;
|
|
|
|
}
|
|
|
|
|
|
|
|
int VRAM::GetNumOfItems()
|
|
|
|
{
|
|
|
|
return(Used.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::InitFromFrame(Frame const & Fr)
|
|
|
|
{
|
|
|
|
/* !!!!! Make this support other bit widths */
|
|
|
|
|
|
|
|
W=Fr.GetWidth();
|
|
|
|
H=Fr.GetHeight();
|
|
|
|
|
|
|
|
if (Fr.GetNumOfCols() <= 16)
|
|
|
|
TypeOfPage=TP_4;
|
|
|
|
else if (Fr.GetNumOfCols() <= 256)
|
|
|
|
TypeOfPage=TP_8;
|
|
|
|
else
|
|
|
|
Error(ERR_FATAL,"Only 4 & 8 bit supported right now");
|
|
|
|
|
|
|
|
W*=GetWidthMul(TypeOfPage);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TPageType TPRect::convertTo16Bit(void)
|
|
|
|
{
|
|
|
|
TPageType oldType;
|
|
|
|
|
|
|
|
switch (TypeOfPage)
|
|
|
|
{
|
|
|
|
case TP_4:
|
|
|
|
// W=GU_AlignVal(W,4)/4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_8:
|
|
|
|
// W=GU_AlignVal(W,2)/2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Error(ERR_FATAL,"Only 4 & 8 bit supported right now");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldType=TypeOfPage;
|
|
|
|
TypeOfPage=TP_16;
|
|
|
|
|
|
|
|
return(oldType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPRect::convertFrom16Bit(TPageType newType)
|
|
|
|
{
|
|
|
|
switch (newType)
|
|
|
|
{
|
|
|
|
case TP_4:
|
|
|
|
// W=W*4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TP_8:
|
|
|
|
// W=W*2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Error(ERR_FATAL,"Only 4 & 8 bit supported right now");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeOfPage=newType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================
|
|
|
|
end */
|
|
|
|
|
|
|
|
|