Add nintendo switch support

This commit is contained in:
2026-03-21 10:18:01 +01:00
parent 6beef97cdf
commit 3b0b103eb3
9 changed files with 214 additions and 76 deletions
+11 -2
View File
@@ -17,6 +17,11 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
set(PD_ENABLE_OPENGL3 OFF) set(PD_ENABLE_OPENGL3 OFF)
set(PD_ENABLE_VULKAN OFF) set(PD_ENABLE_VULKAN OFF)
set(PD_ENABLE_CITRO3D ON) set(PD_ENABLE_CITRO3D ON)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
set(PD_ENABLE_OPENGL2 OFF)
set(PD_ENABLE_OPENGL3 ON)
set(PD_ENABLE_VULKAN OFF)
set(PD_ENABLE_CITRO3D OFF)
endif() endif()
add_library(pd-system STATIC add_library(pd-system STATIC
@@ -76,8 +81,12 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
ctru ctru
) )
else() else()
if(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
target_include_directories(pd-system
PUBLIC $ENV{DEVKITPRO}/portlibs/switch/include
)
endif()
target_link_libraries(pd-system target_link_libraries(pd-system
PUBLIC PUBLIC spirv-helper
spirv-helper
) )
endif() endif()
+1
View File
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/targets.cmake)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/core) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/core)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/gfx) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/gfx)
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

+45
View File
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.22)
set(APP_TITLE "App")
set(APP_AUTHOR "tobid7")
set(APP_VERSION "${CMAKE_PROJECT_VERSION}")
set(APP_ICON "icon.png")
set(APP_ROMFS "romfs")
function(make_3ds_target _NAME TITLE AUTHOR _VERSION ICON ROMFS)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
find_program(3DSXTOOL 3dsxtool)
find_program(SMDHTOOL smdhtool)
add_custom_target(${_NAME}.smdh
COMMAND ${SMDHTOOL} --create "${TITLE}" "${_VERSION}" "${AUTHOR}" "${ICON}"
${_NAME}.smdh
DEPENDS ${_NAME}.elf
COMMENT "Creating ${_NAME}.smdh"
)
add_custom_target(${_NAME}.3dsx
COMMAND ${3DSXTOOL} ${_NAME}.elf ${_NAME}.3dsx --smdh=${_NAME}.smdh
--romfs="${ROMFS}"
DEPENDS ${_NAME}.smdh
COMMENT "Creating ${_NAME}.3dsx"
)
endif()
endfunction()
function(make_nx_target _NAME TITLE AUTHOR _VERSION ICON ROMFS)
if(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
find_program(ELF2NRO elf2nro)
find_program(NACPTOOL nacptool)
add_custom_target(${_NAME}.nacp
COMMAND ${NACPTOOL} --create "${TITLE}" "${AUTHOR}" "${_VERSION}"
${_NAME}.nacp
DEPENDS ${_NAME}.elf
COMMENT "Creating ${_NAME}.nacp"
)
add_custom_target(${_NAME}.nro
COMMAND ${ELF2NRO} ${_NAME}.elf ${_NAME}.nro --nacp=${_NAME}.nacp
--romfsdir="${ROMFS}" --icon="${ICON}"
DEPENDS ${_NAME}.nacp
COMMENT "Creating ${_NAME}.nro"
)
endif()
endfunction()
+34 -2
View File
@@ -5,10 +5,42 @@ project(gfx-tests)
add_executable(gfx-tests ${CMAKE_CURRENT_SOURCE_DIR}/source/main.cpp) add_executable(gfx-tests ${CMAKE_CURRENT_SOURCE_DIR}/source/main.cpp)
target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system stb) target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system stb)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
target_link_libraries(gfx-tests PRIVATE ctru)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
target_link_libraries(gfx-tests
PRIVATE
glad
glfw3
EGL
glapi
drm_nouveau
nx
)
target_compile_definitions(gfx-tests PRIVATE __SWITCH__ ENABLE_NXLINK)
else()
target_link_libraries(gfx-tests PRIVATE glfw) target_link_libraries(gfx-tests PRIVATE glfw)
endif() endif()
install( install(
TARGETS gfx-tests TARGETS gfx-tests
) )
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
make_3ds_target(
"gfx-tests"
"Palladium Gfx Tests"
"tobid7"
"1.0.0"
"${CMAKE_CURRENT_SOURCE_DIR}/../assets/icon48.png"
"${CMAKE_CURRENT_SOURCE_DIR}/../assets"
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
make_nx_target(
"gfx-tests"
"Palladium Gfx Tests"
"tobid7"
"1.0.0"
"${CMAKE_CURRENT_SOURCE_DIR}/../assets/icon.jpg"
"${CMAKE_CURRENT_SOURCE_DIR}/../assets"
)
endif()
+71 -23
View File
@@ -1,4 +1,4 @@
#ifdef __3DS__ #if defined(__3DS__)
#include <3ds.h> #include <3ds.h>
#include <citro3d.h> #include <citro3d.h>
const u32 DisplayTransferFlags = const u32 DisplayTransferFlags =
@@ -6,6 +6,22 @@ const u32 DisplayTransferFlags =
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) |
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)); GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));
#elif defined(__SWITCH__)
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <stdio.h>
#include <switch.h>
static void errorCallback(int errorCode, const char* description) {
printf("Glfw Error %d: %s\n", errorCode, description);
}
#define PASSERT(x) \
if (!x) { \
printf("%s: %s", __PRETTY_FUNCTION__, #x); \
exit(0); \
}
#else #else
#include <glad/glad.h> #include <glad/glad.h>
////////////////////////// //////////////////////////
@@ -44,7 +60,32 @@ class App {
public: public:
App(Driver d = Driver::OpenGL3) : pDriver(d) { App(Driver d = Driver::OpenGL3) : pDriver(d) {
PD::Os::UseDriver<PD::OsDriver>(); PD::Os::UseDriver<PD::OsDriver>();
#ifndef __3DS__ #if defined(__3DS__)
romfsInit();
gfxInitDefault();
consoleInit(GFX_BOTTOM, nullptr);
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>();
#elif defined(__SWITCH__)
PASSERT(glfwInit());
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window =
glfwCreateWindow(1280, 720, "gfx_test (OpenGL3)", nullptr, nullptr);
PASSERT(window);
glfwMakeContextCurrent(window);
PASSERT(gladLoadGL());
glfwSwapInterval(1);
PD::Gfx::UseDriver<PD::GfxOpenGL3>();
#else
glfwInit(); glfwInit();
std::string winname = "gfx_test"; std::string winname = "gfx_test";
if (d == Driver::OpenGL2) { if (d == Driver::OpenGL2) {
@@ -94,22 +135,10 @@ class App {
} }
#endif #endif
glfwSwapInterval(1); glfwSwapInterval(1);
#else
gfxInitDefault();
consoleInit(GFX_BOTTOM, nullptr);
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>();
#endif #endif
PD::Gfx::Init(); PD::Gfx::Init();
#ifdef __3DS__ #if defined(__3DS__) || defined(__SWITCH__)
pTex = LoadTex("sdmc:/icon.png"); pTex = LoadTex("romfs:/icon.png");
#else #else
pTex = LoadTex("icon.png"); pTex = LoadTex("icon.png");
#endif #endif
@@ -124,19 +153,30 @@ class App {
~App() { ~App() {
PD::Gfx::DeleteTexture(pTex); PD::Gfx::DeleteTexture(pTex);
PD::Gfx::Deinit(); PD::Gfx::Deinit();
#ifndef __3DS__ #if !defined(__3DS__)
glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
#endif #endif
} }
void Run() { void Run() {
#ifdef __3DS__ #if defined(__3DS__)
while (aptMainLoop()) { while (aptMainLoop()) {
PD::Gfx::SetViewPort(400, 240); PD::Gfx::SetViewPort(400, 240);
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C3D_FrameDrawOn(Top); C3D_FrameDrawOn(Top);
C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0); C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
#elif defined(__SWITCH__)
while (!glfwWindowShouldClose(window)) {
GLFWgamepadstate _gs;
if (glfwGetGamepadState(GLFW_JOYSTICK_1, &_gs)) {
if (_gs.buttons[GLFW_GAMEPAD_BUTTON_START] == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
PD::Gfx::SetViewPort(1280, 720);
glClearColor(0.1, 0.1, 0.1, 0.1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 1280, 720);
#else #else
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
int ww, wh; int ww, wh;
@@ -159,7 +199,7 @@ class App {
PD::Gfx::Reset(); PD::Gfx::Reset();
PD::Gfx::Draw(pList); PD::Gfx::Draw(pList);
#ifdef __3DS__ #if defined(__3DS__)
C3D_FrameEnd(0); C3D_FrameEnd(0);
#else #else
glfwPollEvents(); glfwPollEvents();
@@ -178,7 +218,7 @@ class App {
} }
private: private:
#ifdef __3DS__ #if defined(__3DS__)
C3D_RenderTarget* Top = nullptr; C3D_RenderTarget* Top = nullptr;
C3D_RenderTarget* Bottom = nullptr; C3D_RenderTarget* Bottom = nullptr;
#else #else
@@ -194,6 +234,13 @@ class App {
}; };
int main(int argc, char** argv) { int main(int argc, char** argv) {
#if defined(__SWITCH__)
socketInitializeDefault();
nxlinkStdio();
romfsInit();
printf("Starting Palladium GFX Tests...\n");
glfwSetErrorCallback(errorCallback);
#endif
Driver drv = Driver::OpenGL3; Driver drv = Driver::OpenGL3;
if (argc == 2) { if (argc == 2) {
if (std::string(argv[1]) == "gl2") { if (std::string(argv[1]) == "gl2") {
@@ -204,7 +251,8 @@ int main(int argc, char** argv) {
drv = Driver::DirectX9; drv = Driver::DirectX9;
} }
} }
App app(drv); App* app = new App(drv);
app.Run(); app->Run();
delete app;
return 0; return 0;
} }
+4 -1
View File
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.22)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
# SPIRV-Helper
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/spirv-helper)
else() else()
# GLAD # GLAD
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad)
@@ -13,7 +16,7 @@ endif()
add_library(stb INTERFACE) add_library(stb INTERFACE)
target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb) target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS" AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
# GLFW # GLFW
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "") set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "") set(GLFW_BUILD_TESTS OFF CACHE BOOL "")