Code:
#pragma pack(1)
struct CMapResourceHeader
{
DWORD mrhWidth;
DWORD mrhHeight;
DWORD mrhNumMaps;
};
struct CMapFileHeader
{
DWORD mfhWidth;
DWORD mfhHeight;
int mfhNumBitmapIDs;
//Bitmap IDs immediately follow - 4 bytes per ID
};
#pragma
class CMapManager;
class CMap
{
protected:
friend class CMapManager;
DWORD *m_pMap;
int m_iNumBitmapIDs;
DWORD *m_dwBitmapIDs;
DWORD m_dwSize;
DWORD m_dwWidth;
DWORD m_dwHeight;
public:
CMap(void):m_pMap(NULL),m_dwSize(0),m_dwWidth(0),m_dwHeight(0) {}
virtual ~CMap(void)
{
if (m_pMap)
{
delete [] m_pMap;
}
}
DWORD *GetMap(void) {return m_pMap;};
void SetMap(DWORD *pMap) {m_pMap=pMap;};
void Load(CString filename)
{
int handle=_open(filename,_O_BINARY | O_RDWR,_S_IREAD);
Clear(0);
CMapFileHeader hdr;
_read(handle,&hdr,sizeof(CMapFileHeader));
m_dwSize=hdr.mfhWidth*hdr.mfhHeight;
m_dwWidth=hdr.mfhWidth;
m_dwHeight=hdr.mfhHeight;
_read(handle,m_pMap,m_dwSize*sizeof(DWORD));
_close(handle);
}
void Save(CString filename)
{
int handle=_open(filename,_O_BINARY | _O_RDWR, S_IWRITE);
CMapFileHeader hdr;
hdr.mfhWidth=m_dwWidth;
hdr.mfhHeight=m_dwHeight;
_write(handle,&hdr,sizeof(CMapFileHeader));
_write(handle,m_pMap,m_dwSize*sizeof(DWORD));
_close(handle);
}
void SaveToHandle(int filehandle)
{
CMapFileHeader hdr;
hdr.mfhWidth=m_dwWidth;
hdr.mfhHeight=m_dwHeight;
CString text;
text.Format("%u %u",m_dwWidth,m_dwHeight);
::MessageBox(0,text,0,0);
_write(filehandle,&hdr,sizeof(CMapFileHeader));
_write(filehandle,m_pMap,m_dwSize*sizeof(DWORD));
}
void LoadFromHandle(int filehandle)
{
CMapFileHeader hdr;
_read(filehandle,&hdr,sizeof(CMapFileHeader));
m_dwWidth=hdr.mfhWidth;
m_dwHeight=hdr.mfhHeight;
m_dwSize=m_dwWidth*m_dwHeight;
//if map exists de-allocate its memory
if (m_pMap) delete [] m_pMap;
//Create/Re-create map
Create(m_dwWidth,m_dwHeight);
//Clear map to empty state
Clear(0xFFFFFFF);
CString text;
text.Format("Width %u Height %u",m_dwWidth,m_dwHeight);
::MessageBox(0,text,0,0);
//Read in data from file
_read(filehandle,m_pMap,m_dwSize*sizeof(DWORD));
}
void Clear(DWORD value)
{
memset(m_pMap,value,m_dwSize*sizeof(DWORD));
}
bool Create(DWORD dwWidth,DWORD dwHeight)
{
//::MessageBox(0,"creating map",0,0);
m_dwSize=dwWidth*dwHeight;
m_dwWidth=dwWidth;
m_dwHeight=dwHeight;
m_pMap=new DWORD[m_dwWidth*m_dwHeight];
return true;
}
bool SetMapXYTo(DWORD dwX,DWORD dwY,DWORD dwValue)
{
DWORD dwOffset=dwY*m_dwWidth+dwX;
if (dwOffset<m_dwSize)
{
m_pMap[dwOffset]=dwValue;
return true;
} else return false;
}
bool SetMapOffsetTo(DWORD dwOffset,DWORD dwValue)
{
if (dwOffset<m_dwSize)
{
m_pMap[dwOffset]=dwValue;
return true;
} else return false;
}
bool GetValueAtXY(DWORD dwX,DWORD dwY,DWORD *outValue)
{
DWORD dwOffset=dwY*m_dwWidth+dwX;
if (dwOffset<m_dwSize)
{
*outValue=m_pMap[dwOffset];
return true;
} else return false;
}
bool GetValueAtOffset(DWORD dwOffset,DWORD *outValue)
{
if (dwOffset<m_dwSize)
{
*outValue=m_pMap[dwOffset];
return true;
} else return false;
}
DWORD GetValueAtXY(DWORD dwX,DWORD dwY)
{
DWORD dwOffset=dwY*m_dwWidth+dwX;
DWORD value=0;
if (dwOffset<m_dwSize)
{
value=m_pMap[dwOffset];
return value;
} else return 0xFFFFFFFF;
}
DWORD GetValueAtOffset(DWORD dwOffset)
{
DWORD value=0;
if (dwOffset<m_dwSize)
{
value=m_pMap[dwOffset];
return value;
} else return 0xFFFFFFFF;
}
};
class CMapManager
{
std::vector<CMap *> Maps;
DWORD m_dwHeight;
DWORD m_dwWidth;
public:
CMapManager(void) {}
virtual ~CMapManager(void)
{
Maps.empty();
}
void ResetData(void)
{
m_dwHeight=0;
m_dwWidth=0;
Maps.empty();
}
void Add(DWORD dwWidth,DWORD dwHeight)
{
m_dwHeight=dwHeight;
m_dwWidth=dwWidth;
CMap *temp=new CMap();
temp->Create(dwWidth,dwHeight);
Maps.push_back(temp);
}
DWORD GetValueAtOffset(int mapnum,DWORD dwOffset)
{
if (mapnum<Maps.size())
{
return Maps[mapnum]->GetValueAtOffset(dwOffset);
}
}
bool SetMapOffsetTo(int mapnum,DWORD dwOffset,DWORD value)
{
if (mapnum<Maps.size())
{
Maps[mapnum]->SetMapOffsetTo(dwOffset,value);
return true;
} else return false;
}
//Returns a pointer to a map
DWORD *GetMap(DWORD ID)
{
if (ID<Maps.size())
{
return Maps[ID]->GetMap();
}
}
CMap *GetMapClass(DWORD ID)
{
if (ID<Maps.size())
{
return Maps[ID];
}
}
DWORD GetNumberOfMaps(void) {return Maps.size();};
void Clear(DWORD mapnum,DWORD value)
{
if (mapnum<Maps.size())
{
Maps[mapnum]->Clear(value);
}
}
/*
struct CMapResourceHeader
{
DWORD mrhWidth;
DWORD mrhHeight;
DWORD mrhNumMaps;
};
*/
void Save(CString filename)
{
int handle=_open(filename,_O_BINARY | _O_RDWR | _O_CREAT,_S_IWRITE);
if (handle==-1)
{
CString errortext;
CString codetext;
switch(errno)
{
case EACCES:
codetext="Access error";break;
case EEXIST:
codetext="File exists";break;
case EINVAL:
codetext="Invalid argument";break;
case EMFILE:
codetext="Too many open handles";break;
case ENOENT:
codetext="Invalid path";break;
}
errortext.Format("Error saving %s - %s",filename,codetext);
::MessageBox(0,errortext,"ERROR",MB_ICONEXCLAMATION);
return;
}
//Fill resource header with info
CMapResourceHeader hdr;
hdr.mrhHeight=m_dwHeight;
hdr.mrhWidth=m_dwWidth;
hdr.mrhNumMaps=Maps.size();
//CString test;
//test.Format("Maps: %u",hdr.mrhNumMaps);
//::MessageBox(0,test,0,0);
//Write resource header to disk
_write(handle,&hdr,sizeof(CMapResourceHeader));
//Loop and write all maps to disk
for (int i=0;i<Maps.size();i++)
{
Maps[i]->SaveToHandle(handle);
}
_close(handle);
}
DWORD Load(CString filename,DWORD &outWidth,DWORD &outHeight)
{
int handle=_open(filename,_O_BINARY | _O_RDWR,_S_IREAD);
if (handle==-1)
{
CString errortext;
errortext.Format("Error loading %s",filename);
::MessageBox(0,errortext,"ERROR",MB_ICONEXCLAMATION);
return 0;
}
//Kill current maps
Maps.empty();
//Fill resource header with info
CMapResourceHeader hdr;
//Read resource header from disk
_read(handle,&hdr,sizeof(CMapResourceHeader));
m_dwHeight=hdr.mrhHeight;
m_dwWidth=hdr.mrhWidth;
outHeight=m_dwHeight;
outWidth=m_dwWidth;
int iMaps=hdr.mrhNumMaps;
//Loop and create all maps from disk
for (int i=0;i<iMaps;i++)
{
Add(m_dwWidth,m_dwHeight);
Maps[i]->LoadFromHandle(handle);
}
_close(handle);
return iMaps;
}
// bool Remove(DWORD ID)
// {
// if (ID<Maps.size())
// {
// Maps.remove
};
This is a work in progress - removing maps from the vector has not been implemented. Feel free to do so.