diff --git a/source/graphics/MapGenerator.cpp b/source/graphics/MapGenerator.cpp index f068cd261b..3d53509e32 100644 --- a/source/graphics/MapGenerator.cpp +++ b/source/graphics/MapGenerator.cpp @@ -20,10 +20,13 @@ #include "MapGenerator.h" #include "graphics/MapIO.h" +#include "graphics/Patch.h" #include "graphics/Terrain.h" #include "lib/status.h" #include "lib/timer.h" +#include "maths/MathUtil.h" #include "ps/CLogger.h" +#include "ps/FileIo.h" #include "ps/Profile.h" #include "ps/scripting/JSInterface_VFS.h" #include "scriptinterface/ScriptConversions.h" @@ -105,6 +108,7 @@ bool CMapGeneratorWorker::Run() JSI_VFS::RegisterScriptFunctions_Maps(*m_ScriptInterface); m_ScriptInterface->RegisterFunction("LoadLibrary"); m_ScriptInterface->RegisterFunction("LoadHeightmapImage"); + m_ScriptInterface->RegisterFunction("LoadMapTerrain"); m_ScriptInterface->RegisterFunction("ExportMap"); m_ScriptInterface->RegisterFunction("SetProgress"); m_ScriptInterface->RegisterFunction("GetTemplate"); @@ -228,7 +232,6 @@ int CMapGeneratorWorker::GetTerrainTileSize(ScriptInterface::CxPrivate* UNUSED(p return TERRAIN_TILE_SIZE; } - bool CMapGeneratorWorker::LoadScripts(const std::wstring& libraryName) { // Ignore libraries that are already loaded @@ -288,6 +291,71 @@ JS::Value CMapGeneratorWorker::LoadHeightmap(ScriptInterface::CxPrivate* pCxPriv return returnValue; } +// See CMapReader::UnpackTerrain, CMapReader::ParseTerrain for the reordering +JS::Value CMapGeneratorWorker::LoadMapTerrain(ScriptInterface::CxPrivate* pCxPrivate, const std::string& filename) +{ + if (!VfsFileExists(filename)) + throw PSERROR_File_OpenFailed(); + + CFileUnpacker unpacker; + unpacker.Read(filename, "PSMP"); + + if (unpacker.GetVersion() < CMapIO::FILE_READ_VERSION) + throw PSERROR_File_InvalidVersion(); + + // unpack size + ssize_t patchesPerSide = (ssize_t)unpacker.UnpackSize(); + size_t verticesPerSide = patchesPerSide * PATCH_SIZE + 1; + + // unpack heightmap + std::vector heightmap; + heightmap.resize(SQR(verticesPerSide)); + unpacker.UnpackRaw(&heightmap[0], SQR(verticesPerSide) * sizeof(u16)); + + // unpack texture names + size_t textureCount = unpacker.UnpackSize(); + std::vector textureNames; + textureNames.reserve(textureCount); + for (size_t i = 0; i < textureCount; ++i) + { + CStr texturename; + unpacker.UnpackString(texturename); + textureNames.push_back(texturename); + } + + // unpack texture IDs per tile + ssize_t tilesPerSide = patchesPerSide * PATCH_SIZE; + std::vector tiles; + tiles.resize(size_t(SQR(tilesPerSide))); + unpacker.UnpackRaw(&tiles[0], sizeof(CMapIO::STileDesc) * tiles.size()); + + // reorder by patches and store and save texture IDs per tile + std::vector textureIDs; + for (ssize_t x = 0; x < tilesPerSide; ++x) + { + size_t patchX = x / PATCH_SIZE; + size_t offX = x % PATCH_SIZE; + for (ssize_t y = 0; y < tilesPerSide; ++y) + { + size_t patchY = y / PATCH_SIZE; + size_t offY = y % PATCH_SIZE; + // m_Priority and m_Tex2Index unused + textureIDs.push_back(tiles[(patchY * patchesPerSide + patchX) * SQR(PATCH_SIZE) + (offY * PATCH_SIZE + offX)].m_Tex1Index); + } + } + + CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); + JSContext* cx = self->m_ScriptInterface->GetContext(); + JSAutoRequest rq(cx); + JS::RootedValue returnValue(cx); + self->m_ScriptInterface->Eval("({})", &returnValue); + self->m_ScriptInterface->SetProperty(returnValue, "height", heightmap); + self->m_ScriptInterface->SetProperty(returnValue, "textureNames", textureNames); + self->m_ScriptInterface->SetProperty(returnValue, "textureIDs", textureIDs); + + return returnValue; +} + ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// diff --git a/source/graphics/MapGenerator.h b/source/graphics/MapGenerator.h index 74fe281d2f..d1dbf3201a 100644 --- a/source/graphics/MapGenerator.h +++ b/source/graphics/MapGenerator.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include #include +#include class CMapGeneratorWorker; @@ -124,6 +125,7 @@ private: static bool LoadLibrary(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name); static void ExportMap(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue data); static JS::Value LoadHeightmap(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& src); + static JS::Value LoadMapTerrain(ScriptInterface::CxPrivate* pCxPrivate, const std::string& filename); static void SetProgress(ScriptInterface::CxPrivate* pCxPrivate, int progress); static CParamNode GetTemplate(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName); static bool TemplateExists(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName);