mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
253 lines
5.9 KiB
C++
253 lines
5.9 KiB
C++
#include "ht.h"
|
|
|
|
namespace wi {
|
|
|
|
TileMap *LoadTileMap(char *pszFn, Size *psizPlayfield)
|
|
{
|
|
TileMap *ptmap = new TileMap;
|
|
if (!ptmap->Load(pszFn, psizPlayfield)) {
|
|
delete ptmap;
|
|
return NULL;
|
|
}
|
|
return ptmap;
|
|
}
|
|
|
|
TileMap::TileMap()
|
|
{
|
|
memset(m_aptseth, 0, sizeof(m_aptseth));
|
|
m_apbTileData = NULL;
|
|
m_cTileSets = 0;
|
|
m_cTiles = 0;
|
|
m_wf = 0;
|
|
m_apbDrawMap = NULL;
|
|
m_pmtseth = NULL;
|
|
}
|
|
|
|
TileMap::~TileMap()
|
|
{
|
|
if (m_wf & kfTmapMapped) {
|
|
gpakr.UnmapFile(&m_fmapTmap);
|
|
for (int nTset = 0; nTset < m_cTileSets; nTset++)
|
|
gpakr.UnmapFile(&m_afmapTset[nTset]);
|
|
}
|
|
if (m_wf & kfMiniTsetMapped)
|
|
gpakr.UnmapFile(&m_fmapMiniTset);
|
|
if (m_apbTileData != NULL)
|
|
gmmgr.FreePtr(m_apbTileData);
|
|
delete[] m_apbDrawMap;
|
|
}
|
|
|
|
bool TileMap::Load(char *psz, Size *psizPlayfield)
|
|
{
|
|
// First try to alloc local map
|
|
|
|
m_ctx = (psizPlayfield->cx + (gcxTile - 1)) / gcxTile + 1;
|
|
m_cty = (psizPlayfield->cy + (gcyTile - 1)) / gcyTile + 1;
|
|
m_apbDrawMap = new byte *[m_ctx * m_cty];
|
|
if (m_apbDrawMap == NULL)
|
|
return false;
|
|
|
|
// Load the tile data
|
|
|
|
m_ptmaph = (TileMapHeader *)gpakr.MapFile(psz, &m_fmapTmap);
|
|
if (m_ptmaph == NULL)
|
|
return false;
|
|
m_wf |= kfTmapMapped;
|
|
m_pwMapData = (word *)(m_ptmaph + 1);
|
|
|
|
// Start loading tsets.
|
|
|
|
m_cTileSets = 0;
|
|
m_cTiles = 0;
|
|
while (true) {
|
|
char sz[kcchFnTset];
|
|
strcpy(sz, m_ptmaph->szFnTset);
|
|
if (m_cTileSets != 0) {
|
|
char szT[8];
|
|
szT[0] = '.';
|
|
itoa(m_cTileSets, &szT[1], 10);
|
|
strcat(sz, szT);
|
|
}
|
|
TileSetHeader *ptseth = (TileSetHeader *)gpakr.MapFile(sz, &m_afmapTset[m_cTileSets]);
|
|
if (ptseth == NULL)
|
|
break;
|
|
m_aptseth[m_cTileSets] = ptseth;
|
|
m_cxTile = BigWord(ptseth->cxTile);
|
|
m_cyTile = BigWord(ptseth->cyTile);
|
|
m_cTileSets++;
|
|
m_cTiles += BigWord(ptseth->cTiles);
|
|
}
|
|
if (m_cTiles == 0)
|
|
return false;
|
|
|
|
// Alloc enough tile pointers to point to the individual tiles
|
|
|
|
byte **apbTileData = new byte *[m_cTiles];
|
|
if (apbTileData == NULL)
|
|
return false;
|
|
|
|
// Fill in the pointers to tile data
|
|
|
|
byte **ppb = apbTileData;
|
|
int cbTile = m_cxTile * m_cyTile;
|
|
for (int nTset = 0; nTset < m_cTileSets; nTset++) {
|
|
TileSetHeader *ptseth = m_aptseth[nTset];
|
|
byte *pbTileData = (byte *)ptseth + kcbTileSetHeader;
|
|
for (int nTile = 0; nTile < BigWord(ptseth->cTiles); nTile++) {
|
|
*ppb = pbTileData;
|
|
ppb++;
|
|
pbTileData += cbTile;
|
|
}
|
|
}
|
|
|
|
// Save away
|
|
|
|
int cbT = sizeof(byte *) * m_cTiles;
|
|
m_apbTileData = (byte **)gmmgr.AllocPtr(cbT);
|
|
if (m_apbTileData == NULL) {
|
|
delete[] apbTileData;
|
|
return false;
|
|
}
|
|
gmmgr.WritePtr(m_apbTileData, 0, apbTileData, cbT);
|
|
delete[] apbTileData;
|
|
|
|
// Load mini tset
|
|
|
|
char sz[50];
|
|
strcpy(sz, m_ptmaph->szFnTset);
|
|
strcat(sz, "mini");
|
|
m_pmtseth = (MiniTileSetHeader *)gpakr.MapFile(sz, &m_fmapMiniTset);
|
|
if (m_pmtseth == NULL)
|
|
return false;
|
|
m_wf |= kfMiniTsetMapped;
|
|
|
|
// We're done
|
|
|
|
return true;
|
|
}
|
|
|
|
MiniTileSetHeader *TileMap::GetMiniTileSetHeader(int nScale)
|
|
{
|
|
MiniTileSetHeader *pmtseth = m_pmtseth;
|
|
while (true) {
|
|
if (BigWord(pmtseth->cxTile) == nScale)
|
|
return pmtseth;
|
|
if (pmtseth->offNext == 0)
|
|
return NULL;
|
|
pmtseth = (MiniTileSetHeader *)((byte *)pmtseth + BigWord(pmtseth->offNext));
|
|
}
|
|
}
|
|
|
|
void TileMap::GetMapSize(Size *psiz)
|
|
{
|
|
psiz->cx = BigWord(m_ptmaph->ctx) * m_cxTile;
|
|
psiz->cy = BigWord(m_ptmaph->cty) * m_cyTile;
|
|
}
|
|
|
|
void TileMap::GetTileSize(Size *psiz)
|
|
{
|
|
psiz->cx = m_cxTile;
|
|
psiz->cy = m_cyTile;
|
|
}
|
|
|
|
void TileMap::Draw(DibBitmap *pbm, int x, int y, int cx, int cy, int xMap, int yMap, byte *pbFogMap, UpdateMap *pupd)
|
|
{
|
|
Assert(!((xMap | yMap) & 1));
|
|
|
|
//For debugging:
|
|
//BitmapType *pbmpScreen = WinGetBitmap(WinGetDisplayWindow());
|
|
//pbBits = (byte *)BmpGetBits(pbmpScreen);
|
|
|
|
// Get the tile coordinates into the map from which drawing is to start
|
|
|
|
int tx = TcFromPc(xMap);
|
|
int ty = TcFromPc(yMap);
|
|
|
|
// Figure map info
|
|
|
|
MapInfo *pmnfo = pupd->GetMapInfo();
|
|
int ctx = TcFromPc(cx - pmnfo->cxLeftTile + gcxTile - 1) + TcFromPc(pmnfo->cxLeftTile + gcxTile - 1);
|
|
int cty = TcFromPc(cy - pmnfo->cyTopTile + gcyTile - 1) + TcFromPc(pmnfo->cyTopTile + gcyTile - 1);
|
|
int ctxMap = BigWord(m_ptmaph->ctx);
|
|
|
|
// Deal with case of map being smaller than the screen
|
|
|
|
Size sizMap;
|
|
GetMapSize(&sizMap);
|
|
|
|
if (sizMap.cx < cx) {
|
|
Assert(xMap == 0);
|
|
ctx = TcFromPc(sizMap.cx);
|
|
}
|
|
if (sizMap.cy < cy) {
|
|
Assert(yMap == 0);
|
|
cty = TcFromPc(sizMap.cy);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
Assert(ctx <= m_ctx);
|
|
Assert(cty <= m_cty);
|
|
Assert(tx + ctx <= BigWord(m_ptmaph->ctx));
|
|
Assert(ty + cty <= BigWord(m_ptmaph->cty));
|
|
Size sizT;
|
|
pupd->GetMapSize(&sizT);
|
|
Assert(sizT.cx == m_ctx && sizT.cy == m_cty);
|
|
#endif
|
|
|
|
// Get running pointers into various maps
|
|
// Note: Fog will be accounted for in updatemap in the near future
|
|
|
|
word iCell = ty * ctxMap + tx;
|
|
word *pwMapT = &m_pwMapData[iCell];
|
|
byte *pbFogT = &pbFogMap[iCell];
|
|
bool *pfInvalid = pupd->GetInvalidMap();
|
|
byte **ppbDrawMap = m_apbDrawMap;
|
|
|
|
int cReturnDrawMap = m_ctx - ctx;
|
|
int cReturnTileMap = ctxMap - ctx;
|
|
for (int tyT = 0; tyT < cty; tyT++) {
|
|
Assert(ty + tyT < BigWord(m_ptmaph->cty));
|
|
for (int txT = 0; txT < ctx; txT++) {
|
|
Assert(tx + txT < BigWord(m_ptmaph->ctx));
|
|
|
|
*ppbDrawMap = NULL;
|
|
if (!IsFogOpaque(*pbFogT)) {
|
|
if (*pfInvalid) {
|
|
word offset = BigWord(*pwMapT);
|
|
Assert(offset < 0xff00);
|
|
*ppbDrawMap = m_apbTileData[offset / 4];
|
|
}
|
|
}
|
|
|
|
ppbDrawMap++;
|
|
pbFogT++;
|
|
pfInvalid++;
|
|
pwMapT++;
|
|
}
|
|
|
|
ppbDrawMap += cReturnDrawMap;
|
|
pfInvalid += cReturnDrawMap;
|
|
pwMapT += cReturnTileMap;
|
|
pbFogT += cReturnTileMap;
|
|
}
|
|
|
|
// Now draw this map
|
|
#if 0
|
|
BitmapType *pbmpScreen = WinGetBitmap(WinGetDisplayWindow());
|
|
byte *pbDib = (byte *)BmpGetBits(pbmpScreen);
|
|
Size sizFill;
|
|
pbm->GetSize(&sizFill);
|
|
Fill(pbDib, sizFill.cx, sizFill.cy, sizFill.cx, 1);
|
|
#else
|
|
byte *pbDib = pbm->GetBits();
|
|
#endif
|
|
|
|
Size sizDib;
|
|
pbm->GetSize(&sizDib);
|
|
pbDib += y * sizDib.cx + x;
|
|
|
|
DrawTileMapThunk(m_apbDrawMap, m_ctx, m_cty, pbDib, sizDib.cx, pmnfo->cxLeftTile, pmnfo->cyTopTile, pmnfo->cxRightTile, pmnfo->cyBottomTile, pmnfo->ctxInside, pmnfo->ctyInside, gcxTile, gcyTile);
|
|
}
|
|
|
|
} // namespace wi
|