Full 3ds support and fix dx9

This commit is contained in:
2026-03-18 11:34:36 +01:00
parent e04046720b
commit 66412ca8e0
4 changed files with 126 additions and 76 deletions

View File

@@ -13,42 +13,47 @@ option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF)
option(PD_BUILD_SHARED "Build Shared Library" OFF) option(PD_BUILD_SHARED "Build Shared Library" OFF)
option(PD_BUILD_TOOLS "Build Palladium Tools" OFF) option(PD_BUILD_TOOLS "Build Palladium Tools" OFF)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
add_compile_options(-Wno-psabi)
endif()
if(${PD_BUILD_TOOLS}) if(${PD_BUILD_TOOLS})
add_subdirectory(tools) add_subdirectory(tools)
endif() endif()
add_subdirectory(vendor) add_subdirectory(vendor)
# # Include Library Source # # Include Library Source
set(PD_SOURCES set(PD_SOURCES
# Common # Common
source/common.cpp source/common.cpp
# Core # Core
source/core/bits.cpp source/core/bits.cpp
source/core/color.cpp source/core/color.cpp
source/core/mat.cpp source/core/mat.cpp
source/core/strings.cpp source/core/strings.cpp
source/core/timer.cpp
# Drivers # Drivers
source/drivers/os.cpp source/drivers/os.cpp
source/drivers/gfx.cpp source/drivers/gfx.cpp
# Lithium # Lithium
source/lithium/pools.cpp source/lithium/pools.cpp
) )
if(${PD_BUILD_SHARED}) if(${PD_BUILD_SHARED})
add_library(palladium SHARED ${PD_SOURCES}) add_library(palladium SHARED ${PD_SOURCES})
target_compile_definitions(palladium PRIVATE PD_BUILD_SHARED) target_compile_definitions(palladium PRIVATE PD_BUILD_SHARED)
else() else()
add_library(palladium STATIC ${PD_SOURCES}) add_library(palladium STATIC ${PD_SOURCES})
target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC) target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC)
endif() endif()
target_compile_definitions(palladium PUBLIC PD_DEBUG) target_compile_definitions(palladium PUBLIC PD_DEBUG)
target_compile_options(palladium target_compile_options(palladium
PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>: PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
> >
@@ -57,75 +62,75 @@ target_compile_options(palladium
add_library(palladium::palladium ALIAS palladium) add_library(palladium::palladium ALIAS palladium)
target_include_directories(palladium target_include_directories(palladium
PUBLIC PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include> $<INSTALL_INTERFACE:include>
) )
target_compile_options(palladium target_compile_options(palladium
PRIVATE PRIVATE
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-O0 -g> $<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-O0 -g>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3> $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3>
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi> $<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/O2> $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/O2>
) )
install( install(
TARGETS palladium TARGETS palladium
EXPORT palladiumTargets EXPORT palladiumTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
) )
install( install(
DIRECTORY include/ DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) )
install(EXPORT palladiumTargets install(EXPORT palladiumTargets
FILE palladiumTargets.cmake FILE palladiumTargets.cmake
NAMESPACE palladium:: NAMESPACE palladium::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
) )
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
configure_package_config_file( configure_package_config_file(
cmake/palladiumConfig.cmake.in cmake/palladiumConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
INSTALL_DESTINATION INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/palladium ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
) )
write_basic_package_version_file( write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
VERSION VERSION
${PROJECT_VERSION} ${PROJECT_VERSION}
COMPATIBILITY COMPATIBILITY
SameMajorVersion SameMajorVersion
) )
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
) )
find_program(CLANG_FORMAT clang-format) find_program(CLANG_FORMAT clang-format)
file(GLOB_RECURSE PD_FMTFILES file(GLOB_RECURSE PD_FMTFILES
CONFIGURE_DEPENDS CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/backends/source/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/backends/source/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/backends/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/backends/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/core/source/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/core/source/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/gfx/source/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/gfx/source/*.cpp
) )
add_custom_target(pd-clang-format add_custom_target(pd-clang-format
COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES} COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES}
COMMENT "Formatting Project Sources" COMMENT "Formatting Project Sources"
) )
add_subdirectory(backends) add_subdirectory(backends)

View File

@@ -55,6 +55,7 @@ struct GfxCitro3D::Impl {
shaderProgram_s pShader; shaderProgram_s pShader;
DVLB_s* pCode; DVLB_s* pCode;
int uLocProjection = 0; int uLocProjection = 0;
C3D_Tex* CurrentTex = nullptr;
std::vector<u8> pShaderRaw; std::vector<u8> pShaderRaw;
GPU_TEXCOLOR TextureTranslateFormat(TextureFormat fmt) { GPU_TEXCOLOR TextureTranslateFormat(TextureFormat fmt) {
@@ -83,14 +84,15 @@ struct GfxCitro3D::Impl {
} }
} }
void SetupPixelStage(GPU_TEXCOLOR clr) { void SetupPixelStage() {
shaderProgramUse(&pShader); shaderProgramUse(&pShader);
C3D_BindProgram(&pShader); C3D_BindProgram(&pShader);
C3D_SetAttrInfo(&pAttr); C3D_SetAttrInfo(&pAttr);
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
if (!CurrentTex) return;
C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env); C3D_TexEnvInit(env);
switch (clr) { switch (CurrentTex->fmt) {
case GPU_A4: case GPU_A4:
case GPU_A8: case GPU_A8:
case GPU_L4: case GPU_L4:
@@ -142,15 +144,30 @@ void GfxCitro3D::SysDeinit() {
void GfxCitro3D::Submit(size_t count, size_t start) { void GfxCitro3D::Submit(size_t count, size_t start) {
if (!impl) return; if (!impl) return;
BindTexture(CurrentTex);
impl->SetupPixelStage(); // needs to be called after
C3D_Mtx proj;
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection,
// (C3D_Mtx*)&Projection);
auto buf = C3D_GetBufInfo();
BufInfo_Init(buf);
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT,
GetIndexBufPtr(start));
impl->CurrentTex = nullptr;
} }
void GfxCitro3D::BindTexture(TextureID id) { void GfxCitro3D::BindTexture(TextureID id) {
if (!impl) return; if (!impl || !id) return;
impl->CurrentTex = (C3D_Tex*)id;
C3D_TexBind(0, (C3D_Tex*)id); C3D_TexBind(0, (C3D_Tex*)id);
} }
void GfxCitro3D::SysReset() { void GfxCitro3D::SysReset() {
if (!impl) return; if (!impl) return;
C3D_CullFace(GPU_CULL_NONE);
} }
Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w, Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
@@ -210,7 +227,7 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) { void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {
if (!tex.GetID()) return; if (!tex.GetID()) return;
UnRegisterTexture(tex); UnregisterTexture(tex);
C3D_Tex* t = reinterpret_cast<C3D_Tex*>(tex.GetID()); C3D_Tex* t = reinterpret_cast<C3D_Tex*>(tex.GetID());
C3D_TexDelete(t); C3D_TexDelete(t);
delete t; delete t;

View File

@@ -37,7 +37,7 @@ VS_OUT main(VS_IN input) {
static const char* g_psCode = R"( static const char* g_psCode = R"(
sampler2D tex : register(s0); sampler2D tex : register(s0);
bool alfa; float alfa;
struct PS_IN { struct PS_IN {
float2 uv : TEXCOORD0; float2 uv : TEXCOORD0;
@@ -46,7 +46,7 @@ struct PS_IN {
float4 main(PS_IN input) : COLOR0 { float4 main(PS_IN input) : COLOR0 {
float4 tc = tex2D(tex, input.uv); float4 tc = tex2D(tex, input.uv);
if (alfa) if (alfa > 0.5)
return float4(input.col.rgb, tc.a * input.col.a); return float4(input.col.rgb, tc.a * input.col.a);
else else
return tc * input.col; return tc * input.col;
@@ -136,6 +136,7 @@ void GfxDirectX9::SysDeinit() {
void GfxDirectX9::Submit(size_t count, size_t start) { void GfxDirectX9::Submit(size_t count, size_t start) {
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return; if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
BindTexture(CurrentTex);
impl->Device->SetVertexShaderConstantF( impl->Device->SetVertexShaderConstantF(
0, reinterpret_cast<const float*>(&Projection), 4); 0, reinterpret_cast<const float*>(&Projection), 4);
@@ -186,7 +187,7 @@ void GfxDirectX9::SysReset() {
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w, Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type, int h, TextureFormat type,
TextureFilter filter) { TextureFilter filter) {
if (!impl || !impl->Device) return 0; if (!impl || !impl->Device) return Li::Texture();
IDirect3DTexture9* tex = nullptr; IDirect3DTexture9* tex = nullptr;
D3DFORMAT fmt = D3DFMT_A8R8G8B8; D3DFORMAT fmt = D3DFMT_A8R8G8B8;
if (type == TextureFormat::RGB24) if (type == TextureFormat::RGB24)
@@ -196,7 +197,7 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
HRESULT hr = impl->Device->CreateTexture(w, h, 1, 0, fmt, D3DPOOL_MANAGED, HRESULT hr = impl->Device->CreateTexture(w, h, 1, 0, fmt, D3DPOOL_MANAGED,
&tex, nullptr); &tex, nullptr);
if (FAILED(hr) || !tex) return 0; if (FAILED(hr) || !tex) return Li::Texture();
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
tex->LockRect(0, &rect, nullptr, 0); tex->LockRect(0, &rect, nullptr, 0);
@@ -209,7 +210,7 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
u8 r = pixels[(y * w + x) * 3 + 0]; u8 r = pixels[(y * w + x) * 3 + 0];
u8 g = pixels[(y * w + x) * 3 + 1]; u8 g = pixels[(y * w + x) * 3 + 1];
u8 b = pixels[(y * w + x) * 3 + 2]; u8 b = pixels[(y * w + x) * 3 + 2];
dst[x] = (0xFF << 24) | (r << 16) | (g << 8) | b; // X8R8G8B8 dst[x] = (0xFF << 24) | (r << 16) | (g << 8) | b;
} }
dstRow += rect.Pitch; dstRow += rect.Pitch;
} }
@@ -222,7 +223,7 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
u8 g = pixels[(y * w + x) * 4 + 1]; u8 g = pixels[(y * w + x) * 4 + 1];
u8 b = pixels[(y * w + x) * 4 + 2]; u8 b = pixels[(y * w + x) * 4 + 2];
u8 a = pixels[(y * w + x) * 4 + 3]; u8 a = pixels[(y * w + x) * 4 + 3];
dst[x] = (a << 24) | (r << 16) | (g << 8) | b; // A8R8G8B8 dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
} }
dstRow += rect.Pitch; dstRow += rect.Pitch;
} }
@@ -246,7 +247,7 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) { void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {
if (!tex.GetID()) return; if (!tex.GetID()) return;
UnRegisterTexture(tex); UnregisterTexture(tex);
IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID(); IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID();
t->Release(); t->Release();
} }

View File

@@ -1,4 +1,12 @@
#ifndef __3DS__ #ifdef __3DS__
#include <3ds.h>
#include <citro3d.h>
const u32 DisplayTransferFlags =
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) |
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) |
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));
#else
#include <glad/glad.h> #include <glad/glad.h>
////////////////////////// //////////////////////////
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -80,6 +88,15 @@ class App {
#endif #endif
glfwSwapInterval(1); glfwSwapInterval(1);
#else #else
gfxInitDefault();
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
Top =
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
Bottom =
C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(Top, GFX_TOP, GFX_LEFT, DisplayTransferFlags);
C3D_RenderTargetSetOutput(Bottom, GFX_BOTTOM, GFX_LEFT,
DisplayTransferFlags);
PD::Gfx::UseDriver<PD::GfxCitro3D>(); PD::Gfx::UseDriver<PD::GfxCitro3D>();
#endif #endif
PD::Gfx::Init(); PD::Gfx::Init();
@@ -97,13 +114,14 @@ class App {
cmd->Reserve(4, 6); cmd->Reserve(4, 6);
cmd->Add(0, 1, 2); cmd->Add(0, 1, 2);
cmd->Add(0, 2, 3); cmd->Add(0, 2, 3);
cmd->Add(PD::Li::Vertex(PD::fvec2(0, 0), PD::fvec2(0, 0), 0xffffffff)); cmd->Add(
cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, 0), PD::fvec2(1, 0), PD::Li::Vertex(PD::fvec2(0, 0), pTex.GetUV().TopLeft(), 0xffffffff));
0xffffffff)); cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, 0),
pTex.GetUV().TopRight(), 0xffffffff));
cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, pTex.GetSize().y), cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, pTex.GetSize().y),
PD::fvec2(1, 1), 0xffffffff)); pTex.GetUV().BotRight(), 0xffffffff));
cmd->Add(PD::Li::Vertex(PD::fvec2(0, pTex.GetSize().y), PD::fvec2(0, 1), cmd->Add(PD::Li::Vertex(PD::fvec2(0, pTex.GetSize().y),
0xffffffff)); pTex.GetUV().BotLeft(), 0xffffffff));
cmd->Tex = pTex.GetID(); cmd->Tex = pTex.GetID();
} }
~App() { ~App() {
@@ -118,8 +136,13 @@ class App {
void Run() { void Run() {
#ifdef __3DS__ #ifdef __3DS__
while (aptMainLoop()) { while (aptMainLoop()) {
PD::Gfx::SetViewPort(400, 240);
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C3D_FrameDrawOn(Top);
C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
#else #else
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
PD::Gfx::SetViewPort(1280, 720);
if (pDriver == Driver::OpenGL2 || pDriver == Driver::OpenGL3) { if (pDriver == Driver::OpenGL2 || pDriver == Driver::OpenGL3) {
glClearColor(0.1, 0.1, 0.1, 0.1); glClearColor(0.1, 0.1, 0.1, 0.1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@@ -135,9 +158,10 @@ class App {
} }
#endif #endif
PD::Gfx::Reset(); PD::Gfx::Reset();
PD::Gfx::SetViewPort(1280, 720);
PD::Gfx::Draw(pPool); PD::Gfx::Draw(pPool);
#ifdef __3DS__ #ifdef __3DS__
C3D_FrameEnd(0);
#else #else
glfwPollEvents(); glfwPollEvents();
if (pDriver == Driver::DirectX9) { if (pDriver == Driver::DirectX9) {
@@ -155,7 +179,10 @@ class App {
} }
private: private:
#ifndef __3DS__ #ifdef __3DS__
C3D_RenderTarget* Top = nullptr;
C3D_RenderTarget* Bottom = nullptr;
#else
GLFWwindow* window = nullptr; GLFWwindow* window = nullptr;
#endif #endif
PD::Pool<PD::Li::Command> pPool; PD::Pool<PD::Li::Command> pPool;