Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Nintendo Switch #4491

Merged
merged 21 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5e15822
WIP support for Nintendo Switch
Mstrodl Feb 19, 2021
38d5312
OpenAL is usable
Mstrodl Feb 20, 2021
2278305
Merge remote-tracking branch 'origin/master' into feature/switch
Mstrodl Feb 20, 2021
2a66f69
Definitely working online
Mstrodl Feb 24, 2021
353c528
Remove some debug code, add manual crash when DEBUG_NXLINK is on
Mstrodl Feb 25, 2021
e6533fb
Merge remote-tracking branch 'origin/master' into feature/switch
Mstrodl Feb 25, 2021
00bc870
Remove more debug logs
Mstrodl Feb 25, 2021
07e05e8
Support touch, account name detection, language detection. Remove res…
Mstrodl Feb 25, 2021
b327294
Stylistic changes
Mstrodl Feb 25, 2021
1b3aaf2
SFXManager: update on main thread
Mstrodl Feb 27, 2021
3387c0b
Add build script, remove crypto.hpp changes, disable opengl recorder …
Mstrodl Feb 28, 2021
1f8d9df
make: use sudo where needed, libs=>lib, portlib=>portlibs
Mstrodl Mar 1, 2021
a26e428
make: build harfbuzz with freetype
Mstrodl Mar 1, 2021
de7d686
main: remove DEBUG_NXLINK
Mstrodl Mar 2, 2021
06e1c4b
Merge remote-tracking branch 'origin/master' into feature/switch
Mstrodl Mar 2, 2021
8588187
socket_address: this comment is no longer relevant
Mstrodl Mar 2, 2021
37170bd
Fix indentation in SDL, remove extra debug logs from InputManager
Mstrodl Mar 2, 2021
9ca3c87
InputManager: make log debug, not info
Mstrodl Mar 2, 2021
ca27497
CMakeLists: add mbedtls include dirs on switch
Mstrodl Mar 2, 2021
d02aecb
main: deinitialize stuff
Mstrodl Mar 3, 2021
2666375
main_loop: fix format
Mstrodl Mar 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 39 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,25 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "STKRelease")
endif()

option(USE_SWITCH "Build targetting switch" OFF)

option(SERVER_ONLY "Create a server only (i.e. no graphics or sound)" OFF)
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
option(USE_SYSTEM_ENET "Use system ENet instead of the built-in version, when available." ON)
option(USE_IPV6 "Allow create or connect to game server with IPv6 address, system enet will not be used." ON)
CMAKE_DEPENDENT_OPTION(USE_IPV6 "Allow create or connect to game server with IPv6 address, system enet will not be used." ON
"NOT USE_SWITCH" OFF)
option(USE_SYSTEM_WIIUSE "Use system WiiUse instead of the built-in version, when available." OFF)
option(USE_SQLITE3 "Use sqlite to manage server stats and ban list." ON)

option(USE_CRYPTO_OPENSSL "Use OpenSSL instead of MbedTLS for cryptography in STK." ON)
CMAKE_DEPENDENT_OPTION(USE_CRYPTO_OPENSSL "Use OpenSSL instead of MbedTLS for cryptography in STK." ON
"NOT USE_SWITCH" OFF)
CMAKE_DEPENDENT_OPTION(BUILD_RECORDER "Build opengl recorder" ON
"NOT SERVER_ONLY;NOT APPLE" OFF)
"NOT SERVER_ONLY;NOT APPLE;NOT USE_SWITCH" OFF)
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_SQUISH "Use system Squish library instead of the built-in version, when available." ON
"NOT SERVER_ONLY" OFF)
CMAKE_DEPENDENT_OPTION(USE_WIIUSE "Support for wiimote input devices" ON
"NOT SERVER_ONLY;NOT CYGWIN" OFF)
"NOT SERVER_ONLY;NOT CYGWIN;NOT USE_SWITCH" OFF)

if(APPLE AND NOT IOS)
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
Expand Down Expand Up @@ -185,7 +189,7 @@ endif()
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/bullet")
include_directories(BEFORE "${PROJECT_SOURCE_DIR}/lib/bullet/src")

if(WIN32 OR CMAKE_SYSTEM_NAME MATCHES "BSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly")
if(WIN32 OR CMAKE_SYSTEM_NAME MATCHES "BSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly" OR USE_SWITCH)
set(LIBRESOLV_LIBRARY)
elseif (HAIKU)
find_library(LIBRESOLV_LIBRARY NAMES network socket)
Expand Down Expand Up @@ -370,7 +374,13 @@ if (NOT SERVER_ONLY)
SET(SHEENBIDI_LIBRARY sheenbidi)

# Freetype
find_package(Freetype)
if (USE_SWITCH)
SET(FREETYPE_INCLUDE_DIRS /opt/devkitpro/portlibs/switch/include/freetype2)
SET(FREETYPE_LIBRARY freetype)
SET(FREETYPE_FOUND YES)
else()
find_package(Freetype)
endif()
if(FREETYPE_FOUND)
include_directories(${FREETYPE_INCLUDE_DIRS})
else()
Expand Down Expand Up @@ -605,6 +615,29 @@ target_link_libraries(supertuxkart
${MCPP_LIBRARY}
)

if (USE_SWITCH)
include(cmake/FindEGL.cmake)
find_library(NX_LIBRARY NAMES nx libnx REQUIRED)
find_library(DRM_LIBRARY NAMES drm_nouveau libdrm_nouveau REQUIRED)
find_library(GLAPI_LIBRARY NAMES glapi libglapi REQUIRED)
target_link_libraries(supertuxkart
${NX_LIBRARY}
-lz
-lfreetype
-lSDL2
-lpng
-lbz2
-lharfbuzz
-logg
-lvorbis
-lopenal
${EGL_LIBRARY}
${DRM_LIBRARY}
${GLAPI_LIBRARY}
${NX_LIBRARY}
)
endif()

if (USE_SQLITE3)
target_link_libraries(supertuxkart ${SQLITE3_LIBRARY})
endif()
Expand Down
Binary file added data/supertuxkart_256.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions lib/enet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ check_function_exists("fcntl" HAS_FCNTL)
check_function_exists("poll" HAS_POLL)
check_function_exists("getaddrinfo" HAS_GETADDRINFO)
check_function_exists("getnameinfo" HAS_GETNAMEINFO)
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
# Switch doesn't support these and cmake freaks out checking them
# because they exist in headers but not libs
if (NOT USE_SWITCH)
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
endif()
check_function_exists("inet_pton" HAS_INET_PTON)
check_function_exists("inet_ntop" HAS_INET_NTOP)
check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" HAS_MSGHDR_FLAGS)
Expand Down
8 changes: 7 additions & 1 deletion lib/irrlicht/source/Irrlicht/CFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ bool CFileSystem::changeWorkingDirectoryTo(const io::path& newDirectory)

io::path CFileSystem::getAbsolutePath(const io::path& filename) const
{
#if defined(_IRR_WINDOWS_CE_PLATFORM_)
#if defined(_IRR_WINDOWS_CE_PLATFORM_) || defined(__SWITCH__)
return filename;
#elif defined(_IRR_WINDOWS_API_)
wchar_t *p=0;
Expand Down Expand Up @@ -958,6 +958,12 @@ bool CFileSystem::existFile(const io::path& filename) const
#if defined(_IRR_WINDOWS_API_)
return (_waccess(StringUtils::utf8ToWide(filename.c_str()).c_str(), F_OK) != -1);
#else
#ifdef __SWITCH__
if(filename.size() == 0)
{
return false;
}
#endif
return (access(filename.c_str(), F_OK) != -1);
#endif
#else
Expand Down
8 changes: 7 additions & 1 deletion lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");

// Switch SDL disables this hint by default: https://github.com/devkitPro/SDL/pull/55#issuecomment-633775255
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "1");

#ifndef MOBILE_STK
// Prevent fullscreen minimizes when losing focus
if (CreationParams.Fullscreen)
Expand Down Expand Up @@ -100,8 +103,11 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
{
SDL_VERSION(&Info.version);

// Switch doesn't support GetWindowWMInfo
#ifndef __SWITCH__
if (!SDL_GetWindowWMInfo(Window, &Info))
return;
#endif
#ifdef IOS_STK
init_objc(&Info, &TopPadding, &BottomPadding, &LeftPadding, &RightPadding);
#endif
Expand All @@ -127,7 +133,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
else
return;
}
#ifndef ANDROID
#if !defined(ANDROID) && !defined(__SWITCH__)
else if (!GUIEngine::isNoGraphics())
{
// Get highdpi native scale using renderer so it will work with any
Expand Down
21 changes: 20 additions & 1 deletion lib/irrlicht/source/Irrlicht/CMountPointReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,13 @@ CMountPointReader::CMountPointReader(IFileSystem * parent, const io::path& basen

const io::path& work = Parent->getWorkingDirectory();

Parent->changeWorkingDirectoryTo(basename);
if(!Parent->changeWorkingDirectoryTo(basename))
{
#ifdef __SWITCH__
printf("Failed changing directory to %s\n", basename.c_str());
perror("Why couldn't we change working directory?");
#endif
}
buildDirectory();
Parent->changeWorkingDirectoryTo(work);

Expand All @@ -119,6 +125,19 @@ void CMountPointReader::buildDirectory()
for (u32 i=0; i < size; ++i)
{
io::path full = list->getFullFileName(i);
#ifdef __SWITCH__
// Real hardware gets sdmc: into the path somehow
auto sdmc = "sdmc:";
auto romfs = "romfs:";
if (full.find(sdmc, 0) == 0)
{
full = full.subString(5, full.size() - 5);
}
else if (full.find(romfs, 0) == 0)
{
full = full.subString(6, full.size() - 6);
}
#endif
full = full.subString(Path.size(), full.size() - Path.size());

if (full == "")
Expand Down
3 changes: 3 additions & 0 deletions lib/mcpp/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
#endif

#include "sys/types.h"
#ifdef __SWITCH__
#define readlink(path,buf,length) 0
#endif
#include "sys/stat.h" /* For stat() */
#if ! defined( S_ISREG)
#define S_ISREG( mode) (mode & S_IFREG)
Expand Down
33 changes: 29 additions & 4 deletions src/audio/sfx_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ SFXManager::SFXManager()
{
// The thread is created even if there atm sfx are disabled
// (since the user might enable it later).
#ifndef __SWITCH__
m_thread = std::thread(std::bind(mainLoop, this));
#endif
setMasterSFXVolume( UserConfigParams::m_sfx_volume );
m_sfx_commands.lock();
m_sfx_commands.getData().clear();
Expand All @@ -108,7 +110,7 @@ SFXManager::SFXManager()
*/
SFXManager::~SFXManager()
{
#ifdef ENABLE_SOUND
#if defined(ENABLE_SOUND) && !defined(__SWITCH__)
if (UserConfigParams::m_enable_sound)
{
m_thread.join();
Expand Down Expand Up @@ -345,33 +347,50 @@ void SFXManager::mainLoop(void *obj)
if (!UserConfigParams::m_enable_sound)
return;

#ifndef __SWITCH__
VS::setThreadName("SFXManager");
#endif
SFXManager *me = (SFXManager*)obj;

std::unique_lock<std::mutex> ul = me->m_sfx_commands.acquireMutex();

#ifdef __SWITCH__
int iterCount = 0;
#endif
// Wait till we have an empty sfx in the queue
while (me->m_sfx_commands.getData().empty() ||
me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT)
while (
#ifdef __SWITCH__
// Don't spend too much time working on audio
++iterCount != 30 && !me->m_sfx_commands.getData().empty()
#else
me->m_sfx_commands.getData().empty() || me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT
#endif
)
{
PROFILER_PUSH_CPU_MARKER("Wait", 255, 0, 0);
bool empty = me->m_sfx_commands.getData().empty();

// Wait in cond_wait for a request to arrive. The 'while' is necessary
// since "spurious wakeups from the pthread_cond_wait ... may occur"
// (pthread_cond_wait man page)!
#ifndef __SWITCH__
while (empty)
{
me->m_condition_variable.wait(ul);
empty = me->m_sfx_commands.getData().empty();
}
#endif
SFXCommand *current = me->m_sfx_commands.getData().front();
me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin());

if (current->m_command == SFX_EXIT)
{
delete current;
#ifdef __SWITCH__
return;
#else
break;
#endif
}
ul.unlock();
PROFILER_POP_CPU_MARKER();
Expand Down Expand Up @@ -460,13 +479,15 @@ void SFXManager::mainLoop(void *obj)
// need to keep the user waiting for STK to exit.
me->setCanBeDeleted();

#ifndef __SWITCH__
// Clean up memory to avoid leak detection
while(!me->m_sfx_commands.getData().empty())
{
delete me->m_sfx_commands.getData().front();
me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin());
}
#endif
#endif // __SWITCH__
#endif // ENABLE_SOUD
return;
} // mainLoop

Expand Down Expand Up @@ -790,6 +811,10 @@ void SFXManager::update()
queue(SFX_UPDATE, (SFXBase*)NULL);
// Wake up the sfx thread to handle all queued up audio commands.
m_condition_variable.notify_one();

#ifdef __SWITCH__
mainLoop(this);
#endif
#endif
} // update

Expand Down
2 changes: 2 additions & 0 deletions src/audio/sfx_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,10 @@ class SFXManager : public NoCopy, public CanBeDeleted
/** Master gain value, taken from the user config value. */
float m_master_gain;

#ifndef __SWITCH__
/** Thread id of the thread running in this object. */
std::thread m_thread;
#endif

uint64_t m_last_update_time;

Expand Down
4 changes: 3 additions & 1 deletion src/config/hardware_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
#include <string>
#ifndef WIN32
# include <sys/param.h> // To get BSD macro
# include <sys/utsname.h>
# ifndef __SWITCH__
# include <sys/utsname.h>
# endif
#endif
#if defined(__APPLE__) || defined(BSD)
# include <sys/sysctl.h>
Expand Down
20 changes: 19 additions & 1 deletion src/graphics/irr_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,17 @@ IrrDriver::IrrDriver()
m_resolution_changing = RES_CHANGE_NONE;

struct irr::SIrrlichtCreationParameters p;
#ifdef __SWITCH__
// Switch doesn't like multiple window create/closes, so we hardcode it
// Aforementioned chicken and egg problem isn't an issue because switch's SDL only supports two resolutions
p.DriverType = video::EDT_OPENGL;
p.Bits = 24U;
p.WindowSize = core::dimension2d<u32>(1280,720);
#else
p.DriverType = video::EDT_NULL;
p.WindowSize = core::dimension2d<u32>(640,480);
p.Bits = 16U;
p.WindowSize = core::dimension2d<u32>(640,480);
#endif
p.Fullscreen = false;
p.SwapInterval = 0;
p.EventReceiver = NULL;
Expand Down Expand Up @@ -366,6 +374,7 @@ void IrrDriver::initDevice()
{
SIrrlichtCreationParameters params;

#ifndef __SWITCH__
// If --no-graphics option was used, the null device can still be used.
if (!GUIEngine::isNoGraphics())
{
Expand Down Expand Up @@ -452,7 +461,11 @@ void IrrDriver::initDevice()
UserConfigParams::m_gamepad_visualisation);

// Try 32 and, upon failure, 24 then 16 bit per pixels
#ifdef __SWITCH__
int bits=24;
#else
for (int bits=32; bits>15; bits -=8)
#endif
{
if(UserConfigParams::logMisc())
Log::verbose("irr_driver", "Trying to create device with "
Expand Down Expand Up @@ -509,8 +522,12 @@ void IrrDriver::initDevice()
*/
m_device = createDeviceEx(params);

#ifdef __SWITCH__
assert(m_device != NULL);
#else
if(m_device)
break;
#endif
} // for bits=32, 24, 16


Expand Down Expand Up @@ -541,6 +558,7 @@ void IrrDriver::initDevice()
}
}
}
#endif // __SWITCH__

if(!m_device)
{
Expand Down