Initial commit
This commit is contained in:
284
engines/hpl1/engine/scene/TileMap.cpp
Normal file
284
engines/hpl1/engine/scene/TileMap.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/scene/TileMap.h"
|
||||
#include "hpl1/engine/graphics/GraphicsTypes.h"
|
||||
#include "hpl1/engine/graphics/RenderObject2D.h"
|
||||
#include "hpl1/engine/graphics/Renderer2D.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/resources/ResourceImage.h"
|
||||
#include "hpl1/engine/resources/Resources.h"
|
||||
#include "hpl1/engine/resources/TileSetManager.h"
|
||||
#include "hpl1/engine/scene/TileMapLineIt.h"
|
||||
#include "hpl1/engine/scene/TileMapRectIt.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cTileMap::cTileMap(cVector2l avSize, float afTileSize, cGraphics *apGraphics, cResources *apResources) {
|
||||
mfTileSize = 1;
|
||||
mvSize = avSize;
|
||||
mfTileSize = afTileSize;
|
||||
mpGraphics = apGraphics;
|
||||
mpResources = apResources;
|
||||
mlShadowLayer = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cTileMap::~cTileMap() {
|
||||
Log(" Deleting tilemap.\n");
|
||||
for (tTileLayerVecIt it = mvTileLayer.begin(); it != mvTileLayer.end(); it++)
|
||||
hplDelete(*it);
|
||||
for (tTileSetVecIt it = mvTileSet.begin(); it != mvTileSet.end(); it++)
|
||||
mpResources->GetTileSetManager()->Destroy(*it);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cTileMap::Render(cCamera2D *apCam) {
|
||||
cRect2f Rect;
|
||||
apCam->GetClipRect(Rect);
|
||||
|
||||
iTileMapIt *TileIt = GetRectIterator(Rect, -1);
|
||||
|
||||
while (TileIt->HasNext()) {
|
||||
RenderTileData(TileIt->Next(), TileIt->GetCurrentLayer());
|
||||
}
|
||||
|
||||
hplDelete(TileIt);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iTileMapIt *cTileMap::GetRectIterator(const cRect2f &aRect, int alLayer) {
|
||||
cVector2l vPos = cVector2l((int)floor(aRect.x / mfTileSize),
|
||||
(int)floor(aRect.y / mfTileSize));
|
||||
|
||||
cVector2l vSize = cVector2l((int)(aRect.w / mfTileSize) + 1,
|
||||
(int)(aRect.h / mfTileSize) + 1);
|
||||
|
||||
// Check if we need yet another grid for x and y
|
||||
if (aRect.x + aRect.w >= (vPos.x + vSize.x) * mfTileSize)
|
||||
vSize.x++;
|
||||
if (aRect.y + aRect.h >= (vPos.y + vSize.y) * mfTileSize)
|
||||
vSize.y++;
|
||||
|
||||
// Log("\nPos: %d:%d\n",vPos.x,vPos.y);
|
||||
// Log("Size: %d:%d\n\n",vSize.x,vSize.y);
|
||||
|
||||
return hplNew(cTileMapRectIt, (vPos, vSize, this, alLayer));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iTileMapIt *cTileMap::GetLineIterator(const cVector2f &avStart, const cVector2f &avEnd, int alLayer) {
|
||||
return hplNew(cTileMapLineIt, (avStart, avEnd, this, alLayer));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector2f cTileMap::GetWorldPos(cVector2f avScreenPos, cCamera2D *apCam) {
|
||||
cVector2f vWorldPos;
|
||||
cRect2f Rect;
|
||||
apCam->GetClipRect(Rect);
|
||||
cVector2f vVirtSize = mpGraphics->GetLowLevel()->GetVirtualSize();
|
||||
|
||||
vWorldPos.x = Rect.x + Rect.w * (avScreenPos.x / ((float)vVirtSize.x));
|
||||
vWorldPos.y = Rect.y + Rect.h * (avScreenPos.y / ((float)vVirtSize.y));
|
||||
|
||||
return vWorldPos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cTile *cTileMap::GetScreenTile(cVector2f avPos, int alLayer, cCamera2D *apCam) {
|
||||
return GetWorldTile(GetWorldPos(avPos, apCam), alLayer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cTileMap::SetScreenTileData(cVector2f avPos, int alLayer, cCamera2D *apCam,
|
||||
int alTileSet, int alTileNum) {
|
||||
cVector2f vWorldPos = GetWorldPos(avPos, apCam);
|
||||
|
||||
cTile *pOldTile = GetWorldTile(vWorldPos, alLayer);
|
||||
|
||||
iTileData *pData = NULL;
|
||||
if (alTileSet >= 0) {
|
||||
cTileSet *pSet = GetTileSet(alTileSet);
|
||||
if (pSet == NULL)
|
||||
return;
|
||||
pData = pSet->Get(alTileNum);
|
||||
if (pData == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
cVector2l vTilePos = cVector2l((int)floor(vWorldPos.x / mfTileSize), (int)floor(vWorldPos.y / mfTileSize));
|
||||
if (vTilePos.x < 0 || vTilePos.y < 0 || vTilePos.x >= mvSize.x || vTilePos.y >= mvSize.y)
|
||||
return;
|
||||
|
||||
if (alLayer < 0 || alLayer >= (int)mvTileLayer.size())
|
||||
return;
|
||||
|
||||
cVector3f vTileWorldPos(vTilePos.x * mfTileSize, vTilePos.y * mfTileSize, mvTileLayer[alLayer]->GetZ());
|
||||
|
||||
int lAngle = 0;
|
||||
if (pOldTile)
|
||||
lAngle = pOldTile->GetAngle();
|
||||
|
||||
cTile *pTile = NULL;
|
||||
if (pData)
|
||||
pTile = hplNew(cTile, (pData, (eTileRotation)lAngle, vTileWorldPos, mfTileSize, NULL));
|
||||
|
||||
mvTileLayer[alLayer]->SetTile(vTilePos.x, vTilePos.y, pTile);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cTileMap::SetScreenTileAngle(cVector2f avPos, int alLayer, cCamera2D *apCam, int alAngle) {
|
||||
cVector2f vWorldPos = GetWorldPos(avPos, apCam);
|
||||
cTile *pTile = GetWorldTile(vWorldPos, alLayer);
|
||||
if (pTile == NULL)
|
||||
return;
|
||||
|
||||
cVector2l vTilePos = cVector2l((int)floor(vWorldPos.x / mfTileSize), (int)floor(vWorldPos.y / mfTileSize));
|
||||
if (vTilePos.x < 0 || vTilePos.y < 0 || vTilePos.x >= mvSize.x || vTilePos.y >= mvSize.y)
|
||||
return;
|
||||
|
||||
cVector3f vTileWorldPos(vTilePos.x * mfTileSize, vTilePos.y * mfTileSize, mvTileLayer[alLayer]->GetZ());
|
||||
|
||||
pTile->SetAngle((eTileRotation)alAngle);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cTile *cTileMap::GetWorldTile(cVector2f avPos, int alLayer) {
|
||||
if (alLayer < 0 || alLayer >= (int)mvTileLayer.size())
|
||||
return NULL;
|
||||
|
||||
return mvTileLayer[alLayer]->GetAt((int)floor(avPos.x / mfTileSize),
|
||||
(int)floor(avPos.y / mfTileSize));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* \param alTileNum
|
||||
* \param alLayer
|
||||
* \param avDir 0=left, 1=right, 2=up, 3 = down
|
||||
* \return num of neighbours
|
||||
*/
|
||||
int cTileMap::GetTileNeighbours4Dir(int alTileNum, int alLayer, bool *avDir) {
|
||||
int lCount = 0;
|
||||
cTileLayer *pLayer = mvTileLayer[alLayer];
|
||||
int lX = alTileNum % mvSize.x;
|
||||
int lY = alTileNum / mvSize.x;
|
||||
|
||||
/*avDir[0] = pLayer->GetAt(lX-1,lY)!=NULL?true:false;
|
||||
avDir[1] = pLayer->GetAt(lX+1,lY)!=NULL?true:false;
|
||||
avDir[2] = pLayer->GetAt(lX,lY-1)!=NULL?true:false;
|
||||
avDir[3] = pLayer->GetAt(lX,lY+1)!=NULL?true:false;*/
|
||||
|
||||
cTile *pTile;
|
||||
cTileDataNormal *pData;
|
||||
|
||||
cVector2l vAdd[4] = {cVector2l(-1, 0), cVector2l(+1, 0), cVector2l(0, -1), cVector2l(0, +1)};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
pTile = pLayer->GetAt(lX + vAdd[i].x, lY + vAdd[i].y);
|
||||
if (pTile != NULL) {
|
||||
pData = static_cast<cTileDataNormal *>(pTile->GetTileData());
|
||||
if (pData->IsSolid())
|
||||
avDir[i] = true;
|
||||
else
|
||||
avDir[i] = false;
|
||||
} else {
|
||||
avDir[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (avDir[i] == true)
|
||||
lCount++;
|
||||
|
||||
return lCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cTileMap::AddTileLayerFront(cTileLayer *apLayer) {
|
||||
if (mvTileLayer.size() < 1) {
|
||||
mvTileLayer.push_back(apLayer);
|
||||
} else {
|
||||
mvTileLayer.push_back(NULL);
|
||||
for (int i = (int)mvTileLayer.size() - 2; i >= 0; i--) {
|
||||
mvTileLayer[i + 1] = mvTileLayer[i];
|
||||
}
|
||||
mvTileLayer[0] = apLayer;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cTileMap::RenderTileData(cTile *apTile, int alLayer) {
|
||||
cTileDataNormal *pData = static_cast<cTileDataNormal *>(apTile->GetTileData());
|
||||
if (pData == NULL)
|
||||
return;
|
||||
cRect2f _obj = cRect2f(apTile->GetPosition().x - mfTileSize / 2,
|
||||
apTile->GetPosition().y - mfTileSize / 2, mfTileSize, mfTileSize);
|
||||
cRenderObject2D _obj2 = cRenderObject2D(pData->GetMaterial(),
|
||||
pData->GetVertexVec(apTile->GetAngle()),
|
||||
pData->GetIndexVec(apTile->GetAngle()),
|
||||
ePrimitiveType_Quad, apTile->GetPosition().z,
|
||||
_obj,
|
||||
NULL, apTile->GetPositionPtr());
|
||||
mpGraphics->GetRenderer2D()->AddObject(_obj2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user