From cbf56dbb4750822650dfc5335e78cc577a596c31 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 17 Jan 2015 03:07:24 +0100 Subject: [PATCH] ESSImport: work on cell fog of war --- apps/essimporter/converter.cpp | 50 ++++++++++++++++++++++++++++++++++ apps/essimporter/converter.hpp | 35 ++++++++++++++++++------ apps/essimporter/importer.cpp | 6 ++-- components/esm/loadcell.cpp | 5 ---- 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index 4f36f13ee..5f7366625 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -37,4 +37,54 @@ namespace ESSImport convertImage(&data[0], data.size(), maph.size, maph.size, Ogre::PF_BYTE_RGB, "map.tga"); } + void ConvertCell::read(ESM::ESMReader &esm) + { + ESM::Cell cell; + std::string id = esm.getHNString("NAME"); + cell.load(esm, false); + + Cell newcell; + newcell.mCell = cell; + + // fog of war + // seems to be a 1-bit pixel format, 16*16 pixels + // TODO: add bleeding of FOW into neighbouring cells (openmw handles this by writing to the textures, + // MW handles it when rendering only) + unsigned char nam8[32]; + if (esm.isNextSub("NAM8")) + { + esm.getHExact(nam8, 32); + + newcell.mFogOfWar.reserve(16*16); + for (int x=0; x<16; ++x) + { + for (int y=0; y<16; ++y) + { + size_t pos = x*16+y; + size_t bytepos = pos/8; + assert(bytepos<32); + int bit = pos%8; + newcell.mFogOfWar.push_back(((nam8[bytepos] >> bit) & (0x1)) ? 0xffffffff : 0x000000ff); + } + } + + std::ostringstream filename; + filename << "fog_" << cell.mData.mX << "_" << cell.mData.mY << ".tga"; + + convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, Ogre::PF_BYTE_RGBA, filename.str()); + } + + std::vector cellrefs; + while (esm.hasMoreSubs()) + { + CellRef ref; + ref.load (esm); + if (esm.isNextSub("DELE")) + std::cout << "deleted ref " << ref.mIndexedRefId << std::endl; + } + + newcell.mRefs = cellrefs; + mCells[id] = newcell; + } + } diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 2662f8c75..011508f36 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "importcrec.hpp" #include "importercontext.hpp" @@ -241,20 +242,36 @@ public: class ConvertCell : public Converter { public: - virtual void read(ESM::ESMReader& esm) + virtual void read(ESM::ESMReader& esm); + + virtual void write(ESM::ESMWriter& esm) { - ESM::Cell cell; - std::string id = esm.getHNString("NAME"); - cell.load(esm, false); - CellRef ref; - while (esm.hasMoreSubs()) + for (std::map::const_iterator it = mCells.begin(); it != mCells.end(); ++it) { - ref.load (esm); - if (esm.isNextSub("DELE")) - std::cout << "deleted ref " << ref.mIndexedRefId << std::endl; + const ESM::Cell& cell = it->second.mCell; + esm.startRecord(ESM::REC_CSTA); + ESM::CellState csta; + csta.mHasFogOfWar = 0; + csta.mId = cell.getCellId(); + csta.mId.save(esm); + // TODO csta.mLastRespawn; + // shouldn't be needed if we respawn on global schedule like in original MW + csta.mWaterLevel = cell.mWater; + csta.save(esm); + esm.endRecord(ESM::REC_CSTA); } } +private: + struct Cell + { + ESM::Cell mCell; + std::vector mRefs; + std::vector mFogOfWar; + }; + + std::map mCells; + }; } diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 96b79e029..b511dfe5e 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -99,16 +99,18 @@ namespace ESSImport void Importer::compare() { - // data that always changes should be blacklisted + // data that always changes (and/or is already fully decoded) should be blacklisted std::set > blacklist; blacklist.insert(std::make_pair("GLOB", "FLTV")); // gamehour blacklist.insert(std::make_pair("REFR", "DATA")); // player position + blacklist.insert(std::make_pair("CELL", "NAM8")); // fog of war File file1; read(mEssFile, file1); File file2; read(mOutFile, file2); // todo rename variable + // FIXME: use max(size1, size2) for (unsigned int i=0; i globals; - const unsigned int recREFR = ESM::FourCC<'R','E','F','R'>::value; const unsigned int recPCDT = ESM::FourCC<'P','C','D','T'>::value; const unsigned int recFMAP = ESM::FourCC<'F','M','A','P'>::value; diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index f6649d94a..e4f847dec 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -111,11 +111,6 @@ void Cell::loadData(ESMReader &esm) } esm.getHNT(mData, "DATA", 12); - - // ess only, unknown - char nam8[32]; - if (esm.isNextSub("NAM8")) - esm.getHExact(nam8, 32); } void Cell::postLoad(ESMReader &esm)