diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..b28167aa9d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "platform/switch"] + path = platform/switch + url = https://github.com/Homebrodot/platform-switch diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index cc93dd540f..b71996c8fe 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -399,6 +399,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b } #endif +#ifdef HORIZON_ENABLED + if (!found) { + if (_load_resource_pack("romfs:/game.pck")) { + found = true; + } + } +#endif // HORIZON_ENABLED + if (!found) { // Try to load data pack at the location of the executable. // As mentioned above, we have two potential names to attempt. diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index bd1e62fc56..a6ca5ff80a 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -93,9 +93,9 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define glClearDepth glClearDepthf // enable extensions manually for android and ios -#ifndef UWP_ENABLED +#if defined IPHONE_ENABLED || defined ANDROID_ENABLED #include // needed to load extensions -#endif +#endif // IPHONE_ENABLED || ANDROID_ENABLED #ifdef IPHONE_ENABLED @@ -103,7 +103,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; //void *glRenderbufferStorageMultisampleAPPLE; //void *glResolveMultisampleFramebufferAPPLE; #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE -#elif defined(ANDROID_ENABLED) +#elif defined(ANDROID_ENABLED) || defined(HORIZON_ENABLED) #include PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; @@ -5986,7 +5986,7 @@ void RasterizerStorageGLES2::initialize() { // If the desktop build is using S3TC, and you export / run from the IDE for android, if the device supports // S3TC it will crash trying to load these textures, as they are not exported in the APK. This is a simple way // to prevent Android devices trying to load S3TC, by faking lack of hardware support. -#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED) +#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED) || defined(HORIZON_ENABLED) config.s3tc_supported = false; #endif diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 617d0b2884..6a0f4af2e0 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -414,6 +414,9 @@ String DirAccessUnix::read_link(String p_file) { p_file = fix_path(p_file); +#ifdef HORIZON_ENABLED + return p_file; +#else // HORIZON_ENABLED char buf[256]; memset(buf, 0, 256); ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf)); @@ -422,9 +425,11 @@ String DirAccessUnix::read_link(String p_file) { link.parse_utf8(buf, len); } return link; +#endif // !HORIZON_ENABLED } Error DirAccessUnix::create_link(String p_source, String p_target) { +#ifndef HORIZON_ENABLED if (p_target.is_rel_path()) p_target = get_current_dir().plus_file(p_target); @@ -433,7 +438,9 @@ Error DirAccessUnix::create_link(String p_source, String p_target) { if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) { return OK; - } else { + } else +#endif // !HORIZON_ENABLED + { return FAILED; } } diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 979c50f941..cd4a962c31 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -41,7 +41,7 @@ #include -#if defined(UNIX_ENABLED) +#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED) #include #endif @@ -131,6 +131,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { return last_error; } +#ifndef HORIZON_ENABLED // Set close on exec to avoid leaking it to subprocesses. int fd = fileno(f); @@ -143,6 +144,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { fcntl(fd, F_SETFD, opts | FD_CLOEXEC); #endif } +#endif // !HORIZON_ENABLED last_error = OK; flags = p_mode_flags; @@ -280,7 +282,7 @@ bool FileAccessUnix::file_exists(const String &p_path) { return false; } -#ifdef UNIX_ENABLED +#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED) // See if we have access to the file if (access(filename.utf8().get_data(), F_OK)) { return false; diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 651d6334ed..1c9d0edd4e 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -31,7 +31,7 @@ #include "ip_unix.h" -#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) +#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) || defined(HORIZON_ENABLED) #include @@ -54,7 +54,9 @@ #ifdef __FreeBSD__ #include #endif +#ifndef HORIZON_ENABLED #include +#endif // !HORIZON_ENABLED #endif #include #include @@ -213,6 +215,9 @@ void IP_Unix::get_local_interfaces(RBMap *r_interfaces) void IP_Unix::get_local_interfaces(RBMap *r_interfaces) const { struct ifaddrs *ifAddrStruct = nullptr; struct ifaddrs *ifa = nullptr; +#ifdef HORIZON_ENABLED + // todo: nifm +#else // HORIZON_ENABLED int family; getifaddrs(&ifAddrStruct); @@ -245,6 +250,7 @@ void IP_Unix::get_local_interfaces(RBMap *r_interfaces) if (ifAddrStruct != nullptr) { freeifaddrs(ifAddrStruct); } +#endif // !HORIZON_ENABLED } #endif diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index 895608e542..610d703f99 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -1,6 +1,3 @@ -#ifndef IP_UNIX_H -#define IP_UNIX_H - /*************************************************************************/ /* ip_unix.h */ /*************************************************************************/ @@ -32,9 +29,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef IP_UNIX_H +#define IP_UNIX_H + #include "core/io/ip.h" -#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) +#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) || defined(HORIZON_ENABLED) class IP_Unix : public IP { GDCLASS(IP_Unix, IP); diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 9c5023f13e..314e589241 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -32,7 +32,7 @@ #include "net_socket_posix.h" #ifndef UNIX_SOCKET_UNAVAILABLE -#if defined(UNIX_ENABLED) +#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED) #include #include @@ -51,7 +51,7 @@ #include #include -#ifdef JAVASCRIPT_ENABLED +#if defined(JAVASCRIPT_ENABLED) || defined(HORIZON_ENABLED) #include #endif @@ -277,11 +277,13 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St memcpy(&greq.imr_interface, if_ip.get_ipv4(), 4); ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); } else { +#ifndef HORIZON_ENABLED struct ipv6_mreq greq; int sock_opt = p_add ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP; memcpy(&greq.ipv6mr_multiaddr, p_ip.get_ipv6(), 16); greq.ipv6mr_interface = if_v6id; ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); +#endif // !HORIZON_ENABLED } ERR_FAIL_COND_V(ret != 0, FAILED); diff --git a/modules/database_sqlite/SCsub b/modules/database_sqlite/SCsub index c18c3a2419..4239b87ca4 100644 --- a/modules/database_sqlite/SCsub +++ b/modules/database_sqlite/SCsub @@ -31,6 +31,9 @@ sources = [ "sqlite3_table_builder.cpp", ] +if module_env["platform"] == "switch": + sources += ["sqlite/nx-vfs.c"] + if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes': # Shared lib compilation module_env.Append(CCFLAGS=['-fPIC']) diff --git a/modules/database_sqlite/sqlite/nx-vfs.c b/modules/database_sqlite/sqlite/nx-vfs.c new file mode 100644 index 0000000000..6b922dcd78 --- /dev/null +++ b/modules/database_sqlite/sqlite/nx-vfs.c @@ -0,0 +1,381 @@ +#include "sqlite3.h" +#include + +// Important points: +// - There is no file truncation +// -> journal_mode=truncate won't work +// - There is no file locking +// -> as far as I know Horizon doesn't support it? +// - Doesn't support temp files +// - Doesn't support dynamic libraries (not my fault) + +// FsFileSystem used to interact with files on SD Card +static FsFileSystem fs; + +// Size of write buffer (in bytes) +#define SQLITE_NXVFS_BUFFERSZ 8192 + +// sqlite3_file * actually points to this structure +typedef struct nxFile nxFile; +struct nxFile { + sqlite3_file base; // Base class + FsFile file; // NX (Horizon) file object + char * buf; // Buffer for writes + int bufSize; // Number of bytes in buffer + sqlite3_int64 bufOffset; // Offset of bytes in buffer from buf[0] +}; + +// Close a file +static int nxClose(sqlite3_file * pFile) { + nxFile * file = (nxFile *) pFile; + fsFileClose(&file->file); + return SQLITE_OK; +} + +// Read data from a file +static int nxRead(sqlite3_file * pFile, void * buf, int bytes, sqlite_int64 offset) { + // Bytes read and result code + u64 read = 0; + Result rc; + + // Read from file + nxFile * file = (nxFile *) pFile; + rc = fsFileRead(&file->file, offset, buf, bytes, FsReadOption_None, &read); + + // Return IO error if result isn't good + if (R_FAILED(rc)) { + return SQLITE_IOERR_READ; + } + + // Check if we read the right amount of bytes + if (read == bytes) { + return SQLITE_OK; + + // Zero-pad the remaining buffer if not enough bytes were read + } else if (read >= 0) { + if (read < bytes) { + memset(&((char *) buf)[read], 0, bytes-read); + } + return SQLITE_IOERR_SHORT_READ; + } + + // Don't think this should be reached? + return SQLITE_IOERR_READ; +} + +// Write to a file (and flush immediately) +static int nxDirectWrite(nxFile * file, const void * buf, int bytes, sqlite_int64 offset) { + Result rc = fsFileWrite(&file->file, offset, buf, bytes, FsWriteOption_Flush); + + // Return IO error if result is not good + if (R_FAILED(rc)) { + return SQLITE_IOERR_WRITE; + } + + return SQLITE_OK; +} + +// Flush file's buffer to disk (no-op if buffer is empty) +static int nxFlushBuffer(nxFile * file) { + int rc = SQLITE_OK; + if (file->buf) { + rc = nxDirectWrite(file, file->buf, file->bufSize, file->bufOffset); + file->buf = NULL; + } + return rc; +} + +// Write to a file (without flushing) +static int nxWrite(sqlite3_file * pFile, const void * buf, int bytes, sqlite_int64 offset) { + nxFile * file = (nxFile *) pFile; + + // If the buffer exists + if (file->buf) { + char * buf2 = (char *) buf; // Pointer to remaining data in write buffer + int bytes2 = bytes; // Remaining number of bytes in write buffer + sqlite3_int64 offset2 = offset; // File offset to write to + + // While there's still bytes to write + while (bytes2 > 0) { + int copy; // Number of bytes to copy into file buffer + + // If the buffer is full or not being used - flush the buffer + if (file->bufSize == SQLITE_NXVFS_BUFFERSZ || file->bufOffset + file->bufSize != offset2) { + int rc = nxFlushBuffer(file); + if (rc != SQLITE_OK) { + return rc; + } + } + file->bufOffset = offset2 - file->bufSize; + + // Copy as much data as possible into the buffer + copy = SQLITE_NXVFS_BUFFERSZ - file->bufSize; + if (copy > bytes2) { + copy = bytes2; + } + memcpy(&file->buf[file->bufSize], buf2, copy); + file->bufSize += copy; + + // Update variables + bytes2 -= copy; + offset2 += copy; + buf2 += copy; + } + + // Otherwise if there's no buffer just write to file + } else { + return nxDirectWrite(file, buf, bytes, offset); + } + + return SQLITE_OK; +} + +// This is meant to truncate a file (maybe I'll get to it later) +// This means that journal_mode=truncate is not supported +static int nxTruncate(sqlite3_file * pFile, sqlite_int64 size) { + return SQLITE_OK; +} + +// Sync contents of file to the disk +static int nxSync(sqlite3_file * pFile, int flags) { + nxFile * file = (nxFile *) pFile; + + // Flush buffer to disk + int tmp = nxFlushBuffer(file); + if (tmp != SQLITE_OK) { + return tmp; + } + + // Call system to flush it's cache + Result rc = fsFileFlush(&file->file); + return (R_SUCCEEDED(rc) ? SQLITE_OK : SQLITE_IOERR_FSYNC); +} + +// Get the size of the file and write to pointer +static int nxFileSize(sqlite3_file * pFile, sqlite_int64 * size) { + nxFile * file = (nxFile *) pFile; + + // Flush buffer to disk first + int tmp = nxFlushBuffer(file); + if (tmp != SQLITE_OK) { + return tmp; + } + + // Query using system call + s64 sz; + Result rc = fsFileGetSize(&file->file, &sz); + if (R_FAILED(rc)) { + return SQLITE_IOERR_FSTAT; + } + *(size) = sz; + return SQLITE_OK; +} + +// All locking functions do nothing +static int nxLock(sqlite3_file * pFile, int lock) { + return SQLITE_OK; +} +static int nxUnlock(sqlite3_file * pFile, int lock) { + return SQLITE_OK; +} +static int nxCheckReservedLock(sqlite3_file * pFile, int lock) { + return SQLITE_OK; +} + +// File control also does nothing +static int nxFileControl(sqlite3_file * pFile, int op, void * arg) { + return SQLITE_NOTFOUND; +} + +// Don't return any info about device +static int nxSectorSize(sqlite3_file * pFile) { + return 0; +} +static int nxDeviceCharacteristics(sqlite3_file * pFile) { + return 0; +} + +// Open a file +static int nxOpen(sqlite3_vfs * vfs, const char * path, sqlite3_file * pFile, int flags, int * outFlags) { + // Set file's IO methods to the ones above + static const sqlite3_io_methods nxIO = { + 1, // iVersion + nxClose, // xClose + nxRead, // xRead + nxWrite, // xWrite + nxTruncate, // xTruncate + nxSync, // xSync + nxFileSize, // xFileSize + nxLock, // xLock + nxUnlock, // xUnlock + nxCheckReservedLock, // xCheckReservedLock + nxFileControl, // xFileControl + nxSectorSize, // xSectorSize + nxDeviceCharacteristics // xDeviceCharacteristics + }; + + nxFile * file = (nxFile *) pFile; + Result rc; + char * tmpBuf = NULL; // Temporary pointer to potential file buffer + + // Don't support temp files + if (path == NULL) { + return SQLITE_IOERR; + } + + // Create file buffer if it's a journal file + if (flags & SQLITE_OPEN_MAIN_JOURNAL) { + tmpBuf = (char *) sqlite3_malloc(SQLITE_NXVFS_BUFFERSZ); + if (!tmpBuf) { + return SQLITE_NOMEM; + } + } + + // Create file if flag is set + if (flags & SQLITE_OPEN_CREATE) { + rc = fsFsCreateFile(&fs, path, 0, 0); + } + + // Choose mode based on flags + u32 mode = 0; + if (flags & SQLITE_OPEN_READONLY) { + mode |= FsOpenMode_Read; + } else if (flags & SQLITE_OPEN_READWRITE) { + mode |= FsOpenMode_Read; + mode |= FsOpenMode_Write; + } + + // Allocate memory for file object and open + memset(pFile, 0, sizeof(nxFile)); + rc = fsFsOpenFile(&fs, path, mode, &file->file); + printf("%s: %i %i\n", path, R_MODULE(rc), R_DESCRIPTION(rc)); + if (R_FAILED(rc)) { + file->base.pMethods = NULL; // Prevents nxClose being called + sqlite3_free(tmpBuf); + return SQLITE_CANTOPEN; + } + file->buf = tmpBuf; + + // Set output flags + if (outFlags) { + *(outFlags) = flags; + } + file->base.pMethods = &nxIO; + return SQLITE_OK; +} + +// Delete the given file +static int nxDelete(sqlite3_vfs * vfs, const char * path, int sync) { + Result rc = fsFsDeleteFile(&fs, path); + + // Commit changes if flag set + if (R_SUCCEEDED(rc) && sync) { + fsFsCommit(&fs); + } + + return (R_SUCCEEDED(rc) ? SQLITE_OK : SQLITE_IOERR_DELETE); +} + +// Check if the file exists +static int nxAccess(sqlite3_vfs * vfs, const char * path, int flags, int * out) { + // Only check exists flag, fake the other ones + if (flags & SQLITE_ACCESS_EXISTS) { + FsDirEntryType type = FsDirEntryType_Dir; + Result rc = fsFsGetEntryType(&fs, path, &type); + if (R_FAILED(rc) || type != FsDirEntryType_File) { + return SQLITE_IOERR_ACCESS; + } + } + + return SQLITE_OK; +} + +// Simply returns the given path (should return full path though) +static int nxFullPathname(sqlite3_vfs * vfs, const char * path, int outBytes, char * outPath) { + int num = strlen(path); + if (outBytes > num) { + num = outBytes; + } + memcpy(outPath, path, num); + + return SQLITE_OK; +} + +// All dynamic library related functions do nothing due to no support +static void * nxDlOpen(sqlite3_vfs * vfs, const char * path){ + return NULL; +} +static void nxDlError(sqlite3_vfs * vfs, int bytes, char * err){ + sqlite3_snprintf(bytes, err, "Loadable extensions are not supported"); + err[bytes-1] = '\0'; +} +static void (*nxDlSym(sqlite3_vfs * vfs, void * handle, const char * z))(void){ + return NULL; +} +static void nxDlClose(sqlite3_vfs * vfs, void * handle){ + return; +} + +// Fill the provided buffer with pseudo-random bytes +static int nxRandomness(sqlite3_vfs * vfs, int bytes, char * buf) { + randomGet((void *) buf, bytes); + return SQLITE_OK; +} + +// Sleep for the given number of microseconds +static int nxSleep(sqlite3_vfs * vfs, int mSecs) { + svcSleepThread(mSecs * 1000); + return mSecs; +} + +// Returns the current time as UTC in Julian days +static int nxCurrentTime(sqlite3_vfs * vfs, double * time) { + u64 ts; + Result rc = timeGetCurrentTime(TimeType_Default, &ts); + if (R_FAILED(rc)) { + return SQLITE_ERROR; + } + + *(time) = ts/86400.0 + 2440587.5; + return SQLITE_OK; +} + +// Returns a pointer to this VFS so it can be used +sqlite3_vfs * sqlite3_nxvfs() { + static sqlite3_vfs nxvfs = { + 1, // iVersion + sizeof(nxFile), // szOsFile + FS_MAX_PATH, // mxPathname + 0, // pNext + "nx", // zName + 0, // pAppData + nxOpen, // xOpen + nxDelete, // xDelete + nxAccess, // xAccess + nxFullPathname, // xFullPathname + nxDlOpen, // xDlOpen + nxDlError, // xDlError + nxDlSym, // xDlSym + nxDlClose, // xDlClose + nxRandomness, // xRandomness + nxSleep, // xSleep + nxCurrentTime, // xCurrentTime + }; + return &nxvfs; +} + +// Opens the FsFileSystem and registers the VFS +SQLITE_API int sqlite3_os_init() { + Result rc = fsOpenImageDirectoryFileSystem(&fs, FsImageDirectoryId_Sd); + if (R_FAILED(rc)) { + return SQLITE_ERROR; + } + sqlite3_vfs_register(sqlite3_nxvfs(), 1); + return SQLITE_OK; +} + +// Closes the FsFileSystem +SQLITE_API int sqlite3_os_end() { + fsFsClose(&fs); + return SQLITE_OK; +} diff --git a/modules/database_sqlite/sqlite/sqlite3.c b/modules/database_sqlite/sqlite/sqlite3.c index 86ff67c1d4..4847f5de77 100644 --- a/modules/database_sqlite/sqlite/sqlite3.c +++ b/modules/database_sqlite/sqlite/sqlite3.c @@ -161,7 +161,9 @@ #else /* This is not VxWorks. */ #define OS_VXWORKS 0 +#ifndef __SWITCH__ #define HAVE_FCHOWN 1 +#endif // __SWITCH__ #define HAVE_READLINK 1 #define HAVE_LSTAT 1 #endif /* defined(_WRS_KERNEL) */ @@ -35553,7 +35555,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ #include #include #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 -# include +#include #endif #if SQLITE_ENABLE_LOCKING_STYLE diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 1f8f2e17fe..b89587daf0 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -1,6 +1,3 @@ -#ifndef GDNATIVE_H -#define GDNATIVE_H - /*************************************************************************/ /* gdnative.h */ /*************************************************************************/ @@ -32,6 +29,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GDNATIVE_H +#define GDNATIVE_H + #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/object/resource.h" diff --git a/modules/gdnative/include/gdn/gdnative.h b/modules/gdnative/include/gdn/gdnative.h index 634ec42825..d2d92939ae 100644 --- a/modules/gdnative/include/gdn/gdnative.h +++ b/modules/gdnative/include/gdn/gdnative.h @@ -1,6 +1,3 @@ -#ifndef GDNATIVE_GDNATIVE_H -#define GDNATIVE_GDNATIVE_H - /*************************************************************************/ /* gdnative.h */ /*************************************************************************/ @@ -32,11 +29,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GDNATIVE_GDNATIVE_H +#define GDNATIVE_GDNATIVE_H + #ifdef __cplusplus extern "C" { #endif -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(__SWITCH__) #define GDCALLINGCONV #elif defined(__APPLE__) #include "TargetConditionals.h" @@ -45,7 +45,7 @@ extern "C" { #elif TARGET_OS_MAC #define GDCALLINGCONV __attribute__((sysv_abi)) #endif -#else // Linux/BSD/Web +#else // !_WIN32 && !__APPLE__ && !__SWITCH__ #if defined(__aarch64__) #define GDCALLINGCONV #else diff --git a/platform/switch b/platform/switch new file mode 160000 index 0000000000..a9baa9c5d3 --- /dev/null +++ b/platform/switch @@ -0,0 +1 @@ +Subproject commit a9baa9c5d3b02e92a98add1ce011d6c832c5302c diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 543f5879f3..dabe1a4448 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -2813,7 +2813,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const // Directional lights aren't handled here, _light_instance_update_shadow is called from elsewhere. // Checking for this in case this changes, as this is assumed. - DEV_CHECK_ONCE(VSG::storage->light_get_type(ins->base) != VS::LIGHT_DIRECTIONAL); + DEV_CHECK_ONCE(RSG::storage->light_get_type(ins->base) != RS::LIGHT_DIRECTIONAL); // Tighter caster culling to the camera frustum should work correctly with multiple viewports + cameras. // The first camera will cull tightly, but if the light is present on more than 1 camera, the second will diff --git a/thirdparty/enet/enet/pandemonium.h b/thirdparty/enet/enet/pandemonium.h index 56d2101c23..02320106b1 100644 --- a/thirdparty/enet/enet/pandemonium.h +++ b/thirdparty/enet/enet/pandemonium.h @@ -1,10 +1,10 @@ #ifndef __ENET_PANDEMONIUM_H__ #define __ENET_PANDEMONIUM_H__ /*************************************************************************/ -/* pandemonium.h */ +/* pandemonium.h */ /*************************************************************************/ /* This file is part of: */ -/* PANDEMONIUM ENGINE */ +/* PANDEMONIUM ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ @@ -29,19 +29,17 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + /** @file pandemonium.h @brief ENet Pandemonium header */ - - - #ifdef WINDOWS_ENABLED #include #include #endif -#ifdef UNIX_ENABLED +#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED) #include #endif diff --git a/thirdparty/libnx/nacp.h b/thirdparty/libnx/nacp.h new file mode 100644 index 0000000000..3a518e4ee4 --- /dev/null +++ b/thirdparty/libnx/nacp.h @@ -0,0 +1,95 @@ +/** +* @file nacp.h +* @brief Control.nacp structure / related code for nacp. +* @copyright libnx Authors + */ + +#pragma once + +#include "thirdparty/libnx/types.h" + +/// Language entry. These strings are UTF-8. +typedef struct { + char name[0x200]; + char author[0x100]; +} NacpLanguageEntry; + +/// ApplicationNeighborDetectionGroupConfiguration +typedef struct { + u64 group_id; ///< GroupId + u8 key[0x10]; +} NacpApplicationNeighborDetectionGroupConfiguration; + +/// NeighborDetectionClientConfiguration +typedef struct { + NacpApplicationNeighborDetectionGroupConfiguration send_group_configuration; ///< SendGroupConfiguration + NacpApplicationNeighborDetectionGroupConfiguration receivable_group_configurations[0x10]; ///< ReceivableGroupConfigurations +} NacpNeighborDetectionClientConfiguration; + +/// ApplicationJitConfiguration +typedef struct { + u64 flags; ///< Flags + u64 memory_size; ///< MemorySize +} NacpApplicationJitConfiguration; + +/// ns ApplicationControlProperty +typedef struct { + NacpLanguageEntry lang[16]; ///< \ref NacpLanguageEntry + u8 isbn[0x25]; ///< Isbn + u8 startup_user_account; ///< StartupUserAccount + u8 user_account_switch_lock; ///< UserAccountSwitchLock + u8 add_on_content_registration_type; ///< AddOnContentRegistrationType + u32 attribute_flag; ///< AttributeFlag + u32 supported_language_flag; ///< SupportedLanguageFlag + u32 parental_control_flag; ///< ParentalControlFlag + u8 screenshot; ///< Screenshot + u8 video_capture; ///< VideoCapture + u8 data_loss_confirmation; ///< DataLossConfirmation + u8 play_log_policy; ///< PlayLogPolicy + u64 presence_group_id; ///< PresenceGroupId + s8 rating_age[0x20]; ///< RatingAge + char display_version[0x10]; ///< DisplayVersion + u64 add_on_content_base_id; ///< AddOnContentBaseId + u64 save_data_owner_id; ///< SaveDataOwnerId + u64 user_account_save_data_size; ///< UserAccountSaveDataSize + u64 user_account_save_data_journal_size; ///< UserAccountSaveDataJournalSize + u64 device_save_data_size; ///< DeviceSaveDataSize + u64 device_save_data_journal_size; ///< DeviceSaveDataJournalSize + u64 bcat_delivery_cache_storage_size; ///< BcatDeliveryCacheStorageSize + u64 application_error_code_category; ///< ApplicationErrorCodeCategory + u64 local_communication_id[0x8]; ///< LocalCommunicationId + u8 logo_type; ///< LogoType + u8 logo_handling; ///< LogoHandling + u8 runtime_add_on_content_install; ///< RuntimeAddOnContentInstall + u8 runtime_parameter_delivery; ///< RuntimeParameterDelivery + u8 reserved_x30f4[0x2]; ///< Reserved + u8 crash_report; ///< CrashReport + u8 hdcp; ///< Hdcp + u64 pseudo_device_id_seed; ///< SeedForPseudoDeviceId + char bcat_passphrase[0x41]; ///< BcatPassphrase + u8 startup_user_account_option; ///< StartupUserAccountOption + u8 reserved_for_user_account_save_data_operation[0x6]; ///< ReservedForUserAccountSaveDataOperation + u64 user_account_save_data_size_max; ///< UserAccountSaveDataSizeMax + u64 user_account_save_data_journal_size_max; ///< UserAccountSaveDataJournalSizeMax + u64 device_save_data_size_max; ///< DeviceSaveDataSizeMax + u64 device_save_data_journal_size_max; ///< DeviceSaveDataJournalSizeMax + u64 temporary_storage_size; ///< TemporaryStorageSize + u64 cache_storage_size; ///< CacheStorageSize + u64 cache_storage_journal_size; ///< CacheStorageJournalSize + u64 cache_storage_data_and_journal_size_max; ///< CacheStorageDataAndJournalSizeMax + u16 cache_storage_index_max; ///< CacheStorageIndexMax + u8 reserved_x318a[0x6]; ///< Reserved + u64 play_log_queryable_application_id[0x10]; ///< PlayLogQueryableApplicationId + u8 play_log_query_capability; ///< PlayLogQueryCapability + u8 repair_flag; ///< RepairFlag + u8 program_index; ///< ProgramIndex + u8 required_network_service_license_on_launch; ///< RequiredNetworkServiceLicenseOnLaunchFlag + u32 reserved_x3214; ///< Reserved + NacpNeighborDetectionClientConfiguration neighbor_detection_client_configuration; ///< NeighborDetectionClientConfiguration + NacpApplicationJitConfiguration jit_configuration; ///< JitConfiguration + u8 reserved_x33c0[0xc40]; ///< Reserved +} NacpStruct; + +/// Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty. +/// If you're using ns you may want to use \ref nsGetApplicationDesiredLanguage instead. +Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry); diff --git a/thirdparty/libnx/nro.h b/thirdparty/libnx/nro.h new file mode 100644 index 0000000000..b10e51e276 --- /dev/null +++ b/thirdparty/libnx/nro.h @@ -0,0 +1,55 @@ +/** +* @file nro.h +* @brief NRO headers. +* @copyright libnx Authors + */ + +#pragma once + +#include "thirdparty/libnx/types.h" + +#define NROHEADER_MAGIC 0x304f524e + +#define NROASSETHEADER_MAGIC 0x54455341 +#define NROASSETHEADER_VERSION 0 + +/// Entry for each segment in the codebin. +typedef struct { + u32 file_off; + u32 size; +} NroSegment; + +/// Offset 0x0 in the NRO. +typedef struct { + u32 unused; + u32 mod_offset; + u8 padding[8]; +} NroStart; + +/// This follows NroStart, the actual nro-header. +typedef struct { + u32 magic; + u32 unk1; + u32 size; + u32 unk2; + NroSegment segments[3]; + u32 bss_size; + u32 unk3; + u8 build_id[0x20]; + u8 padding[0x20]; +} NroHeader; + +/// Custom asset section. +typedef struct { + u64 offset; + u64 size; +} NroAssetSection; + +/// Custom asset header. +typedef struct { + u32 magic; + u32 version; + NroAssetSection icon; + NroAssetSection nacp; + NroAssetSection romfs; +} NroAssetHeader; diff --git a/thirdparty/libnx/types.h b/thirdparty/libnx/types.h new file mode 100644 index 0000000000..fec0af8975 --- /dev/null +++ b/thirdparty/libnx/types.h @@ -0,0 +1,92 @@ +/** +* @file switch/types.h +* @brief Various system types. +* @copyright libnx Authors + */ +#pragma once + +#include +#include +#include +#include + +#ifndef SSIZE_MAX +#ifdef SIZE_MAX +#define SSIZE_MAX ((SIZE_MAX) >> 1) +#endif // SIZE_MAX +#endif // SSIZE_MAX + +typedef uint8_t u8; ///< 8-bit unsigned integer. +typedef uint16_t u16; ///< 16-bit unsigned integer. +typedef uint32_t u32; ///< 32-bit unsigned integer. +typedef uint64_t u64; ///< 64-bit unsigned integer. + +typedef int8_t s8; ///< 8-bit signed integer. +typedef int16_t s16; ///< 16-bit signed integer. +typedef int32_t s32; ///< 32-bit signed integer. +typedef int64_t s64; ///< 64-bit signed integer. + +typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer. +typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer. +typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer. +typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer. + +typedef volatile s8 vs8; ///< 8-bit volatile signed integer. +typedef volatile s16 vs16; ///< 16-bit volatile signed integer. +typedef volatile s32 vs32; ///< 32-bit volatile signed integer. +typedef volatile s64 vs64; ///< 64-bit volatile signed integer. + +typedef u32 Handle; ///< Kernel object handle. +typedef u32 Result; ///< Function error code result type. +typedef void (*ThreadFunc)(void *); ///< Thread entrypoint function. +typedef void (*VoidFn)(void); ///< Function without arguments nor return value. + +typedef struct { u8 uuid[0x10]; } Uuid; ///< Unique identifier. + +typedef struct { float value[3]; } UtilFloat3; ///< 3 floats. + +/// Creates a bitmask from a bit number. +#ifndef BIT +#define BIT(n) (1U<<(n)) +#endif // BIT + +#ifndef BITL +#define BITL(n) (1UL<<(n)) +#endif // BITL + +/// Packs a struct so that it won't include padding bytes. +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif // PACKED + +/// Marks a function as not returning, for the purposes of compiler optimization. +#ifndef NORETURN +#define NORETURN __attribute__((noreturn)) +#endif // NORETURN + +/// Performs a dummy operation on the specified argument in order to silence compiler warnings about unused arguments. +#ifndef IGNORE_ARG +#define IGNORE_ARG(x) (void)(x) +#endif // IGNORE_ARG + +/// Flags a function as deprecated. +#ifndef DEPRECATED +#ifndef LIBNX_NO_DEPRECATION +#define DEPRECATED __attribute__ ((deprecated)) +#else // LIBNX_NO_DEPRECATION +#define DEPRECATED +#endif // LIBNX_NO_DEPRECATION +#endif // DEPRECATED + +/// Flags a function as (always) inline. +#define NX_INLINE __attribute__((always_inline)) static inline + +/// Flags a function as constexpr in C++14 and above; or as (always) inline otherwise. +#if __cplusplus >= 201402L +#define NX_CONSTEXPR NX_INLINE constexpr +#else // __cplusplus >= 201402 +#define NX_CONSTEXPR NX_INLINE +#endif // __cplusplus >= 201402 + +/// Invalid handle. +#define INVALID_HANDLE ((Handle) 0) diff --git a/thirdparty/miniupnpc/src/minissdpc.c b/thirdparty/miniupnpc/src/minissdpc.c index edebb1600a..18be771c62 100644 --- a/thirdparty/miniupnpc/src/minissdpc.c +++ b/thirdparty/miniupnpc/src/minissdpc.c @@ -58,7 +58,15 @@ struct sockaddr_un { #include #include #include +#ifndef __SWITCH__ #include +#else // __SWITCH__ +#define UNIX_PATH_LEN 108 +struct sockaddr_un { + uint16_t sun_family; + char sun_path[UNIX_PATH_LEN]; +}; +#endif // __SWITCH__ #include #include #include