Skip to content

Commit

Permalink
feat: copy parse chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Jan 17, 2022
1 parent 05d9ddc commit 47e0441
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 95 deletions.
9 changes: 8 additions & 1 deletion Code/es_loader/ESLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void ESLoader::LoadFiles()
Vector<CLMT::Data> climateData;
for (auto& climate : climates)
{
climateData.push_back(climate.second->ParseChunks(m_decompressedChunksCache));
climateData.push_back(climate.second->ParseChunks());
}
spdlog::info("refrData count: {}", climateData.size());
}
Expand All @@ -95,3 +95,10 @@ Map<String, Vector<T>> ESLoader::GetRecords() noexcept
}
}

String ESLoader::LoadZString(Buffer::Reader& aReader) noexcept
{
String zstring = String(reinterpret_cast<const char*>(aReader.GetDataAtPosition()));
aReader.Advance(zstring.size() + 1);
return zstring;
}

4 changes: 2 additions & 2 deletions Code/es_loader/ESLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class ESLoader
template<class T>
Map<String, Vector<T>> GetRecords() noexcept;

static String LoadZString(Buffer::Reader& aReader) noexcept;

private:
void FindFiles();
void LoadFiles();
Expand All @@ -24,6 +26,4 @@ class ESLoader
Vector<std::filesystem::path> m_eslFilenames;
Vector<TESFile> m_standardPlugins;
Vector<TESFile> m_lightPlugins;

Map<Record*, SharedPtr<Buffer>> m_decompressedChunksCache{};
};
16 changes: 9 additions & 7 deletions Code/es_loader/Records/CLMT.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
#include "CLMT.h"

CLMT::Data CLMT::ParseChunks(Map<Record*, SharedPtr<Buffer>>& aCompressedChunkCache) noexcept
#include <ESLoader.h>

CLMT::Data CLMT::ParseChunks() noexcept
{
Data data;

IterateChunks(aCompressedChunkCache, [&](ChunkId aChunkId, const uint8_t* apData) {
IterateChunks([&](ChunkId aChunkId, Buffer::Reader& aReader) {
switch (aChunkId)
{
case ChunkId::EDID_ID:
data.m_editorId = reinterpret_cast<const char*>(apData);
data.m_editorId = ESLoader::LoadZString(aReader);
break;
case ChunkId::WLST_ID:
data.m_weatherList = reinterpret_cast<const WeatherList*>(apData);
data.m_weatherList = Chunks::WLST(aReader);
break;
case ChunkId::FNAM_ID:
data.m_sunTexture = reinterpret_cast<const char*>(apData);
data.m_sunTexture = ESLoader::LoadZString(aReader);
break;
case ChunkId::GNAM_ID:
data.m_glareTexture = reinterpret_cast<const char*>(apData);
data.m_glareTexture = ESLoader::LoadZString(aReader);
break;
case ChunkId::TNAM_ID:
data.m_timing = reinterpret_cast<const SunAndMoon*>(apData);
data.m_timing = Chunks::TNAM(aReader);
break;
}
});
Expand Down
30 changes: 7 additions & 23 deletions Code/es_loader/Records/CLMT.h
Original file line number Diff line number Diff line change
@@ -1,43 +1,27 @@
#pragma once

#include "Record.h"
#include "Chunks.h"

// https://en.uesp.net/wiki/Skyrim_Mod:Mod_File_Format/CLMT
class CLMT : Record
{
public:
static constexpr FormEnum kType = FormEnum::CLMT;

struct WeatherList // WLST
{
uint32_t m_weatherId; // WTHR
uint32_t m_chance;
uint32_t m_globalId;
};

struct SunAndMoon // TNAM
{
uint8_t m_sunriseBegin; // times 10 minutes
uint8_t m_sunriseEnd; // times 10 minutes
uint8_t m_sunsetBegin; // times 10 minutes
uint8_t m_sunsetEnd; // times 10 minutes
uint8_t m_volatility; // 0-100
uint8_t m_moons;
};

struct Data
{
// EDID
const char* m_editorId = "";
String m_editorId = "";
// WLST
const WeatherList* m_weatherList = nullptr;
Chunks::WLST m_weatherList;
// FNAM
const char* m_sunTexture = "";
String m_sunTexture = "";
// GNAM
const char* m_glareTexture = "";
String m_glareTexture = "";
//TNAM
const SunAndMoon* m_timing = nullptr;
Chunks::TNAM m_timing;
};

Data ParseChunks(Map<Record*, SharedPtr<Buffer>>& aCompressedChunkCache) noexcept;
Data ParseChunks() noexcept;
};
13 changes: 8 additions & 5 deletions Code/es_loader/Records/CONT.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
#include "CONT.h"

CONT::Data CONT::ParseChunks(Map<Record*, SharedPtr<Buffer>>& aCompressedChunkCache) noexcept
#include <ESLoader.h>

CONT::Data CONT::ParseChunks() noexcept
{
Data data;

IterateChunks(aCompressedChunkCache, [&](ChunkId aChunkId, const uint8_t* apData) {
IterateChunks([&](ChunkId aChunkId, Buffer::Reader& aReader) {
switch (aChunkId)
{
case ChunkId::EDID_ID:
data.m_editorId = reinterpret_cast<const char*>(apData);
data.m_editorId = ESLoader::LoadZString(aReader);
break;
case ChunkId::FULL_ID:
data.m_name = reinterpret_cast<const char*>(apData);
data.m_name = ESLoader::LoadZString(aReader);
break;
case ChunkId::CNTO_ID:
data.m_objects.push_back(*reinterpret_cast<const CONT::Object*>(apData));
Chunks::CNTO cnto(aReader);
data.m_objects.push_back(cnto);
break;
}
});
Expand Down
16 changes: 5 additions & 11 deletions Code/es_loader/Records/CONT.h
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
#pragma once

#include "Record.h"
#include "Chunks.h"

// https://en.uesp.net/wiki/Skyrim_Mod:Mod_File_Format/CONT
class CONT : Record
{
public:
static constexpr FormEnum kType = FormEnum::CONT;

struct Object
{
// CNTO
uint32_t m_formId = 0;
uint32_t m_count = 0;
};

struct Data
{
// EDID
const char* m_editorId = "";
String m_editorId = "";
// FULL
const char* m_name = "";
String m_name = "";
// Objects
Vector<Object> m_objects;
Vector<Chunks::CNTO> m_objects;
};

Data ParseChunks(Map<Record*, SharedPtr<Buffer>>& aCompressedChunkCache) noexcept;
Data ParseChunks() noexcept;
};
49 changes: 39 additions & 10 deletions Code/es_loader/Records/Chunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Chunks
{

PrimaryScripts::PrimaryScripts(const uint8_t* apData, Buffer::Reader& aReader)
PrimaryScripts::PrimaryScripts(Buffer::Reader& aReader)
{
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_version), 2);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_objectFormat), 2);
Expand All @@ -20,33 +20,33 @@ PrimaryScripts::PrimaryScripts(const uint8_t* apData, Buffer::Reader& aReader)
// TODO: ESLoader::ReadZString(Reader&);
uint32_t nameLength = 0;
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&nameLength), 2);
script.m_name = String(reinterpret_cast<const char*>(apData + aReader.GetBytePosition()), nameLength);
script.m_name = String(reinterpret_cast<const char*>(aReader.GetDataAtPosition()), nameLength);
aReader.Advance(nameLength);

aReader.ReadBytes(&script.m_status, 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&script.m_propertyCount), 2);

for (uint16_t j; j < script.m_propertyCount; j++)
for (uint16_t j = 0; j < script.m_propertyCount; j++)
{
ScriptProperty scriptProperty;

// TODO: ESLoader::ReadZString(Reader&);
uint32_t propNameLength = 0;
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&propNameLength), 2);
scriptProperty.m_name = String(reinterpret_cast<const char*>(apData + aReader.GetBytePosition()), propNameLength);
scriptProperty.m_name = String(reinterpret_cast<const char*>(aReader.GetDataAtPosition()), propNameLength);
aReader.Advance(propNameLength);

aReader.ReadBytes(reinterpret_cast<uint8_t*>(&scriptProperty.m_type), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&scriptProperty.m_status), 1);

scriptProperty.ParseValue(apData, aReader, m_objectFormat);
scriptProperty.ParseValue(aReader, m_objectFormat);

script.m_properties.insert(scriptProperty);
script.m_properties.push_back(scriptProperty);
}
}
}

void ScriptProperty::ParseValue(const uint8_t* apData, Buffer::Reader& aReader, int16_t aObjectFormat) noexcept
void ScriptProperty::ParseValue(Buffer::Reader& aReader, int16_t aObjectFormat) noexcept
{
switch (m_type)
{
Expand All @@ -73,22 +73,23 @@ void ScriptProperty::ParseValue(const uint8_t* apData, Buffer::Reader& aReader,
case Type::WSTRING: {
uint32_t stringLength = 0;
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&stringLength), 2);
m_dataSingleValue.m_string = { reinterpret_cast<const char*>(apData + aReader.GetBytePosition()), stringLength };
m_dataSingleValue.m_string = { reinterpret_cast<const char*>(aReader.GetDataAtPosition()), stringLength };
aReader.Advance(stringLength);
break;
}

case Type::OBJECT_ARRAY:
case Type::INT_ARRAY:
case Type::FLOAT_ARRAY:
case Type::BOOL_ARRAY:
case Type::STRING_ARRAY:
case Type::STRING_ARRAY: {
uint32_t sizeOfArray = 0;
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&sizeOfArray), 4);
for (uint32_t i = 0; i < sizeOfArray; i++)
{
ScriptProperty scriptProperty;
scriptProperty.m_type = GetPropertyType(m_type);
ParseValue(apData, aReader, aObjectFormat);
ParseValue(aReader, aObjectFormat);
m_dataArray.push_back(scriptProperty.m_dataSingleValue);
}

Expand All @@ -102,4 +103,32 @@ ScriptProperty::Type ScriptProperty::GetPropertyType(Type aArrayType) noexcept
return static_cast<Type>(static_cast<int>(aArrayType) - 10);
}

CNTO::CNTO(Buffer::Reader& aReader)
{
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_formId), 4);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_count), 4);
}

WLST::WLST(Buffer::Reader& aReader)
{
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_weatherId), 4);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_chance), 4);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_globalId), 4);
}

TNAM::TNAM(Buffer::Reader& aReader)
{
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_sunriseBegin), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_sunriseEnd), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_sunsetBegin), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_sunsetEnd), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_volatility), 1);
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_moons), 1);
}

NAME::NAME(Buffer::Reader& aReader)
{
aReader.ReadBytes(reinterpret_cast<uint8_t*>(&m_baseId), 4);
}

} // namespace
46 changes: 43 additions & 3 deletions Code/es_loader/Records/Chunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct ScriptProperty
} m_string {nullptr, 0};
};

void ParseValue(const uint8_t* apData, Buffer::Reader& aReader, int16_t aObjectFormat) noexcept;
void ParseValue(Buffer::Reader& aReader, int16_t aObjectFormat) noexcept;
Type GetPropertyType(Type aArrayType) noexcept;

String m_name;
Expand All @@ -56,17 +56,57 @@ struct Script
String m_name;
uint8_t m_status;
uint16_t m_propertyCount;
Set<ScriptProperty> m_properties;
Vector<ScriptProperty> m_properties;
};

struct PrimaryScripts
{
PrimaryScripts(const uint8_t* apData, Buffer::Reader& aReader);
PrimaryScripts(Buffer::Reader& aReader);

int16_t m_version = 0;
int16_t m_objectFormat = 0;
uint16_t m_scriptCount = 0;
Vector<Script> m_scripts;
};

struct CNTO
{
CNTO(){}
CNTO(Buffer::Reader& aReader);

uint32_t m_formId{};
uint32_t m_count{};
};

struct WLST
{
WLST(){}
WLST(Buffer::Reader& aReader);

uint32_t m_weatherId{}; // WTHR
uint32_t m_chance{};
uint32_t m_globalId{};
};

struct TNAM
{
TNAM(){}
TNAM(Buffer::Reader& aReader);

uint8_t m_sunriseBegin{}; // times 10 minutes
uint8_t m_sunriseEnd{}; // times 10 minutes
uint8_t m_sunsetBegin{}; // times 10 minutes
uint8_t m_sunsetEnd{}; // times 10 minutes
uint8_t m_volatility{}; // 0-100
uint8_t m_moons{};
};

struct NAME
{
NAME(){}
NAME(Buffer::Reader& aReader);

uint32_t m_baseId{};
};

} // namespace
6 changes: 3 additions & 3 deletions Code/es_loader/Records/REFR.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#include "REFR.h"

REFR::Data REFR::ParseChunks(Map<Record*, SharedPtr<Buffer>>& aCompressedChunkCache) noexcept
REFR::Data REFR::ParseChunks() noexcept
{
Data data;

IterateChunks(aCompressedChunkCache, [&](ChunkId aChunkId, const uint8_t* apData) {
IterateChunks([&](ChunkId aChunkId, Buffer::Reader& aReader) {
switch (aChunkId)
{
case ChunkId::NAME_ID:
data.m_baseId = *reinterpret_cast<const uint32_t*>(apData);
data.m_basicObject = Chunks::NAME(aReader);
break;
}
});
Expand Down
Loading

0 comments on commit 47e0441

Please sign in to comment.