mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
ObjWriting: Dump FontIcon assets as csv files
According to the asset names this seems to be their original format. however since i didn't find any examples of that asset in raw form i just tried to come up with a realistic csv style for it
This commit is contained in:
parent
ccef1dca28
commit
8ec525d3d2
76
src/ObjWriting/Dumping/CsvWriter.cpp
Normal file
76
src/ObjWriting/Dumping/CsvWriter.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "CsvWriter.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
const std::string CsvWriter::LINE_BREAK = "\n";
|
||||
|
||||
CsvWriter::CsvWriter(FileAPI::IFile* file)
|
||||
{
|
||||
m_file = file;
|
||||
m_first_row = true;
|
||||
m_current_column = 0;
|
||||
m_column_count = 0;
|
||||
}
|
||||
|
||||
void CsvWriter::WriteColumn(const std::string& value)
|
||||
{
|
||||
if (m_current_column++ > 0)
|
||||
m_file->Printf(",");
|
||||
|
||||
bool containsSeparator = false;
|
||||
bool containsQuote = false;
|
||||
for (const auto& c : value)
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
containsQuote = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == SEPARATOR)
|
||||
containsSeparator = true;
|
||||
}
|
||||
|
||||
if (containsQuote)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
for(const auto& c : value)
|
||||
{
|
||||
if (c == '"')
|
||||
str << "\"\"";
|
||||
else
|
||||
str << c;
|
||||
}
|
||||
|
||||
m_file->Printf("\"%s\"", str.str().c_str());
|
||||
}
|
||||
else if (containsSeparator)
|
||||
{
|
||||
m_file->Printf("\"%s\"", value.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_file->Printf("%s", value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CsvWriter::NextRow()
|
||||
{
|
||||
if (m_first_row)
|
||||
{
|
||||
m_first_row = false;
|
||||
m_column_count = m_current_column;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(m_current_column < m_column_count)
|
||||
{
|
||||
m_file->Printf(",");
|
||||
m_current_column++;
|
||||
}
|
||||
}
|
||||
|
||||
m_file->Printf("\n");
|
||||
m_current_column = 0;
|
||||
}
|
19
src/ObjWriting/Dumping/CsvWriter.h
Normal file
19
src/ObjWriting/Dumping/CsvWriter.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "Utils/FileAPI.h"
|
||||
|
||||
class CsvWriter
|
||||
{
|
||||
static constexpr char SEPARATOR = ',';
|
||||
static const std::string LINE_BREAK;
|
||||
|
||||
FileAPI::IFile* m_file;
|
||||
unsigned m_column_count;
|
||||
unsigned m_current_column;
|
||||
bool m_first_row;
|
||||
|
||||
public:
|
||||
explicit CsvWriter(FileAPI::IFile* file);
|
||||
|
||||
void WriteColumn(const std::string& value);
|
||||
void NextRow();
|
||||
};
|
244
src/ObjWriting/Game/T6/AssetDumpers/AssetDumperFontIcon.cpp
Normal file
244
src/ObjWriting/Game/T6/AssetDumpers/AssetDumperFontIcon.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
#include "AssetDumperFontIcon.h"
|
||||
|
||||
#include "Dumping/CsvWriter.h"
|
||||
#include "Game/T6/CommonT6.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace T6;
|
||||
|
||||
class AssetDumperFontIconInternal
|
||||
{
|
||||
class KnownAlias
|
||||
{
|
||||
public:
|
||||
std::string m_name;
|
||||
int m_hash;
|
||||
|
||||
explicit KnownAlias(std::string aliasName)
|
||||
: m_name(std::move(aliasName))
|
||||
{
|
||||
m_hash = CommonT6::Com_HashString(m_name.c_str(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
inline static const std::string TYPE_ICON = "icon";
|
||||
inline static const std::string ICON_HEADERS[]
|
||||
{
|
||||
"# index",
|
||||
"# type",
|
||||
"# name",
|
||||
"# material",
|
||||
"# size",
|
||||
"# xScale",
|
||||
"# yScale"
|
||||
};
|
||||
|
||||
inline static const std::string TYPE_ALIAS = "alias";
|
||||
inline static const std::string ALIAS_HEADERS[]
|
||||
{
|
||||
"# index",
|
||||
"# type",
|
||||
"# alias",
|
||||
"# button"
|
||||
};
|
||||
|
||||
inline static const KnownAlias KNOWN_ALIASES[]
|
||||
{
|
||||
KnownAlias("BUTTON_ADS"),
|
||||
KnownAlias("BUTTON_CAC_NEXT"),
|
||||
KnownAlias("BUTTON_CAC_PREV"),
|
||||
KnownAlias("BUTTON_CANCEL"),
|
||||
KnownAlias("BUTTON_CREATE"),
|
||||
KnownAlias("BUTTON_DELETE"),
|
||||
KnownAlias("BUTTON_EDIT"),
|
||||
KnownAlias("BUTTON_EMBLEM_BACKWARD"),
|
||||
KnownAlias("BUTTON_EMBLEM_FLIP"),
|
||||
KnownAlias("BUTTON_EMBLEM_FORWARD"),
|
||||
KnownAlias("BUTTON_EMBLEM_FORWARD_BACKWARD"),
|
||||
KnownAlias("BUTTON_EMBLEM_MOVE"),
|
||||
KnownAlias("BUTTON_EMBLEM_OUTLINE"),
|
||||
KnownAlias("BUTTON_EMBLEM_PALETTE_CYCLE"),
|
||||
KnownAlias("BUTTON_EMBLEM_PALETTE_NEXT"),
|
||||
KnownAlias("BUTTON_EMBLEM_PALETTE_PREV"),
|
||||
KnownAlias("BUTTON_EMBLEM_RESET"),
|
||||
KnownAlias("BUTTON_EMBLEM_ROTATE_LEFT"),
|
||||
KnownAlias("BUTTON_EMBLEM_ROTATE_RIGHT"),
|
||||
KnownAlias("BUTTON_EMBLEM_SCALE"),
|
||||
KnownAlias("BUTTON_FIRE"),
|
||||
KnownAlias("BUTTON_FRIENDSLIST"),
|
||||
KnownAlias("BUTTON_INTERACT"),
|
||||
KnownAlias("BUTTON_LOOK"),
|
||||
KnownAlias("BUTTON_LOOKSTICK"),
|
||||
KnownAlias("BUTTON_LUI_ALT1"),
|
||||
KnownAlias("BUTTON_LUI_DPAD_RL"),
|
||||
KnownAlias("BUTTON_LUI_DPAD_UD"),
|
||||
KnownAlias("BUTTON_LUI_RIGHT_STICK"),
|
||||
KnownAlias("BUTTON_LUI_SHOULDERR"),
|
||||
KnownAlias("BUTTON_MOUSE_LEFT"),
|
||||
KnownAlias("BUTTON_MOUSE_RIGHT"),
|
||||
KnownAlias("BUTTON_MOVE"),
|
||||
KnownAlias("BUTTON_MOVESTICK"),
|
||||
KnownAlias("BUTTON_MP_CANCELCOMMAND"),
|
||||
KnownAlias("BUTTON_MP_CHANGESETTINGS"),
|
||||
KnownAlias("BUTTON_MP_GAMERCARD"),
|
||||
KnownAlias("BUTTON_MP_GAMERREVIEW"),
|
||||
KnownAlias("BUTTON_MP_JOINGAME"),
|
||||
KnownAlias("BUTTON_MP_KICKPLAYER"),
|
||||
KnownAlias("BUTTON_MP_LEAVEGAME"),
|
||||
KnownAlias("BUTTON_MP_LOBBY_GAMERCARD"),
|
||||
KnownAlias("BUTTON_MP_NOTREADY"),
|
||||
KnownAlias("BUTTON_MP_PGDOWN"),
|
||||
KnownAlias("BUTTON_MP_PGUP"),
|
||||
KnownAlias("BUTTON_MP_READY"),
|
||||
KnownAlias("BUTTON_MP_REFRESH"),
|
||||
KnownAlias("BUTTON_MP_SCOREBOARD"),
|
||||
KnownAlias("BUTTON_MP_SIGNIN"),
|
||||
KnownAlias("BUTTON_MP_SPECNEXT"),
|
||||
KnownAlias("BUTTON_MP_SPECPREV"),
|
||||
KnownAlias("BUTTON_MP_STARTGAME"),
|
||||
KnownAlias("BUTTON_MP_TOGGLECHASECAM"),
|
||||
KnownAlias("BUTTON_MP_TOGGLEVIEW"),
|
||||
KnownAlias("BUTTON_NO"),
|
||||
KnownAlias("BUTTON_RECORD_VIEW_NEXT"),
|
||||
KnownAlias("BUTTON_SELECTCHOICE"),
|
||||
KnownAlias("BUTTON_SP_TOGGLEMENU"),
|
||||
KnownAlias("BUTTON_YES"),
|
||||
KnownAlias("CP"),
|
||||
KnownAlias("KEY_DOWN_ARROW"),
|
||||
KnownAlias("KEY_LEFT_ARROW"),
|
||||
KnownAlias("KEY_RIGHT_ARROW"),
|
||||
KnownAlias("KEY_UP_ARROW"),
|
||||
KnownAlias("MOUSE_WHEEL_UP"),
|
||||
KnownAlias("Remote_LStick")
|
||||
};
|
||||
|
||||
CsvWriter m_csv;
|
||||
|
||||
static FontIconEntry* FindEntryByHash(FontIcon* fontIcon, const int hash)
|
||||
{
|
||||
int lowerBound = 0;
|
||||
int upperBound = fontIcon->numEntries;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const int entryIndex = (lowerBound + upperBound) / 2;
|
||||
auto* entry = &fontIcon->fontIconEntry[entryIndex];
|
||||
|
||||
if (entry->fontIconName.hash == hash)
|
||||
return entry;
|
||||
|
||||
if (lowerBound == upperBound)
|
||||
return nullptr;
|
||||
|
||||
if (entry->fontIconName.hash < hash)
|
||||
lowerBound = entryIndex + 1;
|
||||
else
|
||||
upperBound = entryIndex - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static const KnownAlias* FindKnownAliasByHash(const int hash)
|
||||
{
|
||||
for (unsigned i = 0; i < _countof(KNOWN_ALIASES); i++)
|
||||
{
|
||||
if (KNOWN_ALIASES[i].m_hash == hash)
|
||||
return &KNOWN_ALIASES[i];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WriteFontIconEntries(FontIcon* fontIcon)
|
||||
{
|
||||
for (const auto& header : ICON_HEADERS)
|
||||
m_csv.WriteColumn(header);
|
||||
m_csv.NextRow();
|
||||
|
||||
for (int iconIndex = 0; iconIndex < fontIcon->numEntries; iconIndex++)
|
||||
{
|
||||
auto* entry = &fontIcon->fontIconEntry[iconIndex];
|
||||
m_csv.WriteColumn(std::to_string(iconIndex));
|
||||
m_csv.WriteColumn(TYPE_ICON);
|
||||
|
||||
if (entry->fontIconName.string)
|
||||
m_csv.WriteColumn(entry->fontIconName.string);
|
||||
else
|
||||
m_csv.WriteColumn("");
|
||||
|
||||
if (entry->fontIconMaterialHandle && entry->fontIconMaterialHandle->info.name)
|
||||
m_csv.WriteColumn(entry->fontIconMaterialHandle->info.name);
|
||||
else
|
||||
m_csv.WriteColumn("");
|
||||
|
||||
m_csv.WriteColumn(std::to_string(entry->fontIconSize));
|
||||
m_csv.WriteColumn(std::to_string(entry->xScale));
|
||||
m_csv.WriteColumn(std::to_string(entry->yScale));
|
||||
|
||||
m_csv.NextRow();
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFontIconAliases(FontIcon* fontIcon)
|
||||
{
|
||||
for (const auto& header : ALIAS_HEADERS)
|
||||
m_csv.WriteColumn(header);
|
||||
m_csv.NextRow();
|
||||
|
||||
for (int aliasIndex = 0; aliasIndex < fontIcon->numAliasEntries; aliasIndex++)
|
||||
{
|
||||
auto* alias = &fontIcon->fontIconAlias[aliasIndex];
|
||||
m_csv.WriteColumn(std::to_string(aliasIndex));
|
||||
m_csv.WriteColumn(TYPE_ALIAS);
|
||||
|
||||
auto* knownAlias = FindKnownAliasByHash(alias->aliasHash);
|
||||
if (knownAlias)
|
||||
m_csv.WriteColumn(knownAlias->m_name);
|
||||
else
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << '@' << std::hex << alias->aliasHash;
|
||||
|
||||
m_csv.WriteColumn(str.str());
|
||||
}
|
||||
|
||||
auto* referencedEntry = FindEntryByHash(fontIcon, alias->buttonHash);
|
||||
if (referencedEntry && referencedEntry->fontIconName.string)
|
||||
m_csv.WriteColumn(referencedEntry->fontIconName.string);
|
||||
else
|
||||
m_csv.WriteColumn("");
|
||||
|
||||
m_csv.NextRow();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
explicit AssetDumperFontIconInternal(FileAPI::IFile* file)
|
||||
: m_csv(file)
|
||||
{
|
||||
}
|
||||
|
||||
void DumpFontIcon(FontIcon* fontIcon)
|
||||
{
|
||||
WriteFontIconEntries(fontIcon);
|
||||
m_csv.NextRow();
|
||||
|
||||
WriteFontIconAliases(fontIcon);
|
||||
}
|
||||
};
|
||||
|
||||
bool AssetDumperFontIcon::ShouldDump(FontIcon* asset)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AssetDumperFontIcon::GetFileNameForAsset(Zone* zone, FontIcon* asset)
|
||||
{
|
||||
return std::string(asset->name);
|
||||
}
|
||||
|
||||
void AssetDumperFontIcon::DumpAsset(Zone* zone, FontIcon* asset, FileAPI::File* out)
|
||||
{
|
||||
AssetDumperFontIconInternal dumper(out);
|
||||
dumper.DumpFontIcon(asset);
|
||||
}
|
12
src/ObjWriting/Game/T6/AssetDumpers/AssetDumperFontIcon.h
Normal file
12
src/ObjWriting/Game/T6/AssetDumpers/AssetDumperFontIcon.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/T6/T6.h"
|
||||
|
||||
class AssetDumperFontIcon final : public AbstractAssetDumper<T6::FontIcon>
|
||||
{
|
||||
protected:
|
||||
bool ShouldDump(T6::FontIcon* asset) override;
|
||||
std::string GetFileNameForAsset(Zone* zone, T6::FontIcon* asset) override;
|
||||
void DumpAsset(Zone* zone, T6::FontIcon* asset, FileAPI::File* out) override;
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
#include "ZoneDumperT6.h"
|
||||
|
||||
#include "Game/T6/GameT6.h"
|
||||
#include "Game/T6/GameAssetPoolT6.h"
|
||||
|
||||
@ -9,6 +10,7 @@
|
||||
#include "AssetDumpers/AssetDumperStringTable.h"
|
||||
#include "AssetDumpers/AssetDumperLocalizeEntry.h"
|
||||
#include "AssetDumpers/AssetDumperGfxImage.h"
|
||||
#include "AssetDumpers/AssetDumperFontIcon.h"
|
||||
|
||||
bool ZoneDumperT6::CanHandleZone(Zone* zone) const
|
||||
{
|
||||
@ -44,7 +46,7 @@ bool ZoneDumperT6::DumpZone(Zone* zone, const std::string& basePath) const
|
||||
// DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world);
|
||||
// DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def);
|
||||
// DUMP_ASSET_POOL(AssetDumperFont, m_font);
|
||||
// DUMP_ASSET_POOL(AssetDumperFontIcon, m_font_icon);
|
||||
DUMP_ASSET_POOL(AssetDumperFontIcon, m_font_icon);
|
||||
// DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list);
|
||||
// DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def);
|
||||
DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "CommonT6.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
int CommonT6::Com_HashKey(const char* str, const int maxLen)
|
||||
{
|
||||
if (str == nullptr)
|
||||
@ -16,3 +18,22 @@ int CommonT6::Com_HashKey(const char* str, const int maxLen)
|
||||
|
||||
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
||||
}
|
||||
|
||||
int CommonT6::Com_HashString(const char* str, const int len)
|
||||
{
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
int result = 0x1505;
|
||||
int offset = 0;
|
||||
while(str[offset])
|
||||
{
|
||||
if (len > 0 && offset >= len)
|
||||
break;
|
||||
|
||||
const int c = tolower(str[offset++]);
|
||||
result = c + 33 * result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -4,4 +4,5 @@ class CommonT6
|
||||
{
|
||||
public:
|
||||
static int Com_HashKey(const char* str, int maxLen);
|
||||
static int Com_HashString(const char* str, int len);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user