diff --git a/Runtime/AutoMapper/CMappableObject.cpp b/Runtime/AutoMapper/CMappableObject.cpp index f4edeafd9..1f8e9dc57 100644 --- a/Runtime/AutoMapper/CMappableObject.cpp +++ b/Runtime/AutoMapper/CMappableObject.cpp @@ -112,6 +112,7 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha SCOPED_GRAPHICS_DEBUG_GROUP("CMappableObject::Draw", zeus::skCyan); if (IsDoorType(x0_type)) { std::pair colors = GetDoorColors(curArea, mwInfo, alpha); + if (m_doorSurface) // TODO for (int s = 0; s < 6; ++s) { DoorSurface& ds = *m_doorSurface; ds.m_surface.draw(colors.first, s * 4, 4); diff --git a/Runtime/ConsoleVariables/CVarManager.cpp b/Runtime/ConsoleVariables/CVarManager.cpp index 47674b795..47626d91f 100644 --- a/Runtime/ConsoleVariables/CVarManager.cpp +++ b/Runtime/ConsoleVariables/CVarManager.cpp @@ -12,6 +12,14 @@ #include #include +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) +#endif + +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif + namespace metaforce { CVar* com_developer = nullptr; @@ -165,7 +173,13 @@ void CVarManager::serialize() { textOut.WriteString(str); } - auto* file = fopen(filename.c_str(), "wbe"); + auto* file = fopen(filename.c_str(), +#ifdef _MSC_VER + "wb" +#else + "wbe" +#endif + ); if (file != nullptr) { u32 writeLen = memOut.GetWritePosition(); u32 offset = 0; @@ -182,7 +196,13 @@ std::vector CVarManager::loadCVars(const std::string& filename) CBasics::Sstat st; if (CBasics::Stat(filename.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { - auto* file = fopen(filename.c_str(), "rbe"); + auto* file = fopen(filename.c_str(), +#ifdef _MSC_VER + "rb" +#else + "rbe" +#endif + ); if (file != nullptr) { std::unique_ptr inBuf(new u8[st.st_size]); diff --git a/Runtime/Graphics/CCubeRenderer.cpp b/Runtime/Graphics/CCubeRenderer.cpp index 7330deb82..0e8e51b6a 100644 --- a/Runtime/Graphics/CCubeRenderer.cpp +++ b/Runtime/Graphics/CCubeRenderer.cpp @@ -593,7 +593,9 @@ void CCubeRenderer::EndScene() { void CCubeRenderer::SetDebugOption(IRenderer::EDebugOption option, s32 value) { if (option == EDebugOption::PVSState) { - xc8_pvs->SetState(EPVSVisSetState(value)); + if (xc8_pvs) { + xc8_pvs->SetState(EPVSVisSetState(value)); + } } else if (option == EDebugOption::PVSMode) { xc0_pvsMode = EPVSMode(value); } else if (option == EDebugOption::FogDisabled) { diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 97bb6d04a..cc61894d9 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -6,11 +6,11 @@ #include "CToken.hpp" #include "GCNTypes.hpp" #include "Graphics/CCubeModel.hpp" +#include "Graphics/CCubeSurface.hpp" #include "Graphics/CTexture.hpp" #include "IObjectStore.hpp" namespace metaforce { -class CCubeSurface; class CCubeMaterial; enum class CModelFlagBits : u16 { diff --git a/Runtime/Graphics/CTevCombiners.hpp b/Runtime/Graphics/CTevCombiners.hpp index b33945861..2a04c01ee 100644 --- a/Runtime/Graphics/CTevCombiners.hpp +++ b/Runtime/Graphics/CTevCombiners.hpp @@ -25,7 +25,7 @@ public: void Execute(ERglTevStage stage) const; - bool operator<=>(const CTevPass&) const = default; + auto operator<=>(const CTevPass&) const = default; }; extern const CTevPass skPassThru; diff --git a/Runtime/Graphics/CTexture.cpp b/Runtime/Graphics/CTexture.cpp index 8f3738950..62959dec1 100644 --- a/Runtime/Graphics/CTexture.cpp +++ b/Runtime/Graphics/CTexture.cpp @@ -342,7 +342,7 @@ void CTexture::InvalidateTexMap(GX::TexMapID id) { CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, CObjectReference* selfRef) { - const auto label = fmt::format("{} {}", tag.type, tag.id); + const auto label = fmt::format(FMT_STRING("{} {}"), tag.type, tag.id); return TToken::GetIObjObjectFor(std::make_unique(in, label)); } } // namespace metaforce diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index bbdb9f3b6..f49ccd2e7 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -5,6 +5,7 @@ #include "Runtime/CToken.hpp" #include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/Graphics/CModel.hpp" #include "Runtime/RetroTypes.hpp" #include @@ -17,7 +18,6 @@ namespace metaforce { class CAreaOctTree; class CLight; class CMetroidModelInstance; -class CModel; class CPVSVisSet; class CParticleGen; class CSkinnedModel; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 0b9a8a4aa..b5c842a65 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -704,6 +704,7 @@ void CMain::ShutdownSubsystems() { // Metaforce additions CMoviePlayer::Shutdown(); CFont::Shutdown(); + CFluidPlaneManager::Shutdown(); } void CMain::Shutdown() { diff --git a/Runtime/World/CFluidPlaneManager.cpp b/Runtime/World/CFluidPlaneManager.cpp index 74ecae84d..59a80c069 100644 --- a/Runtime/World/CFluidPlaneManager.cpp +++ b/Runtime/World/CFluidPlaneManager.cpp @@ -140,4 +140,8 @@ void CFluidPlaneManager::SetupRippleMap() { "Ripple Map"); } +void CFluidPlaneManager::Shutdown() { + RippleMapTex.reset(); +} + } // namespace metaforce diff --git a/Runtime/World/CFluidPlaneManager.hpp b/Runtime/World/CFluidPlaneManager.hpp index 17b2206a2..fae754e1c 100644 --- a/Runtime/World/CFluidPlaneManager.hpp +++ b/Runtime/World/CFluidPlaneManager.hpp @@ -60,6 +60,8 @@ public: rstl::reserved_vector& SplashRecords() { return x18_splashes; } const CRippleManager& GetRippleManager() const { return x0_rippleManager; } CRippleManager& RippleManager() { return x0_rippleManager; } + + static void Shutdown(); }; } // namespace metaforce diff --git a/aurora/include/aurora/aurora.hpp b/aurora/include/aurora/aurora.hpp index 5351c5bef..ed8686d72 100644 --- a/aurora/include/aurora/aurora.hpp +++ b/aurora/include/aurora/aurora.hpp @@ -178,7 +178,7 @@ struct WindowSize { uint32_t fb_height; float scale; - bool operator<=>(const WindowSize& rhs) const = default; + auto operator<=>(const WindowSize& rhs) const = default; }; enum class MouseButton { None = 0, diff --git a/aurora/include/aurora/gfx.hpp b/aurora/include/aurora/gfx.hpp index b5cbf8af0..5d3f77aa5 100644 --- a/aurora/include/aurora/gfx.hpp +++ b/aurora/include/aurora/gfx.hpp @@ -161,7 +161,7 @@ struct CTevOp { , xc_scale(static_cast(compressedDesc >> 6 & 3)) , x10_regId(static_cast(compressedDesc >> 9 & 3)) {} - bool operator<=>(const CTevOp&) const = default; + auto operator<=>(const CTevOp&) const = default; }; struct ColorPass { GX::TevColorArg x0_a; @@ -177,7 +177,7 @@ struct ColorPass { , x8_c(static_cast(compressedDesc >> 10 & 0x1F)) , xc_d(static_cast(compressedDesc >> 15 & 0x1F)) {} - bool operator<=>(const ColorPass&) const = default; + auto operator<=>(const ColorPass&) const = default; }; struct AlphaPass { GX::TevAlphaArg x0_a; @@ -193,7 +193,7 @@ struct AlphaPass { , x8_c(static_cast(compressedDesc >> 10 & 0x1F)) , xc_d(static_cast(compressedDesc >> 15 & 0x1F)) {} - bool operator<=>(const AlphaPass&) const = default; + auto operator<=>(const AlphaPass&) const = default; }; } // namespace CTevCombiners } // namespace metaforce diff --git a/aurora/lib/aurora.cpp b/aurora/lib/aurora.cpp index f288187be..b1380723f 100644 --- a/aurora/lib/aurora.cpp +++ b/aurora/lib/aurora.cpp @@ -19,7 +19,7 @@ static std::vector g_Args; // SDL static SDL_Window* g_window; -static WindowSize g_windowSize; +WindowSize g_windowSize; // GPU using gpu::g_depthBuffer; diff --git a/aurora/lib/gfx/gx.cpp b/aurora/lib/gfx/gx.cpp index 9e7ce7153..47c1014de 100644 --- a/aurora/lib/gfx/gx.cpp +++ b/aurora/lib/gfx/gx.cpp @@ -129,8 +129,17 @@ void set_chan_mat_src(GX::ChannelID id, GX::ColorSrc src) noexcept { gx::g_colorChannels[id - GX::COLOR0A0].matSrc = src; } -void load_light(GX::LightID id, const Light& light) noexcept { gx::g_lights[id] = light; } -void load_light_ambient(GX::LightID id, const zeus::CColor& ambient) noexcept { gx::g_lights[id] = ambient; } +static inline u8 light_idx(GX::LightID id) { +#ifdef _MSC_VER + unsigned long r = 0; + _BitScanForward(&r, id); + return r; +#else + return __builtin_ctz(id); +#endif +} +void load_light(GX::LightID id, const Light& light) noexcept { gx::g_lights[light_idx(id)] = light; } +void load_light_ambient(GX::LightID id, const zeus::CColor& ambient) noexcept { gx::g_lights[light_idx(id)] = ambient; } void set_light_state(std::bitset bits) noexcept { gx::g_lightState = bits; } namespace gx { @@ -187,6 +196,9 @@ static inline wgpu::BlendFactor to_blend_factor(metaforce::ERglBlendFactor fac) return wgpu::BlendFactor::Dst; case metaforce::ERglBlendFactor::InvDstColor: return wgpu::BlendFactor::OneMinusDst; + default: + Log.report(logvisor::Fatal, FMT_STRING("invalid blend factor {}"), fac); + unreachable(); } } @@ -208,6 +220,9 @@ static inline wgpu::CompareFunction to_compare_function(metaforce::ERglEnum func return wgpu::CompareFunction::GreaterEqual; case metaforce::ERglEnum::Always: return wgpu::CompareFunction::Always; + default: + Log.report(logvisor::Fatal, FMT_STRING("invalid depth fn {}"), func); + unreachable(); } } @@ -328,7 +343,8 @@ wgpu::RenderPipeline build_pipeline(const PipelineConfig& config, const ShaderIn return g_device.CreateRenderPipeline(&descriptor); } -ShaderInfo populate_pipeline_config(PipelineConfig& config, GX::Primitive primitive, const BindGroupRanges& ranges) noexcept { +ShaderInfo populate_pipeline_config(PipelineConfig& config, GX::Primitive primitive, + const BindGroupRanges& ranges) noexcept { for (size_t idx = 0; const auto& item : g_tevStages) { // Copy until disabled TEV stage (indicating end) if (!item) { diff --git a/aurora/lib/gfx/model/shader.cpp b/aurora/lib/gfx/model/shader.cpp index 398e034ab..815a408ea 100644 --- a/aurora/lib/gfx/model/shader.cpp +++ b/aurora/lib/gfx/model/shader.cpp @@ -116,7 +116,7 @@ void queue_surface(const u8* dlStart, u32 dlSize) noexcept { std::vector indices; size_t offset = 0; - while (offset < dlSize) { + while (offset < dlSize - 6) { const auto header = dlStart[offset]; const auto primitive = static_cast(header & 0xF8); const auto vtxFmt = static_cast(header & 0x3); diff --git a/aurora/lib/gpu.cpp b/aurora/lib/gpu.cpp index 0caacba61..a10bbbbe9 100644 --- a/aurora/lib/gpu.cpp +++ b/aurora/lib/gpu.cpp @@ -1,5 +1,7 @@ #include "gpu.hpp" +#include + #include #include #include @@ -9,6 +11,11 @@ #include "dawn/BackendBinding.hpp" +// FIXME hack to avoid crash on Windows +namespace aurora { +extern WindowSize g_windowSize; +} // namespace aurora + namespace aurora::gpu { static logvisor::Module Log("aurora::gpu"); @@ -192,18 +199,17 @@ void initialize(SDL_Window* window) { g_swapChain = g_device.CreateSwapChain(nullptr, &descriptor); } { - int width = 0; - int height = 0; - SDL_GL_GetDrawableSize(window, &width, &height); + const auto size = get_window_size(); g_graphicsConfig = GraphicsConfig{ - .width = static_cast(width), - .height = static_cast(height), + .width = size.fb_width, + .height = size.fb_height, .colorFormat = swapChainFormat, .depthFormat = wgpu::TextureFormat::Depth32Float, .msaaSamples = 1, // TODO 4 .textureAnistropy = 16, }; - resize_swapchain(width, height); + resize_swapchain(size.fb_width, size.fb_height); + g_windowSize = size; } }