almost perfect byte copies, has redundant data

actorid
greye 12 years ago
parent 597b88e95a
commit e69880f77e

@ -714,6 +714,15 @@ int load(Arguments& info)
<< " Value: " << w.mData.mValue << endl;
break;
}
case REC_SSCR:
{
rec = new StartScript();
StartScript &sscr = *(StartScript *) rec;
sscr.load(esm);
if (quiet) break;
cout << "Start script: " << sscr.mScript << endl;
break;
}
default:
if (find(skipped.begin(), skipped.end(), n.val) == skipped.end())
{
@ -832,16 +841,15 @@ int clone(Arguments& info)
esm.startRecord(n.toString(), rec->getFlags());
string id = rec->getId();
// TODO wrap this with std::set
if (n.val == REC_GLOB || n.val == REC_CLAS || n.val == REC_FACT || n.val == REC_RACE || n.val == REC_SOUN
|| n.val == REC_REGN || n.val == REC_BSGN || n.val == REC_LTEX || n.val == REC_STAT || n.val == REC_DOOR
|| n.val == REC_MISC || n.val == REC_WEAP || n.val == REC_CONT || n.val == REC_SPEL || n.val == REC_CREA
|| n.val == REC_BODY || n.val == REC_LIGH || n.val == REC_ENCH || n.val == REC_NPC_ || n.val == REC_ARMO
|| n.val == REC_CLOT || n.val == REC_REPA || n.val == REC_ACTI || n.val == REC_APPA || n.val == REC_LOCK
|| n.val == REC_PROB || n.val == REC_INGR || n.val == REC_BOOK || n.val == REC_ALCH || n.val == REC_LEVI
|| n.val == REC_LEVC)
|| n.val == REC_LEVC || n.val == REC_SNDG || n.val == REC_CELL || n.val == REC_DIAL)
esm.writeHNCString("NAME", id);
else if (n.val == REC_CELL)
esm.writeHNString("NAME", id);
else
esm.writeHNOString("NAME", id);

@ -64,7 +64,7 @@ void ESMWriter::save(std::ostream& file)
for (std::list<MasterData>::iterator it = m_masters.begin(); it != m_masters.end(); ++it)
{
writeHNString("MAST", it->name);
writeHNCString("MAST", it->name);
writeHNT("DATA", it->size);
}

@ -18,12 +18,12 @@ void CellRef::save(ESMWriter &esm)
esm.writeHNT("XSCL", mScale);
}
esm.writeHNOString("ANAM", mOwner);
esm.writeHNOString("BNAM", mGlob);
esm.writeHNOString("XSOL", mSoul);
esm.writeHNOCString("ANAM", mOwner);
esm.writeHNOCString("BNAM", mGlob);
esm.writeHNOCString("XSOL", mSoul);
esm.writeHNOString("CNAM", mFaction);
if (mFactIndex != -1) {
esm.writeHNOCString("CNAM", mFaction);
if (mFactIndex != -2) {
esm.writeHNT("INDX", mFactIndex);
}
@ -31,7 +31,7 @@ void CellRef::save(ESMWriter &esm)
esm.writeHNT("XCHG", mCharge);
}
if (mIntv != 0) {
if (mIntv != -1) {
esm.writeHNT("INTV", mIntv);
}
if (mNam9 != 0) {
@ -44,13 +44,13 @@ void CellRef::save(ESMWriter &esm)
esm.writeHNOCString("DNAM", mDestCell);
}
if (mLockLevel != 0) {
if (mLockLevel != -1) {
esm.writeHNT("FLTV", mLockLevel);
}
esm.writeHNOString("KNAM", mKey);
esm.writeHNOString("TNAM", mTrap);
esm.writeHNOCString("KNAM", mKey);
esm.writeHNOCString("TNAM", mTrap);
if (mUnam != 0) {
if (mUnam != -1) {
esm.writeHNT("UNAM", mUnam);
}
if (mFltv != 0) {
@ -58,6 +58,9 @@ void CellRef::save(ESMWriter &esm)
}
esm.writeHNT("DATA", mPos, 24);
if (mNam0 != 0) {
esm.writeHNT("NAM0", mNam0);
}
}
void Cell::load(ESMReader &esm)
@ -71,7 +74,7 @@ void Cell::load(ESMReader &esm)
esm.getHNT(mData, "DATA", 12);
// Water level
mWater = 0;
mWater = -1;
mNAM0 = 0;
if (mData.mFlags & Interior)
@ -82,6 +85,7 @@ void Cell::load(ESMReader &esm)
int waterl;
esm.getHT(waterl);
mWater = (float) waterl;
mWaterInt = true;
}
else if (esm.isNextSub("WHGT"))
esm.getHT(mWater);
@ -114,11 +118,18 @@ void Cell::save(ESMWriter &esm)
esm.writeHNT("DATA", mData, 12);
if (mData.mFlags & Interior)
{
if (mWater != 0)
esm.writeHNT("WHGT", mWater);
if (mWater != -1) {
if (mWaterInt) {
int water =
(mWater >= 0) ? (int) (mWater + 0.5) : (int) (mWater - 0.5);
esm.writeHNT("INTV", water);
} else {
esm.writeHNT("WHGT", mWater);
}
}
if (mData.mFlags & QuasiEx)
esm.writeHNOString("RGNN", mRegion);
esm.writeHNOCString("RGNN", mRegion);
else
esm.writeHNT("AMBI", mAmbi, 16);
}
@ -157,15 +168,6 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
if (!esm.hasMoreSubs())
return false;
// 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"))
{
esm.skipHSubSize(4);
//esm.getHNOT(NAM0, "NAM0");
}
esm.getHNT(ref.mRefnum, "FRMR");
ref.mRefID = esm.getHNString("NAME");
@ -179,13 +181,13 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
ref.mSoul = esm.getHNOString("XSOL");
ref.mFaction = esm.getHNOString("CNAM");
ref.mFactIndex = -1;
ref.mFactIndex = -2;
esm.getHNOT(ref.mFactIndex, "INDX");
ref.mCharge = -1.0;
esm.getHNOT(ref.mCharge, "XCHG");
ref.mIntv = 0;
ref.mIntv = -1;
ref.mNam9 = 0;
esm.getHNOT(ref.mIntv, "INTV");
esm.getHNOT(ref.mNam9, "NAM9");
@ -201,18 +203,28 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
}
// Integer, despite the name suggesting otherwise
ref.mLockLevel = 0;
ref.mLockLevel = -1;
esm.getHNOT(ref.mLockLevel, "FLTV");
ref.mKey = esm.getHNOString("KNAM");
ref.mTrap = esm.getHNOString("TNAM");
ref.mUnam = 0;
ref.mUnam = -1;
ref.mFltv = 0;
esm.getHNOT(ref.mUnam, "UNAM");
esm.getHNOT(ref.mFltv, "FLTV");
esm.getHNT(ref.mPos, "DATA", 24);
// 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.
ref.mNam0 = 0;
if (esm.isNextSub("NAM0"))
{
esm.getHT(ref.mNam0);
//esm.getHNOT(NAM0, "NAM0");
}
return true;
}

@ -71,6 +71,7 @@ public:
// Brindisi Dorom", where it has the value 100. Also only for
// activators.
int mFltv;
int mNam0;
// Position and rotation of this object within the cell
Position mPos;
@ -120,6 +121,7 @@ struct Cell : public Record
DATAstruct mData;
AMBIstruct mAmbi;
float mWater; // Water level
bool mWaterInt;
int mMapColor;
int mNAM0;

@ -136,17 +136,17 @@ void DialInfo::load(ESMReader &esm)
void DialInfo::save(ESMWriter &esm)
{
esm.writeHNString("INAM", mSelfId);
esm.writeHNString("PNAM", mPrev);
esm.writeHNString("NNAM", mNext);
esm.writeHNCString("INAM", mSelfId);
esm.writeHNCString("PNAM", mPrev);
esm.writeHNCString("NNAM", mNext);
esm.writeHNT("DATA", mData, 12);
esm.writeHNOString("ONAM", mActor);
esm.writeHNOString("RNAM", mRace);
esm.writeHNOString("CNAM", mClass);
esm.writeHNOString("FNAM", mNpcFaction);
esm.writeHNOString("ANAM", mCell);
esm.writeHNOString("DNAM", mPcFaction);
esm.writeHNOString("SNAM", mSound);
esm.writeHNOCString("ONAM", mActor);
esm.writeHNOCString("RNAM", mRace);
esm.writeHNOCString("CNAM", mClass);
esm.writeHNOCString("FNAM", mNpcFaction);
esm.writeHNOCString("ANAM", mCell);
esm.writeHNOCString("DNAM", mPcFaction);
esm.writeHNOCString("SNAM", mSound);
esm.writeHNOString("NAME", mResponse);
for (std::vector<SelectStruct>::iterator it = mSelects.begin(); it != mSelects.end(); ++it)

@ -13,7 +13,7 @@ void Ingredient::load(ESMReader &esm)
esm.getHNT(mData, "IRDT", 56);
mScript = esm.getHNOString("SCRI");
mIcon = esm.getHNOString("ITEX");
/*
// horrible hack to fix broken data in records
for (int i=0; i<4; ++i)
{
@ -36,6 +36,7 @@ void Ingredient::load(ESMReader &esm)
mData.mSkills[i] = -1;
}
}
*/
}
void Ingredient::save(ESMWriter &esm)

@ -10,18 +10,61 @@ void Land::LandData::save(ESMWriter &esm)
{
// TODO: Make this actually work.
esm.writeHNT("VNML", mNormals, sizeof(VNML));
esm.writeHNT("VHGT", mHeights, sizeof(VHGT));
if (mDataTypes & Land::DATA_VNML) {
esm.writeHNT("VNML", mNormals, sizeof(VNML));
}
if (mDataTypes & Land::DATA_VHGT) {
VHGT offsets;
offsets.mHeightOffset = mHeights[0] / HEIGHT_SCALE;
offsets.mUnknown1 = mUnk1;
offsets.mUnknown2 = mUnk2;
float prevY = mHeights[0], prevX;
int number = 0; // avoid multiplication
for (int i = 0; i < LAND_SIZE; ++i) {
float diff = (mHeights[number] - prevY) / HEIGHT_SCALE;
offsets.mHeightData[number] =
(diff >= 0) ? (int8_t) (diff + 0.5) : (int8_t) (diff - 0.5);
prevX = prevY = mHeights[number];
++number;
for (int j = 1; j < LAND_SIZE; ++j) {
diff = (mHeights[number] - prevX) / HEIGHT_SCALE;
offsets.mHeightData[number] =
(diff >= 0) ? (int8_t) (diff + 0.5) : (int8_t) (diff - 0.5);
prevX = mHeights[number];
++number;
}
}
esm.writeHNT("VHGT", offsets, sizeof(VHGT));
}
//esm.writeHNT("WNAM", 0, 81);
esm.startSubRecord("WNAM");
/* esm.startSubRecord("WNAM");
for (int i = 0; i < 81; i++)
esm.writeT((char)0x80, 1);
esm.endRecord("WNAM");
*/
if (mDataTypes & Land::DATA_WNAM) {
esm.writeHNT("WNAM", mWnam, 81);
}
if (mDataTypes & Land::DATA_VCLR)
esm.writeHNT("VCLR", mColours, 3*LAND_NUM_VERTS);
if (mDataTypes & Land::DATA_VTEX)
esm.writeHNT("VTEX", mTextures, 512);
if (mDataTypes & Land::DATA_VTEX) {
uint16_t vtex[256];
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++ )
vtex[(y1*4+y2)*16+(x1*4+x2)] = mTextures[readPos++];
esm.writeHNT("VTEX", vtex, 512);
}
}
Land::Land()
@ -87,7 +130,7 @@ void Land::load(ESMReader &esm)
// We need all three of VNML, VHGT and VTEX in order to use the
// landscape. (Though Morrowind seems to accept terrain without VTEX/VCLR entries)
mHasData = mDataTypes & (DATA_VNML|DATA_VHGT|DATA_WNAM);
mHasData = mDataTypes & (DATA_VNML|DATA_VHGT|DATA_WNAM|DATA_VTEX|DATA_VCLR);
mDataLoaded = false;
mLandData = NULL;
@ -130,32 +173,38 @@ void Land::loadData()
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
//esm.getHNExact(landData->normals, sizeof(VNML), "VNML");
if (mEsm->isNextSub("VNML")) {
mEsm->getHExact(mLandData->mNormals, sizeof(VNML));
}/*
if (mEsm->isNextSub("VNML"))
{
mEsm->skipHSubSize(12675);
}
} */
if (mEsm->isNextSub("VHGT")) {
VHGT rawHeights;
mEsm->getHNExact(&rawHeights, sizeof(VHGT), "VHGT");
int currentHeightOffset = rawHeights.mHeightOffset;
mEsm->getHExact(&rawHeights, sizeof(VHGT));
float currentHeightOffset = rawHeights.mHeightOffset;
for (int y = 0; y < LAND_SIZE; y++)
{
currentHeightOffset += rawHeights.mHeightData[y * LAND_SIZE];
mLandData->mHeights[y * LAND_SIZE] = currentHeightOffset * HEIGHT_SCALE;
int tempOffset = currentHeightOffset;
float tempOffset = currentHeightOffset;
for (int x = 1; x < LAND_SIZE; x++)
{
tempOffset += rawHeights.mHeightData[y * LAND_SIZE + x];
mLandData->mHeights[x + y * LAND_SIZE] = tempOffset * HEIGHT_SCALE;
}
}
mLandData->mUnk1 = rawHeights.mUnknown1;
mLandData->mUnk2 = rawHeights.mUnknown2;
}
if (mEsm->isNextSub("WNAM"))
{
mEsm->skipHSubSize(81);
mEsm->getHExact(mLandData->mWnam, 81);
}
if (mEsm->isNextSub("VCLR"))
{
@ -167,7 +216,7 @@ void Land::loadData()
if (mEsm->isNextSub("VTEX"))
{
//TODO fix magic numbers
uint16_t vtex[512];
uint16_t vtex[256];
mEsm->getHExact(&vtex, 512);
int readPos = 0; //bit ugly, but it works
@ -181,7 +230,7 @@ void Land::loadData()
else
{
mLandData->mUsingColours = false;
memset(&mLandData->mTextures, 0, 512 * sizeof(uint16_t));
memset(mLandData->mTextures, 0, sizeof(mLandData->mTextures));
for (int i = 0; i < LAND_NUM_VERTS; i++)
{
mLandData->mHeights[i] = -256.0f * HEIGHT_SCALE;

@ -79,6 +79,10 @@ struct Land : public Record
char mColours[3 * LAND_NUM_VERTS];
int mDataTypes;
uint8_t mWnam[81];
short mUnk1;
uint8_t mUnk2;
void save(ESMWriter &esm);
};

@ -36,10 +36,10 @@ void MagicEffect::load(ESMReader &esm)
esm.getHNT(mIndex, "INDX");
esm.getHNT(mData, "MEDT", 36);
/*
if (mIndex>=0 && mIndex<NumberOfHardcodedFlags)
mData.mFlags |= HardcodedFlags[mIndex];
*/
mIcon = esm.getHNOString("ITEX");
mParticle = esm.getHNOString("PTEX");

@ -73,7 +73,7 @@ void Pathgrid::load(ESMReader &esm)
void Pathgrid::save(ESMWriter &esm)
{
esm.writeHNT("DATA", mData, 12);
esm.writeHNString("NAME", mCell);
esm.writeHNCString("NAME", mCell);
if (!mPoints.empty())
{

@ -16,8 +16,8 @@ void SoundGenerator::load(ESMReader &esm)
void SoundGenerator::save(ESMWriter &esm)
{
esm.writeHNT("DATA", mType, 4);
esm.writeHNOString("CNAM", mCreature);
esm.writeHNOString("SNAM", mSound);
esm.writeHNOCString("CNAM", mCreature);
esm.writeHNOCString("SNAM", mSound);
}
}

@ -8,13 +8,12 @@ namespace ESM
void StartScript::load(ESMReader &esm)
{
esm.getSubNameIs("DATA");
esm.skipHSub();
mData = esm.getHNString("DATA");
mScript = esm.getHNString("NAME");
}
void StartScript::save(ESMWriter &esm)
{
esm.writeHNString("DATA", "NIET");
esm.writeHNString("DATA", mData);
esm.writeHNString("NAME", mScript);
}

@ -18,6 +18,7 @@ namespace ESM
struct StartScript : public Record
{
std::string mData;
std::string mScript;
// Load a record and add it to the list

Loading…
Cancel
Save