Skip to content

Commit

Permalink
Add partial support for utf-16 and resolve #9
Browse files Browse the repository at this point in the history
  • Loading branch information
user-grinch committed Oct 31, 2024
1 parent 63eee8b commit 9816bff
Show file tree
Hide file tree
Showing 13 changed files with 421 additions and 264 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"xutility": "cpp",
"*.rh": "cpp",
"any": "cpp",
"deque": "cpp"
"deque": "cpp",
"codecvt": "cpp"
}
}
29 changes: 29 additions & 0 deletions include/hotkeys.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "hotkeys.h"

Hotkey::Hotkey(ImGuiKey key1, ImGuiKey key2) {
codes[0] = defaultCodes[0] = key1;

if (key2 == ImGuiKey_None) {
codes[1] = defaultCodes[1] = key1;
} else {
codes[1] = defaultCodes[1] = key2;
}
}

bool Hotkey::Pressed(bool noDelay) {
if (ImGui::GetTime() - lastUpdate < 2.0) return false;

if (noDelay) {
return ImGui::IsKeyDown(codes[0]) && ImGui::IsKeyDown(codes[1]);
} else {
if (ImGui::IsKeyDown(codes[0]) && ImGui::IsKeyDown(codes[1])) {
wPressed = true;
} else {
if (wPressed) {
wPressed = false;
return current == "";
}
}
}
return false;
}
17 changes: 17 additions & 0 deletions include/hotkeys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once
#include <imgui/imgui.h>
#include <imgui/imgui_internal.h>
#include <string>

class Hotkey {
private:
static inline std::string current;
bool wPressed = false;
ImGuiKey codes[2], defaultCodes[2];
double lastUpdate;

public:
Hotkey(ImGuiKey key1 = ImGuiKey_None, ImGuiKey key2 = ImGuiKey_None);

bool Pressed(bool noDelay = false);
};
349 changes: 211 additions & 138 deletions src/editor.cpp

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions src/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ class Editor
static inline ImVec2 MonitorScale = {0, 0};
static inline ImGuiTextFilter Filter = "";


// Action
static void NewArchive();
static void OpenArchive();
static void SaveArchive();
static void SaveArchiveAs();
static void ImportFiles();
static void ImportAndReplaceFiles();
static void ExportAll();
static void ExportSelected();


// Popups
static void AboutPopUp();
static void UpdatePopUp();
Expand All @@ -30,10 +42,10 @@ class Editor
static void AddArchiveEntry(IMGArchive &&archive);

// Returns true if archive with the given name already exists
static bool DoesArchiveExist(const std::string &name);
static bool DoesArchiveExist(const std::wstring &name);

// Returns current search filter text
static const char* GetFilterText();
static const wchar_t* GetFilterText();

// Initializes & runs the IMGEditor
static void Run();
Expand Down
70 changes: 35 additions & 35 deletions src/imgarchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
#include <filesystem>
#include "editor.h"

IMGArchive::IMGArchive(std::string Path, bool CreateNew)
IMGArchive::IMGArchive(std::wstring Path, bool CreateNew)
{
if (CreateNew)
{
this->FileName = Path;
this->bCreateNew = true;
AddLogMessage("Created archive");
AddLogMessage(L"Created archive");
Parser = Parser::Get();
}
else
Expand All @@ -32,36 +32,36 @@ IMGArchive::IMGArchive(std::string Path, bool CreateNew)
if (Parser)
{
Parser->Open(this);
UpdateSelectList("");
UpdateSelectList(L"");
}
}

void IMGArchive::UpdateSelectList(const char *text)
void IMGArchive::UpdateSelectList(const wchar_t *text)
{
SelectedList.clear();
for (EntryInfo &e : EntryList)
{
if (strstr(e.FileName, text))
if (wcsstr(e.FileName, text))
{
SelectedList.push_back(&e);
}
}
}

std::string IMGArchive::GetFileType(const char* name)
std::wstring IMGArchive::GetFileType(const wchar_t* name)
{
if (strstr(name, ".dff")) return "Model";
if (strstr(name, ".txd")) return "Texture";
if (strstr(name, ".col")) return "Collision";
if (strstr(name, ".ifp")) return "Animation";
if (strstr(name, ".ipl")) return "Item placement";
if (strstr(name, ".ide")) return "Item defination";
if (strstr(name, ".dat")) return "Data";

return std::filesystem::path(name).extension().string() + " file";
if (wcsstr(name, L".dff")) return L"Model";
if (wcsstr(name, L".txd")) return L"Texture";
if (wcsstr(name, L".col")) return L"Collision";
if (wcsstr(name, L".ifp")) return L"Animation";
if (wcsstr(name, L".ipl")) return L"Item placement";
if (wcsstr(name, L".ide")) return L"Item defination";
if (wcsstr(name, L".dat")) return L"Data";

return std::filesystem::path(name).extension().wstring() + L" file";
}

void IMGArchive::ExportEntry(EntryInfo *pEntry, std::string filePath, bool log)
void IMGArchive::ExportEntry(EntryInfo *pEntry, std::wstring filePath, bool log)
{
if (Parser)
{
Expand All @@ -76,7 +76,7 @@ void IMGArchive::ExportAll(ArchiveInfo *pInfo)

for (size_t i = 0; i < total; ++i)
{
std::string path = std::format("{}\\{}", pInfo->path, pInfo->pArc->EntryList[i].FileName);
std::wstring path = std::format(L"{}\\{}", pInfo->path, pInfo->pArc->EntryList[i].FileName);
pInfo->pArc->ExportEntry(&pInfo->pArc->EntryList[i], path, false);
pInfo->pArc->ProgressBar.Percentage = (static_cast<float>(i)+1)/ static_cast<float>(total);

Expand All @@ -86,7 +86,7 @@ void IMGArchive::ExportAll(ArchiveInfo *pInfo)
break;
}
}
pInfo->pArc->AddLogMessage("Exported archive");
pInfo->pArc->AddLogMessage(L"Exported archive");
pInfo->pArc->ProgressBar.bInUse = false;
delete pInfo;
}
Expand All @@ -100,7 +100,7 @@ void IMGArchive::ExportSelected(ArchiveInfo *pInfo)
{
if (pInfo->pArc->EntryList[i].bSelected)
{
std::string path = std::format("{}\\{}", pInfo->path, pInfo->pArc->EntryList[i].FileName);
std::wstring path = std::format(L"{}\\{}", pInfo->path, pInfo->pArc->EntryList[i].FileName);
pInfo->pArc->ExportEntry(&pInfo->pArc->EntryList[i], path, false);
pInfo->pArc->ProgressBar.Percentage = (static_cast<float>(i)+1)/ static_cast<float>(total);

Expand All @@ -111,12 +111,12 @@ void IMGArchive::ExportSelected(ArchiveInfo *pInfo)
}
}
}
pInfo->pArc->AddLogMessage("Exported entries");
pInfo->pArc->AddLogMessage(L"Exported entries");
pInfo->pArc->ProgressBar.bInUse = false;
delete pInfo;
}

void IMGArchive::ImportEntry(const std::string &path, bool replace)
void IMGArchive::ImportEntry(const std::wstring &path, bool replace)
{
if (Parser)
{
Expand All @@ -126,9 +126,9 @@ void IMGArchive::ImportEntry(const std::string &path, bool replace)

void IMGArchive::ImportEntries(ArchiveInfo *pInfo)
{
std::vector<std::string> list;
std::string temp = "";
std::string rootDir = "";
std::vector<std::wstring> list;
std::wstring temp = L"";
std::wstring rootDir = L"";
for (char c : pInfo->path)
{
if (c != '\0')
Expand All @@ -137,21 +137,21 @@ void IMGArchive::ImportEntries(ArchiveInfo *pInfo)
}
else
{
if (temp == "")
if (temp == L"")
{
break;
}

temp += "\0";
temp += L"\0";
if (std::filesystem::is_directory(temp)) // skip folders
{
rootDir = std::move(temp) + "\\";
rootDir = std::move(temp) + L"\\";
}
else
{
list.push_back(std::move(rootDir + temp));
}
temp = "";
temp = L"";
}
}

Expand All @@ -164,26 +164,26 @@ void IMGArchive::ImportEntries(ArchiveInfo *pInfo)
if (pInfo->pArc->ProgressBar.bCancel)
{
pInfo->pArc->ProgressBar.bCancel = false;
pInfo->pArc->AddLogMessage("Rebuilding failed");
pInfo->pArc->AddLogMessage(L"Rebuilding failed");
pInfo->pArc->ProgressBar.bInUse = false;
}
}
pInfo->pArc->UpdateSelectList(Editor::GetFilterText());
pInfo->pArc->AddLogMessage("Imported entries");
pInfo->pArc->AddLogMessage(L"Imported entries");
delete pInfo;
}

void IMGArchive::AddLogMessage(std::string &&message)
void IMGArchive::AddLogMessage(std::wstring &&message)
{
LogList.push_back(std::move(message));
}

eImgVer IMGArchive::GetVersion(const std::string &Path)
eImgVer IMGArchive::GetVersion(const std::wstring &Path)
{
eImgVer imgVer = eImgVer::Unknown;

// It's easier to detect v2, so let's do it first
FILE *fp = fopen(Path.c_str(), "rb");
FILE *fp = _wfopen(Path.c_str(), L"rb");
if (fp)
{
char ver[4];
Expand All @@ -197,8 +197,8 @@ eImgVer IMGArchive::GetVersion(const std::string &Path)

// How to actually detect v1?
std::filesystem::path fsPath = std::filesystem::path(Path);
std::string dirPath = Path;
dirPath.replace(dirPath.end()-3, dirPath.end(), "dir");
std::wstring dirPath = Path;
dirPath.replace(dirPath.end()-3, dirPath.end(), L"dir");

// if both .dir & .img exists with same name it's v1 YAY!
if (std::filesystem::exists(fsPath) && std::filesystem::exists(dirPath))
Expand Down
28 changes: 14 additions & 14 deletions src/imgarchive.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ struct EntryInfo
// archive data
uint32_t Offset = 0; // in sectors (each sector is 2048 bytes)
uint32_t Size = 0; // in sectors (each sector is 2048 bytes)
char FileName[24]; // file name in the archive
wchar_t FileName[24]; // file name in the archive

// editor data
std::string Type = "Unknown";
std::string Path = ""; // Path used for importing
std::wstring Type = L"Unknown";
std::wstring Path = L""; // Path used for importing
bool bImported = false; // Was the item imported
bool bRename = false; // Is rename in progress
bool bSelected = false; // Is item currently selected
Expand All @@ -41,7 +41,7 @@ class IParser;
struct ArchiveInfo
{
IMGArchive* pArc;
std::string path;
std::wstring path;
eImgVer outVer = eImgVer::Unknown; // version for the output archive
bool removeExisting = true;
};
Expand All @@ -53,25 +53,25 @@ struct ArchiveInfo
class IMGArchive
{
public:
std::string Path;
std::string FileName;
std::wstring Path;
std::wstring FileName;
std::vector<EntryInfo> EntryList;
std::vector<EntryInfo*> SelectedList;
std::vector<std::string> LogList;
std::vector<std::wstring> LogList;
ProgressInfo ProgressBar;
eImgVer ImageVersion = eImgVer::Two;
IParser *Parser = nullptr;

bool bOpen = true;
bool bCreateNew;

IMGArchive(std::string Path, bool CreateNew = false);
IMGArchive(std::wstring Path, bool CreateNew = false);

// Adds a new message to log
void AddLogMessage(std::string &&message);
void AddLogMessage(std::wstring &&message);

// Export entity
void ExportEntry(EntryInfo *pEntry, std::string filePath, bool log = true);
void ExportEntry(EntryInfo *pEntry, std::wstring filePath, bool log = true);

// Exports the entire archive, should run in a separate thread
static void ExportAll(ArchiveInfo *pInfo);
Expand All @@ -80,13 +80,13 @@ class IMGArchive
static void ExportSelected(ArchiveInfo *pInfo);

// Get file type
static std::string GetFileType(const char* name);
static std::wstring GetFileType(const wchar_t* name);

// Returns archive version
static eImgVer GetVersion(const std::string &archivePath);
static eImgVer GetVersion(const std::wstring &archivePath);

// Import entity
void ImportEntry(const std::string& path, bool replace = false);
void ImportEntry(const std::wstring& path, bool replace = false);

// Imports multiple file entries at once
static void ImportEntries(ArchiveInfo *pInfo);
Expand All @@ -95,5 +95,5 @@ class IMGArchive
static void Save(ArchiveInfo *pInfo);

// Updated the archive search bar selected list
void UpdateSelectList(const char* text);
void UpdateSelectList(const wchar_t* text);
};
Loading

0 comments on commit 9816bff

Please sign in to comment.