Wii U support (#1097)

* Wii U support

* [WiiU] Combined Dockerfile

* [WiiU] Combined Dockerfile

* [WiiU] Combined Dockerfile

* Add Jenkins support

* wiiu: fix scissor clamp

* wiiu: improve button remapping

* wiiu: fix scaling issues

* Update Dockerfile after merge

* Pull assets before build

* Only stop container once

* Adjust logging sinks

* wiiu: Change button mapping to match PC version

* wiiu: Implement controller changes

* wiiu: Update BUILDING.md

Co-authored-by: qurious-pixel <62252937+qurious-pixel@users.noreply.github.com>
Co-authored-by: David Chavez <david@dcvz.io>
This commit is contained in:
GaryOderNichts 2022-08-15 04:57:24 +02:00 committed by GitHub
commit 68e7f2e6c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 5460 additions and 73 deletions

View file

@ -1696,9 +1696,20 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
STORMLIB_NO_AUTO_LINK
)
endif()
endif()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG"
">"
"$<$<CONFIG:Release>:"
"NDEBUG"
">"
"SPDLOG_ACTIVE_LEVEL=3;"
"SPDLOG_NO_THREAD_ID;"
"SPDLOG_NO_TLS;"
"STBI_NO_THREAD_LOCALS;"
)
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG"
@ -1825,6 +1836,26 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_link_options(${PROJECT_NAME} PRIVATE
-pthread
)
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
target_compile_options(${PROJECT_NAME} PRIVATE
-O2
# disable some warnings to not clutter output
-Wno-multichar
-Wno-return-type
-Wno-narrowing
-Wno-switch-outside-range
$<$<COMPILE_LANGUAGE:C>:
-Wno-incompatible-pointer-types
-Wno-discarded-array-qualifiers
-Wno-discarded-qualifiers
-Wno-int-conversion
-Wno-implicit-function-declaration
-Wno-builtin-declaration-mismatch
-Wno-switch-unreachable
-Wno-stringop-overflow
>
)
else()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
set(CPU_OPTION -msse2 -mfpmath=sse)
@ -1908,6 +1939,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
-lglad
Threads::Threads
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
find_package(SDL2 REQUIRED)
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDUtils;"
SDL2::SDL2-static
"$<$<CONFIG:Debug>:-Wl,--wrap=abort>"
)
target_include_directories(${PROJECT_NAME} PRIVATE
${DEVKITPRO}/portlibs/wiiu/include/
)
else()
find_package(SDL2)
set(THREADS_PREFER_PTHREAD_FLAG ON)
@ -1961,7 +2004,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
endif()
endif()
if(NOT CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
INSTALL(TARGETS soh DESTINATION . COMPONENT ship)
endif()
@ -1970,7 +2013,7 @@ execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/gabomdq/
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
INSTALL(FILES ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt DESTINATION ../MacOS COMPONENT ship)
elseif(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoSwitch")
elseif(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "NintendoSwitch|CafeOS")
INSTALL(FILES ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt DESTINATION . COMPONENT ship)
endif()
@ -1982,9 +2025,9 @@ install(CODE "
")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
if (NOT TARGET pathconf)
add_library(pathconf OBJECT switch/pathconf.c)
add_library(pathconf OBJECT platform/pathconf.c)
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE "${ADDITIONAL_LIBRARY_DEPENDENCIES}" $<TARGET_OBJECTS:pathconf> )
else()
@ -2006,4 +2049,10 @@ nx_create_nro(soh
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.nro DESTINATION . COMPONENT ship)
elseif(CMAKE_SYSTEM_NAME MATCHES "CafeOS")
wut_create_rpx(${PROJECT_NAME})
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.rpx DESTINATION . COMPONENT ship)
endif()

View file

@ -60,7 +60,9 @@ void Locale_ResetRegion(void);
u32 func_80001F48(void);
u32 func_80001F8C(void);
u32 Locale_IsRegionNative(void);
#if !defined(__APPLE__) && !defined(__SWITCH__)
#ifdef __WIIU__
void _assert(const char* exp, const char* file, s32 line);
#elif !defined(__APPLE__) && !defined(__SWITCH__)
void __assert(const char* exp, const char* file, s32 line);
#endif
#if defined(__APPLE__) && defined(NDEBUG)

View file

@ -233,7 +233,11 @@ extern GraphicsContext* __gfxCtx;
#define VTX_T(x,y,z,s,t,cr,cg,cb,a) { { x, y, z }, 0, { s, t }, { cr, cg, cb, a } }
#ifdef __WIIU__
#define ASSERT(expression) (void)((!!(expression)) || (_assert(#expression, __FILE__, (unsigned)(__LINE__)), 0))
#else
#define ASSERT(expression) (void)((!!(expression)) || (__assert(#expression, __FILE__, (unsigned)(__LINE__)), 0))
#endif
#define gDPSetTileCustom(pkt, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
do { \

View file

@ -49,6 +49,8 @@
#ifdef __SWITCH__
#include "SwitchImpl.h"
#elif defined(__WIIU__)
#include "WiiUImpl.h"
#endif
#include <Audio.h>
@ -171,6 +173,8 @@ extern "C" void OTRExtScanner() {
extern "C" void InitOTR() {
#ifdef __SWITCH__
Ship::Switch::Init(Ship::PreInitPhase);
#elif defined(__WIIU__)
Ship::WiiU::Init();
#endif
OTRGlobals::Instance = new OTRGlobals();
SaveManager::Instance = new SaveManager();
@ -235,6 +239,7 @@ extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) {
}
extern "C" void Graph_StartFrame() {
#ifndef __WIIU__
// Why -1?
int32_t dwScancode = OTRGlobals::Instance->context->GetWindow()->lastScancode;
OTRGlobals::Instance->context->GetWindow()->lastScancode = -1;
@ -292,6 +297,7 @@ extern "C" void Graph_StartFrame() {
break;
}
}
#endif
OTRGlobals::Instance->context->GetWindow()->StartFrame();
}

View file

@ -152,6 +152,12 @@ void SaveManager::Init() {
// If the global save file exist, load it. Otherwise, create it.
if (std::filesystem::exists(sGlobalPath)) {
std::ifstream input(sGlobalPath);
#ifdef __WIIU__
alignas(0x40) char buffer[8192];
input.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
#endif
nlohmann::json globalBlock;
input >> globalBlock;
@ -474,6 +480,12 @@ void SaveManager::SaveFile(int fileNum) {
}
std::ofstream output(GetFileName(fileNum));
#ifdef __WIIU__
alignas(0x40) char buffer[8192];
output.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
#endif
output << std::setw(4) << baseBlock << std::endl;
InitMeta(fileNum);
@ -486,6 +498,12 @@ void SaveManager::SaveGlobal() {
globalBlock["zTargetSetting"] = gSaveContext.zTargetSetting;
globalBlock["language"] = gSaveContext.language;
std::ofstream output("Save/global.sav");
#ifdef __WIIU__
alignas(0x40) char buffer[8192];
output.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
#endif
output << std::setw(4) << globalBlock << std::endl;
}
@ -494,6 +512,12 @@ void SaveManager::LoadFile(int fileNum) {
InitFile(false);
std::ifstream input(GetFileName(fileNum));
#ifdef __WIIU__
alignas(0x40) char buffer[8192];
input.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
#endif
nlohmann::json saveBlock;
input >> saveBlock;
if (!saveBlock.contains("version")) {
@ -1125,10 +1149,41 @@ void SaveManager::LoadStruct(const std::string& name, LoadStructFunc func) {
}
}
#ifdef __WIIU__
// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
int copy_file(const char* src, const char* dst)
{
alignas(0x40) uint8_t buf[4096];
FILE* r = fopen(src, "r");
if (!r) {
return -1;
}
FILE* w = fopen(dst, "w");
if (!w) {
return -2;
}
size_t res;
while ((res = fread(buf, 1, sizeof(buf), r)) > 0) {
if (fwrite(buf, 1, res, w) != res) {
break;
}
}
fclose(r);
fclose(w);
return res >= 0 ? 0 : res;
}
#endif
void SaveManager::CopyZeldaFile(int from, int to) {
assert(std::filesystem::exists(GetFileName(from)));
DeleteZeldaFile(to);
#ifdef __WIIU__
assert(copy_file(GetFileName(from).c_str(), GetFileName(to).c_str()) == 0);
#else
std::filesystem::copy_file(GetFileName(from), GetFileName(to));
#endif
fileMetaInfo[to].valid = true;
fileMetaInfo[to].deaths = fileMetaInfo[from].deaths;
for (int i = 0; i < ARRAY_COUNT(fileMetaInfo[to].playerName); i++) {
@ -1457,6 +1512,12 @@ void SaveManager::ConvertFromUnversioned() {
#define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE))
std::ifstream input("oot_save.sav", std::ios::binary);
#ifdef __WIIU__
alignas(0x40) char buffer[8192];
input.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
#endif
std::vector<char> data(std::istreambuf_iterator<char>(input), {});
input.close();

View file

@ -1,7 +1,11 @@
#include "global.h"
#ifndef __SWITCH__
#ifdef __WIIU__
void _assert(const char* exp, const char* file, s32 line) {
#else
void __assert(const char* exp, const char* file, s32 line) {
#endif
char msg[256];
osSyncPrintf("Assertion failed: %s, file %s, line %d, thread %d\n", exp, file, line, osGetThreadId(NULL));

View file

@ -397,6 +397,16 @@ s32 CollisionPoly_LineVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* posA, V
(poly->normal.x * posB->x + poly->normal.y * posB->y + poly->normal.z * posB->z) * COLPOLY_NORMAL_FRAC +
plane.originDist;
#ifdef __WIIU__
// on some platforms this ends up as very small numbers due to rounding issues
if (IS_ZERO(planeDistA)) {
planeDistA = 0.0f;
}
if (IS_ZERO(planeDistB)) {
planeDistB = 0.0f;
}
#endif
planeDistDelta = planeDistA - planeDistB;
if ((planeDistA >= 0.0f && planeDistB >= 0.0f) || (planeDistA < 0.0f && planeDistB < 0.0f) ||
(chkOneFace && planeDistA < 0.0f && planeDistB > 0.0f) || IS_ZERO(planeDistDelta)) {