diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 57d951658f..34bcaf34c9 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -9,7 +9,7 @@ namespace ESM void CellRef::save(ESMWriter &esm) { esm.writeHNT("FRMR", refnum); - esm.writeHNString("NAME", refID); + esm.writeHNCString("NAME", refID); if (scale != 1.0) esm.writeHNT("XSCL", scale); @@ -33,7 +33,7 @@ void CellRef::save(ESMWriter &esm) if (teleport) { esm.writeHNT("DODT", doorDest); - esm.writeHNOString("DNAM", destCell); + esm.writeHNOCString("DNAM", destCell); } if (lockLevel != 0) @@ -60,6 +60,7 @@ void Cell::load(ESMReader &esm) // Water level water = 0; + NAM0 = 0; if (data.flags & Interior) { @@ -87,6 +88,8 @@ void Cell::load(ESMReader &esm) region = esm.getHNOString("RGNN"); esm.getHNOT(mapColor, "NAM5"); } + if (esm.isNextSub("NAM0")) + esm.getHT(NAM0); // Save position of the cell references and move on context = esm.getContext(); @@ -112,6 +115,9 @@ void Cell::save(ESMWriter &esm) if (mapColor != 0) esm.writeHNT("NAM5", mapColor); } + + if (NAM0 != 0) + esm.writeHNT("NAM0", NAM0); } void Cell::restore(ESMReader &esm) const @@ -141,9 +147,10 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) // Number of references in the cell? Maximum once in each cell, // but not always at the beginning, and not always right. In other // words, completely useless. + if (esm.isNextSub("NAM0")) { - int i; - esm.getHNOT(i, "NAM0"); + esm.skipHSubSize(4); + //esm.getHNOT(NAM0, "NAM0"); } esm.getHNT(ref.refnum, "FRMR"); diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index f03c541b7e..a485ceb1fa 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -120,6 +120,7 @@ struct Cell : public Record AMBIstruct ambi; float water; // Water level int mapColor; + int NAM0; void load(ESMReader &esm); void save(ESMWriter &esm); diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 512363fa0b..0a6fa63973 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -7,11 +7,18 @@ void Land::LandData::save(ESMWriter &esm) { // TODO: Make this actually work. - //esm.writeHNT("VNML", normals, sizeof(VNML)); + esm.writeHNT("VNML", normals, sizeof(VNML)); esm.writeHNT("VHGT", heights, sizeof(VHGT)); - esm.writeHNT("WNAM", 0, 81); - esm.writeHNT("VCLR", colours, 3*LAND_NUM_VERTS); - esm.writeHNT("VTEX", textures, 512); + //esm.writeHNT("WNAM", 0, 81); + esm.startSubRecord("WNAM"); + for (int i = 0; i < 81; i++) + esm.writeT((char)0x80, 1); + esm.endRecord("WNAM"); + + if (dataTypes & Land::DATA_VCLR) + esm.writeHNT("VCLR", colours, 3*LAND_NUM_VERTS); + if (dataTypes & Land::DATA_VTEX) + esm.writeHNT("VTEX", textures, 512); } Land::Land() @@ -19,7 +26,8 @@ Land::Land() , X(0) , Y(0) , mEsm(NULL) - , hasData(false) +// , hasData(false) + , dataTypes(0) , dataLoaded(false) , landData(NULL) { @@ -30,7 +38,6 @@ Land::~Land() delete landData; } - void Land::load(ESMReader &esm) { mEsm = &esm; @@ -47,36 +54,37 @@ void Land::load(ESMReader &esm) context = esm.getContext(); hasData = false; - int cnt = 0; // Skip these here. Load the actual data when the cell is loaded. if (esm.isNextSub("VNML")) { esm.skipHSubSize(12675); - cnt++; + dataTypes |= DATA_VNML; } if (esm.isNextSub("VHGT")) { esm.skipHSubSize(4232); - cnt++; + dataTypes |= DATA_VHGT; } if (esm.isNextSub("WNAM")) { esm.skipHSubSize(81); + dataTypes |= DATA_WNAM; } if (esm.isNextSub("VCLR")) { esm.skipHSubSize(12675); + dataTypes |= DATA_VCLR; } if (esm.isNextSub("VTEX")) { esm.skipHSubSize(512); - cnt++; + dataTypes |= DATA_VTEX; } // We need all three of VNML, VHGT and VTEX in order to use the - // landscape. - hasData = (cnt == 3); + // landscape. (Though Morrowind seems to accept terrain without VTEX/VCLR entries) + hasData = dataTypes & (DATA_VNML|DATA_VHGT|DATA_WNAM); dataLoaded = false; landData = NULL; @@ -101,7 +109,7 @@ void Land::save(ESMWriter &esm) landData->save(esm); if (!wasLoaded) - unloadData(); + unloadData(); // Don't need to keep the data loaded if it wasn't already } void Land::loadData() @@ -117,6 +125,8 @@ void Land::loadData() { mEsm->restoreContext(context); + memset(landData->normals, 0, LAND_NUM_VERTS * 3); + //esm.getHNExact(landData->normals, sizeof(VNML), "VNML"); if (mEsm->isNextSub("VNML")) { @@ -151,16 +161,19 @@ void Land::loadData() }else{ landData->usingColours = false; } - //TODO fix magic numbers - uint16_t vtex[512]; - mEsm->getHNExact(&vtex, 512, "VTEX"); + if (mEsm->isNextSub("VTEX")) + { + //TODO fix magic numbers + uint16_t vtex[512]; + mEsm->getHExact(&vtex, 512); - int readPos = 0; //bit ugly, but it works - for ( int y1 = 0; y1 < 4; y1++ ) - for ( int x1 = 0; x1 < 4; x1++ ) - for ( int y2 = 0; y2 < 4; y2++) - for ( int x2 = 0; x2 < 4; x2++ ) - landData->textures[(y1*4+y2)*16+(x1*4+x2)] = vtex[readPos++]; + int readPos = 0; //bit ugly, but it works + for ( int y1 = 0; y1 < 4; y1++ ) + for ( int x1 = 0; x1 < 4; x1++ ) + for ( int y2 = 0; y2 < 4; y2++) + for ( int x2 = 0; x2 < 4; x2++ ) + landData->textures[(y1*4+y2)*16+(x1*4+x2)] = vtex[readPos++]; + } } else { @@ -172,6 +185,7 @@ void Land::loadData() } } + landData->dataTypes = dataTypes; dataLoaded = true; } diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index 6a14891f19..1cbe4db12e 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -26,9 +26,18 @@ struct Land : public Record ESM_Context context; bool hasData; - + int dataTypes; bool dataLoaded; + enum + { + DATA_VNML = 1, + DATA_VHGT = 2, + DATA_WNAM = 4, + DATA_VCLR = 8, + DATA_VTEX = 16 + }; + // number of vertices per side static const int LAND_SIZE = 65; @@ -62,11 +71,12 @@ struct Land : public Record { float heightOffset; float heights[LAND_NUM_VERTS]; - //float normals[LAND_NUM_VERTS * 3]; + VNML normals; uint16_t textures[LAND_NUM_TEXTURES]; bool usingColours; char colours[3 * LAND_NUM_VERTS]; + int dataTypes; void save(ESMWriter &esm); };