#include "Stdafx.h" #include "../eterPack/EterPackManager.h" #include "terrain.h" #include ////////////////////////////////////////////////////////////////////////// // Texture Set ////////////////////////////////////////////////////////////////////////// CTextureSet * CTerrainImpl::ms_pTextureSet = NULL; void CTerrainImpl::SetTextureSet(CTextureSet * pTextureSet) { static CTextureSet s_EmptyTextureSet; if (!pTextureSet) ms_pTextureSet = &s_EmptyTextureSet; else ms_pTextureSet = pTextureSet; } CTextureSet * CTerrainImpl::GetTextureSet() { if (!ms_pTextureSet) SetTextureSet(NULL); return ms_pTextureSet; } CTerrainImpl::CTerrainImpl() { Initialize(); } CTerrainImpl::~CTerrainImpl() { Clear(); } void CTerrainImpl::Initialize() { memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight)); m_byNumWater = 0; memset(&m_HeightMapHeader, 0, sizeof(TGA_HEADER)); memset(&m_awShadowMap, 0xFFFF, sizeof(m_awShadowMap)); memset(&m_lpAlphaTexture, NULL, sizeof(m_lpAlphaTexture)); m_lViewRadius = 0; m_wTileMapVersion = 8976; m_fHeightScale = 0.0f; m_lpShadowTexture = NULL; m_lSplatTilesX = 0; m_lSplatTilesY = 0; } void CTerrainImpl::Clear() { for (DWORD i = 0; i < GetTextureSet()->GetTextureCount(); ++i) { if (m_lpAlphaTexture[i]) { m_lpAlphaTexture[i]->Release(); m_lpAlphaTexture[i] = NULL; } } Initialize(); } bool CTerrainImpl::LoadHeightMap(const char*c_szFileName) { Tracef("LoadRawHeightMapFile %s ", c_szFileName); CMappedFile kMappedFile; LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) { Tracen("Error"); TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName); return false; } memcpy(m_awRawHeightMap, lpcvFileData, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE); return true; } bool CTerrainImpl::LoadAttrMap(const char *c_szFileName) { DWORD dwStart = ELTimer_GetMSec(); Tracef("LoadAttrMapFile %s ", c_szFileName); CMappedFile kMappedFile; LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) { TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName); return false; } DWORD dwFileSize = kMappedFile.Size(); BYTE * abFileData = (BYTE *) lpcvFileData; // LoadAttrMap { #pragma pack(push) #pragma pack(1) struct SAttrMapHeader { WORD m_wMagic; WORD m_wWidth; WORD m_wHeight; }; #pragma pack(pop) if (dwFileSize < sizeof(SAttrMapHeader)) { TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName); return false; } SAttrMapHeader kAttrMapHeader; memcpy(&kAttrMapHeader, abFileData, sizeof(kAttrMapHeader)); const WORD c_wAttrMapMagic = 2634; if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic) { TraceError("CTerrainImpl::LoadAttrMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kAttrMapHeader.m_wMagic, kAttrMapHeader.m_wMagic); return false; } if (ATTRMAP_XSIZE != kAttrMapHeader.m_wWidth) { TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_width(%d)!=ATTRMAP_XSIZE(%d)", c_szFileName, kAttrMapHeader.m_wWidth, ATTRMAP_XSIZE); return false; } if (ATTRMAP_YSIZE != kAttrMapHeader.m_wHeight) { TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_height(%d)!=ATTRMAP_YSIZE(%d)", c_szFileName, kAttrMapHeader.m_wHeight, ATTRMAP_YSIZE); return false; } DWORD dwFileRestSize=dwFileSize-sizeof(kAttrMapHeader); DWORD dwFileNeedSize=sizeof(m_abyAttrMap); if (dwFileRestSize != dwFileNeedSize) { TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize); return false; } BYTE* abSrcAttrData= abFileData+sizeof(kAttrMapHeader); memcpy(m_abyAttrMap, abSrcAttrData, sizeof(m_abyAttrMap)); } Tracef("%d\n", ELTimer_GetMSec() - dwStart); return true; } bool CTerrainImpl::RAW_LoadTileMap(const char * c_szFileName) { Tracef("LoadSplatFile %s ", c_szFileName); CMappedFile kMappedFile; LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) { Tracen("Error"); TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName); return false; } memcpy(m_abyTileMap, lpcvFileData, sizeof(BYTE)*(TILEMAP_RAW_XSIZE)*(TILEMAP_RAW_YSIZE)); return true; } bool CTerrainImpl::LoadWaterMap(const char * c_szFileName) { DWORD dwStart = ELTimer_GetMSec(); if (!LoadWaterMapFile(c_szFileName)) { memset(m_abyWaterMap, 0xFF, sizeof(m_abyWaterMap)); m_byNumWater = 0; memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight)); TraceError("CMapOutdoor::LoadWaterMap LoadWaterMapFile(%s) Failed", c_szFileName); return false; } Tracef("LoadWaterMapFile %s %d\n", c_szFileName, ELTimer_GetMSec() - dwStart); return true; } bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName) { CMappedFile kMappedFile; LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) { Tracen("Error"); TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName); return false; } DWORD dwFileSize = kMappedFile.Size(); BYTE* abFileData = (BYTE*)lpcvFileData; { #pragma pack(push) #pragma pack(1) struct SWaterMapHeader { WORD m_wMagic; WORD m_wWidth; WORD m_wHeight; BYTE m_byLayerCount; }; #pragma pack(pop) if (dwFileSize < sizeof(SWaterMapHeader)) { TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName); return false; } SWaterMapHeader kWaterMapHeader; memcpy(&kWaterMapHeader, abFileData, sizeof(kWaterMapHeader)); const WORD c_wWaterMapMagic = 5426; if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic) { TraceError("CTerrainImpl::LoadWaterMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kWaterMapHeader.m_wMagic, c_wWaterMapMagic); return false; } if (WATERMAP_XSIZE != kWaterMapHeader.m_wWidth) { TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_width(%d)!=WATERMAP_XSIZE(%d)", c_szFileName, kWaterMapHeader.m_wWidth, WATERMAP_XSIZE); return false; } if (WATERMAP_YSIZE != kWaterMapHeader.m_wHeight) { TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_height(%d)!=WATERMAP_YSIZE(%d)", c_szFileName, kWaterMapHeader.m_wHeight, WATERMAP_YSIZE); return false; } m_byNumWater = kWaterMapHeader.m_byLayerCount; DWORD dwFileRestSize = dwFileSize - sizeof(kWaterMapHeader); DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(long) * m_byNumWater; DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater; if (dwFileRestSize == dwFileNeedSize2) { WORD wWaterHeight[MAX_WATER_NUM + 1]; BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap); m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater); if (m_byNumWater) { memcpy(wWaterHeight, abSrcWaterHeight, sizeof(WORD) * m_byNumWater); for (int i = 0; i < m_byNumWater; ++i) m_lWaterHeight[i] = wWaterHeight[i]; } } else if (dwFileRestSize != dwFileNeedSize) { TraceError("CTerrainImpl::LoadWaterMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize); return false; } BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap); if (m_byNumWater) memcpy(m_lWaterHeight, abSrcWaterHeight, sizeof(long) * m_byNumWater); } return true; } DWORD CTerrainImpl::GetShadowMapColor(float fx, float fy) { float fMapSize = (float)(TERRAIN_XSIZE); float fooMapSize = 1.0f / fMapSize; if (fx < 0 || fy < 0 || fx >= fMapSize || fy >= fMapSize) return 0xFFFFFFFF; fx = fx * fooMapSize * (float)(SHADOWMAP_XSIZE - 1); fy = fy * fooMapSize * (float)(SHADOWMAP_YSIZE - 1); int ix, iy; PR_FLOAT_TO_INT(fx, ix); PR_FLOAT_TO_INT(fy, iy); WORD w = *(m_awShadowMap + (iy * SHADOWMAP_XSIZE) + ix); int b = w & 0x1f; w >>= 5; b <<= 3; int g = w & 0x1f; w >>= 5; g <<= 3; int r = w & 0x1f; r <<= 3; return (DWORD) (0xff << 24) | (g << 16) | (g << 8) | r; }