From 513bf6aa0e2350a515a326b45a3dd58e56190256 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 24 Sep 2023 12:57:14 -0400 Subject: [PATCH] WAD Converter now creates .material file in the proper directory --- Editor/src/ComponentsPanel/MaterialEditor.cpp | 2 +- Editor/src/Windows/EditorSelectionPanel.cpp | 2 +- Editor/src/Windows/FileSystemUI.cpp | 6 +- Editor/src/Windows/WelcomeWindow.cpp | 4 +- Nuake/src/Core/FileSystem.cpp | 15 +++-- Nuake/src/Core/FileSystem.h | 7 ++- Nuake/src/Rendering/Mesh/Mesh.cpp | 20 ++++++- Nuake/src/Resource/FGD/FGDFile.cpp | 2 +- Nuake/src/Resource/FGD/FGDSerializer.cpp | 2 +- Nuake/src/Resource/Prefab.h | 2 +- Nuake/src/Scene/EditorCamera.cpp | 1 + Nuake/src/Scene/Scene.cpp | 2 +- Nuake/src/Scene/Systems/WadConverter.cpp | 56 ++++++++++++++++--- Nuake/src/Scene/Systems/WadConverter.h | 10 ++-- 14 files changed, 97 insertions(+), 34 deletions(-) diff --git a/Editor/src/ComponentsPanel/MaterialEditor.cpp b/Editor/src/ComponentsPanel/MaterialEditor.cpp index c63386cc..b7a15561 100644 --- a/Editor/src/ComponentsPanel/MaterialEditor.cpp +++ b/Editor/src/ComponentsPanel/MaterialEditor.cpp @@ -27,7 +27,7 @@ void MaterialEditor::Draw(Ref material) std::string fileData = material->Serialize().dump(4); - FileSystem::BeginWriteFile(FileSystem::Root + material->Path); + FileSystem::BeginWriteFile(material->Path); FileSystem::WriteLine(fileData); FileSystem::EndWriteFile(); } diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index 802eb75b..660dad64 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -198,7 +198,7 @@ void EditorSelectionPanel::DrawMaterialPanel(Ref material) { std::string fileData = material->Serialize().dump(4); - FileSystem::BeginWriteFile(FileSystem::Root + material->Path); + FileSystem::BeginWriteFile(material->Path); FileSystem::WriteLine(fileData); FileSystem::EndWriteFile(); } diff --git a/Editor/src/Windows/FileSystemUI.cpp b/Editor/src/Windows/FileSystemUI.cpp index b2652cfa..fb53d409 100644 --- a/Editor/src/Windows/FileSystemUI.cpp +++ b/Editor/src/Windows/FileSystemUI.cpp @@ -338,7 +338,7 @@ namespace Nuake if (file->GetExtension() == ".wad") { - if (ImGui::MenuItem("Extract to PNG")) + if (ImGui::MenuItem("Convert to Materials")) { Nuake::ExtractWad(file->GetAbsolutePath(), FileSystem::Root); } @@ -471,7 +471,7 @@ namespace Nuake material->IsEmbedded = false; auto jsonData = material->Serialize(); - FileSystem::BeginWriteFile(finalPath); + FileSystem::BeginWriteFile(finalPath, true); FileSystem::WriteLine(jsonData.dump(4)); FileSystem::EndWriteFile(); @@ -496,7 +496,7 @@ namespace Nuake if(!String::IsDigit(fileName[0])) { - FileSystem::BeginWriteFile(path); + FileSystem::BeginWriteFile(path, true); FileSystem::WriteLine(TEMPLATE_SCRIPT_FIRST + fileName + TEMPLATE_SCRIPT_SECOND); FileSystem::EndWriteFile(); diff --git a/Editor/src/Windows/WelcomeWindow.cpp b/Editor/src/Windows/WelcomeWindow.cpp index f198d953..e1161d93 100644 --- a/Editor/src/Windows/WelcomeWindow.cpp +++ b/Editor/src/Windows/WelcomeWindow.cpp @@ -329,7 +329,7 @@ namespace Nuake { if (!FileSystem::FileExists(_RecentProjectFilePath, true)) { - FileSystem::BeginWriteFile(_RecentProjectFilePath); + FileSystem::BeginWriteFile(_RecentProjectFilePath, true); FileSystem::WriteLine(_RecentProjectFileDefaultContent); FileSystem::EndWriteFile(); } @@ -358,7 +358,7 @@ namespace Nuake j["Projects"][i] = project.Serialize(); } - FileSystem::BeginWriteFile(_RecentProjectFilePath); + FileSystem::BeginWriteFile(_RecentProjectFilePath, true); FileSystem::WriteLine(j.dump(4)); FileSystem::EndWriteFile(); } diff --git a/Nuake/src/Core/FileSystem.cpp b/Nuake/src/Core/FileSystem.cpp index 17bcab2d..a3eb675b 100644 --- a/Nuake/src/Core/FileSystem.cpp +++ b/Nuake/src/Core/FileSystem.cpp @@ -84,12 +84,17 @@ namespace Nuake } } - bool FileSystem::DirectoryExists(const std::string path) + bool FileSystem::DirectoryExists(const std::string& path) { - return false; + return std::filesystem::exists(path) && std::filesystem::is_directory(path); } - bool FileSystem::FileExists(const std::string path, bool absolute) + bool FileSystem::MakeDirectory(const std::string& path, bool absolute) + { + return std::filesystem::create_directory(absolute ? path : FileSystem::Root + path); + } + + bool FileSystem::FileExists(const std::string& path, bool absolute) { std::string fullPath = absolute ? path : FileSystem::Root + path; @@ -154,10 +159,10 @@ namespace Nuake } std::ofstream FileSystem::fileWriter; - bool FileSystem::BeginWriteFile(const std::string path) + bool FileSystem::BeginWriteFile(const std::string path, bool absolute) { fileWriter = std::ofstream(); - fileWriter.open(path); + fileWriter.open(absolute ? path : FileSystem::Root + path); return false; } diff --git a/Nuake/src/Core/FileSystem.h b/Nuake/src/Core/FileSystem.h index 98ff2f74..23767cb1 100644 --- a/Nuake/src/Core/FileSystem.h +++ b/Nuake/src/Core/FileSystem.h @@ -38,13 +38,14 @@ namespace Nuake static void ScanDirectory(Ref directory); static void GetDirectories(); - static bool DirectoryExists(const std::string path); - static bool FileExists(const std::string path, bool absolute = false); + static bool MakeDirectory(const std::string& path, bool absolute = false); + static bool DirectoryExists(const std::string& path); + static bool FileExists(const std::string& path, bool absolute = false); static std::string ReadFile(const std::string& path, bool absolute = false); static std::ofstream fileWriter; - static bool BeginWriteFile(const std::string path); + static bool BeginWriteFile(const std::string path, bool absolute = false); static bool WriteLine(const std::string line); static void EndWriteFile(); static uintmax_t DeleteFileFromPath(const std::string& path); diff --git a/Nuake/src/Rendering/Mesh/Mesh.cpp b/Nuake/src/Rendering/Mesh/Mesh.cpp index e5e31743..d097dc45 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.cpp +++ b/Nuake/src/Rendering/Mesh/Mesh.cpp @@ -11,6 +11,7 @@ #include "src/Rendering/Buffers/VertexBufferLayout.h" #include +#include namespace Nuake { @@ -153,8 +154,23 @@ namespace Nuake bool Mesh::Deserialize(const json& j) { - m_Material = CreateRef(); - m_Material->Deserialize(j["Material"]); + bool loadedMaterialFile = false; + if (j["Material"].contains("Path")) + { + const std::string materialPath = j["Material"]["Path"]; + if (!materialPath.empty()) + { + Ref newMaterial = ResourceLoader::LoadMaterial(materialPath); + m_Material = newMaterial; + loadedMaterialFile = true; + } + } + + if(!loadedMaterialFile) + { + m_Material = CreateRef(); + m_Material->Deserialize(j["Material"]); + } m_Indices.reserve(j["Indices"].size()); for (auto& i : j["Indices"]) diff --git a/Nuake/src/Resource/FGD/FGDFile.cpp b/Nuake/src/Resource/FGD/FGDFile.cpp index 27f04917..57efceb2 100644 --- a/Nuake/src/Resource/FGD/FGDFile.cpp +++ b/Nuake/src/Resource/FGD/FGDFile.cpp @@ -33,7 +33,7 @@ namespace Nuake { bool FGDFile::Save() { // Write to file. - FileSystem::BeginWriteFile(FileSystem::Root + Path); + FileSystem::BeginWriteFile(Path); FileSystem::WriteLine(Serialize().dump(4)); FileSystem::EndWriteFile(); diff --git a/Nuake/src/Resource/FGD/FGDSerializer.cpp b/Nuake/src/Resource/FGD/FGDSerializer.cpp index c5b83cc3..dd4a2463 100644 --- a/Nuake/src/Resource/FGD/FGDSerializer.cpp +++ b/Nuake/src/Resource/FGD/FGDSerializer.cpp @@ -4,7 +4,7 @@ namespace Nuake { bool FGDSerializer::BeginFGDFile(const std::string path) { - FileSystem::BeginWriteFile(path); + FileSystem::BeginWriteFile(path, true); return true; } diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 414c1814..c79bc2ec 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -33,7 +33,7 @@ namespace Nuake { { Path = path; - FileSystem::BeginWriteFile(path); + FileSystem::BeginWriteFile(path, true); FileSystem::WriteLine(Serialize().dump(4)); FileSystem::EndWriteFile(); } diff --git a/Nuake/src/Scene/EditorCamera.cpp b/Nuake/src/Scene/EditorCamera.cpp index 6674708d..68235241 100644 --- a/Nuake/src/Scene/EditorCamera.cpp +++ b/Nuake/src/Scene/EditorCamera.cpp @@ -2,6 +2,7 @@ #include "../Core/Input.h" #include #include + #include "src/Core/Logger.h" namespace Nuake diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index daff8511..fe23aeb6 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -357,7 +357,7 @@ namespace Nuake { std::string fileContent = Serialize().dump(4); - FileSystem::BeginWriteFile(FileSystem::Root + path); + FileSystem::BeginWriteFile(path); FileSystem::WriteLine(fileContent); FileSystem::EndWriteFile(); diff --git a/Nuake/src/Scene/Systems/WadConverter.cpp b/Nuake/src/Scene/Systems/WadConverter.cpp index d501678b..238e7174 100644 --- a/Nuake/src/Scene/Systems/WadConverter.cpp +++ b/Nuake/src/Scene/Systems/WadConverter.cpp @@ -6,10 +6,14 @@ #define STB_IMAGE_WRITE_IMPLEMENTATION #include "src/Vendors/stb_image/stb_image_write.h" #include +#include namespace Nuake { std::string TargetDirectory = ""; + std::string WadName = ""; + std::vector ConvertedTextures; + unsigned char host_quakepal[768] = { @@ -297,22 +301,26 @@ namespace Nuake // if the image contains fullbright pixels, the output filename // will be given the '_fbr' prefix. bool fullbright = false; - std::vector textureData; textureData.resize(width * height); for (int y = 0; y < height; y++) + { for (int x = 0; x < width; x++) { unsigned char pix = pixels[y * width + x]; - + textureData[y * width + x] = COL_ReadPalette(pix); } + } - const std::string finalFilePath = TargetDirectory + ExpandFileName(lump_name, false); - stbi_write_png(finalFilePath.c_str(), width, height, 4, textureData.data(), width * 4); + const std::string lumpName = ExpandFileName(lump_name, false); + const std::string finalFilePath = TargetDirectory + lumpName; + stbi_write_png((FileSystem::Root + finalFilePath).c_str(), width, height, 4, textureData.data(), width * 4); delete[] pixels; + ConvertedTextures.push_back(std::string(lumpName)); + return true; } @@ -331,13 +339,16 @@ namespace Nuake return; } - auto pathSplits = String::Split(std::string(wadPath.begin(), wadPath.end() - 4), '\\'); - std::string wadName = pathSplits[std::size(pathSplits) - 1]; - TargetDirectory = targetDirectory + "/textures/" + wadName + "/"; + ConvertedTextures = std::vector(); - if (!std::filesystem::exists(TargetDirectory)) + auto pathSplits = String::Split(std::string(wadPath.begin(), wadPath.end() - 4), '\\'); + WadName = pathSplits[std::size(pathSplits) - 1]; + TargetDirectory = "/textures/" + WadName + "/"; + + if (const std::string absoluteDirPath = FileSystem::RelativeToAbsolute(TargetDirectory); + !FileSystem::DirectoryExists(absoluteDirPath)) { - std::filesystem::create_directory(TargetDirectory); + FileSystem::MakeDirectory(absoluteDirPath); } WadOpenRead(wadPath); @@ -396,6 +407,33 @@ namespace Nuake printf("Extracted %d entries, with %d failures\n", num_lumps - failures - skipped, failures); + CreateMaterials(); + + ConvertedTextures.clear(); + + } + + void CreateMaterials() + { + const std::string& materialFolderPath = "/Materials/" + WadName + "/"; + if(!FileSystem::DirectoryExists(materialFolderPath)) + { + FileSystem::MakeDirectory(materialFolderPath); + } + + for (auto& t : ConvertedTextures) + { + Ref material = CreateRef(); + material->IsEmbedded = false; + material->SetAlbedo(TextureManager::Get()->GetTexture(FileSystem::RelativeToAbsolute(TargetDirectory + t))); + auto jsonData = material->Serialize(); + + const std::string materialFilePath = materialFolderPath + std::string(t.begin(), t.end() - 4) + ".material"; + + FileSystem::BeginWriteFile(materialFilePath); + FileSystem::WriteLine(jsonData.dump(4)); + FileSystem::EndWriteFile(); + } } void WadOpenRead(const std::string& filename) diff --git a/Nuake/src/Scene/Systems/WadConverter.h b/Nuake/src/Scene/Systems/WadConverter.h index 6e154659..9d235331 100644 --- a/Nuake/src/Scene/Systems/WadConverter.h +++ b/Nuake/src/Scene/Systems/WadConverter.h @@ -1,15 +1,15 @@ #pragma once #include +#include + namespace Nuake { #define MAKE_RGB(r,g,b) (uint32_t)(((r) << 16) | ((g) << 8) | (b) | (255<<24)) - // John Carmack said the quake palette.lmp can be considered public domain because it is not an important asset to id, so I include it here as a fallback if no external palette file is found. - - +// John Carmack said the quake palette.lmp can be considered public domain because it is not an important asset to id, so I include it here as a fallback if no external palette file is found. #define CMP_LZSS 1 #define CMP_NONE 0 #define TYP_LABEL 1 @@ -20,7 +20,6 @@ namespace Nuake #define TYP_QPIC 66 #define TYP_QTEX 65 #define TYP_SOUND 67 - #define MIP_LEVELS 4 typedef struct miptex_s { @@ -83,6 +82,8 @@ namespace Nuake } pic_header_t; + + int WAD2_EntryType(int entry); bool WAD2_ReadData(int entry, int offset, int length, void *buffer); void ExtractWad(const std::string& wadFilePath, const std::string& outputDir); @@ -90,4 +91,5 @@ namespace Nuake bool MIP_ExtractPicture(int entry, const char *lump_name); void WAD2_CloseRead(void); void WadOpenRead(const std::string& filename); + void CreateMaterials(); } \ No newline at end of file