diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c1036b2..cac61eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR) project(isle LANGUAGES CXX C VERSION 0.1) if(WIIU) - add_library(libstdc_WiiU STATIC IMPORTED) + add_library(libstdc_WiiU STATIC IMPORTED) set_target_properties(libstdc_WiiU PROPERTIES IMPORTED_LOCATION /opt/devkitpro/devkitPPC/powerpc-eabi/lib/libstdc++.a INTERFACE_INCLUDE_DIRECTORIES /opt/devkitpro/devkitPPC/powerpc-eabi/include/c++/15.1.0 @@ -597,6 +597,9 @@ if (ISLE_BUILD_APP) if (WIN32) target_link_libraries(isle PRIVATE winmm) endif() + if (WIIU) + target_sources(isle PRIVATE 3rdparty/atomic-dummy/atomic.c) + endif() # Link LEGO1 target_link_libraries(isle PRIVATE lego1) if(ISLE_DEBUG) @@ -649,7 +652,7 @@ if (ISLE_BUILD_APP) endif() if (WIIU) target_sources(isle PRIVATE - ISLE/wiiu/config.cpp + ISLE/wiiu/config.cpp ) endif() if(Python3_FOUND) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index e44b3141..313bd11b 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -294,13 +294,6 @@ void IsleApp::SetupVideoFlags( } } -#ifdef __WUT__ -int main(int argc, char** argv) -{ - return 0; -} -#endif - SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) { *appstate = NULL; diff --git a/miniwin/CMakeLists.txt b/miniwin/CMakeLists.txt index e80ec5b1..cb3d3b08 100644 --- a/miniwin/CMakeLists.txt +++ b/miniwin/CMakeLists.txt @@ -90,6 +90,14 @@ if(NINTENDO_3DS) endif() endif() +if(WIIU) + message(STATUS "Enabling GX2 renderer") + target_sources(miniwin PRIVATE src/d3drm/backends/gx2/renderer.cpp) + list(APPEND GRAPHICS_BACKENDS USE_GX2) +else() + message(STATUS "🧩 GX2 support not enabled") +endif() + if(WIN32 AND NOT WINDOWS_STORE) target_sources(miniwin PRIVATE src/d3drm/backends/directx9/actual.cpp diff --git a/miniwin/src/d3drm/backends/gx2/renderer.cpp b/miniwin/src/d3drm/backends/gx2/renderer.cpp index 76117361..031274eb 100644 --- a/miniwin/src/d3drm/backends/gx2/renderer.cpp +++ b/miniwin/src/d3drm/backends/gx2/renderer.cpp @@ -1,9 +1,7 @@ +#include "d3drmrenderer_gx2.h" #include #include #include -#include -#include -#include #include #include #include @@ -12,98 +10,124 @@ #include #include -struct IsleGX2Backend { - GX2RBuffer positionBuffer; - GX2RBuffer colourBuffer; - WHBGfxShaderGroup shaderGroup; - bool rendering = false; +#ifndef D3D_OK +#define D3D_OK S_OK +#endif - void Init(const char* shaderPath) - { - WHBLogUdpInit(); - WHBProcInit(); - WHBGfxInit(); - WHBMountSdCard(); - char path[256]; - sprintf(path, "%s/%s", WHBGetSdCardMountPath(), shaderPath); - FILE* f = fopen(path, "rb"); - if (!f) { - return; - } - fseek(f, 0, SEEK_END); - size_t fsize = ftell(f); - rewind(f); - char* data = (char*) malloc(fsize); - fread(data, 1, fsize, f); - WHBGfxLoadGFDShaderGroup(&shaderGroup, 0, data); - free(data); - WHBGfxInitShaderAttribute(&shaderGroup, "aPosition", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32); - WHBGfxInitShaderAttribute(&shaderGroup, "aColour", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32); - WHBGfxInitFetchShader(&shaderGroup); - } +static struct IsleGX2Backend { + bool initialized = false; + bool rendering = false; - void StartFrame() - { - if (rendering) { - return; - } - WHBGfxBeginRender(); - WHBGfxBeginRenderTV(); - rendering = true; - } + void Init(const char* shaderPath) + { + if (initialized) return; + WHBLogUdpInit(); + WHBProcInit(); + WHBGfxInit(); + WHBMountSdCard(); + initialized = true; + } - void EndFrame() - { - if (!rendering) { - return; - } - WHBGfxFinishRenderTV(); - WHBGfxBeginRenderDRC(); - WHBGfxFinishRenderDRC(); - WHBGfxFinishRender(); - rendering = false; - } + void StartFrame() + { + if (rendering) return; + WHBGfxBeginRender(); + WHBGfxBeginRenderTV(); + rendering = true; + } - void Clear(float r, float g, float b) - { - StartFrame(); - WHBGfxClearColor(r, g, b, 1.0f); - } + void EndFrame() + { + if (!rendering) return; + WHBGfxFinishRenderTV(); + WHBGfxBeginRenderDRC(); + WHBGfxFinishRenderDRC(); + WHBGfxFinishRender(); + rendering = false; + } - void Flip() { EndFrame(); } + void Clear(float r, float g, float b) + { + StartFrame(); + WHBGfxClearColor(r, g, b, 1.0f); + } - void Shutdown() - { - WHBUnmountSdCard(); - WHBGfxShutdown(); - WHBProcShutdown(); - WHBLogUdpDeinit(); - } -}; + void Flip() + { + EndFrame(); + } -static IsleGX2Backend g_backend; + void Shutdown() + { + if (!initialized) return; + WHBUnmountSdCard(); + WHBGfxShutdown(); + WHBProcShutdown(); + WHBLogUdpDeinit(); + initialized = false; + } -extern "C" void IsleBackendInit(const char* shaderPath) +} g_backend; + +// ------------------------------------ +// GX2Renderer Implementation +// ------------------------------------ + +GX2Renderer::GX2Renderer(DWORD width, DWORD height) { - g_backend.Init(shaderPath); + m_width = width; + m_height = height; + m_virtualWidth = width; + m_virtualHeight = height; + + g_backend.Init("content/renderer.gsh"); } -extern "C" void IsleBackendStartFrame() + +GX2Renderer::~GX2Renderer() { - g_backend.StartFrame(); + g_backend.Shutdown(); } -extern "C" void IsleBackendEndFrame() + +HRESULT GX2Renderer::BeginFrame() { - g_backend.EndFrame(); + g_backend.StartFrame(); + return D3D_OK; } -extern "C" void IsleBackendClear(float r, float g, float b) + +void GX2Renderer::EnableTransparency() { - g_backend.Clear(r, g, b); + // GX2 blending can be configured here if needed } -extern "C" void IsleBackendFlip() + +HRESULT GX2Renderer::FinalizeFrame() { - g_backend.Flip(); + g_backend.EndFrame(); + return D3D_OK; } -extern "C" void IsleBackendShutdown() + +void GX2Renderer::Clear(float r, float g, float b) { - g_backend.Shutdown(); + g_backend.Clear(r, g, b); } + +void GX2Renderer::Flip() +{ + g_backend.Flip(); +} + +void GX2Renderer::Resize(int width, int height, const ViewportTransform& viewportTransform) +{ + m_width = width; + m_height = height; + m_viewportTransform = viewportTransform; +} + +void GX2Renderer::PushLights(const SceneLight* vertices, size_t count) {} +void GX2Renderer::SetProjection(const D3DRMMATRIX4D&, D3DVALUE, D3DVALUE) {} +void GX2Renderer::SetFrustumPlanes(const Plane*) {} +Uint32 GX2Renderer::GetTextureId(IDirect3DRMTexture*, bool, float, float) { return 0; } +Uint32 GX2Renderer::GetMeshId(IDirect3DRMMesh*, const MeshGroup*) { return 0; } +void GX2Renderer::SubmitDraw(DWORD, const D3DRMMATRIX4D&, const D3DRMMATRIX4D&, const D3DRMMATRIX4D&, const Matrix3x3&, const Appearance&) {} +void GX2Renderer::Draw2DImage(Uint32, const SDL_Rect&, const SDL_Rect&, FColor) {} +void GX2Renderer::Download(SDL_Surface*) {} +void GX2Renderer::SetDither(bool) {} diff --git a/miniwin/src/d3drm/d3drmrenderer.cpp b/miniwin/src/d3drm/d3drmrenderer.cpp index f1e1fb8b..b18d54be 100644 --- a/miniwin/src/d3drm/d3drmrenderer.cpp +++ b/miniwin/src/d3drm/d3drmrenderer.cpp @@ -11,6 +11,9 @@ #ifdef USE_CITRO3D #include "d3drmrenderer_citro3d.h" #endif +#ifdef USE_GX2 +#include "d3drmrenderer_gx2.h" +#endif #ifdef USE_DIRECTX9 #include "d3drmrenderer_directx9.h" #endif @@ -62,6 +65,11 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer( return new Citro3DRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); } #endif +#ifdef USE_GX2 + if (SDL_memcmp(guid, &GX2_GUID, sizeof(GUID)) == 0) { + return new GX2Renderer(DDSDesc.dwWidth, DDSDesc.dwHeight); + } +#endif #ifdef USE_DIRECTX9 if (SDL_memcmp(guid, &DirectX9_GUID, sizeof(GUID)) == 0) { return DirectX9Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); @@ -87,6 +95,9 @@ void Direct3DRMRenderer_EnumDevices(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICE #ifdef USE_CITRO3D Citro3DRenderer_EnumDevice(cb, ctx); #endif +#ifdef USE_GX2 + GX2Renderer_EnumDevice(cb, ctx); +#endif #ifdef USE_DIRECTX9 DirectX9Renderer_EnumDevice(cb, ctx); #endif diff --git a/miniwin/src/internal/d3drmrenderer_gx2.h b/miniwin/src/internal/d3drmrenderer_gx2.h index 6681798b..befc4173 100644 --- a/miniwin/src/internal/d3drmrenderer_gx2.h +++ b/miniwin/src/internal/d3drmrenderer_gx2.h @@ -1,30 +1,57 @@ #pragma once #include "d3drmrenderer.h" +#include "ddraw_impl.h" #include #include +#include DEFINE_GUID(GX2_GUID, 0xA12B56F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x53); class GX2Renderer : public Direct3DRMRenderer { public: - GX2Renderer(DWORD width, DWORD height); - ~GX2Renderer() override; + GX2Renderer(DWORD width, DWORD height); + ~GX2Renderer() override; + + // --- Overrides from Direct3DRMRenderer --- + void PushLights(const SceneLight* vertices, size_t count) override; + void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; + void SetFrustumPlanes(const Plane* frustumPlanes) override; + Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI = false, float scaleX = 0, float scaleY = 0) override; + Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; + HRESULT BeginFrame() override; + void EnableTransparency() override; + void SubmitDraw( + DWORD meshId, + const D3DRMMATRIX4D& modelViewMatrix, + const D3DRMMATRIX4D& worldMatrix, + const D3DRMMATRIX4D& viewMatrix, + const Matrix3x3& normalMatrix, + const Appearance& appearance + ) override; + HRESULT FinalizeFrame() override; + void Resize(int width, int height, const ViewportTransform& viewportTransform) override; + void Clear(float r, float g, float b) override; + void Flip() override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; + void Download(SDL_Surface* target) override; + void SetDither(bool dither) override; }; +// --- Enum device helper --- inline static void GX2Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - D3DDEVICEDESC halDesc = {}; - halDesc.dcmColorModel = D3DCOLOR_RGB; - halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; - halDesc.dwDeviceZBufferBitDepth = DDBD_24; - halDesc.dwDeviceRenderBitDepth = DDBD_32; - halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; - halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; - halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; + D3DDEVICEDESC halDesc = {}; + halDesc.dcmColorModel = D3DCOLOR_RGB; + halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; + halDesc.dwDeviceZBufferBitDepth = DDBD_24; + halDesc.dwDeviceRenderBitDepth = DDBD_32; + halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; + halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; + halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; - D3DDEVICEDESC helDesc = {}; + D3DDEVICEDESC helDesc = {}; - EnumDevice(cb, ctx, "GX2", &halDesc, &helDesc, GX2_GUID); + EnumDevice(cb, ctx, "GX2", &halDesc, &helDesc, GX2_GUID); }