Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

Commit

Permalink
(#6) Cleaned GenericRecord.h of game-specific stuff
Browse files Browse the repository at this point in the history
Moved the game-specific game-specific Record out of the file
`src/common/GenericRecord.h` and into new files named after each
class' name, on the `src/game/<game>` folder.
  • Loading branch information
leandor committed Jul 1, 2017
1 parent c5fb675 commit c4017b0
Show file tree
Hide file tree
Showing 6 changed files with 564 additions and 390 deletions.
289 changes: 0 additions & 289 deletions src/common/GenericRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,292 +660,3 @@ void Record::IsChanged(bool value)
{
SETBIT(CBash_Flags, _fIsChanged, value);
}

FNVRecord::FNVRecord(unsigned char *_recData):
Record(_recData),
formVersion(0)
{
memset(&versionControl2[0], 0x00, 2);
}

FNVRecord::~FNVRecord()
{
//
}

bool FNVRecord::Read()
{
if(IsLoaded() || IsChanged())
return false;
uint32_t recSize = *(uint32_t*)&recData[-20];

//Check against the original record flags to see if it is compressed since the current flags may have changed
if ((*(uint32_t*)&recData[-16] & fIsCompressed) != 0)
{
unsigned char localBuffer[BUFFERSIZE];
uint32_t expandedRecSize = *(uint32_t*)recData;
unsigned char *buffer = (expandedRecSize >= BUFFERSIZE) ? new unsigned char[expandedRecSize] : &localBuffer[0];
uncompress(buffer, (uLongf*)&expandedRecSize, &recData[4], recSize - 4);
ParseRecord(buffer, buffer + expandedRecSize, true);
if(buffer != &localBuffer[0])
delete [] buffer;
}
else
ParseRecord(recData, recData + recSize);

IsLoaded(true);
return true;
}

uint32_t FNVRecord::Write(FileWriter &writer, const bool &bMastersChanged, FormIDResolver &expander, FormIDResolver &collapser, std::vector<FormIDResolver *> &Expanders)
{
uint32_t recSize = 0;
uint32_t recType = GetType();

collapser.Accept(formID);

if(!IsChanged())
{
if(bMastersChanged || flags != *(uint32_t*)&recData[-16])
{
//if masters have changed, all formIDs have to be updated...
//or if the flags have changed internally (notably fIsDeleted or fIsCompressed, possibly others)
//so the record can't just be written as is.
if(Read())
{
//if(expander.IsValid(data)) //optimization disabled for testing
// VisitFormIDs(expander);
//printer("Looking for correct expander\n");
int32_t index = -1;
for(uint32_t x = 0; x < Expanders.size(); ++x)
if(IsValid(*Expanders[x]))
{
//if(index != -1)
// {
// printer("Multiple 'Correct' expanders found (%08X)! Using last one found (likely incorrect unless lucky)\n", formID);
// printer(" %i: %08X, %08X, %08X\n", index, Expanders[index]->FileStart, data, Expanders[index]->FileEnd);
// printer(" %i: %08X, %08X, %08X\n", x, Expanders[x]->FileStart, data, Expanders[x]->FileEnd);
// printer("Expanders:\n");
// for(uint32_t z = 0; z < Expanders.size(); ++z)
// printer(" %i of %i: %08X, %08X\n", z, Expanders.size(), Expanders[z]->FileStart, Expanders[z]->FileEnd);
// }
index = x;
break;
}
if(index == -1)
{
printer("Unable to find the correct expander!\n");
VisitFormIDs(expander);
}
else
VisitFormIDs(*Expanders[index]);
}
}
else
{
//if masters have not changed, the record can just be written from the read buffer
recSize = *(uint32_t*)&recData[-20];

writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
writer.file_write(recData, recSize);
Unload();
return recSize + 24;
}
}

VisitFormIDs(collapser);

if(!IsDeleted())
{
//IsCompressed(true); //Test code
WriteRecord(writer);
recSize = IsCompressed() ? writer.record_compress() : writer.record_size();
writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
//if(IsCompressed())
// {
// printer("Compressed: %08X\n", formID);
// }
writer.record_flush();
}
else
{
writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
}

expander.Accept(formID);
if(IsChanged())
VisitFormIDs(expander);
else
Unload();
return recSize + 24;
}

TES5Record::TES5Record(unsigned char *_recData):
Record(_recData),
formVersion(0)
{
memset(&versionControl2[0], 0x00, 2);
}

TES5Record::TES5Record(TES5Record *srcRecord)
{
if (srcRecord == NULL)
return;

flags = srcRecord->flags;
formID = srcRecord->formID;
flagsUnk = srcRecord->flagsUnk;
formVersion = srcRecord->formVersion;
versionControl2[0] = srcRecord->versionControl2[0];
versionControl2[1] = srcRecord->versionControl2[1];

recData = srcRecord->recData;
}

TES5Record::~TES5Record()
{
//
}

bool TES5Record::Read()
{
if(IsLoaded() || IsChanged())
return false;
uint32_t recSize = *(uint32_t*)&recData[-20];

//Check against the original record flags to see if it is compressed since the current flags may have changed
if ((*(uint32_t*)&recData[-16] & fIsCompressed) != 0)
{
unsigned char localBuffer[BUFFERSIZE];
uint32_t expandedRecSize = *(uint32_t*)recData;
unsigned char *buffer = (expandedRecSize >= BUFFERSIZE) ? new unsigned char[expandedRecSize] : &localBuffer[0];
uncompress(buffer, (uLongf*)&expandedRecSize, &recData[4], recSize - 4);
ParseRecord(buffer, buffer + expandedRecSize, true);
if(buffer != &localBuffer[0])
delete [] buffer;
}
else
ParseRecord(recData, recData + recSize);

IsLoaded(true);
return true;
}

uint32_t TES5Record::Write(FileWriter &writer, const bool &bMastersChanged, FormIDResolver &expander, FormIDResolver &collapser, std::vector<FormIDResolver *> &Expanders)
{
uint32_t recSize = 0;
uint32_t recType = GetType();

collapser.Accept(formID);

if(!IsChanged())
{
if(bMastersChanged || flags != *(uint32_t*)&recData[-16])
{
//if masters have changed, all formIDs have to be updated...
//or if the flags have changed internally (notably fIsDeleted or fIsCompressed, possibly others)
//so the record can't just be written as is.
if(Read())
{
//if(expander.IsValid(data)) //optimization disabled for testing
// VisitFormIDs(expander);
//printer("Looking for correct expander\n");
int32_t index = -1;
for(uint32_t x = 0; x < Expanders.size(); ++x)
if(IsValid(*Expanders[x]))
{
//if(index != -1)
// {
// printer("Multiple 'Correct' expanders found (%08X)! Using last one found (likely incorrect unless lucky)\n", formID);
// printer(" %i: %08X, %08X, %08X\n", index, Expanders[index]->FileStart, data, Expanders[index]->FileEnd);
// printer(" %i: %08X, %08X, %08X\n", x, Expanders[x]->FileStart, data, Expanders[x]->FileEnd);
// printer("Expanders:\n");
// for(uint32_t z = 0; z < Expanders.size(); ++z)
// printer(" %i of %i: %08X, %08X\n", z, Expanders.size(), Expanders[z]->FileStart, Expanders[z]->FileEnd);
// }
index = x;
break;
}
if(index == -1)
{
printer("Unable to find the correct expander!\n");
VisitFormIDs(expander);
}
else
VisitFormIDs(*Expanders[index]);
}
}
else
{
//if masters have not changed, the record can just be written from the read buffer
recSize = *(uint32_t*)&recData[-20];

writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
writer.file_write(recData, recSize);
Unload();
return recSize + 24;
}
}

VisitFormIDs(collapser);

if(!IsDeleted())
{
//IsCompressed(true); //Test code
WriteRecord(writer);
recSize = IsCompressed() ? writer.record_compress() : writer.record_size();
writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
//if(IsCompressed())
// {
// printer("Compressed: %08X\n", formID);
// }
writer.record_flush();
}
else
{
writer.file_write(&recType, 4);
writer.file_write(&recSize, 4);
writer.file_write(&flags, 4);
writer.file_write(&formID, 4);
writer.file_write(&flagsUnk, 4);
writer.file_write(&formVersion, 2);
writer.file_write(&versionControl2[0], 2);
}

expander.Accept(formID);
if(IsChanged())
VisitFormIDs(expander);
else
Unload();
return recSize + 24;
}
101 changes: 0 additions & 101 deletions src/common/GenericRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,104 +265,3 @@ struct Record
bool IsChanged();
void IsChanged(bool value);
};

class FNVRecord : public Record
{
protected:
enum FNVHeaderFlags
{
fIsESM = 0x00000001,
fIsTaken = 0x00000002, //From OBSE, unconfirmed, requires fIsDeleted also be set
fUnknown1 = 0x00000004,
fUnknown2 = 0x00000008,
fUnknown3 = 0x00000010,
fIsDeleted = 0x00000020,
fIsBorderRegion = 0x00000040, //Has Tree LOD / Constant / Hidden From Local Map (FNV)
fIsTurnOffFire = 0x00000080,
fIsInaccessible = 0x00000100, // (FNV)
fIsCastsShadows = 0x00000200, //On Local Map / Motion Blur (FNV)
fIsQuestOrPersistent = 0x00000400,
fIsInitiallyDisabled = 0x00000800,
fIsIgnored = 0x00001000,
fIsNoVoiceFilter = 0x00002000, // (FNV)
fIsTemporary = 0x00004000, //From OBSE, unconfirmed
fIsVisibleWhenDistant = 0x00008000,
fIsRandomAnimStartOrHighPriorityLOD = 0x00010000, // (FNV)
fIsDangerousOrOffLimits = 0x00020000, // Radio Station (Talking Activator) (FNV)
fIsCompressed = 0x00040000,
fIsCantWait = 0x00080000, // Platform Specific Texture (FNV)
fUnknown4 = 0x00100000,
fUnknown5 = 0x00200000,
fUnknown6 = 0x00400000,
fUnknown7 = 0x00800000,
fUnknown8 = 0x01000000,
fIsObstacleOrNoAIAcquire = 0x02000000, // (FNV)
fIsNavMeshFilter = 0x04000000, // (FNV)
fIsNavMeshBoundBox = 0x08000000, // (FNV)
fIsNonPipboyOrAutoReflected = 0x10000000, // (FNV)
fIsChildUsableOrAutoRefracted = 0x20000000, // (FNV)
fIsNavMeshGround = 0x40000000, // (FNV)
fUnknown9 = 0x80000000
};

public:
uint16_t formVersion; //FNV
uint8_t versionControl2[2]; //FNV

FNVRecord(unsigned char *_recData=NULL);
virtual ~FNVRecord();

bool Read();
uint32_t Write(FileWriter &writer, const bool &bMastersChanged, FormIDResolver &expander, FormIDResolver &collapser, std::vector<FormIDResolver *> &Expanders);
};

class TES5Record : public Record
{
protected:
enum TES5HeaderFlags
{
fIsESM = 0x00000001,
fUnknown01 = 0x00000002,
fUnknown02 = 0x00000004,
fUnknown03 = 0x00000008,
fUnknown04 = 0x00000010,
fUnknown05 = 0x00000020,
fUnknown06 = 0x00000040,
fUnknown07 = 0x00000080,
fUnknown08 = 0x00000100,
fUnknown09 = 0x00000200,
fUnknown10 = 0x00000400,
fUnknown11 = 0x00000800,
fUnknown12 = 0x00001000,
fUnknown13 = 0x00002000,
fUnknown14 = 0x00004000,
fUnknown15 = 0x00008000,
fUnknown16 = 0x00010000,
fUnknown17 = 0x00020000,
fUnknown18 = 0x00040000,
fUnknown19 = 0x00080000,
fUnknown20 = 0x00100000,
fUnknown21 = 0x00200000,
fUnknown22 = 0x00400000,
fUnknown23 = 0x00800000,
fUnknown24 = 0x01000000,
fUnknown25 = 0x02000000,
fUnknown26 = 0x04000000,
fUnknown27 = 0x08000000,
fUnknown28 = 0x10000000,
fUnknown29 = 0x20000000,
fUnknown30 = 0x40000000,
fUnknown31 = 0x80000000
};

public:
uint16_t formVersion; //TES5
uint8_t versionControl2[2]; //TES5

TES5Record(unsigned char *_recData=NULL);
TES5Record(TES5Record *srcRecord);
virtual ~TES5Record();

bool Read();
uint32_t Write(FileWriter &writer, const bool &bMastersChanged, FormIDResolver &expander, FormIDResolver &collapser, std::vector<FormIDResolver *> &Expanders);
};
Loading

0 comments on commit c4017b0

Please sign in to comment.