diff --git a/.gitignore b/.gitignore index 29e5299e4..7577afcb3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,8 @@ version.h *.autosave docs/* .idea/ -Editor/platforms/win/metaforce.rc +Runtime/platforms/win/metaforce.rc .vs/ out/ cmake-build-*/ -build/ \ No newline at end of file +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ace80388c..076807cbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -395,7 +395,6 @@ add_subdirectory(extern/athena) add_subdirectory(extern/boo) add_subdirectory(hecl/shaderc) include(hecl/ApplicationTools.cmake) -add_subdirectory(specter/shaders) add_subdirectory(Shaders) add_subdirectory(extern/libSquish) add_subdirectory(extern/libpng) @@ -441,23 +440,14 @@ add_subdirectory(extern/freetype2) if (NOT MSVC) target_compile_options(freetype PRIVATE -Wno-implicit-fallthrough) endif() -add_subdirectory(specter) -target_include_directories(specter PRIVATE ${CMAKE_SOURCE_DIR}) -target_link_libraries(specter PRIVATE nod) add_subdirectory(assetnameparser) add_compile_definitions(URDE_ZIP_INPUT_STREAM=1) # Enable CZipInputStream now that zlib header is known add_subdirectory(DataSpec) add_subdirectory(extern/kabufuda) -add_subdirectory(Editor) add_subdirectory(extern/jbus) set(JBUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/jbus/include) -set(CLIENT_SOURCES - ${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.hpp - ${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryBase.cpp - ${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryMP1.hpp - ${CMAKE_SOURCE_DIR}/Editor/ProjectResourceFactoryMP1.cpp) add_subdirectory(NESEmulator) add_subdirectory(Runtime) add_subdirectory(mpcksum) diff --git a/DataSpec/CMakeLists.txt b/DataSpec/CMakeLists.txt index 9fcef398b..5b20012db 100644 --- a/DataSpec/CMakeLists.txt +++ b/DataSpec/CMakeLists.txt @@ -75,7 +75,7 @@ add_library(AssetNameMapNull get_target_property(HECL_INCLUDES hecl-full INCLUDE_DIRECTORIES) target_include_directories(RetroDataSpec PUBLIC ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${HECL_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}) -target_link_libraries(RetroDataSpec PUBLIC amuse zeus nod specter squish ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} lzokay logvisor) +target_link_libraries(RetroDataSpec PUBLIC amuse zeus nod squish ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} lzokay logvisor) if(COMMAND add_sanitizers) add_sanitizers(RetroDataSpec) endif() diff --git a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp b/DataSpec/DNAMP1/ScriptObjects/Actor.hpp index d48187394..9b094f042 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Actor.hpp @@ -6,12 +6,12 @@ namespace DataSpec::DNAMP1 { struct Actor : IScriptObject { AT_DECL_DNA_YAMLV - String<-1> name SO_NAME_SPECPROP(); - Value location SO_LOCATION_SPECPROP(); - Value orientation SO_ORIENTATION_SPECPROP(); - Value scale SO_SCALE_SPECPROP(); - Value collisionExtent SO_COLLISION_EXTENT_SPECPROP(); - Value collisionOffset SO_COLLISION_OFFSET_SPECPROP(); + String<-1> name; + Value location; + Value orientation; + Value scale; + Value collisionExtent; + Value collisionOffset; Value mass; Value zMomentum; HealthInfo healthInfo; diff --git a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp index fc72b1dd1..53f118ef8 100644 --- a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp @@ -3,18 +3,9 @@ #include "../DNAMP1.hpp" #include "../SAVW.hpp" #include "zeus/CAABox.hpp" -#include "specter/genie.hpp" #include -#define SO_NAME_SPECPROP() SPECTER_PROPERTY("Name", "Instance name; Used to debug scripting events") -#define SO_LOCATION_SPECPROP() SPECTER_PROPERTY("Location", "World relative location of the Actor instance") -#define SO_ORIENTATION_SPECPROP() SPECTER_PROPERTY("Orientation", "Object local axis-angle") -#define SO_SCALE_SPECPROP() SPECTER_PROPERTY("Scale", "Object local scale") -#define SO_COLLISION_EXTENT_SPECPROP() SPECTER_PROPERTY("Collision Extent", "") -#define SO_COLLISION_OFFSET_SPECPROP() SPECTER_PROPERTY("Collision Offset", "") -#define SO_ACTIVE_SPECPROP() SPECTER_PROPERTY("Active", "If enabled, object instance is drawn and updated") - namespace DataSpec::DNAMP1 { zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale, const zeus::CVector3f& orientation, diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp index 8685fd832..4d73d1e3b 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp @@ -3,7 +3,6 @@ #include "../../DNACommon/DNACommon.hpp" #include "../DNAMP1.hpp" #include "../SAVW.hpp" -#include "specter/genie.hpp" namespace DataSpec::DNAMP1 { @@ -49,7 +48,7 @@ enum class EPickupType : atUint32 { World = 38, Spirit = 39, Newborn = 40 -} SPECTER_ENUM("Pickup Type", "", EPickupType); +}; enum class ESpecialFunctionType : atUint32 { What, @@ -85,7 +84,7 @@ enum class ESpecialFunctionType : atUint32 { Ending, FusionRelay, WeaponSwitch // PAL Only -} SPECTER_ENUM("Special Function", "", ESpecialFunctionType); +}; struct AnimationParameters : BigDNA { AT_DECL_DNA_YAML @@ -211,9 +210,9 @@ struct GrappleParameters : BigDNA { struct HealthInfo : BigDNA { AT_DECL_DNA_YAML Value propertyCount; - Value health SPECTER_PROPERTY("Health", "Base health for object"); - Value knockbackResistance SPECTER_PROPERTY("Knockback Resistance", ""); -} SPECTER_PROPERTY("Health Info", ""); + Value health; + Value knockbackResistance; +}; struct LightParameters : BigDNA { AT_DECL_DNA_YAML diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt deleted file mode 100644 index ff2aaa1bf..000000000 --- a/Editor/CMakeLists.txt +++ /dev/null @@ -1,112 +0,0 @@ -add_subdirectory(locale) -add_subdirectory(icons) -add_subdirectory(badging) - -unset(URDE_PLAT_LIBS) - -if(WIN32) - configure_file(platforms/win/metaforce.rc.in "${CMAKE_CURRENT_SOURCE_DIR}/platforms/win/metaforce.rc" @ONLY) - set(PLAT_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/platforms/win/metaforce.rc" platforms/win/metaforce.manifest) - if(WINDOWS_STORE) - set(UWP_ASSETS - platforms/win/Assets/LargeTile.scale-100.png - platforms/win/Assets/LargeTile.scale-125.png - platforms/win/Assets/LargeTile.scale-150.png - platforms/win/Assets/LargeTile.scale-200.png - platforms/win/Assets/LargeTile.scale-400.png - platforms/win/Assets/SmallTile.scale-100.png - platforms/win/Assets/SmallTile.scale-125.png - platforms/win/Assets/SmallTile.scale-150.png - platforms/win/Assets/SmallTile.scale-200.png - platforms/win/Assets/SmallTile.scale-400.png - platforms/win/Assets/SplashScreen.scale-100.png - platforms/win/Assets/SplashScreen.scale-125.png - platforms/win/Assets/SplashScreen.scale-150.png - platforms/win/Assets/SplashScreen.scale-200.png - platforms/win/Assets/SplashScreen.scale-400.png - platforms/win/Assets/Square44x44Logo.scale-100.png - platforms/win/Assets/Square44x44Logo.scale-125.png - platforms/win/Assets/Square44x44Logo.scale-150.png - platforms/win/Assets/Square44x44Logo.scale-200.png - platforms/win/Assets/Square44x44Logo.scale-400.png - platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png - platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png - platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png - platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png - platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png - platforms/win/Assets/Square150x150Logo.scale-100.png - platforms/win/Assets/Square150x150Logo.scale-125.png - platforms/win/Assets/Square150x150Logo.scale-150.png - platforms/win/Assets/Square150x150Logo.scale-200.png - platforms/win/Assets/Square150x150Logo.scale-400.png - platforms/win/Assets/metaforce.scale-100.png - platforms/win/Assets/metaforce.scale-125.png - platforms/win/Assets/metaforce.scale-150.png - platforms/win/Assets/metaforce.scale-200.png - platforms/win/Assets/metaforce.scale-400.png - platforms/win/Assets/WideTile.scale-100.png - platforms/win/Assets/WideTile.scale-125.png - platforms/win/Assets/WideTile.scale-150.png - platforms/win/Assets/WideTile.scale-200.png - platforms/win/Assets/WideTile.scale-400.png) - set_property(SOURCE platforms/win/Package.appxmanifest PROPERTY VS_DEPLOYMENT_CONTENT 1) - set_property(SOURCE ${UWP_ASSETS} PROPERTY VS_DEPLOYMENT_CONTENT 1) - set_property(SOURCE ${UWP_ASSETS} PROPERTY VS_DEPLOYMENT_LOCATION "Assets") - list(APPEND PLAT_SRCS ${UWP_ASSETS} platforms/win/Package.appxmanifest) - endif() -elseif(APPLE) - # nothing -elseif(UNIX) - add_subdirectory(platforms/freedesktop) - declare_wmicon_target() - set(PLAT_SRCS mainicon_netwm.cpp) - set(URDE_PLAT_LIBS rt) -endif() - -add_executable(metaforce WIN32 - main.cpp ${PLAT_SRCS} - Space.hpp Space.cpp - SplashScreen.hpp SplashScreen.cpp - ResourceBrowser.hpp ResourceBrowser.cpp - ModelViewer.hpp ModelViewer.cpp - ParticleEditor.hpp ParticleEditor.cpp - InformationCenter.hpp InformationCenter.hpp - ProjectManager.hpp ProjectManager.cpp - ViewManager.hpp ViewManager.cpp - Resource.hpp Resource.cpp - Camera.hpp Camera.cpp - GameMode.hpp GameMode.cpp) - -target_include_directories(metaforce PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/Runtime # FIXME atdna cmake issue - ${CMAKE_BINARY_DIR}) - -target_link_libraries(metaforce - MetaforceIcons - MetaforceBadging - RuntimeCommon - amuse - RetroDataSpec - kabufuda - ${URDE_PLAT_LIBS}) - -target_atdna(metaforce atdna_Space.cpp Space.hpp) -target_atdna(metaforce atdna_ResourceBrowser.cpp ResourceBrowser.hpp) -target_atdna(metaforce atdna_ModelViewer.cpp ModelViewer.hpp) -target_atdna(metaforce atdna_ParticleEditor.cpp ParticleEditor.hpp) -target_atdna(metaforce atdna_InformationCenter.cpp InformationCenter.hpp) -target_atdna(metaforce atdna_GameMode.cpp GameMode.hpp) - -if(COMMAND add_sanitizers) - add_sanitizers(metaforce) -endif() - -if (NOT WINDOWS_STORE) - add_dependencies(metaforce visigen hecl) -else() - set_property(TARGET metaforce PROPERTY VS_WINRT_COMPONENT TRUE) - # This should match the Package.appxmanifest - set_property(TARGET metaforce PROPERTY VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION "10.0.14393.0") -endif() diff --git a/Editor/Camera.cpp b/Editor/Camera.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/Editor/Camera.hpp b/Editor/Camera.hpp deleted file mode 100644 index 9942cfb79..000000000 --- a/Editor/Camera.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "zeus/CProjection.hpp" -#include "zeus/CFrustum.hpp" -#include "zeus/CQuaternion.hpp" -#include "zeus/CVector3f.hpp" -#include "zeus/Math.hpp" - -namespace metaforce { -class Camera { - zeus::CFrustum m_frustum; - zeus::CProjection m_projection; - zeus::CVector3f m_position; - zeus::CQuaternion m_orientation; - -public: - void setPosition(const zeus::CVector3f& position) { m_position = position; } - void setOrientation(const zeus::CQuaternion& orientation) { m_orientation = orientation; } - - const zeus::CMatrix4f& projectionMatrix() const { return m_projection.getCachedMatrix(); } - const zeus::CProjection& projection() const { return m_projection; } - - virtual void think() {} -}; -} // namespace metaforce diff --git a/Editor/GameMode.cpp b/Editor/GameMode.cpp deleted file mode 100644 index dfeda37cf..000000000 --- a/Editor/GameMode.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "GameMode.hpp" - -namespace metaforce { -void GameMode::think() { ViewerSpace::think(); } - -void GameMode::View::draw(boo::IGraphicsCommandQueue* gfxQ) { - if (m_gMode.m_main) - m_gMode.m_main->Draw(); -} - -} // namespace metaforce diff --git a/Editor/GameMode.hpp b/Editor/GameMode.hpp deleted file mode 100644 index b5ab29ddc..000000000 --- a/Editor/GameMode.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "Space.hpp" -#include "ViewManager.hpp" -#include "Runtime/IMain.hpp" - -namespace metaforce { -class GameMode : public ViewerSpace { - std::shared_ptr m_main; - - struct State : Space::State { - AT_DECL_DNA_YAMLV - Value showToolbar = true; - } m_state; - - const Space::State& spaceState() const override { return m_state; } - - struct View : specter::View { - GameMode& m_gMode; - - View(GameMode& gMode, specter::ViewResources& res) : specter::View(res, gMode.m_vm.rootView()), m_gMode(gMode) {} - - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - }; - - std::unique_ptr m_view; - -public: - GameMode(ViewManager& vm, Space* parent) : ViewerSpace(vm, Class::GameMode, parent) { reloadState(); } - - GameMode(ViewManager& vm, Space* parent, const GameMode& other) : GameMode(vm, parent) { - m_state = other.m_state; - reloadState(); - } - - GameMode(ViewManager& vm, Space* parent, ConfigReader& r) : GameMode(vm, parent) { - m_state.read(r); - reloadState(); - } - - void reloadState() override {} - - specter::View* buildContentView(specter::ViewResources& res) override { - m_view.reset(new View(*this, res)); - return m_view.get(); - } - - void think() override; - - Space* copy(Space* parent) const override { return new GameMode(m_vm, parent, *this); } - - bool usesToolbar() const override { return m_state.showToolbar; } -}; -} // namespace metaforce diff --git a/Editor/InformationCenter.cpp b/Editor/InformationCenter.cpp deleted file mode 100644 index 3a2d69cfc..000000000 --- a/Editor/InformationCenter.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "InformationCenter.hpp" - -namespace metaforce {} diff --git a/Editor/InformationCenter.hpp b/Editor/InformationCenter.hpp deleted file mode 100644 index 733d55fc0..000000000 --- a/Editor/InformationCenter.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "Space.hpp" -#include "ViewManager.hpp" - -namespace metaforce { -class InformationCenter : public ViewerSpace { - struct State : Space::State { - AT_DECL_DNA_YAMLV - Value showLog; - } m_state; - - const Space::State& spaceState() const override { return m_state; } - - struct View : specter::View { - InformationCenter& m_ic; - std::vector m_log; - - View(InformationCenter& ic, specter::ViewResources& res) : specter::View(res, ic.m_vm.rootView()), m_ic(ic) {} - }; - - std::unique_ptr m_view; - -public: - InformationCenter(ViewManager& vm, Space* parent) : ViewerSpace(vm, Class::InformationCenter, parent) { - reloadState(); - } - - InformationCenter(ViewManager& vm, Space* parent, const InformationCenter& other) : InformationCenter(vm, parent) { - m_state = other.m_state; - reloadState(); - } - - InformationCenter(ViewManager& vm, Space* parent, ConfigReader& r) : InformationCenter(vm, parent) { - m_state.read(r); - reloadState(); - } - - void reloadState() override {} - - specter::View* buildContentView(specter::ViewResources& res) override { - m_view.reset(new View(*this, res)); - return m_view.get(); - } - - Space* copy(Space* parent) const override { return new InformationCenter(m_vm, parent, *this); } - - bool usesToolbar() const override { return true; } -}; -} // namespace metaforce diff --git a/Editor/ModelViewer.cpp b/Editor/ModelViewer.cpp deleted file mode 100644 index 41f83237d..000000000 --- a/Editor/ModelViewer.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "ModelViewer.hpp" - -namespace metaforce { - -void ModelViewer::View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { - specter::View::resized(root, sub); - m_scissorRect = sub; -} - -} // namespace metaforce diff --git a/Editor/ModelViewer.hpp b/Editor/ModelViewer.hpp deleted file mode 100644 index fe993ebfa..000000000 --- a/Editor/ModelViewer.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "Space.hpp" -#include "ViewManager.hpp" -#include "Camera.hpp" - -namespace metaforce { -class ModelViewer : public ViewerSpace { - struct State : Space::State { - AT_DECL_DNA_YAMLV - enum class Mode { Solid, Material, Wireframe }; - - Value renderMode = Mode::Material; - Value cameraPosition; - Value cameraOrientation; - - } m_state; - - const Space::State& spaceState() const override { return m_state; } - std::unique_ptr m_lineRenderer; - struct View : specter::View { - ModelViewer& m_mv; - boo::SWindowRect m_scissorRect; - - View(ModelViewer& mv, specter::ViewResources& res) : specter::View(res, mv.m_vm.rootView()), m_mv(mv) {} - - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) override; - }; - - Camera m_camera; - std::unique_ptr m_view; - -public: - ModelViewer(ViewManager& vm, Space* parent) : ViewerSpace(vm, Class::ModelViewer, parent) { - reloadState(); - m_lineRenderer.reset(new metaforce::CLineRenderer(metaforce::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true)); - } - - ModelViewer(ViewManager& vm, Space* parent, const ModelViewer& other) : ModelViewer(vm, parent) { - m_state = other.m_state; - reloadState(); - } - - ModelViewer(ViewManager& vm, Space* parent, ConfigReader& r) : ModelViewer(vm, parent) { - m_state.read(r); - reloadState(); - } - - void reloadState() override { - m_camera.setPosition(m_state.cameraPosition); - m_camera.setOrientation(m_state.cameraOrientation); - } - - Space* copy(Space* parent) const override { return new ModelViewer(m_vm, parent, *this); } - - specter::View* buildContentView(specter::ViewResources& res) override { - m_view.reset(new View(*this, res)); - return m_view.get(); - } - - bool usesToolbar() const override { return true; } -}; - -} // namespace metaforce diff --git a/Editor/ParticleEditor.cpp b/Editor/ParticleEditor.cpp deleted file mode 100644 index 5188d18e2..000000000 --- a/Editor/ParticleEditor.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "ParticleEditor.hpp" - -namespace metaforce {} diff --git a/Editor/ParticleEditor.hpp b/Editor/ParticleEditor.hpp deleted file mode 100644 index 58280f8cb..000000000 --- a/Editor/ParticleEditor.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "Space.hpp" - -namespace metaforce { - -class EffectEditor : public EditorSpace { - struct State : Space::State { - AT_DECL_DNA_YAMLV - String<-1> path; - } m_state; - const Space::State& spaceState() const override { return m_state; } - - struct View : specter::View { - View(specter::ViewResources& res, specter::View& parent) : specter::View(res, parent) {} - }; - - specter::View* buildContentView(specter::ViewResources& res) override { return nullptr; } - -public: - EffectEditor(ViewManager& vm, Space* parent) : EditorSpace(vm, Class::EffectEditor, parent) {} - EffectEditor(ViewManager& vm, Space* parent, ConfigReader& r) : EffectEditor(vm, parent) { m_state.read(r); } - EffectEditor(ViewManager& vm, Space* parent, const EffectEditor& other) : EffectEditor(vm, parent) { - m_state = other.m_state; - } - - Space* copy(Space* parent) const override { return new EffectEditor(m_vm, parent, *this); } - - bool usesToolbar() const override { return true; } -}; - -} // namespace metaforce diff --git a/Editor/ProjectManager.cpp b/Editor/ProjectManager.cpp deleted file mode 100644 index 1d0de2a23..000000000 --- a/Editor/ProjectManager.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "ProjectManager.hpp" -#include "ViewManager.hpp" -#include "DataSpecRegistry.hpp" -#include "hecl/Blender/Connection.hpp" -#include "version.h" - -namespace metaforce { -static logvisor::Module Log("URDE::ProjectManager"); -ProjectManager* ProjectManager::g_SharedManager = nullptr; - -CToken ProjectResourcePool::GetObj(std::string_view name) { - CToken ret = CSimplePool::GetObj(name); - if (ret) - return ret; - - hecl::ProjectPath path(*m_parent.project(), name); - SObjectTag tag = - static_cast(x18_factory).TagFromPath(path); - if (tag) - return CSimplePool::GetObj(tag); - - return {}; -} - -CToken ProjectResourcePool::GetObj(std::string_view name, const CVParamTransfer& pvxfer) { - CToken ret = CSimplePool::GetObj(name, pvxfer); - if (ret) - return ret; - - hecl::ProjectPath path(*m_parent.project(), name); - SObjectTag tag = - static_cast(x18_factory).TagFromPath(path); - if (tag) - return CSimplePool::GetObj(tag, pvxfer); - - return {}; -} - -bool ProjectManager::m_registeredSpecs = false; -ProjectManager::ProjectManager(ViewManager& vm) -: m_vm(vm), m_clientProc(nullptr), m_factoryMP1(m_clientProc), m_objStore(m_factoryMP1, *this) { - if (!m_registeredSpecs) { - HECLRegisterDataSpecs(); - m_registeredSpecs = true; - } - g_SharedManager = this; -} - -bool ProjectManager::newProject(hecl::SystemStringView path) { - hecl::ProjectRootPath projPath = hecl::SearchForProject(path); - if (projPath) { - Log.report(logvisor::Warning, FMT_STRING(_SYS_STR("project already exists at '{}'")), path); - return false; - } - - hecl::MakeDir(path.data()); - m_proj = std::make_unique(path); - if (!*m_proj) { - m_proj.reset(); - return false; - } - - m_vm.ProjectChanged(*m_proj); - m_vm.SetupEditorView(); - saveProject(); - - m_vm.m_mainWindow->setTitle(fmt::format(FMT_STRING(_SYS_STR("{} - Metaforce {} [{}]")), - m_proj->getProjectRootPath().getLastComponent(), METAFORCE_WC_DESCRIBE_SYS, m_vm.platformName())); - m_vm.DismissSplash(); - m_vm.FadeInEditors(); - - return true; -} - -bool ProjectManager::openProject(hecl::SystemStringView path) { - OPTICK_EVENT(); - hecl::SystemString subPath; - hecl::ProjectRootPath projPath = hecl::SearchForProject(path, subPath); - if (!projPath) { - Log.report(logvisor::Warning, FMT_STRING(_SYS_STR("project doesn't exist at '{}'")), path); - return false; - } - - m_proj = std::make_unique(projPath); - if (!*m_proj) { - m_proj.reset(); - return false; - } - - athena::io::YAMLDocReader r; - const auto makeProj = [this, &r, &subPath](bool needsSave) { - m_vm.ProjectChanged(*m_proj); - - if (needsSave) - m_vm.SetupEditorView(); - else - m_vm.SetupEditorView(r); - - const bool doRun = hecl::StringUtils::BeginsWith(subPath, _SYS_STR("out")); - if (doRun) { - m_mainMP1.emplace(nullptr, nullptr, m_vm.m_mainBooFactory, m_vm.m_mainCommandQueue, m_vm.m_renderTex); - m_vm.InitMP1(*m_mainMP1); - } - - if (needsSave) - saveProject(); - - m_vm.m_mainWindow->setTitle(fmt::format(FMT_STRING(_SYS_STR("{} - Metaforce {} [{}]")), - m_proj->getProjectRootPath().getLastComponent(), METAFORCE_WC_DESCRIBE_SYS, - m_vm.platformName())); - m_vm.DismissSplash(); - m_vm.FadeInEditors(); - m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath()); - return true; - }; - - const hecl::ProjectPath metaforceSpacesPath(*m_proj, _SYS_STR(".hecl/metaforce_spaces.yaml")); - athena::io::FileReader reader(metaforceSpacesPath.getAbsolutePath()); - - if (!reader.isOpen()) { - return makeProj(true); - } - - const auto readHandler = [](void* data, unsigned char* buffer, size_t size, size_t* size_read) { - auto* const reader = static_cast(data); - return athena::io::YAMLAthenaReader(reader, buffer, size, size_read); - }; - - yaml_parser_set_input(r.getParser(), readHandler, &reader); - if (!r.ValidateClassType("MetaforceSpacesState")) { - return makeProj(true); - } - - r.reset(); - reader.seek(0, athena::SeekOrigin::Begin); - if (!r.parse(&reader)) { - return makeProj(true); - } - - return makeProj(false); -} - -bool ProjectManager::extractGame(hecl::SystemStringView path) { return false; } - -bool ProjectManager::saveProject() { - if (!m_proj) - return false; - - hecl::ProjectPath oldSpacesPath(*m_proj, _SYS_STR(".hecl/~metaforce_spaces.yaml")); - athena::io::FileWriter writer(oldSpacesPath.getAbsolutePath()); - if (!writer.isOpen()) - return false; - - athena::io::YAMLDocWriter w("UrdeSpacesState"); - m_vm.SaveEditorView(w); - if (!w.finish(&writer)) - return false; - - hecl::ProjectPath newSpacesPath(*m_proj, _SYS_STR(".hecl/metaforce_spaces.yaml")); - - hecl::Unlink(newSpacesPath.getAbsolutePath().data()); - hecl::Rename(oldSpacesPath.getAbsolutePath().data(), newSpacesPath.getAbsolutePath().data()); - - m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath()); - - return true; -} - -void ProjectManager::mainUpdate() { - OPTICK_EVENT(); - if (m_precooking) { - if (!m_factoryMP1.IsBusy()) - m_precooking = false; - else - return; - } - - if (m_mainMP1) { - if (m_mainMP1->Proc()) { - m_mainMP1->Shutdown(); - m_mainMP1 = std::nullopt; - } - } -} - -void ProjectManager::mainDraw() { - if (m_precooking) - return; - - if (m_mainMP1) - m_mainMP1->Draw(); -} - -void ProjectManager::shutdown() { - if (m_mainMP1) - m_mainMP1->Shutdown(); - m_clientProc.shutdown(); - m_factoryMP1.Shutdown(); - hecl::blender::Connection::Shutdown(); -} - -} // namespace metaforce diff --git a/Editor/ProjectManager.hpp b/Editor/ProjectManager.hpp deleted file mode 100644 index 458b3ad71..000000000 --- a/Editor/ProjectManager.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "hecl/Database.hpp" -#include "athena/DNAYaml.hpp" -#include "ProjectResourceFactoryMP1.hpp" -#include "Runtime/CSimplePool.hpp" -#include "hecl/Runtime.hpp" -#include "MP1/MP1.hpp" - -namespace metaforce { -class ViewManager; - -using ConfigReader = athena::io::YAMLDocReader; -using ConfigWriter = athena::io::YAMLDocWriter; - -class ProjectResourcePool : public CSimplePool { - class ProjectManager& m_parent; - -public: - ProjectResourcePool(IFactory& factory, ProjectManager& parent) : CSimplePool(factory), m_parent(parent) {} - CToken GetObj(std::string_view) override; - CToken GetObj(std::string_view, const CVParamTransfer&) override; -}; - -class ProjectManager { - ViewManager& m_vm; - std::unique_ptr m_proj; - static bool m_registeredSpecs; - hecl::ClientProcess m_clientProc; - ProjectResourceFactoryMP1 m_factoryMP1; - ProjectResourcePool m_objStore; - std::optional m_mainMP1; - bool m_precooking = false; - -public: - static ProjectManager* g_SharedManager; - ProjectManager(ViewManager& vm); - operator bool() const { return m_proj.operator bool(); } - - hecl::Database::Project* project() { return m_proj.get(); } - ProjectResourcePool& objectStore() { return m_objStore; } - ProjectResourceFactoryMP1& resourceFactoryMP1() { return m_factoryMP1; } - MP1::CMain* gameMain() { return m_mainMP1 ? &*m_mainMP1 : nullptr; } - SObjectTag TagFromPath(hecl::SystemStringView path) const { - return m_factoryMP1.ProjectResourceFactoryBase::TagFromPath(path); - } - - bool newProject(hecl::SystemStringView path); - bool openProject(hecl::SystemStringView path); - bool extractGame(hecl::SystemStringView path); - bool saveProject(); - - void mainUpdate(); - void mainDraw(); - void shutdown(); -}; - -} // namespace metaforce diff --git a/Editor/ProjectResourceFactoryBase.cpp b/Editor/ProjectResourceFactoryBase.cpp deleted file mode 100644 index 0b10f40e9..000000000 --- a/Editor/ProjectResourceFactoryBase.cpp +++ /dev/null @@ -1,467 +0,0 @@ -#include "Editor/ProjectResourceFactoryBase.hpp" - -#include "Runtime/IObj.hpp" - -#include - -#undef min -#undef max - -namespace metaforce { -static logvisor::Module Log("metaforce::ProjectResourceFactoryBase"); - -void ProjectResourceFactoryBase::BeginBackgroundIndex(hecl::Database::Project& proj, - const hecl::Database::DataSpecEntry& origSpec, - const hecl::Database::DataSpecEntry& pcSpec) { - CancelBackgroundIndex(); - m_proj = &proj; - m_origSpec = &origSpec; - m_pcSpec = &pcSpec; - m_cookSpec = pcSpec.m_factory(proj, hecl::Database::DataSpecTool::Cook); - return static_cast(*m_cookSpec).beginBackgroundIndex(); -} - -bool ProjectResourceFactoryBase::SyncCook(const hecl::ProjectPath& working) { - Log.report(logvisor::Warning, FMT_STRING(_SYS_STR("sync-cooking {}")), working.getRelativePath()); - return m_clientProc.syncCook(working, m_cookSpec.get(), hecl::blender::SharedBlenderToken, false, false); -} - -CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path, - const CVParamTransfer& paramXfer, CObjectReference* selfRef) { - /* Ensure cooked rep is on the filesystem */ - std::optional fr; - if (!PrepForReadSync(tag, path, fr)) - return {}; - - /* All good, build resource */ - if (m_factoryMgr.CanMakeMemory(tag)) { - u32 length = fr->length(); - std::unique_ptr memBuf = fr->readUBytes(length); - CFactoryFnReturn ret = m_factoryMgr.MakeObjectFromMemory(tag, std::move(memBuf), length, false, paramXfer, selfRef); - Log.report(logvisor::Info, FMT_STRING("sync-built {}"), tag); - return ret; - } - - CFactoryFnReturn ret = m_factoryMgr.MakeObject(tag, *fr, paramXfer, selfRef); - Log.report(logvisor::Info, FMT_STRING("sync-built {}"), tag); - return ret; -} - -void ProjectResourceFactoryBase::AsyncTask::EnsurePath(const metaforce::SObjectTag& tag, const hecl::ProjectPath& path) { - if (!m_workingPath) { - m_workingPath = path; - - /* Ensure requested resource is on the filesystem */ - if (!path.isFileOrGlob()) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to find resource path '{}'")), path.getRelativePath()); - m_failed = true; - return; - } - - /* Cached resolve (try PC first, then original) */ - m_cookedPath = path.getCookedPath(*m_parent.m_pcSpec); - if (!m_cookedPath.isFile()) - m_cookedPath = path.getCookedPath(*m_parent.m_origSpec); - if (!m_cookedPath.isFile() || m_cookedPath.getModtime() < path.getModtime()) { - /* Last chance type validation */ - metaforce::SObjectTag verifyTag = m_parent.TagFromPath(path); - if (verifyTag.type != tag.type) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("{}: expected type '{}', found '{}'")), path.getRelativePath(), - tag.type, verifyTag.type); - m_failed = true; - return; - } - - /* Get cooked representation path */ - m_cookedPath = m_parent.GetCookedPath(path, true); - - /* Perform mod-time comparison */ - if (!m_cookedPath.isFile() || m_cookedPath.getModtime() < path.getModtime()) { - /* Start a background cook here */ - m_cookTransaction = m_parent.m_clientProc.addCookTransaction(path, false, false, m_parent.m_cookSpec.get()); - return; - } - } - - CookComplete(); - } -} - -void ProjectResourceFactoryBase::AsyncTask::CookComplete() { - /* Ensure cooked rep is on the filesystem */ - athena::io::FileReader fr(m_cookedPath.getAbsolutePath(), 32 * 1024, false); - if (fr.hasError()) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to open cooked resource path '{}'")), m_cookedPath.getAbsolutePath()); - m_failed = true; - return; - } - - /* Ready for buffer transaction at this point */ - u32 availSz = std::max(0, s32(fr.length()) - s32(x14_resOffset)); - x14_resSize = std::min(x14_resSize, availSz); - if (xc_targetDataRawPtr) { - m_bufTransaction = - m_parent.m_clientProc.addBufferTransaction(m_cookedPath, xc_targetDataRawPtr, x14_resSize, x14_resOffset); - } else if (xc_targetDataPtr || xc_targetObjPtr) { - x10_loadBuffer.reset(new u8[x14_resSize]); - m_bufTransaction = - m_parent.m_clientProc.addBufferTransaction(m_cookedPath, x10_loadBuffer.get(), x14_resSize, x14_resOffset); - } else { - /* Skip buffer transaction if no target pointers set */ - m_complete = true; - } -} - -bool ProjectResourceFactoryBase::AsyncTask::AsyncPump() { - if (m_failed || m_complete) - return true; - - if (m_bufTransaction) { - if (m_bufTransaction->m_complete) { - m_complete = true; - return true; - } - } else if (m_cookTransaction) { - if (m_cookTransaction->m_complete) - CookComplete(); - } - - return m_failed; -} - -void ProjectResourceFactoryBase::AsyncTask::WaitUntilComplete() { - using ItType = std::unordered_map>::iterator>::iterator; - ItType search = m_parent.m_asyncLoadMap.find(x0_tag); - if (search == m_parent.m_asyncLoadMap.end()) - return; - for (ItType tmp = search; !m_parent.AsyncPumpTask(tmp); tmp = search) { - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - } -} - -using AsyncTask = ProjectResourceFactoryBase::AsyncTask; - -std::shared_ptr ProjectResourceFactoryBase::_AddTask(const std::shared_ptr& ptr) { - m_asyncLoadMap.insert({ptr->x0_tag, m_asyncLoadList.insert(m_asyncLoadList.end(), ptr)}); - return ptr; -} - -std::list>::iterator -ProjectResourceFactoryBase::_RemoveTask(std::list>::iterator it) { - m_asyncLoadMap.erase((*it)->x0_tag); - return m_asyncLoadList.erase(it); -} - -std::unordered_map>::iterator>::iterator -ProjectResourceFactoryBase::_RemoveTask( - std::unordered_map>::iterator>::iterator it) { - if (it != m_asyncLoadMap.end()) { - m_asyncLoadList.erase(it->second); - return m_asyncLoadMap.erase(it); - } - return it; -}; - -std::unordered_map>::iterator>::iterator -ProjectResourceFactoryBase::_RemoveTask(const SObjectTag& tag) { - return _RemoveTask(m_asyncLoadMap.find(tag)); -}; - -bool ProjectResourceFactoryBase::PrepForReadSync(const SObjectTag& tag, const hecl::ProjectPath& path, - std::optional& fr) { - /* Ensure requested resource is on the filesystem */ - if (!path.isFileOrGlob()) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to find resource path '{}'")), path.getAbsolutePath()); - return false; - } - - /* Cached resolve (try PC first, then original) */ - hecl::ProjectPath cooked = path.getCookedPath(*m_pcSpec); - if (!cooked.isFile()) - cooked = path.getCookedPath(*m_origSpec); - if (!cooked.isFile() || cooked.getModtime() < path.getModtime()) { - /* Last chance type validation */ - metaforce::SObjectTag verifyTag = TagFromPath(path); - if (verifyTag.type != tag.type) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("{}: expected type '{}', found '{}'")), path.getRelativePath(), - tag.type, verifyTag.type); - return false; - } - - /* Get cooked representation path */ - cooked = GetCookedPath(path, true); - - /* Perform mod-time comparison */ - if (!cooked.isFile() || cooked.getModtime() < path.getModtime()) { - /* Do a blocking cook here */ - if (!SyncCook(path)) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to cook resource path '{}'")), path.getAbsolutePath()); - return false; - } - } - } - - /* Ensure cooked rep is on the filesystem */ - fr.emplace(cooked.getAbsolutePath(), 32 * 1024, false); - if (fr->hasError()) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to open cooked resource path '{}'")), cooked.getAbsolutePath()); - return false; - } - - return true; -} - -std::unique_ptr ProjectResourceFactoryBase::Build(const metaforce::SObjectTag& tag, - const metaforce::CVParamTransfer& paramXfer, - CObjectReference* selfRef) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id on type '{}'"), tag.type); - - const hecl::ProjectPath* resPath = nullptr; - if (!WaitForTagReady(tag, resPath)) - return {}; - auto asyncSearch = m_asyncLoadMap.find(tag); - if (asyncSearch != m_asyncLoadMap.end()) { - /* Async spinloop */ - AsyncTask& task = **asyncSearch->second; - task.EnsurePath(task.x0_tag, *resPath); - - /* Pump load pipeline (cooking if needed) */ - while (!task.AsyncPump()) { - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - } - - if (task.m_complete && task.x10_loadBuffer) { - /* Load complete, build resource */ - std::unique_ptr newObj; - if (m_factoryMgr.CanMakeMemory(task.x0_tag)) { - newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer), task.x14_resSize, false, - task.x18_cvXfer, selfRef); - } else { - athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize); - newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, selfRef); - } - - //*task.xc_targetObjPtr = newObj.get(); - Log.report(logvisor::Warning, FMT_STRING("spin-built {}"), task.x0_tag); - - _RemoveTask(asyncSearch); - return newObj; - } else if (task.m_complete) { - Log.report(logvisor::Error, FMT_STRING("unable to spin-build {}; Resource requested as cook-only"), task.x0_tag); - } else { - Log.report(logvisor::Error, FMT_STRING("unable to spin-build {}"), task.x0_tag); - } - - _RemoveTask(asyncSearch); - return {}; - } - - /* Fall-back to sync build */ - return BuildSync(tag, *resPath, paramXfer, selfRef); -} - -std::shared_ptr ProjectResourceFactoryBase::BuildAsyncInternal(const metaforce::SObjectTag& tag, - const metaforce::CVParamTransfer& paramXfer, - std::unique_ptr* objOut, - CObjectReference* selfRef) { - if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) - return {}; - return _AddTask(std::make_unique(*this, tag, objOut, paramXfer, selfRef)); -} - -void ProjectResourceFactoryBase::BuildAsync(const metaforce::SObjectTag& tag, const metaforce::CVParamTransfer& paramXfer, - std::unique_ptr* objOut, CObjectReference* selfRef) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id on type '{}'"), tag.type); - - BuildAsyncInternal(tag, paramXfer, objOut, selfRef); -} - -u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id on type '{}'"), tag.type); - - /* Ensure resource at requested path is indexed and not cooking */ - const hecl::ProjectPath* resPath = nullptr; - if (!WaitForTagReady(tag, resPath)) - return {}; - - /* Ensure cooked rep is on the filesystem */ - std::optional fr; - if (!PrepForReadSync(tag, *resPath, fr)) - return {}; - - return fr->length(); -} - -std::shared_ptr ProjectResourceFactoryBase::LoadResourceAsync(const metaforce::SObjectTag& tag, - void* target) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) - return {}; - return std::static_pointer_cast( - _AddTask(std::make_shared(*this, tag, reinterpret_cast(target)))); -} - -std::shared_ptr ProjectResourceFactoryBase::LoadResourcePartAsync(const metaforce::SObjectTag& tag, - u32 off, u32 size, void* target) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) - return {}; - return std::static_pointer_cast( - _AddTask(std::make_shared(*this, tag, reinterpret_cast(target), size, off))); -} - -std::unique_ptr ProjectResourceFactoryBase::LoadResourceSync(const metaforce::SObjectTag& tag) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - - /* Ensure resource at requested path is indexed and not cooking */ - const hecl::ProjectPath* resPath = nullptr; - if (!WaitForTagReady(tag, resPath)) - return {}; - - /* Ensure cooked rep is on the filesystem */ - std::optional fr; - if (!PrepForReadSync(tag, *resPath, fr)) - return {}; - - return fr->readUBytes(fr->length()); -} - -std::unique_ptr ProjectResourceFactoryBase::LoadNewResourcePartSync(const metaforce::SObjectTag& tag, u32 off, - u32 size) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - - /* Ensure resource at requested path is indexed and not cooking */ - const hecl::ProjectPath* resPath = nullptr; - if (!WaitForTagReady(tag, resPath)) - return {}; - - /* Ensure cooked rep is on the filesystem */ - std::optional fr; - if (!PrepForReadSync(tag, *resPath, fr)) - return {}; - - s32 sz = std::min(s32(size), std::max(0, s32(fr->length()) - s32(off))); - fr->seek(off, athena::SeekOrigin::Begin); - return fr->readUBytes(sz); -} - -std::shared_ptr ProjectResourceFactoryBase::CookResourceAsync(const metaforce::SObjectTag& tag) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) - return {}; - return _AddTask(std::make_shared(*this, tag)); -} - -void ProjectResourceFactoryBase::CancelBuild(const metaforce::SObjectTag& tag) { _RemoveTask(tag); } - -bool ProjectResourceFactoryBase::CanBuild(const metaforce::SObjectTag& tag) { - if (!tag.id.IsValid()) - Log.report(logvisor::Fatal, FMT_STRING("attempted to access null id")); - - const hecl::ProjectPath* resPath = nullptr; - if (!WaitForTagReady(tag, resPath)) - return false; - - if (resPath->isFile()) - return true; - - return false; -} - -const metaforce::SObjectTag* ProjectResourceFactoryBase::GetResourceIdByName(std::string_view name) const { - return static_cast(*m_cookSpec).getResourceIdByName(name); -} - -FourCC ProjectResourceFactoryBase::GetResourceTypeById(CAssetId id) const { - return static_cast(*m_cookSpec).getResourceTypeById(id); -} - -void ProjectResourceFactoryBase::EnumerateResources(const std::function& lambda) const { - return static_cast(*m_cookSpec).enumerateResources(lambda); -} - -void ProjectResourceFactoryBase::EnumerateNamedResources( - const std::function& lambda) const { - return static_cast(*m_cookSpec).enumerateNamedResources(lambda); -} - -template -bool ProjectResourceFactoryBase::AsyncPumpTask(ItType& it) { - /* Ensure requested resource is in the index */ - AsyncTask& task = _GetAsyncTask(it); - hecl::ProjectPath path = static_cast(*m_cookSpec).pathFromTag(task.x0_tag); - if (!path) { - if (!static_cast(*m_cookSpec).backgroundIndexRunning()) { - Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to find async load resource ({})")), task.x0_tag); - it = _RemoveTask(it); - } - return true; - } - task.EnsurePath(task.x0_tag, path); - - /* Pump load pipeline (cooking if needed) */ - if (task.AsyncPump()) { - if (task.m_complete) { - /* Load complete, build resource */ - if (task.xc_targetObjPtr) { - /* Factory build */ - std::unique_ptr newObj; - if (m_factoryMgr.CanMakeMemory(task.x0_tag)) { - newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer), task.x14_resSize, - false, task.x18_cvXfer, task.m_selfRef); - } else { - athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize); - newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef); - } - - *task.xc_targetObjPtr = std::move(newObj); - Log.report(logvisor::Info, FMT_STRING("async-built {}"), task.x0_tag); - } else if (task.xc_targetDataPtr) { - /* Buffer only */ - *task.xc_targetDataPtr = std::move(task.x10_loadBuffer); - Log.report(logvisor::Info, FMT_STRING("async-loaded {}"), task.x0_tag); - } else if (task.xc_targetDataRawPtr) { - /* Buffer only raw */ - Log.report(logvisor::Info, FMT_STRING("async-loaded {}"), task.x0_tag); - } - } - - it = _RemoveTask(it); - return true; - } - ++it; - return false; -} - -template bool ProjectResourceFactoryBase::AsyncPumpTask>::iterator>( - std::list>::iterator& it); -template bool ProjectResourceFactoryBase::AsyncPumpTask< - std::unordered_map>::iterator>::iterator>( - std::unordered_map>::iterator>::iterator& it); - -void ProjectResourceFactoryBase::AsyncIdle() { - /* Consume completed transactions, they will be processed this cycle at the latest */ - std::list> completed; - m_clientProc.swapCompletedQueue(completed); - - /* Begin self-profiling loop */ - std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); - for (auto it = m_asyncLoadList.begin(); it != m_asyncLoadList.end();) { - /* Allow 8 milliseconds (roughly 1/2 frame-time) for each async build cycle */ - std::chrono::steady_clock::time_point resStart = std::chrono::steady_clock::now(); - if (std::chrono::duration_cast(resStart - start).count() > 8) - break; - - AsyncPumpTask(it); - } -} - -} // namespace metaforce diff --git a/Editor/ProjectResourceFactoryBase.hpp b/Editor/ProjectResourceFactoryBase.hpp deleted file mode 100644 index 208e3a8bb..000000000 --- a/Editor/ProjectResourceFactoryBase.hpp +++ /dev/null @@ -1,163 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "DataSpec/SpecBase.hpp" - -#include "Runtime/CFactoryMgr.hpp" -#include "Runtime/CResFactory.hpp" -#include "Runtime/IFactory.hpp" - -#include -#include - -namespace metaforce { - -class ProjectResourceFactoryBase : public IFactory { - friend class ProjectResourcePool; - hecl::ClientProcess& m_clientProc; - -public: - struct AsyncTask : metaforce::IDvdRequest { - ProjectResourceFactoryBase& m_parent; - - SObjectTag x0_tag; - // IDvdRequest* x8_dvdReq = nullptr; - std::unique_ptr* xc_targetDataPtr = nullptr; - u8* xc_targetDataRawPtr = nullptr; - std::unique_ptr* xc_targetObjPtr = nullptr; - std::unique_ptr x10_loadBuffer; - u32 x14_resSize = UINT32_MAX; - u32 x14_resOffset = 0; - CVParamTransfer x18_cvXfer; - CObjectReference* m_selfRef = nullptr; - - hecl::ProjectPath m_workingPath; - hecl::ProjectPath m_cookedPath; - std::shared_ptr m_cookTransaction; - std::shared_ptr m_bufTransaction; - bool m_failed = false; - bool m_complete = false; - - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, std::unique_ptr& ptr) - : m_parent(parent), x0_tag(tag), xc_targetDataPtr(&ptr) {} - - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, std::unique_ptr& ptr, u32 size, u32 off) - : m_parent(parent), x0_tag(tag), xc_targetDataPtr(&ptr), x14_resSize(size), x14_resOffset(off) {} - - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, u8* ptr) - : m_parent(parent), x0_tag(tag), xc_targetDataRawPtr(ptr) {} - - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, u8* ptr, u32 size, u32 off) - : m_parent(parent), x0_tag(tag), xc_targetDataRawPtr(ptr), x14_resSize(size), x14_resOffset(off) {} - - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, std::unique_ptr* ptr, - const CVParamTransfer& xfer, CObjectReference* selfRef) - : m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {} - - /* Cook only */ - AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag) : m_parent(parent), x0_tag(tag) {} - - void EnsurePath(const metaforce::SObjectTag& tag, const hecl::ProjectPath& path); - void CookComplete(); - bool AsyncPump(); - void WaitUntilComplete() override; - bool IsComplete() override { return m_complete; } - void PostCancelRequest() override {} - EMediaType GetMediaType() const override { return EMediaType::Real; } - }; - -protected: - hecl::Database::Project* m_proj = nullptr; - const hecl::Database::DataSpecEntry* m_origSpec = nullptr; - const hecl::Database::DataSpecEntry* m_pcSpec = nullptr; - /* Used to resolve cooked paths */ - std::unique_ptr m_cookSpec; - metaforce::CFactoryMgr m_factoryMgr; - - std::list> m_asyncLoadList; - std::unordered_map>::iterator> m_asyncLoadMap; - std::shared_ptr _AddTask(const std::shared_ptr& ptr); - std::list>::iterator _RemoveTask(std::list>::iterator it); - std::unordered_map>::iterator>::iterator - _RemoveTask(std::unordered_map>::iterator>::iterator it); - std::unordered_map>::iterator>::iterator - _RemoveTask(const SObjectTag& tag); - - static AsyncTask& _GetAsyncTask(std::list>::iterator it) { return **it; } - static AsyncTask& - _GetAsyncTask(std::unordered_map>::iterator>::iterator it) { - return **it->second; - } - - bool PrepForReadSync(const SObjectTag& tag, const hecl::ProjectPath& path, - std::optional& fr); - - bool WaitForTagReady(const metaforce::SObjectTag& tag, const hecl::ProjectPath*& pathOut) { - return static_cast(*m_cookSpec).waitForTagReady(tag, pathOut); - } - SObjectTag TagFromPath(const hecl::ProjectPath& path) const { - return static_cast(*m_cookSpec).tagFromPath(path); - } - SObjectTag BuildTagFromPath(const hecl::ProjectPath& path) const { - return static_cast(*m_cookSpec).buildTagFromPath(path); - } - void GetTagListForFile(const char* pakName, std::vector& out) const override { - return static_cast(*m_cookSpec).getTagListForFile(pakName, out); - } - void CancelBackgroundIndex() { - if (m_cookSpec) - return static_cast(*m_cookSpec).cancelBackgroundIndex(); - } - void BeginBackgroundIndex(hecl::Database::Project& proj, const hecl::Database::DataSpecEntry& origSpec, - const hecl::Database::DataSpecEntry& pcSpec); - - bool SyncCook(const hecl::ProjectPath& working); - CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path, const CVParamTransfer& paramXfer, - CObjectReference* selfRef); - std::shared_ptr BuildAsyncInternal(const metaforce::SObjectTag&, const metaforce::CVParamTransfer&, - std::unique_ptr*, CObjectReference* selfRef); - -public: - ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {} - std::unique_ptr Build(const metaforce::SObjectTag&, const metaforce::CVParamTransfer&, - CObjectReference* selfRef) override; - void BuildAsync(const metaforce::SObjectTag&, const metaforce::CVParamTransfer&, std::unique_ptr*, - CObjectReference* selfRef) override; - void CancelBuild(const metaforce::SObjectTag&) override; - bool CanBuild(const metaforce::SObjectTag&) override; - const metaforce::SObjectTag* GetResourceIdByName(std::string_view) const override; - FourCC GetResourceTypeById(CAssetId id) const override; - hecl::ProjectPath GetCookedPath(const hecl::ProjectPath& working, bool pcTarget) const { - return static_cast(*m_cookSpec).getCookedPath(working, pcTarget); - } - - void EnumerateResources(const std::function& lambda) const override; - void EnumerateNamedResources(const std::function& lambda) const override; - - u32 ResourceSize(const SObjectTag& tag) override; - std::shared_ptr LoadResourceAsync(const metaforce::SObjectTag& tag, void* target) override; - std::shared_ptr LoadResourcePartAsync(const metaforce::SObjectTag& tag, u32 off, u32 size, - void* target) override; - std::unique_ptr LoadResourceSync(const metaforce::SObjectTag& tag) override; - std::unique_ptr LoadNewResourcePartSync(const metaforce::SObjectTag& tag, u32 off, u32 size) override; - - std::shared_ptr CookResourceAsync(const metaforce::SObjectTag& tag); - - template - bool AsyncPumpTask(ItType& it); - void AsyncIdle() override; - void Shutdown() { CancelBackgroundIndex(); } - bool IsBusy() const { return m_asyncLoadMap.size() != 0; } - - SObjectTag TagFromPath(hecl::SystemStringView path) const { return TagFromPath(hecl::ProjectPath(*m_proj, path)); } - - ~ProjectResourceFactoryBase() override { Shutdown(); } -}; - -} // namespace metaforce diff --git a/Editor/ProjectResourceFactoryMP1.cpp b/Editor/ProjectResourceFactoryMP1.cpp deleted file mode 100644 index e940a1345..000000000 --- a/Editor/ProjectResourceFactoryMP1.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "Editor/ProjectResourceFactoryMP1.hpp" - -#include "Runtime/CDependencyGroup.hpp" -#include "Runtime/CGameHintInfo.hpp" -#include "Runtime/CSaveWorld.hpp" -#include "Runtime/CSimplePool.hpp" -#include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/IOStreams.hpp" -#include "Runtime/Audio/CAudioGroupSet.hpp" -#include "Runtime/Audio/CMidiManager.hpp" -#include "Runtime/Audio/CSfxManager.hpp" -#include "Runtime/AutoMapper/CMapArea.hpp" -#include "Runtime/AutoMapper/CMapUniverse.hpp" -#include "Runtime/AutoMapper/CMapWorld.hpp" -#include "Runtime/CScannableObjectInfo.hpp" -#include "Runtime/Character/CAllFormatsAnimSource.hpp" -#include "Runtime/Character/CAnimCharacterSet.hpp" -#include "Runtime/Character/CAnimPOIData.hpp" -#include "Runtime/Character/CCharLayoutInfo.hpp" -#include "Runtime/Character/CSkinRules.hpp" -#include "Runtime/Collision/CCollidableOBBTreeGroup.hpp" -#include "Runtime/Collision/CCollisionResponseData.hpp" -#include "Runtime/Graphics/CModel.hpp" -#include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/GuiSys/CGuiFrame.hpp" -#include "Runtime/GuiSys/CRasterFont.hpp" -#include "Runtime/GuiSys/CStringTable.hpp" -#include "Runtime/Particle/CDecalDataFactory.hpp" -#include "Runtime/Particle/CElectricDescription.hpp" -#include "Runtime/Particle/CGenDescription.hpp" -#include "Runtime/Particle/CParticleDataFactory.hpp" -#include "Runtime/Particle/CParticleElectricDataFactory.hpp" -#include "Runtime/Particle/CParticleSwooshDataFactory.hpp" -#include "Runtime/Particle/CProjectileWeaponDataFactory.hpp" -#include "Runtime/Particle/CSwooshDescription.hpp" -#include "Runtime/Particle/CWeaponDescription.hpp" -#include "Runtime/World/CPathFindArea.hpp" - -#include "DataSpec/DNACommon/TXTR.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP1; -extern hecl::Database::DataSpecEntry SpecEntMP1PC; -} // namespace DataSpec - -namespace metaforce { - -ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc) -: ProjectResourceFactoryBase(clientProc) { - m_factoryMgr.AddFactory(FOURCC('TXTR'), FMemFactoryFunc(FTextureFactory)); - m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory)); - m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame)); - m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory)); - m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(FModelFactory)); - m_factoryMgr.AddFactory(FOURCC('CINF'), FFactoryFunc(FCharLayoutInfo)); - m_factoryMgr.AddFactory(FOURCC('CSKR'), FFactoryFunc(FSkinRulesFactory)); - m_factoryMgr.AddFactory(FOURCC('ANCS'), FFactoryFunc(FAnimCharacterSet)); - m_factoryMgr.AddFactory(FOURCC('ANIM'), FFactoryFunc(AnimSourceFactory)); - m_factoryMgr.AddFactory(FOURCC('EVNT'), FFactoryFunc(AnimPOIDataFactory)); - m_factoryMgr.AddFactory(FOURCC('DCLN'), FFactoryFunc(FCollidableOBBTreeGroupFactory)); - m_factoryMgr.AddFactory(FOURCC('DGRP'), FFactoryFunc(FDependencyGroupFactory)); - m_factoryMgr.AddFactory(FOURCC('AGSC'), FMemFactoryFunc(FAudioGroupSetDataFactory)); - m_factoryMgr.AddFactory(FOURCC('CSNG'), FFactoryFunc(FMidiDataFactory)); - m_factoryMgr.AddFactory(FOURCC('ATBL'), FFactoryFunc(FAudioTranslationTableFactory)); - m_factoryMgr.AddFactory(FOURCC('STRG'), FFactoryFunc(FStringTableFactory)); - m_factoryMgr.AddFactory(FOURCC('HINT'), FFactoryFunc(FHintFactory)); - m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory)); - m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory)); - m_factoryMgr.AddFactory(FOURCC('SCAN'), FFactoryFunc(FScannableObjectInfoFactory)); - m_factoryMgr.AddFactory(FOURCC('CRSC'), FFactoryFunc(FCollisionResponseDataFactory)); - m_factoryMgr.AddFactory(FOURCC('SWHC'), FFactoryFunc(FParticleSwooshDataFactory)); - m_factoryMgr.AddFactory(FOURCC('ELSC'), FFactoryFunc(FParticleElectricDataFactory)); - m_factoryMgr.AddFactory(FOURCC('WPSC'), FFactoryFunc(FProjectileWeaponDataFactory)); - m_factoryMgr.AddFactory(FOURCC('DPSC'), FFactoryFunc(FDecalDataFactory)); - m_factoryMgr.AddFactory(FOURCC('MAPA'), FFactoryFunc(FMapAreaFactory)); - m_factoryMgr.AddFactory(FOURCC('MAPU'), FFactoryFunc(FMapUniverseFactory)); - m_factoryMgr.AddFactory(FOURCC('PATH'), FMemFactoryFunc(FPathFindAreaFactory)); -} - -void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp) { - BeginBackgroundIndex(proj, DataSpec::SpecEntMP1, DataSpec::SpecEntMP1PC); -} - -} // namespace metaforce diff --git a/Editor/ProjectResourceFactoryMP1.hpp b/Editor/ProjectResourceFactoryMP1.hpp deleted file mode 100644 index be57121d3..000000000 --- a/Editor/ProjectResourceFactoryMP1.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Editor/ProjectResourceFactoryBase.hpp" -#include "Runtime/CToken.hpp" - -namespace metaforce { -class MP1OriginalIDs; -class CSimplePool; - -class ProjectResourceFactoryMP1 : public ProjectResourceFactoryBase { -public: - ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc); - void IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp); -}; - -} // namespace metaforce diff --git a/Editor/Resource.cpp b/Editor/Resource.cpp deleted file mode 100644 index e02d8ff7d..000000000 --- a/Editor/Resource.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "Resource.hpp" - -namespace metaforce { - -Space::Class Resource::DeduceDefaultSpaceClass(const hecl::ProjectPath& path) { - athena::io::FileReader r(path.getAbsolutePath(), 32 * 1024, false); - if (r.hasError()) - return Space::Class::None; - return Space::Class::None; -} - -} // namespace metaforce diff --git a/Editor/Resource.hpp b/Editor/Resource.hpp deleted file mode 100644 index 5385e19b8..000000000 --- a/Editor/Resource.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "hecl/Database.hpp" -#include "Space.hpp" - -namespace metaforce { - -/** Combines a ProjectPath with actively used Space references - * - * This class is intended to be heap-allocated in a hierarchical mapping, so the entire tree - * of resources is available in-memory to systems that need it. Refreshes of the index will - * continue to use existing allocations that haven't been deleted. - * - * The key purpose of this class is to centrally register observer-nodes for resources that - * are updated via editing, or external file changes. - */ -class Resource { -public: - using ProjectDataSpec = hecl::Database::Project::ProjectDataSpec; - -private: - hecl::ProjectPath m_path; - Space::Class m_defaultClass = Space::Class::None; - // EditorSpace* m_editingSpace = nullptr; - std::vector m_viewingSpaces; - -public: - static Space::Class DeduceDefaultSpaceClass(const hecl::ProjectPath& path); - explicit Resource(hecl::ProjectPath&& path) - : m_path(std::move(path)), m_defaultClass(DeduceDefaultSpaceClass(m_path)) {} - const hecl::ProjectPath& path() const { return m_path; } -}; - -/** Provides centralized hierarchical lookup and ownership of Resource nodes */ -class ResourceTree { -public: - struct Node { - std::map> m_subnodes; - std::map> m_resources; - }; - -private: - std::unique_ptr m_rootNode; -}; - -} // namespace metaforce diff --git a/Editor/ResourceBrowser.cpp b/Editor/ResourceBrowser.cpp deleted file mode 100644 index 5ce3f99e2..000000000 --- a/Editor/ResourceBrowser.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ResourceBrowser.hpp" - -namespace metaforce { -#define BROWSER_MARGIN 8 - -bool ResourceBrowser::navigateToPath(const hecl::ProjectPath& pathIn) { - if (pathIn.isFile()) - m_path = pathIn.getParentPath(); - else - m_path = pathIn; - - m_comps = m_path.getPathComponents(); - - hecl::DirectoryEnumerator dEnum( - m_path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, - m_state.sortColumn == State::SortColumn::Size, - m_state.sortDir == specter::SortDirection::Descending && - (m_state.sortColumn == State::SortColumn::Name || m_state.sortColumn == State::SortColumn::Size), - true); - m_resListingBind.updateListing(dEnum); - if (m_pathButtons) - m_pathButtons->setButtons(m_comps); - - if (m_view) { - m_view->m_resListing.m_view->selectRow(-1); - m_view->m_resListing.m_view->updateData(); - m_view->updateSize(); - } - - return true; -} - -void ResourceBrowser::pathButtonActivated(size_t idx) { - if (idx >= m_comps.size()) - return; - - hecl::SystemString dir; - bool needSlash = false; - size_t i = 0; - for (const hecl::SystemString& d : m_comps) { - if (needSlash) - dir += _SYS_STR('/'); - if (d != _SYS_STR("/")) - needSlash = true; - dir += d; - if (++i > idx) - break; - } - navigateToPath(hecl::ProjectPath(*m_vm.project(), dir)); -} - -void ResourceBrowser::View::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - m_resListing.mouseDown(coord, button, mod); -} - -void ResourceBrowser::View::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - m_resListing.mouseUp(coord, button, mod); -} - -void ResourceBrowser::View::mouseMove(const boo::SWindowCoord& coord) { m_resListing.mouseMove(coord); } - -void ResourceBrowser::View::mouseLeave(const boo::SWindowCoord& coord) { m_resListing.mouseLeave(coord); } - -void ResourceBrowser::View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { - specter::View::resized(root, sub); - m_resListing.m_view->resized(root, sub); -} -void ResourceBrowser::View::draw(boo::IGraphicsCommandQueue* gfxQ) { m_resListing.m_view->draw(gfxQ); } - -} // namespace metaforce diff --git a/Editor/ResourceBrowser.hpp b/Editor/ResourceBrowser.hpp deleted file mode 100644 index bb3f24fee..000000000 --- a/Editor/ResourceBrowser.hpp +++ /dev/null @@ -1,205 +0,0 @@ -#pragma once - -#include "Space.hpp" -#include "ViewManager.hpp" -#include "specter/PathButtons.hpp" -#include "specter/Table.hpp" - -namespace metaforce { - -class ResourceBrowser : public Space, public specter::IPathButtonsBinding { - struct State : Space::State { - AT_DECL_DNA_YAMLV - String<-1> path; - Value columnSplits[3] = {0.0f, 0.7f, 0.9f}; - enum class SortColumn { Name, Type, Size }; - Value sortColumn = SortColumn::Name; - Value sortDir = specter::SortDirection::Ascending; - } m_state; - const Space::State& spaceState() const override { return m_state; } - - hecl::ProjectPath m_path; - std::vector m_comps; - - void pathButtonActivated(size_t idx) override; - - struct ResListingDataBind : specter::ITableDataBinding, specter::ITableStateBinding { - ResourceBrowser& m_rb; - - struct Entry { - hecl::SystemString m_path; - std::string m_name; - std::string m_type; - std::string m_size; - }; - std::vector m_entries; - - std::string m_nameCol; - std::string m_typeCol; - std::string m_sizeCol; - - std::string m_dirStr; - std::string m_projStr; - std::string m_fileStr; - - size_t columnCount() const override { return 3; } - size_t rowCount() const override { return m_entries.size(); } - - std::string_view header(size_t cIdx) const override { - switch (cIdx) { - case 0: - return m_nameCol; - case 1: - return m_typeCol; - case 2: - return m_sizeCol; - default: - break; - } - return {}; - } - - std::string_view cell(size_t cIdx, size_t rIdx) const override { - switch (cIdx) { - case 0: - return m_entries.at(rIdx).m_name; - case 1: - return m_entries.at(rIdx).m_type; - case 2: - return m_entries.at(rIdx).m_size; - default: - break; - } - return {}; - } - - bool columnSplitResizeAllowed() const override { return true; } - - float getColumnSplit(size_t cIdx) const override { return m_rb.m_state.columnSplits[cIdx]; } - - void setColumnSplit(size_t cIdx, float split) override { m_rb.m_state.columnSplits[cIdx] = split; } - - void updateListing(const hecl::DirectoryEnumerator& dEnum) { - m_entries.clear(); - m_entries.reserve(dEnum.size()); - - for (const hecl::DirectoryEnumerator::Entry& d : dEnum) { - m_entries.emplace_back(); - Entry& ent = m_entries.back(); - ent.m_path = d.m_path; - hecl::SystemUTF8Conv nameUtf8(d.m_name); - ent.m_name = nameUtf8.str(); - if (d.m_isDir) { - if (hecl::SearchForProject(d.m_path)) - ent.m_type = m_projStr; - else - ent.m_type = m_dirStr; - } else { - ent.m_type = m_fileStr; - ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale), - hecl::HNFlags::B | hecl::HNFlags::Decimal); - } - } - - m_needsUpdate = false; - } - - bool m_needsUpdate = false; - - specter::SortDirection getSort(size_t& cIdx) const override { - cIdx = size_t(m_rb.m_state.sortColumn); - if (cIdx > 2) - cIdx = 0; - return m_rb.m_state.sortDir; - } - - void setSort(size_t cIdx, specter::SortDirection dir) override { - m_rb.m_state.sortDir = dir; - m_rb.m_state.sortColumn = State::SortColumn(cIdx); - m_needsUpdate = true; - } - - void setSelectedRow(size_t rIdx) override {} - - void rowActivated(size_t rIdx) override {} - - ResListingDataBind(ResourceBrowser& rb, const specter::IViewManager& vm) : m_rb(rb) { - m_nameCol = vm.translate(); - m_typeCol = vm.translate(); - m_sizeCol = vm.translate(); - m_dirStr = vm.translate(); - m_projStr = vm.translate(); - m_fileStr = vm.translate(); - } - - } m_resListingBind; - - struct View : specter::View { - ResourceBrowser& m_ro; - specter::ViewChild> m_resListing; - - View(ResourceBrowser& ro, specter::ViewResources& res) : specter::View(res, ro.m_vm.rootView()), m_ro(ro) { - m_resListing.m_view.reset(new specter::Table(res, *this, &ro.m_resListingBind, &ro.m_resListingBind, 3)); - } - - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseMove(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) override; - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - }; - std::unique_ptr m_view; - - std::unique_ptr m_pathButtons; - -public: - ResourceBrowser(ViewManager& vm, Space* parent) - : Space(vm, Class::ResourceBrowser, parent), m_resListingBind(*this, vm) { - reloadState(); - } - ResourceBrowser(ViewManager& vm, Space* parent, const ResourceBrowser& other) : ResourceBrowser(vm, parent) { - m_state = other.m_state; - reloadState(); - } - ResourceBrowser(ViewManager& vm, Space* parent, ConfigReader& r) : ResourceBrowser(vm, parent) { - m_state.read(r); - reloadState(); - } - - void reloadState() override { - hecl::ProjectPath pp(*m_vm.project(), m_state.path); - if (m_state.path.empty() || pp.isNone()) { - m_state.path = m_vm.project()->getProjectWorkingPath().getRelativePathUTF8(); - navigateToPath(hecl::ProjectPath(*m_vm.project(), m_state.path)); - } else - navigateToPath(pp); - } - - void think() override { - if (m_resListingBind.m_needsUpdate) - reloadState(); - } - - bool navigateToPath(const hecl::ProjectPath& path); - - Space* copy(Space* parent) const override { return new ResourceBrowser(m_vm, parent, *this); } - - void buildToolbarView(specter::ViewResources& res, specter::Toolbar& tb) override { - m_pathButtons.reset(new specter::PathButtons(res, tb, *this, true)); - tb.push_back(m_pathButtons.get(), 1); - reloadState(); - } - - specter::View* buildContentView(specter::ViewResources& res) override { - m_view.reset(new View(*this, res)); - return m_view.get(); - } - - bool usesToolbar() const override { return true; } - - unsigned toolbarUnits() const override { return 2; } -}; - -} // namespace metaforce diff --git a/Editor/Space.cpp b/Editor/Space.cpp deleted file mode 100644 index 213da9762..000000000 --- a/Editor/Space.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "Space.hpp" -#include "ViewManager.hpp" -#include "ResourceBrowser.hpp" -#include "ParticleEditor.hpp" -#include "ModelViewer.hpp" -#include "InformationCenter.hpp" -#include "GameMode.hpp" -#include "icons/icons.hpp" -#include "specter/Menu.hpp" - -namespace metaforce { -static logvisor::Module Log("URDE::Space"); - -Space::Space(ViewManager& vm, Class cls, Space* parent) -: m_spaceMenuNode(*this), m_spaceSelectBind(*this), m_vm(vm), m_class(cls), m_parent(parent) {} - -specter::View* Space::buildSpaceView(specter::ViewResources& res) { - if (usesToolbar()) { - m_spaceView.reset( - new specter::Space(res, *m_parent->basisView(), *this, specter::Toolbar::Position::Bottom, toolbarUnits())); - specter::View* sview = buildContentView(res); - m_spaceView->setContentView(sview); - specter::Toolbar& tb = *m_spaceView->toolbar(); - specter::Icon* classIcon = SpaceMenuNode::LookupClassIcon(m_class); - const zeus::CColor* classColor = SpaceMenuNode::LookupClassColor(m_class); - m_spaceSelectButton.reset(new specter::Button(res, tb, &m_spaceSelectBind, "", classIcon, - specter::Button::Style::Block, - classColor ? *classColor : zeus::skWhite)); - tb.push_back(m_spaceSelectButton.get(), 0); - buildToolbarView(res, tb); - return m_spaceView.get(); - } else { - m_spaceView.reset(new specter::Space(res, *m_parent->basisView(), *this, specter::Toolbar::Position::None, 0)); - specter::View* sview = buildContentView(res); - m_spaceView->setContentView(sview); - return m_spaceView.get(); - } -} - -std::vector Space::SpaceMenuNode::s_subNodeDats = { - {Class::ResourceBrowser, - "Resource Browser", - GetIcon(SpaceIcon::ResourceBrowser), - {0.0f, 1.0f, 0.0f, 1.0f}}, - {Class::EffectEditor, - "Effect Editor", - GetIcon(SpaceIcon::ParticleEditor), - {1.0f, 0.5f, 0.0f, 1.0f}}, - {Class::ModelViewer, "Model Viewer", GetIcon(SpaceIcon::ModelViewer), {0.95f, 0.95f, 0.95f, 1.0f}}, - {Class::InformationCenter, - "Information Center", - GetIcon(SpaceIcon::InformationCenter), - {0.0f, 1.0f, 1.0f, 1.0f}}, - {Class::GameMode, "Game Mode", GetIcon(SpaceIcon::GameMode), {}}}; -std::string Space::SpaceMenuNode::s_text = "Space Types"; - -template -static void RecurseTranslations(ViewManager& vm, std::vector::iterator it) { - it->m_text = vm.translate(); -} - -template -static void RecurseTranslations(ViewManager& vm, std::vector::iterator it) { - RecurseTranslations(vm, it); - RecurseTranslations(vm, ++it); -} - -void Space::SpaceMenuNode::InitializeStrings(ViewManager& vm) { - s_text = vm.translate(); - RecurseTranslations(vm, s_subNodeDats.begin()); -} - -std::unique_ptr Space::SpaceSelectBind::buildMenu(const specter::Button* button) { - return std::unique_ptr( - new specter::Menu(m_space.m_vm.rootView().viewRes(), *m_space.m_spaceView, &m_space.m_spaceMenuNode)); -} - -specter::View* RootSpace::buildSpaceView(specter::ViewResources& res) { - specter::View* newRoot = buildContentView(res); - m_vm.RootSpaceViewBuilt(newRoot); - return newRoot; -} - -specter::View* RootSpace::basisView() { return &m_vm.rootView(); } - -specter::View* SplitSpace::buildContentView(specter::ViewResources& res) { - int clearance = res.pixelFactor() * SPECTER_TOOLBAR_GAUGE; - m_splitView.reset( - new specter::SplitView(res, *m_parent->basisView(), this, m_state.axis, m_state.split, clearance, clearance)); - if (m_slots[0]) - m_splitView->setContentView(0, m_slots[0]->buildSpaceView(res)); - if (m_slots[1]) - m_splitView->setContentView(1, m_slots[1]->buildSpaceView(res)); - return m_splitView.get(); -} - -void SplitSpace::setChildSlot(unsigned slot, std::unique_ptr&& space) { - if (slot > 1) - Log.report(logvisor::Fatal, FMT_STRING("invalid slot {} for SplitView"), slot); - m_slots[slot] = std::move(space); - m_slots[slot]->m_parent = this; -} - -void SplitSpace::joinViews(specter::SplitView* thisSplit, int thisSlot, specter::SplitView* otherSplit, int otherSlot) { - if (thisSplit == otherSplit) { - SplitSpace* thisSS = m_slots[thisSlot]->castToSplitSpace(); - if (thisSS) { - int ax = thisSS->m_state.axis == specter::SplitView::Axis::Horizontal ? 1 : 0; - const boo::SWindowRect& thisRect = m_splitView->subRect(); - const boo::SWindowRect& subRect = thisSS->m_splitView->subRect(); - int splitPx = subRect.location[ax] + subRect.size[ax] * thisSS->m_state.split - thisRect.location[ax]; - thisSS->m_state.split = splitPx / float(thisRect.size[ax]); - } - m_parent->exchangeSpaceSplitJoin(this, std::move(m_slots[thisSlot])); - m_vm.BuildSpaceViews(); - } else { - for (int i = 0; i < 2; ++i) { - SplitSpace* otherSS = m_slots[i]->castToSplitSpace(); - if (otherSS && otherSS->m_splitView.get() == otherSplit) { - int ax = m_state.axis == specter::SplitView::Axis::Horizontal ? 1 : 0; - const boo::SWindowRect& thisRect = m_splitView->subRect(); - const boo::SWindowRect& subRect = otherSS->m_splitView->subRect(); - int splitPx = subRect.location[ax] + subRect.size[ax] * otherSS->m_state.split - thisRect.location[ax]; - m_state.split = splitPx / float(thisRect.size[ax]); - exchangeSpaceSplitJoin(otherSS, std::move(otherSS->m_slots[otherSlot ^ 1])); - m_vm.BuildSpaceViews(); - break; - } - } - } -} - -specter::ISplitSpaceController* Space::spaceSplit(specter::SplitView::Axis axis, int thisSlot) { - if (m_parent) { - /* Reject split operations with insufficient clearance */ - int clearance = m_vm.m_viewResources.pixelFactor() * SPECTER_TOOLBAR_GAUGE; - if (axis == specter::SplitView::Axis::Horizontal) { - if (m_spaceView->subRect().size[1] <= clearance) - return nullptr; - } else { - if (m_spaceView->subRect().size[0] <= clearance) - return nullptr; - } - - SplitSpace* ss = new SplitSpace(m_vm, m_parent, axis); - ss->setChildSlot(thisSlot, m_parent->exchangeSpaceSplitJoin(this, std::unique_ptr(ss))); - ss->setChildSlot(thisSlot ^ 1, std::unique_ptr(copy(ss))); - m_vm.BuildSpaceViews(); - return ss; - } - return nullptr; -} - -std::unique_ptr RootSpace::exchangeSpaceSplitJoin(Space* removeSpace, std::unique_ptr&& keepSpace) { - std::unique_ptr ret = std::move(keepSpace); - - if (removeSpace == m_spaceTree.get()) { - m_spaceTree.swap(ret); - m_spaceTree->m_parent = this; - } else - Log.report(logvisor::Fatal, FMT_STRING("RootSpace::exchangeSpaceSplitJoin() failure")); - - return ret; -} - -std::unique_ptr SplitSpace::exchangeSpaceSplitJoin(Space* removeSpace, std::unique_ptr&& keepSpace) { - std::unique_ptr ret = std::move(keepSpace); - - if (removeSpace == m_slots[0].get()) { - m_slots[0].swap(ret); - m_slots[0]->m_parent = this; - } else if (removeSpace == m_slots[1].get()) { - m_slots[1].swap(ret); - m_slots[1]->m_parent = this; - } else - Log.report(logvisor::Fatal, FMT_STRING("SplitSpace::exchangeSpaceSplitJoin() failure")); - - return ret; -} - -template -static Space* BuildNewSpace(ViewManager& vm, Space::Class cls, Space* parent, Reader& r) { - using Class = Space::Class; - switch (cls) { - case Class::SplitSpace: - return new SplitSpace(vm, parent, r); - case Class::ResourceBrowser: - return new ResourceBrowser(vm, parent, r); - case Class::EffectEditor: - return new EffectEditor(vm, parent, r); - case Class::ModelViewer: - return new ModelViewer(vm, parent, r); - case Class::InformationCenter: - return new InformationCenter(vm, parent, r); - case Class::GameMode: - return new GameMode(vm, parent, r); - default: - break; - } - return nullptr; -} - -void Space::saveState(athena::io::IStreamWriter& w) const { - w.writeUint32Big(atUint32(m_class)); - spaceState().write(w); -} - -void Space::saveState(athena::io::YAMLDocWriter& w) const { - w.writeUint32("class", atUint32(m_class)); - spaceState().write(w); -} - -Space* Space::NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigReader& r) { - Class cls = Class(r.readUint32("class")); - return BuildNewSpace(vm, cls, parent, r); -} - -RootSpace* Space::NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r) { - Class cls = Class(r.readUint32("class")); - if (cls != Class::RootSpace) - return nullptr; - return new RootSpace(vm, r); -} - -void Space::SpaceMenuNode::SubNode::activated(const boo::SWindowCoord& coord) { - std::unique_ptr newSpace; - switch (m_data.m_cls) { - case Class::InformationCenter: - if (m_space.cls() == Class::InformationCenter) - newSpace.reset(new InformationCenter(m_space.m_parent->m_vm, m_space.m_parent)); - break; - case Class::EffectEditor: - if (m_space.cls() == Class::EffectEditor) - newSpace.reset(new EffectEditor(m_space.m_parent->m_vm, m_space.m_parent)); - break; - case Class::ResourceBrowser: - if (m_space.cls() == Class::ResourceBrowser) - newSpace.reset(new ResourceBrowser(m_space.m_parent->m_vm, m_space.m_parent)); - break; - case Class::ModelViewer: - if (m_space.cls() == Class::ModelViewer) - newSpace.reset(new ModelViewer(m_space.m_parent->m_vm, m_space.m_parent)); - break; - case Class::GameMode: - if (m_space.cls() == Class::GameMode) - newSpace.reset(new GameMode(m_space.m_parent->m_vm, m_space.m_parent)); - break; - default: - break; - } - if (newSpace) { - Space* parent = m_space.m_parent; - m_space.m_parent->exchangeSpaceSplitJoin(&m_space, std::move(newSpace)); - parent->m_vm.BuildSpaceViews(); - } -} - -} // namespace metaforce diff --git a/Editor/Space.hpp b/Editor/Space.hpp deleted file mode 100644 index 4f6b49aae..000000000 --- a/Editor/Space.hpp +++ /dev/null @@ -1,378 +0,0 @@ -#pragma once - -#include "athena/DNAYaml.hpp" -#include "specter/Space.hpp" -#include "specter/IMenuNode.hpp" -#include "specter/Button.hpp" -#include "specter/MultiLineTextView.hpp" -#include "specter/ViewResources.hpp" -#include "specter/RootView.hpp" -#include "ProjectManager.hpp" - -namespace specter { -class View; -class SplitView; -class ViewResources; -class Toolbar; -struct Icon; -} // namespace specter -namespace metaforce { -class ViewManager; -class RootSpace; -class SplitSpace; - -class Space : public specter::ISpaceController { - friend class SplitSpace; - -public: - virtual ~Space() = default; - Space(const Space& other) = delete; - Space& operator=(const Space& other) = delete; - - /** Common encoded-enumeration for all space classes */ - enum class Class { - None, - RootSpace, - SplitSpace, - TestSpace, - ResourceBrowser, - ModelViewer, - EffectEditor, - InformationCenter, - GameMode - }; - - struct State : athena::io::DNAVYaml { - Delete _d; - }; - static Space* NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigReader& r); - static RootSpace* NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r); - - struct SpaceMenuNode final : specter::IMenuNode { - struct SubNodeData final : specter::IMenuNode { - Class m_cls; - std::string m_text; - specter::Icon& m_icon; - zeus::CColor m_color; - const std::string* text() const override { return &m_text; } - void activated(const boo::SWindowCoord& coord) override {} - - SubNodeData(Class cls, const char* text, specter::Icon& icon, const zeus::CColor& color) - : m_cls(cls), m_text(text), m_icon(icon), m_color(color) {} - }; - static std::vector s_subNodeDats; - - struct SubNode final : specter::IMenuNode { - Space& m_space; - const SubNodeData& m_data; - const std::string* text() const override { return &m_data.m_text; } - void activated(const boo::SWindowCoord& coord) override; - - SubNode(Space& space, const SubNodeData& data) : m_space(space), m_data(data) {} - }; - std::vector m_subNodes; - - SpaceMenuNode(Space& space) { - m_subNodes.reserve(s_subNodeDats.size()); - for (const SubNodeData& sn : s_subNodeDats) - m_subNodes.emplace_back(space, sn); - } - - static std::string s_text; - const std::string* text() const override { return &s_text; } - - size_t subNodeCount() const override { return m_subNodes.size(); } - IMenuNode* subNode(size_t idx) override { return &m_subNodes[idx]; } - - static void InitializeStrings(ViewManager& vm); - static const std::string* LookupClassString(Class cls) { - for (const SubNodeData& sn : s_subNodeDats) - if (sn.m_cls == cls) - return &sn.m_text; - return nullptr; - } - static specter::Icon* LookupClassIcon(Class cls) { - for (SubNodeData& sn : s_subNodeDats) - if (sn.m_cls == cls) - return &sn.m_icon; - return nullptr; - } - static const zeus::CColor* LookupClassColor(Class cls) { - for (SubNodeData& sn : s_subNodeDats) - if (sn.m_cls == cls) - return &sn.m_color; - return nullptr; - } - } m_spaceMenuNode; - - struct SpaceSelectBind : specter::IButtonBinding { - Space& m_space; - std::string_view name(const specter::Control* control) const override { return SpaceMenuNode::s_text; } - - MenuStyle menuStyle(const specter::Button* button) const override { return MenuStyle::Primary; } - std::unique_ptr buildMenu(const specter::Button* button) override; - - SpaceSelectBind(Space& space) : m_space(space) {} - } m_spaceSelectBind; - std::unique_ptr m_spaceSelectButton; - -protected: - friend class ViewManager; - friend class RootSpace; - ViewManager& m_vm; - Class m_class = Class::None; - Space* m_parent; - std::unique_ptr m_spaceView; - Space(ViewManager& vm, Class cls, Space* parent); - - /* Allows common Space code to access DNA-encoded state */ - virtual const Space::State& spaceState() const = 0; - - /* Structural control */ - virtual bool usesToolbar() const { return false; } - virtual unsigned toolbarUnits() const { return 1; } - virtual void buildToolbarView(specter::ViewResources& res, specter::Toolbar& tb) {} - virtual specter::View* buildContentView(specter::ViewResources& res) = 0; - virtual specter::View* buildSpaceView(specter::ViewResources& res); - -public: - virtual void saveState(athena::io::IStreamWriter& w) const; - virtual void saveState(athena::io::YAMLDocWriter& w) const; - virtual void reloadState() {} - - virtual void think() {} - - virtual Space* copy(Space* parent) const = 0; - bool spaceSplitAllowed() const override { return true; } - - specter::ISplitSpaceController* spaceSplit(specter::SplitView::Axis axis, int thisSlot) override; - virtual std::unique_ptr exchangeSpaceSplitJoin(Space* removeSpace, std::unique_ptr&& keepSpace) { - return std::unique_ptr(); - } - - virtual specter::View* basisView() { return m_spaceView.get(); } - Class cls() const { return m_class; } - SplitSpace* castToSplitSpace(); -}; - -class RootSpace : public Space { - friend class ViewManager; - std::unique_ptr m_rootView; - std::unique_ptr m_spaceTree; - - struct State : Space::State{AT_DECL_DNA_YAMLV } m_state; - const Space::State& spaceState() const override { return m_state; } - -public: - RootSpace(ViewManager& vm) : Space(vm, Class::RootSpace, nullptr) {} - RootSpace(ViewManager& vm, ConfigReader& r) : RootSpace(vm) { - m_state.read(r); - if (auto rec = r.enterSubRecord("spaceTree")) - m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r)); - } - - void think() override { - OPTICK_EVENT(); - if (m_spaceTree) - m_spaceTree->think(); - } - - void saveState(athena::io::IStreamWriter& w) const override { - w.writeUint32Big(atUint32(m_class)); - m_state.write(w); - - if (m_spaceTree) - m_spaceTree->saveState(w); - else - w.writeUint32Big(0); - } - - void saveState(athena::io::YAMLDocWriter& w) const override { - w.writeUint32("class", atUint32(m_class)); - m_state.write(w); - - if (auto rec = w.enterSubRecord("spaceTree")) { - if (m_spaceTree) - m_spaceTree->saveState(w); - else - w.writeUint32("class", 0); - } - } - - void setChild(std::unique_ptr&& space) { - m_spaceTree = std::move(space); - m_spaceTree->m_parent = this; - } - - Space* copy(Space* parent) const override { return nullptr; } - bool spaceSplitAllowed() const override { return false; } - - specter::View* buildSpaceView(specter::ViewResources& res) override; - specter::View* buildContentView(specter::ViewResources& res) override { return m_spaceTree->buildSpaceView(res); } - - std::unique_ptr exchangeSpaceSplitJoin(Space* removeSpace, std::unique_ptr&& keepSpace) override; - - specter::View* basisView() override; -}; - -class SplitSpace : public Space, public specter::ISplitSpaceController { - friend class ViewManager; - std::unique_ptr m_slots[2]; - std::unique_ptr m_splitView; - struct State : Space::State { - AT_DECL_DNA_YAMLV - Value axis = specter::SplitView::Axis::Horizontal; - Value split = 0.5; - } m_state; - const Space::State& spaceState() const override { return m_state; } - -public: - SplitSpace(ViewManager& vm, Space* parent, specter::SplitView::Axis axis) : Space(vm, Class::SplitSpace, parent) { - m_state.axis = axis; - reloadState(); - } - SplitSpace(ViewManager& vm, Space* parent, ConfigReader& r) - : SplitSpace(vm, parent, specter::SplitView::Axis::Horizontal) { - m_state.read(r); - if (auto rec = r.enterSubRecord("slot0")) - m_slots[0].reset(NewSpaceFromConfigStream(vm, this, r)); - if (auto rec = r.enterSubRecord("slot1")) - m_slots[1].reset(NewSpaceFromConfigStream(vm, this, r)); - reloadState(); - } - - void reloadState() override { - m_state.split = std::min(1.f, std::max(0.f, m_state.split)); - if (m_state.axis != specter::SplitView::Axis::Horizontal && m_state.axis != specter::SplitView::Axis::Vertical) - m_state.axis = specter::SplitView::Axis::Horizontal; - if (m_splitView) { - m_splitView->setSplit(m_state.split); - m_splitView->setAxis(m_state.axis); - } - } - - void think() override { - if (m_slots[0]) - m_slots[0]->think(); - if (m_slots[1]) - m_slots[1]->think(); - } - - void saveState(athena::io::IStreamWriter& w) const override { - w.writeUint32Big(atUint32(m_class)); - m_state.write(w); - - if (m_slots[0]) - m_slots[0]->saveState(w); - else - w.writeUint32Big(0); - - if (m_slots[1]) - m_slots[1]->saveState(w); - else - w.writeUint32Big(0); - } - - void saveState(athena::io::YAMLDocWriter& w) const override { - w.writeUint32("class", atUint32(m_class)); - m_state.write(w); - - if (auto rec = w.enterSubRecord("slot0")) { - if (m_slots[0]) - m_slots[0]->saveState(w); - else - w.writeUint32("class", 0); - } - - if (auto rec = w.enterSubRecord("slot1")) { - if (m_slots[1]) - m_slots[1]->saveState(w); - else - w.writeUint32("class", 0); - } - } - - void setChildSlot(unsigned slot, std::unique_ptr&& space); - - specter::View* buildSpaceView(specter::ViewResources& res) override { return buildContentView(res); } - specter::View* buildContentView(specter::ViewResources& res) override; - - Space* copy(Space* parent) const override { return nullptr; } - bool spaceSplitAllowed() const override { return false; } - - ISpaceController* spaceJoin(int keepSlot) { - if (m_parent) { - ISpaceController* ret = m_slots[keepSlot].get(); - m_parent->exchangeSpaceSplitJoin(this, std::move(m_slots[keepSlot])); - return ret; - } - return nullptr; - } - - std::unique_ptr exchangeSpaceSplitJoin(Space* removeSpace, std::unique_ptr&& keepSpace) override; - - specter::SplitView* splitView() override { return m_splitView.get(); } - void updateSplit(float split) override { m_state.split = split; } - void joinViews(specter::SplitView* thisSplit, int thisSlot, specter::SplitView* otherSplit, int otherSlot) override; - - void setAxis(specter::SplitView::Axis axis) { - m_state.axis = axis; - reloadState(); - } - - specter::SplitView::Axis axis() const { return m_state.axis; } - float split() const { return m_state.split; } - - specter::View* basisView() override { return m_splitView.get(); } -}; -inline SplitSpace* Space::castToSplitSpace() { - return cls() == Class::SplitSpace ? static_cast(this) : nullptr; -} - -class ViewerSpace : public Space { -public: - ViewerSpace(ViewManager& vm, Class cls, Space* parent) : Space(vm, cls, parent) {} -}; - -class EditorSpace : public Space { -public: - EditorSpace(ViewManager& vm, Class cls, Space* parent) : Space(vm, cls, parent) {} -}; - -class GameSpace : public Space { -public: - GameSpace(ViewManager& vm, Class cls, Space* parent) : Space(vm, cls, parent) {} -}; - -class TestSpace : public Space { - std::unique_ptr m_button; - std::unique_ptr m_textView; - - std::string m_contentStr; - std::string m_buttonStr; - - specter::IButtonBinding* m_binding; - -public: - TestSpace(ViewManager& vm, Space* parent, std::string_view content, std::string_view button, - specter::IButtonBinding* binding) - : Space(vm, Class::TestSpace, parent), m_contentStr(content), m_buttonStr(button), m_binding(binding) {} - - struct State : Space::State{AT_DECL_DNA_YAMLV} m_state; - const Space::State& spaceState() const override { return m_state; } - - bool usesToolbar() const override { return true; } - void buildToolbarView(specter::ViewResources& res, specter::Toolbar& tb) override { - m_button.reset(new specter::Button(res, tb, m_binding, m_buttonStr)); - tb.push_back(m_button.get(), 0); - } - - specter::View* buildContentView(specter::ViewResources& res) override { - m_textView.reset(new specter::MultiLineTextView(res, *m_spaceView, res.m_heading14)); - m_textView->setBackground(res.themeData().viewportBackground()); - m_textView->typesetGlyphs(m_contentStr, res.themeData().uiText()); - return m_textView.get(); - } -}; - -} // namespace metaforce diff --git a/Editor/SplashScreen.cpp b/Editor/SplashScreen.cpp deleted file mode 100644 index a38120d23..000000000 --- a/Editor/SplashScreen.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "SplashScreen.hpp" -#include "version.h" -#include "badging/Badging.hpp" - -namespace metaforce { - -#define SPLASH_WIDTH 555 -#define SPLASH_HEIGHT 100 - -#define WIRE_START 0 -#define WIRE_FRAMES 60 -#define SOLID_START 40 -#define SOLID_FRAMES 40 -#define TEXT_START 80 -#define TEXT_FRAMES 40 - -#define LINE_WIDTH 2 -#define TEXT_MARGIN 10 - -SplashScreen::SplashScreen(ViewManager& vm, specter::ViewResources& res) -: ModalWindow(res, vm.rootView(), - specter::RectangleConstraint(SPLASH_WIDTH * res.pixelFactor(), SPLASH_HEIGHT * res.pixelFactor())) -, m_vm(vm) -, m_textColor(res.themeData().uiText()) { - if (METAFORCE_WC_DATE[0] != '\0' && METAFORCE_WC_REVISION[0] != '\0' && METAFORCE_WC_BRANCH[0] != '\0') { - m_buildInfoStr = fmt::format(FMT_STRING("{}: {}\n{}: {}\n{}: {}"), - vm.translate(), METAFORCE_WC_DESCRIBE, - vm.translate(), METAFORCE_WC_BRANCH, - vm.translate(), METAFORCE_WC_REVISION/*, - vm.translate(), METAFORCE_WC_DATE*/); - } -} - -void SplashScreen::think() { - if (phase() == Phase::Done) { - return; - } - OPTICK_EVENT(); - - ModalWindow::think(); -} - -void SplashScreen::updateContentOpacity(float opacity) { - specter::ViewResources& res = rootView().viewRes(); - - if (!m_title && res.fontCacheReady()) { - m_title.reset(new specter::TextView(res, *this, res.m_titleFont)); - zeus::CColor clearColor = res.themeData().uiText(); - clearColor[3] = 0.0; - m_title->typesetGlyphs("Metaforce", clearColor); - - m_buildInfo.reset(new specter::MultiLineTextView(res, *this, res.m_mainFont, specter::TextView::Alignment::Right)); - m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor); - - m_badgeText.reset(new specter::TextView(res, *this, res.m_heading18)); - m_badgeText->typesetGlyphs(BADGE_PHRASE, clearColor); - - m_infoStr = std::make_unique(res, *this, res.m_mainFont); - m_infoStr->typesetGlyphs("No game detected. Use metaforce-gui or check README for command-line options."sv, clearColor); - - updateSize(); - } - - zeus::CColor clearColor = res.themeData().uiText(); - clearColor[3] = 0.0; - zeus::CColor color = zeus::CColor::lerp(clearColor, res.themeData().uiText(), opacity); - m_title->colorGlyphs(color); - m_buildInfo->colorGlyphs(color); - m_badgeText->colorGlyphs(color); - m_infoStr->colorGlyphs(color); -} - -void SplashScreen::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { - ModalWindow::resized(root, sub); - float pf = rootView().viewRes().pixelFactor(); - - boo::SWindowRect centerRect = subRect(); - centerRect.location[0] = root.size[0] / 2 - (SPLASH_WIDTH * pf / 2.0); - centerRect.location[1] = root.size[1] / 2 - (SPLASH_HEIGHT * pf / 2.0); - - boo::SWindowRect textRect = centerRect; - textRect.location[0] += TEXT_MARGIN * pf; - textRect.location[1] += (SPLASH_HEIGHT - 28) * pf; - if (m_title) { - m_title->resized(root, textRect); - - textRect.location[1] -= m_title->nominalHeight() * 0.75; - m_badgeText->resized(root, textRect); - - textRect.location[0] = centerRect.location[0] + (SPLASH_WIDTH - TEXT_MARGIN) * pf; - textRect.location[1] = centerRect.location[1] + (SPLASH_HEIGHT - 36) * pf - 5 * pf; - m_buildInfo->resized(root, textRect); - - textRect.size[0] = m_infoStr->nominalWidth(); - textRect.size[1] = m_infoStr->nominalHeight(); - textRect.location[1] = centerRect.location[1] + 20 * pf; - textRect.location[0] = centerRect.location[0] + SPLASH_WIDTH * 2 / 4 * pf - m_infoStr->nominalWidth() / 2; - m_infoStr->resized(root, textRect); - } -} - -void SplashScreen::draw(boo::IGraphicsCommandQueue* gfxQ) { - if (phase() == Phase::Done) - return; - ModalWindow::draw(gfxQ); - - if (m_title) { - m_title->draw(gfxQ); - m_buildInfo->draw(gfxQ); - m_badgeText->draw(gfxQ); - m_infoStr->draw(gfxQ); - } -} - -} // namespace metaforce diff --git a/Editor/SplashScreen.hpp b/Editor/SplashScreen.hpp deleted file mode 100644 index c23b9bccf..000000000 --- a/Editor/SplashScreen.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "specter/View.hpp" -#include "specter/ModalWindow.hpp" -#include "specter/MultiLineTextView.hpp" -#include "specter/FileBrowser.hpp" -#include "specter/Menu.hpp" -#include "specter/Icon.hpp" - -#include "ViewManager.hpp" - -namespace metaforce { -static logvisor::Module Log("specter::SplashScreen"); - -class SplashScreen : public specter::ModalWindow { - ViewManager& m_vm; - - zeus::CColor m_textColor; - - std::unique_ptr m_title; - std::string m_buildInfoStr; - std::unique_ptr m_buildInfo; - std::unique_ptr m_badgeText; - - std::unique_ptr m_infoStr; - -public: - SplashScreen(ViewManager& vm, specter::ViewResources& res); - void think() override; - void updateContentOpacity(float opacity) override; - - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) override; - void draw(boo::IGraphicsCommandQueue* gfxQ) override; -}; - -} // namespace metaforce diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp deleted file mode 100644 index 645050e89..000000000 --- a/Editor/ViewManager.cpp +++ /dev/null @@ -1,437 +0,0 @@ -#include "ViewManager.hpp" -#include "specter/Space.hpp" -#include "specter/Menu.hpp" -#include "SplashScreen.hpp" -#include "locale/locale.hpp" -#include "ResourceBrowser.hpp" -#include "icons/icons.hpp" -#include "badging/Badging.hpp" -#include "Runtime/Graphics/CModel.hpp" -#include "Runtime/Graphics/CGraphics.hpp" -#include "Runtime/Character/CSkinRules.hpp" -#include "Graphics/CMetroidModelInstance.hpp" -#include "World/CWorldTransManager.hpp" -#include "Graphics/Shaders/CColoredQuadFilter.hpp" -#include "Audio/CStreamAudioManager.hpp" -#include "Runtime/CStateManager.hpp" -#include "Runtime/World/CPlayer.hpp" -#include "hecl/Pipeline.hpp" -#include "version.h" -#include -#include "optick.h" - -using YAMLNode = athena::io::YAMLNode; - -extern hecl::SystemString ExeDir; - -namespace metaforce { - -void ViewManager::InitMP1(MP1::CMain& main) { - main.Init(m_fileStoreManager, &m_cvarManager, m_mainWindow.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); - if (!m_noShaderWarmup) - main.WarmupShaders(); - - m_testGameView.reset(new TestGameView(*this, m_viewResources, *m_rootView, m_cvarManager)); - - m_rootView->accessContentViews().clear(); - m_rootView->accessContentViews().push_back(m_testGameView.get()); - m_rootView->updateSize(); -} - -void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { - specter::View::resized(root, sub); - metaforce::CGraphics::SetViewportResolution({sub.size[0], sub.size[1]}); - if (m_debugText) { - boo::SWindowRect newSub = sub; - newSub.location[1] = 5 * m_vm.m_viewResources.pixelFactor(); - m_debugText->resized(root, newSub); - } -} - -void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ) { - m_vm.m_projManager.mainDraw(); - if (m_debugText) - m_debugText->draw(gfxQ); -} - -void ViewManager::TestGameView::think() { - OPTICK_EVENT(); - if (!m_debugText) { - m_debugText.reset(new specter::MultiLineTextView(m_vm.m_viewResources, *this, m_vm.m_viewResources.m_monoFont18)); - boo::SWindowRect sub = subRect(); - sub.location[1] = 5 * m_vm.m_viewResources.pixelFactor(); - m_debugText->resized(rootView().subRect(), sub); - } - - if (m_debugText) { - std::string overlayText; - if (g_StateManager) { - if (m_vm.m_cvarCommons.m_debugOverlayShowFrameCounter->toBoolean()) - overlayText += fmt::format(FMT_STRING("Frame: {}\n"), g_StateManager->GetUpdateFrameIndex()); - - if (m_vm.m_cvarCommons.m_debugOverlayShowFramerate->toBoolean()) - overlayText += fmt::format(FMT_STRING("FPS: {}\n"), metaforce::CGraphics::GetFPS()); - - if (m_vm.m_cvarCommons.m_debugOverlayShowInGameTime->toBoolean()) { - double igt = g_GameState->GetTotalPlayTime(); - u32 ms = u64(igt * 1000) % 1000; - auto pt = std::div(igt, 3600); - overlayText += - fmt::format(FMT_STRING("PlayTime: {:02d}:{:02d}:{:02d}.{:03d}\n"), pt.quot, pt.rem / 60, pt.rem % 60, ms); - } - - if (g_StateManager->GetCurrentArea() != nullptr && m_vm.m_cvarCommons.m_debugOverlayShowRoomTimer->toBoolean()) { - double igt = g_GameState->GetTotalPlayTime(); - if (m_currentRoom != g_StateManager->GetCurrentArea()) { - m_currentRoom = static_cast(g_StateManager->GetCurrentArea()); - m_lastRoomTime = igt - m_currentRoomStart; - m_currentRoomStart = igt; - } - double currentRoomTime = igt - m_currentRoomStart; - u32 curFrames = std::round(u32(currentRoomTime * 60)); - u32 lastFrames = std::round(u32(m_lastRoomTime * 60)); - overlayText += fmt::format(FMT_STRING("Room Time:{:8.3f}/{:6d}| Last Room:{:8.3f}/{:6d}\n"), currentRoomTime, - curFrames, m_lastRoomTime, lastFrames); - } - - if (g_StateManager->Player() && m_vm.m_cvarCommons.m_debugOverlayPlayerInfo->toBoolean()) { - const CPlayer& pl = g_StateManager->GetPlayer(); - const zeus::CQuaternion plQ = zeus::CQuaternion(pl.GetTransform().getRotation().buildMatrix3f()); - const zeus::CTransform camXf = g_StateManager->GetCameraManager()->GetCurrentCameraTransform(*g_StateManager); - const zeus::CQuaternion camQ = zeus::CQuaternion(camXf.getRotation().buildMatrix3f()); - overlayText += fmt::format(FMT_STRING("Player Position: x {}, y {}, z {}\n" - " Roll: {}, Pitch: {}, Yaw: {}\n" - " Momentum: x {}, y: {}, z: {}\n" - " Velocity: x {}, y: {}, z: {}\n" - "Camera Position: x {}, y {}, z {}\n" - " Roll: {}, Pitch: {}, Yaw: {}\n"), - pl.GetTranslation().x(), pl.GetTranslation().y(), pl.GetTranslation().z(), - zeus::radToDeg(plQ.roll()), zeus::radToDeg(plQ.pitch()), zeus::radToDeg(plQ.yaw()), - pl.GetMomentum().x(), pl.GetMomentum().y(), pl.GetMomentum().z(), - pl.GetVelocity().x(), pl.GetVelocity().y(), pl.GetVelocity().z(), camXf.origin.x(), - camXf.origin.y(), camXf.origin.z(), zeus::radToDeg(camQ.roll()), - zeus::radToDeg(camQ.pitch()), zeus::radToDeg(camQ.yaw())); - } - if (m_vm.m_cvarCommons.m_debugOverlayWorldInfo->toBoolean()) { - TLockedToken tbl = - g_SimplePool->GetObj({FOURCC('STRG'), g_StateManager->GetWorld()->IGetStringTableAssetId()}); - const metaforce::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); - overlayText += fmt::format(FMT_STRING("World: 0x{}{}, Area: {}\n"), g_GameState->CurrentWorldAssetId(), - (tbl.IsLoaded() ? (" " + hecl::Char16ToUTF8(tbl->GetString(0))).c_str() : ""), aId); - } - - const metaforce::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); - if (m_vm.m_cvarCommons.m_debugOverlayAreaInfo->toBoolean() && g_StateManager->GetWorld() && - g_StateManager->GetWorld()->DoesAreaExist(aId)) { - const auto& layerStates = g_GameState->CurrentWorldState().GetLayerState(); - std::string layerBits; - u32 totalActive = 0; - for (u32 i = 0; i < layerStates->GetAreaLayerCount(aId); ++i) { - if (layerStates->IsLayerActive(aId, i)) { - ++totalActive; - layerBits += "1"; - } else - layerBits += "0"; - } - overlayText += fmt::format(FMT_STRING("Area AssetId: 0x{}, Total Objects: {}\n" - "Active Layer bits: {}\n"), - g_StateManager->GetWorld()->GetArea(aId)->GetAreaAssetId(), - g_StateManager->GetAllObjectList().size(), layerBits); - } - } - - if (m_vm.m_cvarCommons.m_debugOverlayShowRandomStats->toBoolean()) { - overlayText += fmt::format(FMT_STRING("CRandom16::Next calls: {}\n"), metaforce::CRandom16::GetNumNextCalls()); - } - - if (m_vm.m_cvarCommons.m_debugOverlayShowResourceStats->toBoolean()) - overlayText += fmt::format(FMT_STRING("Resource Objects: {}\n"), g_SimplePool->GetLiveObjects()); - - if (!overlayText.empty()) - m_debugText->typesetGlyphs(overlayText); - } -} - -specter::View* ViewManager::BuildSpaceViews() { - m_rootSpaceView = m_rootSpace->buildSpaceView(m_viewResources); - return m_rootSpaceView; -} - -specter::RootView* ViewManager::SetupRootView() { - m_rootView.reset(new specter::RootView(*this, m_viewResources, m_mainWindow.get())); - m_rootView->setBackground(zeus::skBlack); - return m_rootView.get(); -} - -SplashScreen* ViewManager::SetupSplashView() { - m_splash.reset(new SplashScreen(*this, m_viewResources)); - if (!m_showSplash) - m_splash->close(true); - return m_splash.get(); -} - -void ViewManager::RootSpaceViewBuilt(specter::View* view) { - std::vector& cViews = m_rootView->accessContentViews(); - cViews.clear(); - cViews.push_back(view); - cViews.push_back(m_splash.get()); - m_rootView->updateSize(); -} - -void ViewManager::ProjectChanged(hecl::Database::Project& proj) { - CDvdFile::Shutdown(); - // FIXME trilogy hack - hecl::ProjectPath projectPath(proj.getProjectWorkingPath(), _SYS_STR("out/files/MP1")); - if (!projectPath.isDirectory()) { - projectPath = hecl::ProjectPath(proj.getProjectWorkingPath(), _SYS_STR("out/files")); - } - CDvdFile::Initialize(projectPath); -} - -void ViewManager::SetupEditorView() { - m_rootSpace.reset(new RootSpace(*this)); - - SplitSpace* split = new SplitSpace(*this, nullptr, specter::SplitView::Axis::Horizontal); - m_rootSpace->setChild(std::unique_ptr(split)); - split->setChildSlot(0, std::make_unique(*this, split)); - split->setChildSlot(1, std::make_unique(*this, split)); - - BuildSpaceViews(); -} - -void ViewManager::SetupEditorView(ConfigReader& r) { - m_rootSpace.reset(Space::NewRootSpaceFromConfigStream(*this, r)); - BuildSpaceViews(); -} - -void ViewManager::SaveEditorView(ConfigWriter& w) { - if (!m_rootSpace) - return; - m_rootSpace->saveState(w); -} - -void ViewManager::DismissSplash() { - if (!m_showSplash) - return; - m_showSplash = false; - m_splash->close(); -} - -ViewManager::ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr) -: m_fileStoreManager(fileMgr) -, m_cvarManager(cvarMgr) -, m_cvarCommons(cvarMgr) -, m_projManager(*this) -, m_fontCache(fileMgr) -, m_locale(locale::SystemLocaleOrEnglish()) -, m_recentProjectsPath(fmt::format(FMT_STRING(_SYS_STR("{}/recent_projects.txt")), fileMgr.getStoreRoot())) -, m_recentFilesPath(fmt::format(FMT_STRING(_SYS_STR("{}/recent_files.txt")), fileMgr.getStoreRoot())) { - Space::SpaceMenuNode::InitializeStrings(*this); - char path[2048]; - hecl::Sstat theStat; - - auto fp = hecl::FopenUnique(m_recentProjectsPath.c_str(), _SYS_STR("r"), hecl::FileLockType::Read); - if (fp) { - while (std::fgets(path, std::size(path), fp.get())) { - std::string pathStr(path); - pathStr.pop_back(); - hecl::SystemStringConv pathStrView(pathStr); - if (!hecl::Stat(pathStrView.c_str(), &theStat) && S_ISDIR(theStat.st_mode)) { - m_recentProjects.emplace_back(pathStrView.sys_str()); - } - } - } - - fp = hecl::FopenUnique(m_recentFilesPath.c_str(), _SYS_STR("r"), hecl::FileLockType::Read); - if (fp) { - while (std::fgets(path, std::size(path), fp.get())) { - std::string pathStr(path); - pathStr.pop_back(); - hecl::SystemStringConv pathStrView(pathStr); - if (!hecl::Stat(pathStrView.c_str(), &theStat) && S_ISDIR(theStat.st_mode)) { - m_recentFiles.emplace_back(pathStrView.sys_str()); - } - } - } -} - -ViewManager::~ViewManager() {} - -void ViewManager::pushRecentProject(hecl::SystemStringView path) { - for (hecl::SystemString& testPath : m_recentProjects) { - if (path == testPath) - return; - } - m_recentProjects.emplace_back(path); - - const auto fp = hecl::FopenUnique(m_recentProjectsPath.c_str(), _SYS_STR("w"), hecl::FileLockType::Write); - if (fp == nullptr) { - return; - } - - for (const hecl::SystemString& pPath : m_recentProjects) { - fmt::print(fp.get(), FMT_STRING("{}\n"), hecl::SystemUTF8Conv(pPath)); - } -} - -void ViewManager::pushRecentFile(hecl::SystemStringView path) { - for (hecl::SystemString& testPath : m_recentFiles) { - if (path == testPath) - return; - } - m_recentFiles.emplace_back(path); - - const auto fp = hecl::FopenUnique(m_recentFilesPath.c_str(), _SYS_STR("w"), hecl::FileLockType::Write); - if (fp == nullptr) { - return; - } - - for (const hecl::SystemString& pPath : m_recentFiles) { - fmt::print(fp.get(), FMT_STRING("{}\n"), hecl::SystemUTF8Conv(pPath)); - } -} - -void ViewManager::init(boo::IApplication* app) { - m_mainWindow = app->newWindow(_SYS_STR("Metaforce")); - m_mainWindow->showWindow(); - m_mainWindow->setWaitCursor(true); - if (m_cvarCommons.getFullscreen()) { - m_mainWindow->setFullscreen(true); - } - - float pixelFactor = m_mainWindow->getVirtualPixelFactor(); - - m_mainBooFactory = m_mainWindow->getMainContextDataFactory(); - m_pipelineConv = hecl::NewPipelineConverter(m_mainBooFactory); - hecl::conv = m_pipelineConv.get(); - m_mainPlatformName = m_mainBooFactory->platformName(); - m_mainWindow->setTitle( - fmt::format(FMT_STRING(_SYS_STR("Metaforce {} [{}]")), METAFORCE_WC_DESCRIBE_SYS, m_mainPlatformName)); - m_mainCommandQueue = m_mainWindow->getCommandQueue(); - m_viewResources.init(m_mainBooFactory, &m_fontCache, &m_themeData, pixelFactor); - InitializeIcons(m_viewResources); - InitializeBadging(m_viewResources); - m_viewResources.prepFontCacheAsync(m_mainWindow.get()); - specter::RootView* root = SetupRootView(); - m_showSplash = true; - root->accessContentViews().push_back(SetupSplashView()); - root->updateSize(); - m_renderTex = root->renderTex(); - m_mainWindow->setWaitCursor(false); - m_voiceEngine = boo::NewAudioVoiceEngine(); - m_voiceEngine->setVolume(0.7f); - m_amuseAllocWrapper.emplace(*m_voiceEngine); - - for (const auto& arg : app->getArgs()) { - hecl::Sstat theStat; - if (!hecl::Stat((arg + _SYS_STR("/out")).c_str(), &theStat) && S_ISDIR(theStat.st_mode)) { - hecl::ProjectRootPath rootPath(arg); - hecl::Database::Project tmp(rootPath); // Force project creation - } - if (m_deferedProject.empty() && hecl::SearchForProject(arg)) - m_deferedProject = arg + _SYS_STR("/out"); - if (arg == _SYS_STR("--no-shader-warmup")) - m_noShaderWarmup = true; - else if (arg == _SYS_STR("--no-sound")) - m_voiceEngine->setVolume(0.f); - } - - if (m_deferedProject.empty()) { - /* Default behavior - search upwards for packaged project containing the program */ - if (hecl::ProjectRootPath projRoot = hecl::SearchForProject(ExeDir)) { - hecl::SystemString rootPath(projRoot.getAbsolutePath()); - hecl::Sstat theStat; - if (!hecl::Stat((rootPath + _SYS_STR("/out/files/Metroid1.upak")).c_str(), &theStat) && S_ISREG(theStat.st_mode)) - m_deferedProject = rootPath + _SYS_STR("/out"); - } - } -} - -bool ViewManager::proc() { - if (!m_deferedProject.empty() && m_viewResources.fontCacheReady()) { - m_projManager.openProject(m_deferedProject); - m_deferedProject.clear(); - } - - boo::IGraphicsCommandQueue* gfxQ = m_mainWindow->getCommandQueue(); - if (m_rootView->isDestroyed()) - return false; - - if (m_updatePf) { - OPTICK_EVENT("m_updatePf"); - m_viewResources.resetPixelFactor(m_reqPf); - specter::RootView* root = SetupRootView(); - if (m_rootSpace) - BuildSpaceViews(); - else { - std::vector& cViews = m_rootView->accessContentViews(); - cViews.push_back(SetupSplashView()); - } - root->updateSize(); - m_updatePf = false; - } - - { - OPTICK_EVENT("m_rootView->DispatchEvents"); - m_rootView->dispatchEvents(); - } - { - OPTICK_EVENT("m_rootView->internalThink"); - m_rootView->internalThink(); - } - if (m_rootSpace) - m_rootSpace->think(); - if (m_splash) - m_splash->think(); - - if (m_deferSplit) { - SplitSpace* ss = static_cast(m_deferSplit->spaceSplit(m_deferSplitAxis, m_deferSplitThisSlot)); - m_rootView->startSplitDrag(ss->splitView(), m_deferSplitCoord); - m_deferSplit = nullptr; - } - - ++m_editorFrames; - if (m_rootSpaceView && m_editorFrames <= 30) - m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1, 1, 1, 0}, {1, 1, 1, 1}, m_editorFrames / 30.0)); - - m_cvarManager.proc(); - m_projManager.mainUpdate(); - - if (m_testGameView) - m_testGameView->think(); - - { - OPTICK_EVENT("Draw"); - if (g_Renderer) - g_Renderer->BeginScene(); - m_rootView->draw(gfxQ); - if (g_Renderer) - g_Renderer->EndScene(); - gfxQ->execute(); - } - if (g_ResFactory) - g_ResFactory->AsyncIdle(); -#ifndef URDE_MSAN - m_voiceEngine->pumpAndMixVoices(); -#endif - if (!m_skipWait || !hecl::com_developer->toBoolean()) { - OPTICK_EVENT("waitForRetrace"); - m_mainWindow->waitForRetrace(); - } - CBooModel::ClearModelUniformCounters(); - CGraphics::TickRenderTimings(); - ++logvisor::FrameIndex; - return true; -} - -void ViewManager::stop() { - m_mainWindow->getCommandQueue()->stopRenderer(); - m_projManager.shutdown(); - CDvdFile::Shutdown(); - DestroyIcons(); - DestroyBadging(); - m_viewResources.destroyResData(); - m_fontCache.destroyAtlases(); -} - -} // namespace metaforce diff --git a/Editor/ViewManager.hpp b/Editor/ViewManager.hpp deleted file mode 100644 index 9533bb797..000000000 --- a/Editor/ViewManager.hpp +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once - -#include "hecl/CVarManager.hpp" -#include "hecl/CVarCommons.hpp" -#include "boo/audiodev/IAudioVoiceEngine.hpp" -#include "amuse/BooBackend.hpp" -#include "ProjectManager.hpp" -#include "Space.hpp" -#include "specter/IViewManager.hpp" -#include "specter/FontCache.hpp" -#include "specter/ViewResources.hpp" - -#include "Runtime/CGameHintInfo.hpp" -#include "Runtime/Particle/CElementGen.hpp" -#include "Runtime/Graphics/CLineRenderer.hpp" -#include "Runtime/Graphics/CMoviePlayer.hpp" -#include "Runtime/Graphics/CModel.hpp" -#include "Runtime/Particle/CGenDescription.hpp" -#include "Runtime/Character/CAssetFactory.hpp" -#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp" -#include "Runtime/Graphics/Shaders/CXRayBlurFilter.hpp" -#include "Runtime/Graphics/Shaders/CCameraBlurFilter.hpp" -#include "Runtime/Audio/CStaticAudioPlayer.hpp" - -namespace hecl { -class PipelineConverterBase; -} - -namespace metaforce { -class SplashScreen; - -class ViewManager final : public specter::IViewManager { - friend class ProjectManager; - friend class Space; - friend class RootSpace; - friend class SplitSpace; - - std::shared_ptr m_mainWindow; - hecl::Runtime::FileStoreManager& m_fileStoreManager; - hecl::CVarManager& m_cvarManager; - hecl::CVarCommons m_cvarCommons; - ProjectManager m_projManager; - specter::FontCache m_fontCache; - specter::DefaultThemeData m_themeData; - specter::ViewResources m_viewResources; - locale::ELocale m_locale = locale::ELocale::en_US; - boo::IGraphicsDataFactory* m_mainBooFactory = nullptr; - boo::IGraphicsCommandQueue* m_mainCommandQueue = nullptr; - std::unique_ptr m_pipelineConv; - boo::ObjToken m_renderTex; - const boo::SystemChar* m_mainPlatformName; - - std::unique_ptr m_rootView; - std::unique_ptr m_splash; - std::unique_ptr m_rootSpace; - specter::View* m_rootSpaceView = nullptr; - bool m_skipWait = false; - - class TestGameView : public specter::View { - ViewManager& m_vm; - std::unique_ptr m_debugText; - const void* m_currentRoom = nullptr; - double m_lastRoomTime = 0.f; - double m_currentRoomStart = 0.f; - - public: - TestGameView(ViewManager& vm, specter::ViewResources& res, specter::View& parent, hecl::CVarManager& cvarMgr) - : View(res, parent), m_vm(vm) {} - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) override; - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - void think() override; - - void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mkey) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->mouseDown(coord, button, mkey); - } - - void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mkey) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->mouseUp(coord, button, mkey); - } - - void mouseMove(const boo::SWindowCoord& coord) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->mouseMove(coord); - } - - void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& sd) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->scroll(coord, sd); - } - - void charKeyDown(unsigned long cc, boo::EModifierKey mkey, bool repeat) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->charKeyDown(cc, mkey, repeat); - } - - void charKeyUp(unsigned long cc, boo::EModifierKey mkey) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->charKeyUp(cc, mkey); - } - - void specialKeyDown(boo::ESpecialKey skey, boo::EModifierKey mkey, bool repeat) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->specialKeyDown(skey, mkey, repeat); - - if (skey == boo::ESpecialKey::F1) - m_vm.m_skipWait = true; - } - - void specialKeyUp(boo::ESpecialKey skey, boo::EModifierKey mkey) override { - if (MP1::CMain* m = m_vm.m_projManager.gameMain()) - if (MP1::CGameArchitectureSupport* as = m->GetArchSupport()) - as->specialKeyUp(skey, mkey); - - if (skey == boo::ESpecialKey::F1) - m_vm.m_skipWait = false; - } - }; - std::unique_ptr m_testGameView; - std::unique_ptr m_voiceEngine; - std::optional m_amuseAllocWrapper; - - hecl::SystemString m_recentProjectsPath; - std::vector m_recentProjects; - hecl::SystemString m_recentFilesPath; - std::vector m_recentFiles; - - bool m_updatePf = false; - float m_reqPf; - - specter::View* BuildSpaceViews(); - specter::RootView* SetupRootView(); - SplashScreen* SetupSplashView(); - void RootSpaceViewBuilt(specter::View* view); - void ProjectChanged(hecl::Database::Project& proj); - void SetupEditorView(); - void SetupEditorView(ConfigReader& r); - void SaveEditorView(ConfigWriter& w); - - bool m_showSplash = false; - void DismissSplash(); - - unsigned m_editorFrames = 120; - void FadeInEditors() { m_editorFrames = 0; } - - void InitMP1(MP1::CMain& main); - - Space* m_deferSplit = nullptr; - specter::SplitView::Axis m_deferSplitAxis; - int m_deferSplitThisSlot; - boo::SWindowCoord m_deferSplitCoord; - hecl::SystemString m_deferedProject; - bool m_noShaderWarmup = false; - -public: - ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr); - ~ViewManager(); - - specter::RootView& rootView() const { return *m_rootView; } - void requestPixelFactor(float pf) { - m_reqPf = pf; - m_updatePf = true; - } - - ProjectManager& projectManager() { return m_projManager; } - hecl::Database::Project* project() { return m_projManager.project(); } - locale::ELocale getTranslatorLocale() const override { return m_locale; } - - void deferSpaceSplit(specter::ISpaceController* split, specter::SplitView::Axis axis, int thisSlot, - const boo::SWindowCoord& coord) override { - m_deferSplit = static_cast(split); - m_deferSplitAxis = axis; - m_deferSplitThisSlot = thisSlot; - m_deferSplitCoord = coord; - } - - const std::vector* recentProjects() const override { return &m_recentProjects; } - void pushRecentProject(hecl::SystemStringView path) override; - - const std::vector* recentFiles() const override { return &m_recentFiles; } - void pushRecentFile(hecl::SystemStringView path) override; - - void init(boo::IApplication* app); - const boo::SystemChar* platformName() { return m_mainPlatformName; } - bool proc(); - void stop(); - - void deferOpenProject(const hecl::SystemString& path) { m_deferedProject = path; } -}; - -} // namespace metaforce diff --git a/Editor/badging/Badging.cpp b/Editor/badging/Badging.cpp deleted file mode 100644 index 8f4719626..000000000 --- a/Editor/badging/Badging.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "Badging.hpp" -#include "athena/MemoryReader.hpp" - -#include -#include - -extern "C" uint8_t URDE_BADGE[]; -extern "C" size_t URDE_BADGE_SZ; - -namespace metaforce { -static logvisor::Module Log("URDE::badging"); -static specter::Icon g_BadgeIcon; - -void InitializeBadging(specter::ViewResources& viewRes) { - athena::io::MemoryReader r(URDE_BADGE, URDE_BADGE_SZ); - - size_t fmt = r.readUint32Big(); - if (fmt != 16) - Log.report(logvisor::Fatal, FMT_STRING("incorrect icon texture format")); - size_t width = r.readUint16Big(); - size_t height = r.readUint16Big(); - size_t mips = r.readUint32Big(); - size_t decompSz = r.readUint32Big(); - - std::unique_ptr texels(new uint8_t[decompSz]); - uLongf destSz = decompSz; - size_t pos = r.position(); - if (uncompress(texels.get(), &destSz, URDE_BADGE + pos, URDE_BADGE_SZ - pos) != Z_OK) - Log.report(logvisor::Fatal, FMT_STRING("unable to decompress badge")); - - viewRes.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { - specter::IconAtlas<1, 1> atlas; - - atlas.initializeAtlas(ctx.newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8, - boo::TextureClampMode::Repeat, texels.get(), destSz)); - g_BadgeIcon = atlas.getIcon(0, 0); - return true; - } BooTrace); -} - -void DestroyBadging() { g_BadgeIcon.m_tex.reset(); } - -specter::Icon& GetBadge() { return g_BadgeIcon; } - -} // namespace metaforce diff --git a/Editor/badging/Badging.hpp b/Editor/badging/Badging.hpp deleted file mode 100644 index 7004a32e9..000000000 --- a/Editor/badging/Badging.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "specter/ViewResources.hpp" - -namespace metaforce { -void InitializeBadging(specter::ViewResources& viewRes); -void DestroyBadging(); - -specter::Icon& GetBadge(); -} // namespace metaforce - -#ifndef BADGE_PHRASE -#define BADGE_PHRASE "Alpha" -#endif diff --git a/Editor/badging/CMakeLists.txt b/Editor/badging/CMakeLists.txt deleted file mode 100644 index 6657f5760..000000000 --- a/Editor/badging/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -if(NOT CMAKE_CROSSCOMPILING) - -add_executable(packbadge packbadge.c) -find_library(M_LIB m) -if(NOT M_LIB) - unset(M_LIB CACHE) -endif() -target_link_libraries(packbadge ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${M_LIB}) -target_include_directories(packbadge PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) - -################## -# Package Export # -################## - -# Add all targets to the build-tree export set -export(TARGETS packbadge FILE "${CMAKE_CURRENT_BINARY_DIR}/metaforce-packbadgeTargets.cmake") - -# Export the package for use from the build-tree -# (this registers the build-tree with a global CMake-registry) -export(PACKAGE metaforce-packbadge) - -# Create the atdnaConfig.cmake -# ... for the build tree -configure_file(metaforce-packbadgeConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/metaforce-packbadgeConfig.cmake" @ONLY) -# ... for the install tree -configure_file(metaforce-packbadgeConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/metaforce-packbadgeConfig.cmake" @ONLY) -# ... for both -configure_file(metaforce-packbadgeConfigVersion.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/metaforce-packbadgeConfigVersion.cmake" @ONLY) - -else() -find_package(metaforce-packbadge REQUIRED) -endif() - -add_custom_command(OUTPUT badge.bin COMMAND $ - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/badge.png - ${CMAKE_CURRENT_BINARY_DIR}/badge.bin - MAIN_DEPENDENCY badge.png COMMENT "Generating badge.bin") - -bintoc(badge.cpp ${CMAKE_CURRENT_BINARY_DIR}/badge.bin URDE_BADGE) -add_library(MetaforceBadging - badge.cpp badge.bin - Badging.hpp Badging.cpp) -target_link_libraries(MetaforceBadging PUBLIC specter) diff --git a/Editor/badging/badge.png b/Editor/badging/badge.png deleted file mode 100644 index 925dd90e9..000000000 Binary files a/Editor/badging/badge.png and /dev/null differ diff --git a/Editor/badging/metaforce-packbadgeConfig.cmake.in b/Editor/badging/metaforce-packbadgeConfig.cmake.in deleted file mode 100644 index cb77a1e60..000000000 --- a/Editor/badging/metaforce-packbadgeConfig.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -# - Config file for the packbadge package - -# Compute paths -get_filename_component(PACKBADGE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - -# Our library dependencies (contains definitions for IMPORTED targets) -if(NOT TARGET packbadge AND NOT packbadge_BINARY_DIR) - include("${PACKBADGE_CMAKE_DIR}/metaforce-packbadgeTargets.cmake") -endif() diff --git a/Editor/badging/metaforce-packbadgeConfigVersion.cmake.in b/Editor/badging/metaforce-packbadgeConfigVersion.cmake.in deleted file mode 100644 index 05eda9878..000000000 --- a/Editor/badging/metaforce-packbadgeConfigVersion.cmake.in +++ /dev/null @@ -1,12 +0,0 @@ -set(PACKAGE_VERSION "@PACKBADGE_VERSION@") - -# Check whether the requested PACKAGE_FIND_VERSION is compatible -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_EXACT TRUE) - endif() -endif() - diff --git a/Editor/badging/packbadge.c b/Editor/badging/packbadge.c deleted file mode 100644 index 4a1b84c00..000000000 --- a/Editor/badging/packbadge.c +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#if __FreeBSD__ -#include -#endif - -#if _WIN32 -#define _bswap32(v) _byteswap_ulong(v) -#define _bswap16(v) _byteswap_ushort(v) -#define WIN32_LEAN_AND_MEAN -#include -#else -#define _bswap32(v) __builtin_bswap32(v) -#define _bswap16(v) __builtin_bswap16(v) -#endif - -int main(int argc, char* argv[]) -{ - if (argc < 3) - { - fprintf(stderr, "Usage: packbadge \n"); - return 1; - } - - /* Validate input */ - FILE* fp = fopen(argv[1], "rb"); - if (!fp) - { - fprintf(stderr, "'%s' is not able to be opened for reading as a regular file\n", argv[1]); - return 1; - } - - FILE* ofp = fopen(argv[2], "wb"); - if (!ofp) - { - fprintf(stderr, "'%s' is not able to be opened for writing as a regular file\n", argv[2]); - return 1; - } - - size_t decompSz = 0; - int numMips = 1; - - z_stream z = {0}; - size_t rowSz = 0; - uLong rowSzC = 0; - png_bytep row; - png_bytep rowC; - - /* Get PNG data */ - char header[8]; - fread(header, 1, 8, fp); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) - { - fprintf(stderr, "invalid PNG signature in '%s'\n", argv[1]); - fclose(fp); - fclose(ofp); - return 1; - } - - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!pngRead) - { - fprintf(stderr, "unable to initialize libpng\n"); - fclose(fp); - fclose(ofp); - return 1; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) - { - fprintf(stderr, "unable to initialize libpng info\n"); - fclose(fp); - fclose(ofp); - return 1; - } - - if (setjmp(png_jmpbuf(pngRead))) - { - fprintf(stderr, "unable to initialize libpng I/O for '%s'\n", argv[1]); - fclose(fp); - fclose(ofp); - return 1; - } - - png_init_io(pngRead, fp); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - png_uint_32 width = png_get_image_width(pngRead, info); - png_uint_32 height = png_get_image_height(pngRead, info); - decompSz = width * height * 4; - png_byte colorType = png_get_color_type(pngRead, info); - png_byte bitDepth = png_get_bit_depth(pngRead, info); - - if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) - { - fprintf(stderr, "'%s' is not in RGBA color mode\n", argv[1]); - fclose(fp); - fclose(ofp); - return 1; - } - - if (bitDepth != 8) - { - fprintf(stderr, "'%s' is not 8 bits-per-channel\n", argv[1]); - fclose(fp); - fclose(ofp); - return 1; - } - - if (setjmp(png_jmpbuf(pngRead))) - { - fprintf(stderr, "unable to read image in '%s'\n", argv[1]); - fclose(fp); - fclose(ofp); - return 1; - } - - uint32_t fmt = _bswap32(16); - uint16_t w = _bswap16(width); - uint16_t h = _bswap16(height); - uint32_t mips = _bswap32(numMips); - uint32_t dsz = _bswap32(decompSz); - fwrite(&fmt, 1, 4, ofp); - fwrite(&w, 1, 2, ofp); - fwrite(&h, 1, 2, ofp); - fwrite(&mips, 1, 4, ofp); - fwrite(&dsz, 1, 4, ofp); - - rowSz = width*4; - rowSzC = compressBound(rowSz); - deflateInit(&z, Z_DEFAULT_COMPRESSION); - - row = malloc(rowSz); - rowC = malloc(rowSzC); - - for (png_uint_32 r=0 ; r - ARGS ${INKSCAPE_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/icons.svg - ${CMAKE_CURRENT_BINARY_DIR}/icons.bin - MAIN_DEPENDENCY icons.svg COMMENT "Generating icons.bin") -endif() - -bintoc(icons_dat.cpp ${CMAKE_CURRENT_BINARY_DIR}/icons.bin URDE_ICONS) -add_library(MetaforceIcons icons.cpp icons.hpp icons.bin icons_dat.cpp) -target_link_libraries(MetaforceIcons PUBLIC specter) diff --git a/Editor/icons/IconDownload.cmake b/Editor/icons/IconDownload.cmake deleted file mode 100644 index 682a2aad3..000000000 --- a/Editor/icons/IconDownload.cmake +++ /dev/null @@ -1,3 +0,0 @@ -message(STATUS "Inkscape not found; downloading icons to '${CMAKE_CURRENT_BINARY_DIR}/icons.bin'") -file(DOWNLOAD "https://axiodl.com/files/icons.bin" - ${CMAKE_CURRENT_BINARY_DIR}/icons.bin SHOW_PROGRESS EXPECTED_HASH SHA1=412baa3b12163a89b306ebfef2a395762105a8d4) \ No newline at end of file diff --git a/Editor/icons/icons.cpp b/Editor/icons/icons.cpp deleted file mode 100644 index e06fc6e6b..000000000 --- a/Editor/icons/icons.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "icons.hpp" -#include "athena/MemoryReader.hpp" -#include - -extern "C" uint8_t URDE_ICONS[]; -extern "C" size_t URDE_ICONS_SZ; - -namespace metaforce { -static logvisor::Module Log("URDE::icons"); - -specter::IconAtlas<8, 8> g_IconAtlas; - -void InitializeIcons(specter::ViewResources& viewRes) { - athena::io::MemoryReader r(URDE_ICONS, URDE_ICONS_SZ); - size_t fmt = r.readUint32Big(); - if (fmt != 16) - Log.report(logvisor::Fatal, FMT_STRING("incorrect icon texture format")); - size_t width = r.readUint16Big(); - size_t height = r.readUint16Big(); - size_t mips = r.readUint32Big(); - size_t decompSz = r.readUint32Big(); - - std::unique_ptr texels(new uint8_t[decompSz]); - uLongf destSz = decompSz; - size_t pos = r.position(); - if (uncompress(texels.get(), &destSz, URDE_ICONS + pos, URDE_ICONS_SZ - pos) != Z_OK) - Log.report(logvisor::Fatal, FMT_STRING("unable to decompress icons")); - - viewRes.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { - g_IconAtlas.initializeAtlas(ctx.newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8, - boo::TextureClampMode::Repeat, texels.get(), destSz)); - return true; - } BooTrace); -} - -void DestroyIcons() { g_IconAtlas.destroyAtlas(); } - -specter::Icon& GetIcon(SpaceIcon icon) { - switch (icon) { - case SpaceIcon::ResourceBrowser: - return g_IconAtlas.getIcon(0, 0); - case SpaceIcon::ParticleEditor: - return g_IconAtlas.getIcon(0, 1); - case SpaceIcon::WorldEditor: - return g_IconAtlas.getIcon(0, 2); - case SpaceIcon::InformationCenter: - return g_IconAtlas.getIcon(0, 3); - case SpaceIcon::ModelViewer: - return g_IconAtlas.getIcon(0, 4); - case SpaceIcon::GameMode: - return g_IconAtlas.getIcon(0, 5); - default: - return g_IconAtlas.getIcon(6, 0); - } -} - -specter::Icon& GetIcon(MonoIcon icon) { - switch (icon) { - case MonoIcon::Sync: - return g_IconAtlas.getIcon(7, 0); - case MonoIcon::Edit: - return g_IconAtlas.getIcon(7, 1); - case MonoIcon::Caution: - return g_IconAtlas.getIcon(7, 2); - case MonoIcon::Save: - return g_IconAtlas.getIcon(7, 3); - case MonoIcon::Filter: - return g_IconAtlas.getIcon(7, 4); - case MonoIcon::Document: - return g_IconAtlas.getIcon(7, 5); - case MonoIcon::ZoomOut: - return g_IconAtlas.getIcon(7, 6); - case MonoIcon::ZoomIn: - return g_IconAtlas.getIcon(7, 7); - case MonoIcon::Exclaim: - return g_IconAtlas.getIcon(6, 0); - case MonoIcon::Clock: - return g_IconAtlas.getIcon(6, 1); - case MonoIcon::Gamepad: - return g_IconAtlas.getIcon(6, 2); - case MonoIcon::Unlink: - return g_IconAtlas.getIcon(6, 3); - case MonoIcon::Link: - return g_IconAtlas.getIcon(6, 4); - case MonoIcon::Folder: - return g_IconAtlas.getIcon(6, 5); - case MonoIcon::Info: - return g_IconAtlas.getIcon(6, 6); - default: - return g_IconAtlas.getIcon(6, 0); - } -} - -} // namespace metaforce diff --git a/Editor/icons/icons.hpp b/Editor/icons/icons.hpp deleted file mode 100644 index b222a65af..000000000 --- a/Editor/icons/icons.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "specter/Icon.hpp" -#include "specter/ViewResources.hpp" - -namespace metaforce { -void InitializeIcons(specter::ViewResources& viewRes); -void DestroyIcons(); - -enum class SpaceIcon { ResourceBrowser, ParticleEditor, WorldEditor, ModelViewer, InformationCenter, GameMode }; -specter::Icon& GetIcon(SpaceIcon icon); - -enum class MonoIcon { - Sync, - Edit, - Caution, - Save, - Filter, - Document, - ZoomOut, - ZoomIn, - - Exclaim, - Clock, - Gamepad, - Unlink, - Link, - Folder, - Info -}; -specter::Icon& GetIcon(MonoIcon icon); - -} // namespace metaforce diff --git a/Editor/icons/icons.svg b/Editor/icons/icons.svg deleted file mode 100644 index e5134622b..000000000 --- a/Editor/icons/icons.svg +++ /dev/null @@ -1,469 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Editor/icons/metaforce-packiconsConfig.cmake.in b/Editor/icons/metaforce-packiconsConfig.cmake.in deleted file mode 100644 index 89f7681e6..000000000 --- a/Editor/icons/metaforce-packiconsConfig.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -# - Config file for the packicons package - -# Compute paths -get_filename_component(PACKICONS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - -# Our library dependencies (contains definitions for IMPORTED targets) -if(NOT TARGET packicons AND NOT packicons_BINARY_DIR) - include("${PACKICONS_CMAKE_DIR}/metaforce-packiconsTargets.cmake") -endif() diff --git a/Editor/icons/metaforce-packiconsConfigVersion.cmake.in b/Editor/icons/metaforce-packiconsConfigVersion.cmake.in deleted file mode 100644 index da3ba016d..000000000 --- a/Editor/icons/metaforce-packiconsConfigVersion.cmake.in +++ /dev/null @@ -1,12 +0,0 @@ -set(PACKAGE_VERSION "@PACKICONS_VERSION@") - -# Check whether the requested PACKAGE_FIND_VERSION is compatible -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_EXACT TRUE) - endif() -endif() - diff --git a/Editor/icons/packicons.c b/Editor/icons/packicons.c deleted file mode 100644 index b017d6e99..000000000 --- a/Editor/icons/packicons.c +++ /dev/null @@ -1,345 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#if __FreeBSD__ -#include -#endif - -#if _WIN32 -#define _bswap32(v) _byteswap_ulong(v) -#define _bswap16(v) _byteswap_ushort(v) -#define WIN32_LEAN_AND_MEAN -#include -#else -#define _bswap32(v) __builtin_bswap32(v) -#define _bswap16(v) __builtin_bswap16(v) -#endif - -static int CountBits(uint32_t n) -{ - int ret = 0; - for (int i=0 ; i<32 ; ++i) - if (((n >> i) & 1) != 0) - ++ret; - return ret; -} - -int main(int argc, char* argv[]) -{ - if (argc < 4) - { - fprintf(stderr, "Usage: packicons \n"); - return 1; - } - - /* Validate inkscape */ - char command[2048]; - FILE* fp; - -#if _WIN32 - STARTUPINFOA sinfo = {sizeof(STARTUPINFOA)}; - - HANDLE hChildStd_OUT_Rd = NULL; - HANDLE hChildStd_OUT_Wr = NULL; - - SECURITY_ATTRIBUTES saAttr; - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - // Create a pipe for the child process's STDOUT. - if (!CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0)) - { - fprintf(stderr, "unable to CreatePipe\n"); - return 1; - } - - // Ensure the read handle to the pipe for STDOUT is not inherited - if (!SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) - { - fprintf(stderr, "unable to SetHandleInformation\n"); - return 1; - } - - sinfo.hStdError = hChildStd_OUT_Wr; - sinfo.hStdOutput = hChildStd_OUT_Wr; - sinfo.dwFlags |= STARTF_USESTDHANDLES; - - PROCESS_INFORMATION pinfo; - if (!CreateProcessA(argv[1], " --version", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo)) - { - LPSTR messageBuffer = NULL; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); - fprintf(stderr, "unable to launch inkscape from %s: %s\n", argv[1], messageBuffer); - return 1; - } - CloseHandle(hChildStd_OUT_Wr); - CloseHandle(pinfo.hThread); - - char readback[8]; - DWORD bytesRead = 0; - if (!ReadFile(hChildStd_OUT_Rd, readback, 8, &bytesRead, NULL) || bytesRead != 8 || - strncmp(readback, "Inkscape", 8)) - { - fprintf(stderr, "'%s' did not return expected \"Inkscape\"\n", command); - CloseHandle(hChildStd_OUT_Rd); - CloseHandle(pinfo.hProcess); - return 1; - } - CloseHandle(hChildStd_OUT_Rd); - WaitForSingleObject(pinfo.hProcess, INFINITE); - CloseHandle(pinfo.hProcess); - -#else - snprintf(command, 2048, "%s --version", argv[1]); - fp = popen(command, "r"); - if (!fp) - { - fprintf(stderr, "'%s' is not executable on this system\n", command); - return 1; - } - - char readback[8]; - if (fread(readback, 1, 8, fp) != 8 || strncmp(readback, "Inkscape", 8)) - { - fprintf(stderr, "'%s' did not return expected \"Inkscape\"\n", command); - pclose(fp); - return 1; - } - pclose(fp); - -#endif - - /* Validate input */ - fp = fopen(argv[2], "rb"); - if (!fp) - { - fprintf(stderr, "'%s' is not able to be opened for reading as a regular file\n", argv[2]); - return 1; - } - fclose(fp); - -#ifdef _WIN32 - char* TMPDIR = getenv("TEMP"); - if (!TMPDIR) - TMPDIR = (char*)"\\Temp"; -#else - char* TMPDIR = getenv("TMPDIR"); - if (!TMPDIR) - TMPDIR = (char*)"/tmp"; -#endif - - FILE* ofp = fopen(argv[3], "wb"); - if (!ofp) - { - fprintf(stderr, "'%s' is not able to be opened for writing as a regular file\n", argv[3]); - return 1; - } - - size_t decompSz = 0; - int numMips = 0; - for (int i=512 ; i>=1 ; i/=2) - { - decompSz += i*i*4; - ++numMips; - } - - z_stream z = {0}; - size_t rowSz = 0; - uLong rowSzC = 0; - png_bytep row; - png_bytep rowC; - - for (int i=512 ; i>=1 ; i/=2) - { - printf("Rendering icons @%dx%d\n", i, i); - fflush(stdout); - -#if _WIN32 - snprintf(command, 2048, " --export-filename=\"%s/icon_pack.png\" --export-width=%d --export-height=%d \"%s\"", - TMPDIR, i, i, argv[2]); - - STARTUPINFOA sinfo = {sizeof(STARTUPINFOA)}; - PROCESS_INFORMATION pinfo; - if (!CreateProcessA(argv[1], command, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo)) - { - LPSTR messageBuffer = NULL; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); - fprintf(stderr, "unable to launch inkscape from %s: %s\n", argv[1], messageBuffer); - return 1; - } - CloseHandle(pinfo.hThread); - WaitForSingleObject(pinfo.hProcess, INFINITE); - CloseHandle(pinfo.hProcess); - -#else - snprintf(command, 2048, "%s --export-filename=\"%s/icon_pack.png\" --export-width=%d --export-height=%d \"%s\"", - argv[1], TMPDIR, i, i, argv[2]); - fp = popen(command, "r"); - if (!fp) - { - fprintf(stderr, "'%s' is not executable on this system\n", command); - fclose(ofp); - return 1; - } - int status = pclose(fp); - if (WEXITSTATUS(status)) - { - fprintf(stderr, "'%s' failed\n", command); - fclose(ofp); - return 1; - } -#endif - - /* Get PNG data */ - snprintf(command, 2048, "%s/icon_pack.png", TMPDIR); - fp = fopen(command, "rb"); - if (!fp) - { - fprintf(stderr, "unable to open '%s' for reading\n", command); - fclose(ofp); - return 1; - } - - char header[8]; - fread(header, 1, 8, fp); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) - { - fprintf(stderr, "invalid PNG signature in '%s'\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!pngRead) - { - fprintf(stderr, "unable to initialize libpng\n"); - fclose(fp); - fclose(ofp); - return 1; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) - { - fprintf(stderr, "unable to initialize libpng info\n"); - fclose(fp); - fclose(ofp); - return 1; - } - - if (setjmp(png_jmpbuf(pngRead))) - { - fprintf(stderr, "unable to initialize libpng I/O for '%s'\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - png_init_io(pngRead, fp); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - png_uint_32 width = png_get_image_width(pngRead, info); - png_uint_32 height = png_get_image_height(pngRead, info); - png_byte colorType = png_get_color_type(pngRead, info); - png_byte bitDepth = png_get_bit_depth(pngRead, info); - - if (CountBits(width) != 1 || CountBits(height) != 1) - { - fprintf(stderr, "'%s' is not power-of-2 in one or both dimensions\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) - { - fprintf(stderr, "'%s' is not in RGBA color mode\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - if (bitDepth != 8) - { - fprintf(stderr, "'%s' is not 8 bits-per-channel\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - if (setjmp(png_jmpbuf(pngRead))) - { - fprintf(stderr, "unable to read image in '%s'\n", command); - fclose(fp); - fclose(ofp); - return 1; - } - - if (i == 512) - { - uint32_t fmt = _bswap32(16); - uint16_t w = _bswap16(width); - uint16_t h = _bswap16(height); - uint32_t mips = _bswap32(numMips); - uint32_t dsz = _bswap32(decompSz); - fwrite(&fmt, 1, 4, ofp); - fwrite(&w, 1, 2, ofp); - fwrite(&h, 1, 2, ofp); - fwrite(&mips, 1, 4, ofp); - fwrite(&dsz, 1, 4, ofp); - - rowSz = width*4; - rowSzC = compressBound(rowSz); - deflateInit(&z, Z_DEFAULT_COMPRESSION); - row = malloc(rowSz); - rowC = malloc(rowSzC); - } - - for (png_uint_32 r=0 ; r - ARGS ${LOCALES_OUT} ${LOCALES_IN} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS genlocales ${LOCALES_IN}) - -add_library(UrdeLocales ${LOCALES_OUT} locale.hpp locale.cpp) -target_link_libraries(UrdeLocales fmt) -target_include_directories(UrdeLocales PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -target_link_libraries(specter PUBLIC UrdeLocales) diff --git a/Editor/locale/en_GB.yaml b/Editor/locale/en_GB.yaml deleted file mode 100644 index 2b5a4cf0c..000000000 --- a/Editor/locale/en_GB.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: "British English" -en_GB: - color: "Colour" diff --git a/Editor/locale/en_US.yaml b/Editor/locale/en_US.yaml deleted file mode 100644 index 3e3871aaf..000000000 --- a/Editor/locale/en_US.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: "US English" -en_US: - color: "Color" - branch: "Branch" - commit: "Commit" - release: "Release" - date: "Date" - new_project: "New Project" - open_project: "Open Project" - extract_game: "Extract Game" - name: "Name" - type: "Type" - size: "Size" - directory: "Directory" - file: "File" - file_name: "File Name" - cancel: "Cancel" - system_locations: "System Locations" - recent_projects: "Recent Projects" - recent_files: "Recent Files" - scroll_left: "Scroll Left" - scroll_right: "Scroll Right" - ok: "OK" - cancel: "Cancel" - boundary_action: "Boundary Action" - split: "Split" - join: "Join" - hecl_project: "HECL Project" - no_access_as_dir: "Unable to access '{}' as directory" - file_field_empty: "Unable to save empty file" - overwrite_confirm: "Overwrite '{}'?" - directory_field_empty: "Unable to make empty-named directory" - no_overwrite_file: "Unable to make directory over file" - no_overwrite_project: "Unable to make project within existing project" - no_access_as_file: "Unable to access '{}' as file" - space_types: "Space Types" - resource_browser: "Resource Browser" - effect_editor: "Effect Editor" - model_viewer: "Model Viewer" - information_center: "Information Center" - game_mode: "Game Mode" - version: "Version" \ No newline at end of file diff --git a/Editor/locale/genlocales.cpp b/Editor/locale/genlocales.cpp deleted file mode 100644 index 36bad71dd..000000000 --- a/Editor/locale/genlocales.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include -#include "athena/FileReader.hpp" -#include "athena/YAMLDocReader.hpp" - -#include -#include - -int main(int argc, char** argv) { - if (argc < 3) { - fmt::print(FMT_STRING("{} ...\n"), argv[0]); - return 1; - } - - std::ofstream out(argv[1]); - if (!out.is_open()) { - fmt::print(FMT_STRING("Unable to open {} for writing\n"), argv[1]); - return 1; - } - - std::unordered_set seenLocales; - std::stringstream enumLocales; - std::stringstream declLocales; - std::unordered_set seenKeys; - std::stringstream keys; - std::stringstream lookups; - std::stringstream dos; - - for (int i = 2; i < argc; ++i) { - athena::io::FileReader fr(argv[i]); - if (!fr.isOpen()) { - fmt::print(FMT_STRING("Unable to open {} for reading\n"), argv[i]); - return 1; - } - athena::io::YAMLDocReader r; - if (!r.parse(&fr)) { - fmt::print(FMT_STRING("Unable to parse {}\n"), argv[i]); - return 1; - } - - std::string name; - std::string fullName; - athena::io::YAMLNode* listNode = nullptr; - for (const auto& c : r.getRootNode()->m_mapChildren) { - if (c.first == "name") { - fullName = c.second->m_scalarString; - } else { - name = c.first; - listNode = c.second.get(); - } - } - if (fullName.empty()) { - fmt::print(FMT_STRING("Unable to find 'name' node in {}\n"), argv[i]); - return 1; - } - if (!listNode) { - fmt::print(FMT_STRING("Unable to find list node in {}\n"), argv[i]); - return 1; - } - - if (seenLocales.find(name) == seenLocales.end()) { - seenLocales.insert(name); - fmt::print(enumLocales, FMT_STRING(" {},\n"), name); - fmt::print(declLocales, - FMT_STRING("struct {0} {{ static constexpr auto Name = \"{0}\"sv; static constexpr auto FullName = \"{1}\"sv; }};\n"), - name, fullName); - fmt::print(dos, - FMT_STRING(" case ELocale::{0}:\n" - " return act.template Do<{0}>(std::forward(args)...);\n"), name); - fmt::print(lookups, FMT_STRING("/* {} */\n"), name); - for (const auto& k : listNode->m_mapChildren) { - if (seenKeys.find(k.first) == seenKeys.end()) { - seenKeys.insert(k.first); - fmt::print(keys, FMT_STRING("struct {} {{}};\n"), k.first); - } - fmt::print(lookups, - FMT_STRING("template<> struct Lookup<{}, {}> {{ static constexpr auto Value() {{ return FMT_STRING(\"{}\"); }} }};\n"), - name, k.first, k.second->m_scalarString); - } - } - lookups << '\n'; - } - - out << "/* Locales */\n" - "enum class ELocale {\n" - " Invalid = -1,\n"; - out << enumLocales.str(); - out << " MAXLocale\n" - "};\n"; - out << declLocales.str(); - out << "\n" - "using DefaultLocale = en_US;\n" - "template struct Lookup {\n" - " static_assert(!std::is_same_v, \"The default locale must translate all keys\");\n" - " static constexpr auto Value() { return Lookup::Value(); }\n" - "};\n" - "\n" - "/* Keys */\n"; - out << keys.str(); - out << "\n"; - out << lookups.str(); - out << "template \n" - "constexpr auto Do(ELocale l, Action act, Args&&... args) {\n" - " switch (l) {\n" - " default:\n"; - out << dos.str(); - out << " }\n" - "}\n"; - - return 0; -} diff --git a/Editor/locale/ja_JP.yaml b/Editor/locale/ja_JP.yaml deleted file mode 100644 index 847736741..000000000 --- a/Editor/locale/ja_JP.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: "日本語" -ja_JP: - color: "色" - branch: "分派" - commit: "預ける" - date: "年月日" - new_project: "新しいプロジェクト" - open_project: "プロジェクトを開きます" - extract_game: "ビデオゲームを抽出" - name: "名" - type: "タイプ" - size: "サイズ" - directory: "ディレクトリ" - file: "ファイル" - file_name: "ファイル名" - cancel: "キャンセル" - system_locations: "システムの場所" - recent_projects: "最近使ったプロジェクト" - recent_files: "最近使用したファイル" diff --git a/Editor/locale/locale.cpp b/Editor/locale/locale.cpp deleted file mode 100644 index ff6d0bb34..000000000 --- a/Editor/locale/locale.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "locale.hpp" -#include -#include -#include - -#undef min -#undef max - -namespace locale { - -std::vector> ListLocales() { - std::vector> ret; - ret.reserve(std::size_t(ELocale::MAXLocale)); - for (ELocale l = ELocale(0); l < ELocale::MAXLocale; l = ELocale(int(l) + 1)) - ret.emplace_back(GetName(l), GetFullName(l)); - return ret; -} - -ELocale LookupLocale(std::string_view name) { - for (ELocale l = ELocale(0); l < ELocale::MAXLocale; l = ELocale(int(l) + 1)) - if (name == GetName(l)) - return l; - return ELocale::Invalid; -} - -ELocale SystemLocaleOrEnglish() { - const char* sysLocale = std::setlocale(LC_ALL, nullptr); - size_t sysLocaleLen = std::strlen(sysLocale); - for (ELocale l = ELocale(0); l < ELocale::MAXLocale; l = ELocale(int(l) + 1)) { - auto name = GetName(l); - if (!name.compare(0, std::min(name.size(), sysLocaleLen), sysLocale)) - return l; - } - return ELocale::en_US; -} - -} // namespace locale diff --git a/Editor/locale/locale.hpp b/Editor/locale/locale.hpp deleted file mode 100644 index 86d4aad7e..000000000 --- a/Editor/locale/locale.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include -#include -#include - -#include - -namespace locale { -using namespace std::literals; -#include - -struct DoGetName { - template - constexpr auto Do() { return L::Name; } -}; -constexpr auto GetName(ELocale l) { - return Do(l, DoGetName()); -} - -struct DoGetFullName { - template - constexpr auto Do() { return L::FullName; } -}; -constexpr auto GetFullName(ELocale l) { - return Do(l, DoGetFullName()); -} - -template -struct DoTranslate { - template - constexpr auto Do(Args&&... args) { return fmt::format(Lookup::Value(), std::forward(args)...); } -}; -template -constexpr auto Translate(ELocale l, Args&&... args) { - return Do(l, DoTranslate(), std::forward(args)...); -} - -std::vector> ListLocales(); -ELocale LookupLocale(std::string_view name); -ELocale SystemLocaleOrEnglish(); - -} // namespace locale diff --git a/Editor/main.cpp b/Editor/main.cpp deleted file mode 100644 index 980d12988..000000000 --- a/Editor/main.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "logvisor/logvisor.hpp" -#include "boo/boo.hpp" -#include "specter/specter.hpp" -#include "hecl/CVarManager.hpp" -#include "Runtime/CBasics.hpp" -#include "ViewManager.hpp" -#include "hecl/hecl.hpp" -#include "hecl/CVarCommons.hpp" -#include "hecl/Console.hpp" -#include "fmt/chrono.h" -#include "version.h" -#include "optick.h" - -static logvisor::Module AthenaLog("Athena"); -static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, fmt::string_view fmt, - fmt::format_args args) { - AthenaLog.vreport(logvisor::Level(level), fmt, args); -} - -namespace metaforce { -static logvisor::Module Log{"Metaforce"}; - -static hecl::SystemString CPUFeatureString(const zeus::CPUInfo& cpuInf) { - hecl::SystemString features; -#if defined(__x86_64__) || defined(_M_X64) - auto AddFeature = [&features](const hecl::SystemChar* str) { - if (!features.empty()) - features += _SYS_STR(", "); - features += str; - }; - if (cpuInf.AESNI) - AddFeature(_SYS_STR("AES-NI")); - if (cpuInf.SSE1) - AddFeature(_SYS_STR("SSE")); - if (cpuInf.SSE2) - AddFeature(_SYS_STR("SSE2")); - if (cpuInf.SSE3) - AddFeature(_SYS_STR("SSE3")); - if (cpuInf.SSSE3) - AddFeature(_SYS_STR("SSSE3")); - if (cpuInf.SSE4a) - AddFeature(_SYS_STR("SSE4a")); - if (cpuInf.SSE41) - AddFeature(_SYS_STR("SSE4.1")); - if (cpuInf.SSE42) - AddFeature(_SYS_STR("SSE4.2")); - if (cpuInf.AVX) - AddFeature(_SYS_STR("AVX")); - if (cpuInf.AVX2) - AddFeature(_SYS_STR("AVX2")); -#endif - return features; -} - -struct Application : boo::IApplicationCallback { - hecl::Runtime::FileStoreManager& m_fileMgr; - hecl::CVarManager& m_cvarManager; - hecl::CVarCommons& m_cvarCommons; - std::unique_ptr m_viewManager; - - std::atomic_bool m_running = {true}; - - Application(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr, hecl::CVarCommons& cvarCmns) - : m_fileMgr(fileMgr) - , m_cvarManager(cvarMgr) - , m_cvarCommons(cvarCmns) - , m_viewManager(std::make_unique(m_fileMgr, m_cvarManager)) {} - - virtual ~Application() = default; - - int appMain(boo::IApplication* app) override { - initialize(app); - m_viewManager->init(app); - while (m_running.load()) { - OPTICK_FRAME("MainThread"); - if (!m_viewManager->proc()) - break; - } - m_viewManager->stop(); - m_viewManager->projectManager().saveProject(); - m_cvarManager.serialize(); - m_viewManager.reset(); - return 0; - } - void appQuitting(boo::IApplication*) override { m_running.store(false); } - void appFilesOpen(boo::IApplication*, const std::vector& paths) override { - for (const auto& path : paths) { - hecl::ProjectRootPath projPath = hecl::SearchForProject(path); - if (projPath) { - m_viewManager->deferOpenProject(path); - break; - } - } - } - - void initialize(boo::IApplication* app) { - zeus::detectCPU(); - - for (const boo::SystemString& arg : app->getArgs()) { - if (arg.find(_SYS_STR("--verbosity=")) == 0 || arg.find(_SYS_STR("-v=")) == 0) { - hecl::SystemUTF8Conv utf8Arg(arg.substr(arg.find_last_of('=') + 1)); - hecl::VerbosityLevel = atoi(utf8Arg.c_str()); - hecl::LogModule.report(logvisor::Info, FMT_STRING("Set verbosity level to {}"), hecl::VerbosityLevel); - } - } - - const zeus::CPUInfo& cpuInf = zeus::cpuFeatures(); - Log.report(logvisor::Info, FMT_STRING("CPU Name: {}"), cpuInf.cpuBrand); - Log.report(logvisor::Info, FMT_STRING("CPU Vendor: {}"), cpuInf.cpuVendor); - Log.report(logvisor::Info, FMT_STRING(_SYS_STR("CPU Features: {}")), CPUFeatureString(cpuInf)); - } - - std::string getGraphicsApi() const { return m_cvarCommons.getGraphicsApi(); } - - uint32_t getSamples() const { return m_cvarCommons.getSamples(); } - - uint32_t getAnisotropy() const { return m_cvarCommons.getAnisotropy(); } - - bool getDeepColor() const { return m_cvarCommons.getDeepColor(); } - - int64_t getTargetFrameTime() { return m_cvarCommons.getVariableFrameTime() ? 0 : 1000000000L / 60; } -}; - -} // namespace metaforce - -static hecl::SystemChar CwdBuf[1024]; -hecl::SystemString ExeDir; - -static void SetupBasics(bool logging) { - auto result = zeus::validateCPU(); - if (!result.first) { -#if _WIN32 && !WINDOWS_STORE - std::wstring msg = fmt::format(FMT_STRING(L"ERROR: This build of Metaforce requires the following CPU features:\n{}\n"), - metaforce::CPUFeatureString(result.second)); - MessageBoxW(nullptr, msg.c_str(), L"CPU error", MB_OK | MB_ICONERROR); -#else - fmt::print(stderr, FMT_STRING("ERROR: This build of Metaforce requires the following CPU features:\n{}\n"), - metaforce::CPUFeatureString(result.second)); -#endif - exit(1); - } - - logvisor::RegisterStandardExceptions(); - if (logging) - logvisor::RegisterConsoleLogger(); - atSetExceptionHandler(AthenaExc); - -#if SENTRY_ENABLED - hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("sentry-native-metaforce")}; - hecl::SystemUTF8Conv cacheDir{fileMgr.getStoreRoot()}; - logvisor::RegisterSentry("metaforce", METAFORCE_WC_DESCRIBE, cacheDir.c_str()); -#endif -} - -static bool IsClientLoggingEnabled(int argc, const boo::SystemChar** argv) { - for (int i = 1; i < argc; ++i) - if (!hecl::StrNCmp(argv[i], _SYS_STR("-l"), 2)) - return true; - return false; -} - -#if !WINDOWS_STORE -#if _WIN32 -int wmain(int argc, const boo::SystemChar** argv) -#else -int main(int argc, const boo::SystemChar** argv) -#endif -{ - if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) { - fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE); - return 100; - } - - SetupBasics(IsClientLoggingEnabled(argc, argv)); - hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("metaforce")}; - hecl::CVarManager cvarMgr{fileMgr}; - hecl::CVarCommons cvarCmns{cvarMgr}; - - std::vector args; - for (int i = 1; i < argc; ++i) - args.push_back(argv[i]); - cvarMgr.parseCommandLine(args); - - hecl::SystemString logFile{hecl::SystemStringConv(cvarCmns.getLogFile()).c_str()}; - hecl::SystemString logFilePath; - if (!logFile.empty()) { - std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - char buf[100]; - std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time)); - hecl::SystemString timeStr = hecl::SystemStringConv(buf).c_str(); - logFilePath = fmt::format(FMT_STRING(_SYS_STR("{}/{}-{}")), fileMgr.getStoreRoot(), timeStr, logFile); - logvisor::RegisterFileLogger(logFilePath.c_str()); - } - - if (hecl::SystemChar* cwd = hecl::Getcwd(CwdBuf, 1024)) { - if (hecl::PathRelative(argv[0])) - ExeDir = hecl::SystemString(cwd) + _SYS_STR('/'); - hecl::SystemString Argv0(argv[0]); - hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\")); - if (lastIdx != hecl::SystemString::npos) - ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx); - } - - /* Handle -j argument */ - hecl::SetCpuCountOverride(argc, argv); - - metaforce::Application appCb(fileMgr, cvarMgr, cvarCmns); - int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, _SYS_STR("metaforce"), - _SYS_STR("Metaforce"), argc, argv, appCb.getGraphicsApi(), appCb.getSamples(), - appCb.getAnisotropy(), appCb.getDeepColor(), appCb.getTargetFrameTime(), false); - // printf("IM DYING!!\n"); - return ret; -} -#endif - -#if WINDOWS_STORE -#include "boo/UWPViewProvider.hpp" -using namespace Windows::ApplicationModel::Core; - -[Platform::MTAThread] int WINAPIV main(Platform::Array ^ params) { - SetupBasics(false); - metaforce::Application appCb; - auto viewProvider = - ref new boo::ViewProvider(appCb, _SYS_STR("metaforce"), _SYS_STR("Metaforce"), _SYS_STR("metaforce"), params, false); - CoreApplication::Run(viewProvider); - return 0; -} - -#elif _WIN32 -int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) { - int argc = 0; - const boo::SystemChar** argv; - if (lpCmdLine[0]) - argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc)); - static boo::SystemChar selfPath[1024]; - GetModuleFileNameW(nullptr, selfPath, 1024); - static const boo::SystemChar* booArgv[32] = {}; - booArgv[0] = selfPath; - for (int i = 0; i < argc; ++i) - booArgv[i + 1] = argv[i]; - - const DWORD outType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)); - if (IsClientLoggingEnabled(argc + 1, booArgv) && outType == FILE_TYPE_UNKNOWN) - logvisor::CreateWin32Console(); - return wmain(argc + 1, booArgv); -} -#endif diff --git a/Editor/platforms/freedesktop/CMakeLists.txt b/Editor/platforms/freedesktop/CMakeLists.txt deleted file mode 100644 index 990fbf1cb..000000000 --- a/Editor/platforms/freedesktop/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_executable(mkwmicon mkwmicon.c) -target_link_libraries(mkwmicon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) -target_include_directories(mkwmicon PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) - -macro(declare_wmicon_target) -add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_netwm.bin - COMMAND $ - ARGS ${CMAKE_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_netwm.bin - DEPENDS - ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop/128x128/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop/64x64/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop/48x48/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop/32x32/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop/16x16/apps/metaforce.png - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Editor/platforms/freedesktop - COMMENT "Generating mainicon_netwm.bin") -bintoc(mainicon_netwm.cpp ${CMAKE_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_netwm.bin MAINICON_NETWM) -endmacro() diff --git a/Runtime/CMain.cpp b/Runtime/CMain.cpp new file mode 100644 index 000000000..c2e3923ca --- /dev/null +++ b/Runtime/CMain.cpp @@ -0,0 +1,509 @@ +#include +#include +#include +#include + +#include "boo/boo.hpp" +#include "logvisor/logvisor.hpp" + +#include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/MP1/MP1.hpp" +#include "cmake-build-debug-llvm/hecl/DataSpecRegistry.hpp" +#include "amuse/BooBackend.hpp" +#include "../version.h" + +using namespace std::literals; + +static logvisor::Module AthenaLog("Athena"); +static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, fmt::string_view fmt, + fmt::format_args args) { + AthenaLog.vreport(logvisor::Level(level), fmt, args); +} + +class Limiter { + using delta_clock = std::chrono::steady_clock; + using nanotime_t = std::chrono::nanoseconds::rep; + +public: + void Sleep(nanotime_t targetFrameTime) { + if (targetFrameTime == 0) { + return; + } + + auto start = delta_clock::now(); + nanotime_t adjustedSleepTime = ShouldSleep(targetFrameTime); + if (adjustedSleepTime > 0) { + std::this_thread::sleep_for(std::chrono::nanoseconds(adjustedSleepTime)); + nanotime_t overslept = TimeSince(start) - adjustedSleepTime; + if (overslept < targetFrameTime) { + m_overheadTimes[m_overheadTimeIdx] = overslept; + m_overheadTimeIdx = (m_overheadTimeIdx + 1) % m_overheadTimes.size(); + } + } + m_oldTime = delta_clock::now(); + } + + nanotime_t ShouldSleep(nanotime_t targetFrameTime) { + nanotime_t sleepTime = targetFrameTime - TimeSince(m_oldTime); + m_overhead = std::accumulate(m_overheadTimes.begin(), m_overheadTimes.end(), nanotime_t{}) / + static_cast(m_overheadTimes.size()); + if (sleepTime > m_overhead) { + return sleepTime - m_overhead; + } + return 0; + } + +private: + delta_clock::time_point m_oldTime; + std::array m_overheadTimes{}; + size_t m_overheadTimeIdx = 0; + nanotime_t m_overhead = 0; + + nanotime_t TimeSince(delta_clock::time_point start) { + return std::chrono::duration_cast(delta_clock::now() - start).count(); + } +}; + +extern hecl::SystemString ExeDir; + +namespace metaforce { +static logvisor::Module Log{"Metaforce"}; + +std::optional g_mainMP1; + +static hecl::SystemString CPUFeatureString(const zeus::CPUInfo& cpuInf) { + hecl::SystemString features; +#if defined(__x86_64__) || defined(_M_X64) + auto AddFeature = [&features](const hecl::SystemChar* str) { + if (!features.empty()) + features += _SYS_STR(", "); + features += str; + }; + if (cpuInf.AESNI) + AddFeature(_SYS_STR("AES-NI")); + if (cpuInf.SSE1) + AddFeature(_SYS_STR("SSE")); + if (cpuInf.SSE2) + AddFeature(_SYS_STR("SSE2")); + if (cpuInf.SSE3) + AddFeature(_SYS_STR("SSE3")); + if (cpuInf.SSSE3) + AddFeature(_SYS_STR("SSSE3")); + if (cpuInf.SSE4a) + AddFeature(_SYS_STR("SSE4a")); + if (cpuInf.SSE41) + AddFeature(_SYS_STR("SSE4.1")); + if (cpuInf.SSE42) + AddFeature(_SYS_STR("SSE4.2")); + if (cpuInf.AVX) + AddFeature(_SYS_STR("AVX")); + if (cpuInf.AVX2) + AddFeature(_SYS_STR("AVX2")); +#endif + return features; +} + +struct WindowCallback : boo::IWindowCallback { + bool m_fullscreenToggleRequested = false; + boo::SWindowRect m_lastRect; + bool m_rectDirty = false; + bool m_windowInvalid = false; + + void resized(const boo::SWindowRect& rect, bool sync) override { + m_lastRect = rect; + m_rectDirty = true; + } + + void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->mouseDown(coord, button, mods); + } + } + } + + void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->mouseUp(coord, button, mods); + } + } + } + + void mouseMove(const boo::SWindowCoord& coord) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->mouseMove(coord); + } + } + } + + void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->scroll(coord, scroll); + } + } + } + + void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->charKeyDown(charCode, mods, isRepeat); + } + } + } + + void charKeyUp(unsigned long charCode, boo::EModifierKey mods) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->charKeyUp(charCode, mods); + } + } + } + + void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->specialKeyDown(key, mods, isRepeat); + } + } + if (key == boo::ESpecialKey::Enter && True(mods & boo::EModifierKey::Alt)) + m_fullscreenToggleRequested = true; + } + + void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) override { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->specialKeyUp(key, mods); + } + } + } + + void destroyed() override { m_windowInvalid = true; } +}; + +struct Application : boo::IApplicationCallback { + std::shared_ptr m_window; + WindowCallback m_windowCallback; + hecl::Runtime::FileStoreManager& m_fileMgr; + hecl::CVarManager& m_cvarManager; + hecl::CVarCommons& m_cvarCommons; + + boo::ObjToken m_renderTex; + hecl::SystemString m_deferredProject; + std::unique_ptr m_proj; + std::optional m_amuseAllocWrapper; + std::unique_ptr m_voiceEngine; + std::unique_ptr m_pipelineConv; + + Limiter m_limiter{}; + std::atomic_bool m_running = {true}; + bool m_noShaderWarmup = false; + +public: + Application(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr, hecl::CVarCommons& cvarCmns) + : m_fileMgr(fileMgr), m_cvarManager(cvarMgr), m_cvarCommons(cvarCmns) {} + + int appMain(boo::IApplication* app) override { + initialize(app); + + m_window = app->newWindow(_SYS_STR("Metaforce"sv)); + if (!m_window) { + return 1; + } + m_window->setCallback(&m_windowCallback); + m_window->showWindow(); + + boo::SWindowRect rect = m_window->getWindowFrame(); + m_window->getMainContextDataFactory()->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { + m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3); + return true; + } BooTrace); + + m_pipelineConv = hecl::NewPipelineConverter(m_window->getMainContextDataFactory()); + hecl::conv = m_pipelineConv.get(); + + m_voiceEngine = boo::NewAudioVoiceEngine(); + m_voiceEngine->setVolume(0.7f); + m_amuseAllocWrapper.emplace(*m_voiceEngine); + + hecl::ProjectPath projectPath; + for (const auto& arg : app->getArgs()) { + hecl::Sstat theStat; + if (!hecl::Stat((arg + _SYS_STR("/out")).c_str(), &theStat) && S_ISDIR(theStat.st_mode)) { + hecl::ProjectRootPath rootPath(arg); + hecl::Database::Project tmp(rootPath); // Force project creation + } + if (m_deferredProject.empty() && hecl::SearchForProject(arg)) + m_deferredProject = arg; + if (arg == _SYS_STR("--no-shader-warmup")) + m_noShaderWarmup = true; + else if (arg == _SYS_STR("--no-sound")) + m_voiceEngine->setVolume(0.f); + } + + if (m_deferredProject.empty()) { + /* Default behavior - search upwards for packaged project containing the program */ + if (hecl::ProjectRootPath projRoot = hecl::SearchForProject(ExeDir)) { + hecl::SystemString rootPath(projRoot.getAbsolutePath()); + hecl::Sstat theStat; + if (hecl::Stat((rootPath + _SYS_STR("/out/files/MP1/Metroid1.upak")).c_str(), &theStat) == 0 && + S_ISREG(theStat.st_mode)) + m_deferredProject = rootPath + _SYS_STR("/out"); + } + } + + while (m_running) { + onAppIdle(); + } + + if (m_window) { + m_window->getCommandQueue()->stopRenderer(); + } + if (g_mainMP1) + g_mainMP1->Shutdown(); + g_mainMP1.reset(); + m_voiceEngine.reset(); + m_amuseAllocWrapper.reset(); + CDvdFile::Shutdown(); + return 0; + } + + void initialize(boo::IApplication* app) { + zeus::detectCPU(); + + for (const boo::SystemString& arg : app->getArgs()) { + if (arg.find(_SYS_STR("--verbosity=")) == 0 || arg.find(_SYS_STR("-v=")) == 0) { + hecl::SystemUTF8Conv utf8Arg(arg.substr(arg.find_last_of('=') + 1)); + hecl::VerbosityLevel = atoi(utf8Arg.c_str()); + hecl::LogModule.report(logvisor::Info, FMT_STRING("Set verbosity level to {}"), hecl::VerbosityLevel); + } + } + + const zeus::CPUInfo& cpuInf = zeus::cpuFeatures(); + Log.report(logvisor::Info, FMT_STRING("CPU Name: {}"), cpuInf.cpuBrand); + Log.report(logvisor::Info, FMT_STRING("CPU Vendor: {}"), cpuInf.cpuVendor); + Log.report(logvisor::Info, FMT_STRING(_SYS_STR("CPU Features: {}")), CPUFeatureString(cpuInf)); + } + + void onAppIdle() noexcept { + if (!m_deferredProject.empty()) { + hecl::SystemString subPath; + hecl::ProjectRootPath projPath = hecl::SearchForProject(m_deferredProject, subPath); + if (!projPath) { + Log.report(logvisor::Error, FMT_STRING(_SYS_STR("project doesn't exist at '{}'")), m_deferredProject); + m_running.store(false); + return; + } + m_proj = std::make_unique(projPath); + m_deferredProject.clear(); + hecl::ProjectPath projectPath{m_proj->getProjectWorkingPath(), _SYS_STR("out/files/MP1")}; + CDvdFile::Initialize(projectPath); + } + if (!m_proj) { + Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Project directory not specified"))); + m_running.store(false); + return; + } + + m_cvarManager.proc(); + + if (m_windowCallback.m_windowInvalid) { + m_running.store(false); + return; + } + + m_window->waitForRetrace(); + + boo::IGraphicsCommandQueue* gfxQ = m_window->getCommandQueue(); + if (m_windowCallback.m_rectDirty) { + boo::SWindowRect& rect = m_windowCallback.m_lastRect; + gfxQ->resizeRenderTexture(m_renderTex, rect.size[0], rect.size[1]); + metaforce::CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); + m_windowCallback.m_rectDirty = false; + } + + if (m_windowCallback.m_fullscreenToggleRequested) { + m_window->setFullscreen(!m_window->isFullscreen()); + m_windowCallback.m_fullscreenToggleRequested = false; + } + + if (!g_mainMP1) { + g_mainMP1.emplace(nullptr, nullptr, m_window->getMainContextDataFactory(), gfxQ, m_renderTex.get()); + g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_window.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); + if (!m_noShaderWarmup) { + g_mainMP1->WarmupShaders(); + } + } + + if (g_mainMP1->Proc()) { + m_running.store(false); + return; + } + + gfxQ->setRenderTarget(m_renderTex); + { + OPTICK_EVENT("Draw"); + if (g_Renderer) + g_Renderer->BeginScene(); + g_mainMP1->Draw(); + if (g_Renderer) + g_Renderer->EndScene(); + gfxQ->execute(); + } + gfxQ->resolveDisplay(m_renderTex); + + if (g_ResFactory != nullptr) { + int64_t targetFrameTime = getTargetFrameTime(); + do { + g_ResFactory->AsyncIdle(); + } while (m_limiter.ShouldSleep(targetFrameTime) != 0); + m_limiter.Sleep(targetFrameTime); + } + + if (m_voiceEngine) { + m_voiceEngine->pumpAndMixVoices(); + } + CBooModel::ClearModelUniformCounters(); + CGraphics::TickRenderTimings(); + ++logvisor::FrameIndex; + } + + void appQuitting(boo::IApplication* /*unused*/) override { m_running.store(false); } + + [[nodiscard]] std::string getGraphicsApi() const { return m_cvarCommons.getGraphicsApi(); } + + [[nodiscard]] uint32_t getSamples() const { return m_cvarCommons.getSamples(); } + + [[nodiscard]] uint32_t getAnisotropy() const { return m_cvarCommons.getAnisotropy(); } + + [[nodiscard]] bool getDeepColor() const { return m_cvarCommons.getDeepColor(); } + + [[nodiscard]] int64_t getTargetFrameTime() const { return m_cvarCommons.getVariableFrameTime() ? 0 : 1000000000L / 60; } +}; + +} // namespace metaforce + +static hecl::SystemChar CwdBuf[1024]; +hecl::SystemString ExeDir; + +static void SetupBasics(bool logging) { + auto result = zeus::validateCPU(); + if (!result.first) { +#if _WIN32 && !WINDOWS_STORE + std::wstring msg = + fmt::format(FMT_STRING(L"ERROR: This build of Metaforce requires the following CPU features:\n{}\n"), + metaforce::CPUFeatureString(result.second)); + MessageBoxW(nullptr, msg.c_str(), L"CPU error", MB_OK | MB_ICONERROR); +#else + fmt::print(stderr, FMT_STRING("ERROR: This build of Metaforce requires the following CPU features:\n{}\n"), + metaforce::CPUFeatureString(result.second)); +#endif + exit(1); + } + + logvisor::RegisterStandardExceptions(); + if (logging) + logvisor::RegisterConsoleLogger(); + atSetExceptionHandler(AthenaExc); + +#if SENTRY_ENABLED + hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("sentry-native-metaforce")}; + hecl::SystemUTF8Conv cacheDir{fileMgr.getStoreRoot()}; + logvisor::RegisterSentry("metaforce", METAFORCE_WC_DESCRIBE, cacheDir.c_str()); +#endif +} + +static bool IsClientLoggingEnabled(int argc, const boo::SystemChar** argv) { + for (int i = 1; i < argc; ++i) + if (!hecl::StrNCmp(argv[i], _SYS_STR("-l"), 2)) + return true; + return false; +} + +#if !WINDOWS_STORE +#if _WIN32 +int wmain(int argc, const boo::SystemChar** argv) +#else +int main(int argc, const boo::SystemChar** argv) +#endif +{ + if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) { + fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE); + return 100; + } + + SetupBasics(IsClientLoggingEnabled(argc, argv)); + hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("metaforce")}; + hecl::CVarManager cvarMgr{fileMgr}; + hecl::CVarCommons cvarCmns{cvarMgr}; + + std::vector args; + for (int i = 1; i < argc; ++i) + args.push_back(argv[i]); + cvarMgr.parseCommandLine(args); + + hecl::SystemString logFile{hecl::SystemStringConv(cvarCmns.getLogFile()).c_str()}; + hecl::SystemString logFilePath; + if (!logFile.empty()) { + std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + char buf[100]; + std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time)); + hecl::SystemString timeStr = hecl::SystemStringConv(buf).c_str(); + logFilePath = fmt::format(FMT_STRING(_SYS_STR("{}/{}-{}")), fileMgr.getStoreRoot(), timeStr, logFile); + logvisor::RegisterFileLogger(logFilePath.c_str()); + } + + if (hecl::SystemChar* cwd = hecl::Getcwd(CwdBuf, 1024)) { + if (hecl::PathRelative(argv[0])) + ExeDir = hecl::SystemString(cwd) + _SYS_STR('/'); + hecl::SystemString Argv0(argv[0]); + hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\")); + if (lastIdx != hecl::SystemString::npos) + ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx); + } + + /* Handle -j argument */ + hecl::SetCpuCountOverride(argc, argv); + + metaforce::Application appCb(fileMgr, cvarMgr, cvarCmns); + int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, _SYS_STR("metaforce"), + _SYS_STR("Metaforce"), argc, argv, appCb.getGraphicsApi(), appCb.getSamples(), + appCb.getAnisotropy(), appCb.getDeepColor(), false); + return ret; +} +#endif + +#if WINDOWS_STORE +#include "boo/UWPViewProvider.hpp" +using namespace Windows::ApplicationModel::Core; + +[Platform::MTAThread] int WINAPIV main(Platform::Array ^ params) { + SetupBasics(false); + metaforce::Application appCb; + auto viewProvider = ref new boo::ViewProvider(appCb, _SYS_STR("metaforce"), _SYS_STR("Metaforce"), + _SYS_STR("metaforce"), params, false); + CoreApplication::Run(viewProvider); + return 0; +} + +#elif _WIN32 +int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) { + int argc = 0; + const boo::SystemChar** argv; + if (lpCmdLine[0]) + argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc)); + static boo::SystemChar selfPath[1024]; + GetModuleFileNameW(nullptr, selfPath, 1024); + static const boo::SystemChar* booArgv[32] = {}; + booArgv[0] = selfPath; + for (int i = 0; i < argc; ++i) + booArgv[i + 1] = argv[i]; + + const DWORD outType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)); + if (IsClientLoggingEnabled(argc + 1, booArgv) && outType == FILE_TYPE_UNKNOWN) + logvisor::CreateWin32Console(); + return wmain(argc + 1, booArgv); +} +#endif diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 78a557668..b31f55147 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -49,8 +49,9 @@ if(APPLE) endif() set(RUNTIME_SOURCES_A + MkCastTo.py + TCastTo.hpp TCastTo.cpp RetroTypes.hpp RetroTypes.cpp - ${CLIENT_SOURCES} ${MP1_SOURCES} ${AUDIO_SOURCES} ${AUTOMAPPER_SOURCES} @@ -114,8 +115,6 @@ set(RUNTIME_SOURCES_B CGameHintInfo.hpp CGameHintInfo.cpp rstl.hpp GameGlobalObjects.hpp GameGlobalObjects.cpp - MkCastTo.py - TCastTo.hpp TCastTo.cpp GCNTypes.hpp CTextureCache.hpp CTextureCache.cpp CMayaSpline.hpp CMayaSpline.cpp @@ -136,16 +135,82 @@ set(RUNTIME_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) set(RUNTIME_LIBRARIES ${HECL_APPLICATION_REPS_TARGETS_LIST} RetroDataSpec AssetNameMapNull NESEmulator libjpeg-turbo jbus kabufuda discord-rpc logvisor OptickCore) -if(MSVC) - # WTF MS???? LINK.EXE is unable to address static libraries larger than 4GB. - # This is a hack to split this large library in two. - add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A}) - add_runtime_common_library(RuntimeCommonB ${RUNTIME_SOURCES_B}) - target_include_directories(RuntimeCommonB PUBLIC ${RUNTIME_INCLUDES}) - target_link_libraries(RuntimeCommonB PUBLIC ${RUNTIME_LIBRARIES}) - target_link_libraries(RuntimeCommon PUBLIC RuntimeCommonB) -else() - add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A} ${RUNTIME_SOURCES_B}) - target_include_directories(RuntimeCommon PUBLIC ${RUNTIME_INCLUDES}) - target_link_libraries(RuntimeCommon PUBLIC ${RUNTIME_LIBRARIES}) +add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A}) +target_include_directories(RuntimeCommon PUBLIC ${RUNTIME_INCLUDES}) +add_runtime_common_library(RuntimeCommonB ${RUNTIME_SOURCES_B}) +target_link_libraries(RuntimeCommonB PUBLIC ${RUNTIME_LIBRARIES}) +target_link_libraries(RuntimeCommon PUBLIC RuntimeCommonB) + +if(WIN32) + configure_file(platforms/win/metaforce.rc.in "${CMAKE_CURRENT_SOURCE_DIR}/platforms/win/metaforce.rc" @ONLY) + set(PLAT_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/platforms/win/metaforce.rc" platforms/win/metaforce.manifest) + if(WINDOWS_STORE) + set(UWP_ASSETS + platforms/win/Assets/LargeTile.scale-100.png + platforms/win/Assets/LargeTile.scale-125.png + platforms/win/Assets/LargeTile.scale-150.png + platforms/win/Assets/LargeTile.scale-200.png + platforms/win/Assets/LargeTile.scale-400.png + platforms/win/Assets/SmallTile.scale-100.png + platforms/win/Assets/SmallTile.scale-125.png + platforms/win/Assets/SmallTile.scale-150.png + platforms/win/Assets/SmallTile.scale-200.png + platforms/win/Assets/SmallTile.scale-400.png + platforms/win/Assets/SplashScreen.scale-100.png + platforms/win/Assets/SplashScreen.scale-125.png + platforms/win/Assets/SplashScreen.scale-150.png + platforms/win/Assets/SplashScreen.scale-200.png + platforms/win/Assets/SplashScreen.scale-400.png + platforms/win/Assets/Square44x44Logo.scale-100.png + platforms/win/Assets/Square44x44Logo.scale-125.png + platforms/win/Assets/Square44x44Logo.scale-150.png + platforms/win/Assets/Square44x44Logo.scale-200.png + platforms/win/Assets/Square44x44Logo.scale-400.png + platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png + platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png + platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png + platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png + platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png + platforms/win/Assets/Square150x150Logo.scale-100.png + platforms/win/Assets/Square150x150Logo.scale-125.png + platforms/win/Assets/Square150x150Logo.scale-150.png + platforms/win/Assets/Square150x150Logo.scale-200.png + platforms/win/Assets/Square150x150Logo.scale-400.png + platforms/win/Assets/metaforce.scale-100.png + platforms/win/Assets/metaforce.scale-125.png + platforms/win/Assets/metaforce.scale-150.png + platforms/win/Assets/metaforce.scale-200.png + platforms/win/Assets/metaforce.scale-400.png + platforms/win/Assets/WideTile.scale-100.png + platforms/win/Assets/WideTile.scale-125.png + platforms/win/Assets/WideTile.scale-150.png + platforms/win/Assets/WideTile.scale-200.png + platforms/win/Assets/WideTile.scale-400.png) + set_property(SOURCE platforms/win/Package.appxmanifest PROPERTY VS_DEPLOYMENT_CONTENT 1) + set_property(SOURCE ${UWP_ASSETS} PROPERTY VS_DEPLOYMENT_CONTENT 1) + set_property(SOURCE ${UWP_ASSETS} PROPERTY VS_DEPLOYMENT_LOCATION "Assets") + list(APPEND PLAT_SRCS ${UWP_ASSETS} platforms/win/Package.appxmanifest) + endif() +elseif(APPLE) + # nothing +elseif(UNIX) + add_subdirectory(platforms/freedesktop) + declare_wmicon_target() + set(PLAT_SRCS mainicon_netwm.cpp) + set(PLAT_LIBS rt) +endif() + +add_executable(metaforce CMain.cpp ${PLAT_SRCS}) +target_link_libraries(metaforce PUBLIC RuntimeCommon ${PLAT_LIBS}) + +if(COMMAND add_sanitizers) + add_sanitizers(metaforce) +endif() + +if (NOT WINDOWS_STORE) + add_dependencies(metaforce visigen hecl) +else() + set_property(TARGET metaforce PROPERTY VS_WINRT_COMPONENT TRUE) + # This should match the Package.appxmanifest + set_property(TARGET metaforce PROPERTY VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION "10.0.14393.0") endif() diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 85e4144b5..37eb1bbfa 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -1,7 +1,5 @@ #include "Runtime/Character/CModelData.hpp" -#include "Editor/ProjectManager.hpp" - #include "Runtime/CPlayerState.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" diff --git a/Runtime/Graphics/CMoviePlayer.cpp b/Runtime/Graphics/CMoviePlayer.cpp index d779c590d..9c4865c90 100644 --- a/Runtime/Graphics/CMoviePlayer.cpp +++ b/Runtime/Graphics/CMoviePlayer.cpp @@ -1,17 +1,17 @@ #include "Runtime/Graphics/CMoviePlayer.hpp" -#include "Runtime/CDvdRequest.hpp" #include "Runtime/Audio/g721.h" +#include "Runtime/CDvdRequest.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include -#include #include -#include #include namespace metaforce { +zeus::CMatrix4f g_PlatformMatrix; + /* used in the original to look up fixed-point dividends on a * MIDI-style volume scale (0-127) -> (n/0x8000) */ static const u16 StaticVolumeLookup[] = { @@ -46,7 +46,14 @@ static float SfxVolume = 1.f; static const char* BlockNames[] = {"SpecterViewBlock"}; static const char* TexNames[] = {"texY", "texU", "texV"}; -void CMoviePlayer::Initialize() { +void CMoviePlayer::Initialize(boo::IGraphicsDataFactory* factory) { + switch (factory->platform()) { + case boo::IGraphicsDataFactory::Platform::Vulkan: + g_PlatformMatrix.m[1][1] = -1.f; + break; + default: + break; + } YUVShaderPipeline = hecl::conv->convert(Shader_CMoviePlayerShader{}); TjHandle = tjInitDecompress(); } @@ -200,7 +207,7 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo /* All set for GPU resources */ CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { m_blockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(m_viewVertBlock), 1); - m_vertBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(specter::View::TexShaderVert), 4); + m_vertBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 4); /* Allocate textures here (rather than at decode time) */ x80_textures.reserve(3); diff --git a/Runtime/Graphics/CMoviePlayer.hpp b/Runtime/Graphics/CMoviePlayer.hpp index bcc02a991..606d9ee11 100644 --- a/Runtime/Graphics/CMoviePlayer.hpp +++ b/Runtime/Graphics/CMoviePlayer.hpp @@ -6,12 +6,15 @@ #include "Runtime/CDvdFile.hpp" #include "Runtime/RetroTypes.hpp" +#include #include -#include +#include #include namespace metaforce { +extern zeus::CMatrix4f g_PlatformMatrix; + class CMoviePlayer : public CDvdFile { public: enum class EPlayMode { Stopped, Playing }; @@ -31,26 +34,26 @@ private: u32 firstFrameOffset; u32 lastFrameOffset; void swapBig(); - } x28_thpHead; + } x28_thpHead{}; struct THPComponents { u32 numComponents; enum class Type : u8 { Video = 0x0, Audio = 0x1, None = 0xff } comps[16]; void swapBig(); - } x58_thpComponents; + } x58_thpComponents{}; struct THPVideoInfo { u32 width; u32 height; void swapBig(); - } x6c_videoInfo; + } x6c_videoInfo{}; struct THPAudioInfo { u32 numChannels; u32 sampleRate; u32 numSamples; void swapBig(); - } x74_audioInfo; + } x74_audioInfo{}; struct THPFrameHeader { u32 nextSize; @@ -108,11 +111,30 @@ private: std::unique_ptr m_yuvBuf; - specter::View::ViewBlock m_viewVertBlock; + struct TexShaderVert { + zeus::CVector3f m_pos; + zeus::CVector2f m_uv; + }; + struct ViewBlock { + zeus::CMatrix4f m_mv; + zeus::CColor m_color = zeus::skWhite; + void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub) { + m_mv[0][0] = 2.0f / root.size[0]; + m_mv[1][1] = 2.0f / root.size[1]; + m_mv[3][0] = sub.location[0] * m_mv[0][0] - 1.0f; + m_mv[3][1] = sub.location[1] * m_mv[1][1] - 1.0f; + } + void finalAssign(const ViewBlock& other) { + m_mv = g_PlatformMatrix * other.m_mv; + m_color = other.m_color; + } + }; + + ViewBlock m_viewVertBlock; boo::ObjToken m_blockBuf; boo::ObjToken m_vertBuf; - specter::View::TexShaderVert m_frame[4]; + TexShaderVert m_frame[4]; static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo); void DecodeFromRead(const void* data); @@ -145,7 +167,7 @@ public: void Update(float dt); std::pair GetVideoDimensions() const { return {x6c_videoInfo.width, x6c_videoInfo.height}; } - static void Initialize(); + static void Initialize(boo::IGraphicsDataFactory* factory); static void Shutdown(); }; diff --git a/Runtime/GuiSys/CGuiPane.cpp b/Runtime/GuiSys/CGuiPane.cpp index 27a73ee7b..fcee45b6d 100644 --- a/Runtime/GuiSys/CGuiPane.cpp +++ b/Runtime/GuiSys/CGuiPane.cpp @@ -10,7 +10,7 @@ CGuiPane::CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, con void CGuiPane::ScaleDimensions(const zeus::CVector3f& scale) { InitializeBuffers(); - for (specter::View::TexShaderVert& v : xc0_verts) { + for (TexShaderVert& v : xc0_verts) { v.m_pos -= xc8_scaleCenter; v.m_pos *= scale; v.m_pos += xc8_scaleCenter; diff --git a/Runtime/GuiSys/CGuiPane.hpp b/Runtime/GuiSys/CGuiPane.hpp index 5d5ccd76c..4b054bf31 100644 --- a/Runtime/GuiSys/CGuiPane.hpp +++ b/Runtime/GuiSys/CGuiPane.hpp @@ -5,8 +5,6 @@ #include "Runtime/GuiSys/CGuiWidget.hpp" -#include - #include #include @@ -16,8 +14,12 @@ class CGuiPane : public CGuiWidget { protected: zeus::CVector2f xb8_dim; + struct TexShaderVert { + zeus::CVector3f m_pos; + zeus::CVector2f m_uv; + }; /* Originally a vert-buffer pointer for GX */ - std::vector xc0_verts; + std::vector xc0_verts; // u32 x104_ = 4; /* vert count */ zeus::CVector3f xc8_scaleCenter; diff --git a/Runtime/MP1/CPauseScreen.hpp b/Runtime/MP1/CPauseScreen.hpp index 2178653a6..32a7e84a0 100644 --- a/Runtime/MP1/CPauseScreen.hpp +++ b/Runtime/MP1/CPauseScreen.hpp @@ -2,7 +2,6 @@ #include -#include "Editor/ProjectResourceFactoryBase.hpp" #include "Runtime/rstl.hpp" #include "Runtime/MP1/CInGameGuiManager.hpp" #include "Runtime/MP1/CPauseScreenBase.hpp" diff --git a/Runtime/MP1/CSlideShow.cpp b/Runtime/MP1/CSlideShow.cpp index c94b5964c..0e39f11a3 100644 --- a/Runtime/MP1/CSlideShow.cpp +++ b/Runtime/MP1/CSlideShow.cpp @@ -2,7 +2,9 @@ #include -#include "Editor/ProjectManager.hpp" +#include "Runtime/CArchitectureMessage.hpp" +#include "Runtime/CGameState.hpp" +#include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" namespace metaforce { diff --git a/Runtime/MP1/CTweaks.cpp b/Runtime/MP1/CTweaks.cpp index 8343ffb39..b835ad376 100644 --- a/Runtime/MP1/CTweaks.cpp +++ b/Runtime/MP1/CTweaks.cpp @@ -14,9 +14,9 @@ #include "DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp" #include "DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp" -#include "Editor/ProjectManager.hpp" - +#include "Runtime/IMain.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/AutoMapper/CMappableObject.hpp" #include "Runtime/World/CPlayerCameraBob.hpp" #include diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 33ee7bc74..a7f297a3f 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -269,6 +269,7 @@ CMain::BooSetter::BooSetter(boo::IGraphicsDataFactory* factory, boo::IGraphicsCo CRandomStaticFilter::Initialize(); CEnvFxShaders::Initialize(); CNESShader::Initialize(); + CMoviePlayer::Initialize(factory); } void CMain::RegisterResourceTweaks() {} @@ -407,7 +408,6 @@ void CMain::ResetGameState() { void CMain::InitializeSubsystems() { CBasics::Initialize(); CModelShaders::Initialize(); - CMoviePlayer::Initialize(); CLineRenderer::Initialize(); CElementGen::Initialize(); CAnimData::InitializeCache(); diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index dd0e82785..87f578086 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -2,7 +2,6 @@ #include -#include "Editor/ProjectResourceFactoryBase.hpp" #include "Runtime/CObjectList.hpp" #include "Runtime/CToken.hpp" #include "Runtime/RetroTypes.hpp" diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 19d69e221..aa543a1d2 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -1,7 +1,5 @@ #include "Runtime/World/ScriptLoader.hpp" -#include "Editor/ProjectResourceFactoryMP1.hpp" - #include "Runtime/Camera/CCinematicCamera.hpp" #include "Runtime/Camera/CPathCamera.hpp" #include "Runtime/Collision/CCollidableOBBTreeGroup.hpp" diff --git a/Editor/platforms/freedesktop/1024x1024/apps/metaforce.png b/Runtime/platforms/freedesktop/1024x1024/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/1024x1024/apps/metaforce.png rename to Runtime/platforms/freedesktop/1024x1024/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/128x128/apps/metaforce.png b/Runtime/platforms/freedesktop/128x128/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/128x128/apps/metaforce.png rename to Runtime/platforms/freedesktop/128x128/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/16x16/apps/metaforce.png b/Runtime/platforms/freedesktop/16x16/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/16x16/apps/metaforce.png rename to Runtime/platforms/freedesktop/16x16/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/256x256/apps/metaforce.png b/Runtime/platforms/freedesktop/256x256/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/256x256/apps/metaforce.png rename to Runtime/platforms/freedesktop/256x256/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/32x32/apps/metaforce.png b/Runtime/platforms/freedesktop/32x32/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/32x32/apps/metaforce.png rename to Runtime/platforms/freedesktop/32x32/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/48x48/apps/metaforce.png b/Runtime/platforms/freedesktop/48x48/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/48x48/apps/metaforce.png rename to Runtime/platforms/freedesktop/48x48/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/512x512/apps/metaforce.png b/Runtime/platforms/freedesktop/512x512/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/512x512/apps/metaforce.png rename to Runtime/platforms/freedesktop/512x512/apps/metaforce.png diff --git a/Editor/platforms/freedesktop/64x64/apps/metaforce.png b/Runtime/platforms/freedesktop/64x64/apps/metaforce.png similarity index 100% rename from Editor/platforms/freedesktop/64x64/apps/metaforce.png rename to Runtime/platforms/freedesktop/64x64/apps/metaforce.png diff --git a/Runtime/platforms/freedesktop/CMakeLists.txt b/Runtime/platforms/freedesktop/CMakeLists.txt new file mode 100644 index 000000000..855056423 --- /dev/null +++ b/Runtime/platforms/freedesktop/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable(mkwmicon mkwmicon.c) +target_link_libraries(mkwmicon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) +target_include_directories(mkwmicon PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) + +macro(declare_wmicon_target) +add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin + COMMAND $ + ARGS ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin + DEPENDS + ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/128x128/apps/metaforce.png + ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/64x64/apps/metaforce.png + ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/48x48/apps/metaforce.png + ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/32x32/apps/metaforce.png + ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/16x16/apps/metaforce.png + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop + COMMENT "Generating mainicon_netwm.bin") +bintoc(mainicon_netwm.cpp ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin MAINICON_NETWM) +endmacro() diff --git a/Editor/platforms/freedesktop/mkwmicon.c b/Runtime/platforms/freedesktop/mkwmicon.c similarity index 100% rename from Editor/platforms/freedesktop/mkwmicon.c rename to Runtime/platforms/freedesktop/mkwmicon.c diff --git a/Editor/platforms/freedesktop/urde.desktop b/Runtime/platforms/freedesktop/urde.desktop similarity index 100% rename from Editor/platforms/freedesktop/urde.desktop rename to Runtime/platforms/freedesktop/urde.desktop diff --git a/Editor/platforms/win/Assets/LargeTile.scale-100.png b/Runtime/platforms/win/Assets/LargeTile.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/LargeTile.scale-100.png rename to Runtime/platforms/win/Assets/LargeTile.scale-100.png diff --git a/Editor/platforms/win/Assets/LargeTile.scale-125.png b/Runtime/platforms/win/Assets/LargeTile.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/LargeTile.scale-125.png rename to Runtime/platforms/win/Assets/LargeTile.scale-125.png diff --git a/Editor/platforms/win/Assets/LargeTile.scale-150.png b/Runtime/platforms/win/Assets/LargeTile.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/LargeTile.scale-150.png rename to Runtime/platforms/win/Assets/LargeTile.scale-150.png diff --git a/Editor/platforms/win/Assets/LargeTile.scale-200.png b/Runtime/platforms/win/Assets/LargeTile.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/LargeTile.scale-200.png rename to Runtime/platforms/win/Assets/LargeTile.scale-200.png diff --git a/Editor/platforms/win/Assets/LargeTile.scale-400.png b/Runtime/platforms/win/Assets/LargeTile.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/LargeTile.scale-400.png rename to Runtime/platforms/win/Assets/LargeTile.scale-400.png diff --git a/Editor/platforms/win/Assets/SmallTile.scale-100.png b/Runtime/platforms/win/Assets/SmallTile.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/SmallTile.scale-100.png rename to Runtime/platforms/win/Assets/SmallTile.scale-100.png diff --git a/Editor/platforms/win/Assets/SmallTile.scale-125.png b/Runtime/platforms/win/Assets/SmallTile.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/SmallTile.scale-125.png rename to Runtime/platforms/win/Assets/SmallTile.scale-125.png diff --git a/Editor/platforms/win/Assets/SmallTile.scale-150.png b/Runtime/platforms/win/Assets/SmallTile.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/SmallTile.scale-150.png rename to Runtime/platforms/win/Assets/SmallTile.scale-150.png diff --git a/Editor/platforms/win/Assets/SmallTile.scale-200.png b/Runtime/platforms/win/Assets/SmallTile.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/SmallTile.scale-200.png rename to Runtime/platforms/win/Assets/SmallTile.scale-200.png diff --git a/Editor/platforms/win/Assets/SmallTile.scale-400.png b/Runtime/platforms/win/Assets/SmallTile.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/SmallTile.scale-400.png rename to Runtime/platforms/win/Assets/SmallTile.scale-400.png diff --git a/Editor/platforms/win/Assets/SplashScreen.scale-100.png b/Runtime/platforms/win/Assets/SplashScreen.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/SplashScreen.scale-100.png rename to Runtime/platforms/win/Assets/SplashScreen.scale-100.png diff --git a/Editor/platforms/win/Assets/SplashScreen.scale-125.png b/Runtime/platforms/win/Assets/SplashScreen.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/SplashScreen.scale-125.png rename to Runtime/platforms/win/Assets/SplashScreen.scale-125.png diff --git a/Editor/platforms/win/Assets/SplashScreen.scale-150.png b/Runtime/platforms/win/Assets/SplashScreen.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/SplashScreen.scale-150.png rename to Runtime/platforms/win/Assets/SplashScreen.scale-150.png diff --git a/Editor/platforms/win/Assets/SplashScreen.scale-200.png b/Runtime/platforms/win/Assets/SplashScreen.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/SplashScreen.scale-200.png rename to Runtime/platforms/win/Assets/SplashScreen.scale-200.png diff --git a/Editor/platforms/win/Assets/SplashScreen.scale-400.png b/Runtime/platforms/win/Assets/SplashScreen.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/SplashScreen.scale-400.png rename to Runtime/platforms/win/Assets/SplashScreen.scale-400.png diff --git a/Editor/platforms/win/Assets/Square150x150Logo.scale-100.png b/Runtime/platforms/win/Assets/Square150x150Logo.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/Square150x150Logo.scale-100.png rename to Runtime/platforms/win/Assets/Square150x150Logo.scale-100.png diff --git a/Editor/platforms/win/Assets/Square150x150Logo.scale-125.png b/Runtime/platforms/win/Assets/Square150x150Logo.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/Square150x150Logo.scale-125.png rename to Runtime/platforms/win/Assets/Square150x150Logo.scale-125.png diff --git a/Editor/platforms/win/Assets/Square150x150Logo.scale-150.png b/Runtime/platforms/win/Assets/Square150x150Logo.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/Square150x150Logo.scale-150.png rename to Runtime/platforms/win/Assets/Square150x150Logo.scale-150.png diff --git a/Editor/platforms/win/Assets/Square150x150Logo.scale-200.png b/Runtime/platforms/win/Assets/Square150x150Logo.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/Square150x150Logo.scale-200.png rename to Runtime/platforms/win/Assets/Square150x150Logo.scale-200.png diff --git a/Editor/platforms/win/Assets/Square150x150Logo.scale-400.png b/Runtime/platforms/win/Assets/Square150x150Logo.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/Square150x150Logo.scale-400.png rename to Runtime/platforms/win/Assets/Square150x150Logo.scale-400.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png b/Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png rename to Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-16.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png b/Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png rename to Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-24.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png b/Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png rename to Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-256.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png b/Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png rename to Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-32.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png b/Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png rename to Runtime/platforms/win/Assets/Square44x44Logo.altform-unplated_targetsize-48.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.scale-100.png b/Runtime/platforms/win/Assets/Square44x44Logo.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.scale-100.png rename to Runtime/platforms/win/Assets/Square44x44Logo.scale-100.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.scale-125.png b/Runtime/platforms/win/Assets/Square44x44Logo.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.scale-125.png rename to Runtime/platforms/win/Assets/Square44x44Logo.scale-125.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.scale-150.png b/Runtime/platforms/win/Assets/Square44x44Logo.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.scale-150.png rename to Runtime/platforms/win/Assets/Square44x44Logo.scale-150.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.scale-200.png b/Runtime/platforms/win/Assets/Square44x44Logo.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.scale-200.png rename to Runtime/platforms/win/Assets/Square44x44Logo.scale-200.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.scale-400.png b/Runtime/platforms/win/Assets/Square44x44Logo.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.scale-400.png rename to Runtime/platforms/win/Assets/Square44x44Logo.scale-400.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.targetsize-16.png b/Runtime/platforms/win/Assets/Square44x44Logo.targetsize-16.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.targetsize-16.png rename to Runtime/platforms/win/Assets/Square44x44Logo.targetsize-16.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.targetsize-24.png b/Runtime/platforms/win/Assets/Square44x44Logo.targetsize-24.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.targetsize-24.png rename to Runtime/platforms/win/Assets/Square44x44Logo.targetsize-24.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.targetsize-256.png b/Runtime/platforms/win/Assets/Square44x44Logo.targetsize-256.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.targetsize-256.png rename to Runtime/platforms/win/Assets/Square44x44Logo.targetsize-256.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.targetsize-32.png b/Runtime/platforms/win/Assets/Square44x44Logo.targetsize-32.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.targetsize-32.png rename to Runtime/platforms/win/Assets/Square44x44Logo.targetsize-32.png diff --git a/Editor/platforms/win/Assets/Square44x44Logo.targetsize-48.png b/Runtime/platforms/win/Assets/Square44x44Logo.targetsize-48.png similarity index 100% rename from Editor/platforms/win/Assets/Square44x44Logo.targetsize-48.png rename to Runtime/platforms/win/Assets/Square44x44Logo.targetsize-48.png diff --git a/Editor/platforms/win/Assets/WideTile.scale-100.png b/Runtime/platforms/win/Assets/WideTile.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/WideTile.scale-100.png rename to Runtime/platforms/win/Assets/WideTile.scale-100.png diff --git a/Editor/platforms/win/Assets/WideTile.scale-125.png b/Runtime/platforms/win/Assets/WideTile.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/WideTile.scale-125.png rename to Runtime/platforms/win/Assets/WideTile.scale-125.png diff --git a/Editor/platforms/win/Assets/WideTile.scale-150.png b/Runtime/platforms/win/Assets/WideTile.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/WideTile.scale-150.png rename to Runtime/platforms/win/Assets/WideTile.scale-150.png diff --git a/Editor/platforms/win/Assets/WideTile.scale-200.png b/Runtime/platforms/win/Assets/WideTile.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/WideTile.scale-200.png rename to Runtime/platforms/win/Assets/WideTile.scale-200.png diff --git a/Editor/platforms/win/Assets/WideTile.scale-400.png b/Runtime/platforms/win/Assets/WideTile.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/WideTile.scale-400.png rename to Runtime/platforms/win/Assets/WideTile.scale-400.png diff --git a/Editor/platforms/win/Assets/metaforce.scale-100.png b/Runtime/platforms/win/Assets/metaforce.scale-100.png similarity index 100% rename from Editor/platforms/win/Assets/metaforce.scale-100.png rename to Runtime/platforms/win/Assets/metaforce.scale-100.png diff --git a/Editor/platforms/win/Assets/metaforce.scale-125.png b/Runtime/platforms/win/Assets/metaforce.scale-125.png similarity index 100% rename from Editor/platforms/win/Assets/metaforce.scale-125.png rename to Runtime/platforms/win/Assets/metaforce.scale-125.png diff --git a/Editor/platforms/win/Assets/metaforce.scale-150.png b/Runtime/platforms/win/Assets/metaforce.scale-150.png similarity index 100% rename from Editor/platforms/win/Assets/metaforce.scale-150.png rename to Runtime/platforms/win/Assets/metaforce.scale-150.png diff --git a/Editor/platforms/win/Assets/metaforce.scale-200.png b/Runtime/platforms/win/Assets/metaforce.scale-200.png similarity index 100% rename from Editor/platforms/win/Assets/metaforce.scale-200.png rename to Runtime/platforms/win/Assets/metaforce.scale-200.png diff --git a/Editor/platforms/win/Assets/metaforce.scale-400.png b/Runtime/platforms/win/Assets/metaforce.scale-400.png similarity index 100% rename from Editor/platforms/win/Assets/metaforce.scale-400.png rename to Runtime/platforms/win/Assets/metaforce.scale-400.png diff --git a/Editor/platforms/win/Package.appxmanifest b/Runtime/platforms/win/Package.appxmanifest similarity index 100% rename from Editor/platforms/win/Package.appxmanifest rename to Runtime/platforms/win/Package.appxmanifest diff --git a/Editor/platforms/win/mainicon.ico b/Runtime/platforms/win/mainicon.ico similarity index 100% rename from Editor/platforms/win/mainicon.ico rename to Runtime/platforms/win/mainicon.ico diff --git a/Editor/platforms/win/metaforce.aps b/Runtime/platforms/win/metaforce.aps similarity index 100% rename from Editor/platforms/win/metaforce.aps rename to Runtime/platforms/win/metaforce.aps diff --git a/Editor/platforms/win/metaforce.manifest b/Runtime/platforms/win/metaforce.manifest similarity index 100% rename from Editor/platforms/win/metaforce.manifest rename to Runtime/platforms/win/metaforce.manifest diff --git a/Editor/platforms/win/metaforce.rc.in b/Runtime/platforms/win/metaforce.rc.in similarity index 96% rename from Editor/platforms/win/metaforce.rc.in rename to Runtime/platforms/win/metaforce.rc.in index 9310d4336..3689ed173 100644 --- a/Editor/platforms/win/metaforce.rc.in +++ b/Runtime/platforms/win/metaforce.rc.in @@ -1,33 +1,33 @@ -#include "winver.h" -#define IDI_ICON1 101 - -IDI_ICON1 ICON DISCARDABLE "mainicon.ico" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 - FILEFLAGS 0x0L - FILEFLAGSMASK 0x3fL - FILEOS 0x00040004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "CompanyName", "AxioDL" - VALUE "FileDescription", "Metaforce" - VALUE "FileVersion", "@METAFORCE_WC_DESCRIBE@" - VALUE "LegalCopyright", "Copyright (C) 2015-@CURRENT_YEAR@ AxioDL Team" - VALUE "InternalName", "metaforce" - VALUE "OriginalFilename", "metaforce.exe" - VALUE "ProductName", "Metaforce" - VALUE "ProductVersion", "@METAFORCE_WC_DESCRIBE@" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END +#include "winver.h" +#define IDI_ICON1 101 + +IDI_ICON1 ICON DISCARDABLE "mainicon.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "AxioDL" + VALUE "FileDescription", "Metaforce" + VALUE "FileVersion", "@METAFORCE_WC_DESCRIBE@" + VALUE "LegalCopyright", "Copyright (C) 2015-@CURRENT_YEAR@ AxioDL Team" + VALUE "InternalName", "metaforce" + VALUE "OriginalFilename", "metaforce.exe" + VALUE "ProductName", "Metaforce" + VALUE "ProductVersion", "@METAFORCE_WC_DESCRIBE@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/extern/boo b/extern/boo index f4b1e1295..55deba091 160000 --- a/extern/boo +++ b/extern/boo @@ -1 +1 @@ -Subproject commit f4b1e1295674272fcf3d0de97e919318e966e52d +Subproject commit 55deba091336b787d405a8747bff9757713e7960 diff --git a/extern/imgui b/extern/imgui new file mode 160000 index 000000000..8877eab39 --- /dev/null +++ b/extern/imgui @@ -0,0 +1 @@ +Subproject commit 8877eab3933c7031e2b41f372b852618db219489 diff --git a/lxd-build-appimage.sh b/lxd-build-appimage.sh index c9e6a5da0..400fec55a 100755 --- a/lxd-build-appimage.sh +++ b/lxd-build-appimage.sh @@ -52,8 +52,8 @@ popd mkdir -p /metaforce-appdir/usr/{bin,share/{applications,icons/hicolor}} cp /metaforce-build/Binaries/{hecl,metaforce-gui,metaforce,visigen} /metaforce-appdir/usr/bin strip -s /metaforce-appdir/usr/bin/{hecl,metaforce-gui,metaforce,visigen} -cp -r /metaforce/Editor/platforms/freedesktop/{16x16,32x32,48x48,64x64,128x128,256x256,512x512,1024x1024} /metaforce-appdir/usr/share/icons/hicolor -cp /metaforce/Editor/platforms/freedesktop/metaforce.desktop /metaforce-appdir/usr/share/applications +cp -r /metaforce/Runtime/platforms/freedesktop/{16x16,32x32,48x48,64x64,128x128,256x256,512x512,1024x1024} /metaforce-appdir/usr/share/icons/hicolor +cp /metaforce/Runtime/platforms/freedesktop/metaforce.desktop /metaforce-appdir/usr/share/applications sed -i 's/Exec=.*/Exec=metaforce-gui/' /metaforce-appdir/usr/share/applications/metaforce.desktop VERSION=$VERSION /linuxdeploy-$(uname -m).AppImage --appdir /metaforce-appdir --plugin qt --output appimage END @@ -67,7 +67,7 @@ lxc exec $CONTAINER_NAME -- bash -c "while ! systemctl status network.target &>/ # Run build script lxc exec $CONTAINER_NAME -t -- bash /root/dobuild.sh -# Retrieve AppImage +# Retrieve AppImage lxc file pull $CONTAINER_NAME/URDE-$VERSION-$(uname -m).AppImage . # Cleanup