From 53474c6682c5303aa18c9441d71f394f7aa0f4e8 Mon Sep 17 00:00:00 2001 From: Caroline Bell Date: Wed, 14 Feb 2024 11:39:09 -0600 Subject: [PATCH 01/20] Add Switch submodule --- .gitmodules | 3 + core/config/project_settings.cpp | 8 + drivers/gles2/rasterizer_storage_gles2.cpp | 8 +- drivers/unix/dir_access_unix.cpp | 9 +- drivers/unix/file_access_unix.cpp | 6 +- drivers/unix/ip_unix.cpp | 8 +- drivers/unix/ip_unix.h | 8 +- drivers/unix/net_socket_posix.cpp | 6 +- modules/database_sqlite/SCsub | 3 + modules/database_sqlite/sqlite/nx-vfs.c | 381 +++++++++++++++++++ modules/database_sqlite/sqlite/sqlite3.c | 4 +- modules/gdnative/gdnative.h | 6 +- modules/gdnative/include/gdn/gdnative.h | 10 +- platform/switch | 1 + servers/rendering/rendering_server_scene.cpp | 2 +- thirdparty/enet/enet/pandemonium.h | 10 +- thirdparty/libnx/nacp.h | 95 +++++ thirdparty/libnx/nro.h | 55 +++ thirdparty/libnx/types.h | 92 +++++ thirdparty/miniupnpc/src/minissdpc.c | 8 + 20 files changed, 693 insertions(+), 30 deletions(-) create mode 100644 .gitmodules create mode 100644 modules/database_sqlite/sqlite/nx-vfs.c create mode 160000 platform/switch create mode 100644 thirdparty/libnx/nacp.h create mode 100644 thirdparty/libnx/nro.h create mode 100644 thirdparty/libnx/types.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..b28167aa9 --- /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 cc93dd540..b71996c8f 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 bd1e62fc5..a6ca5ff80 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 617d0b288..6a0f4af2e 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 979c50f94..cd4a962c3 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 651d6334e..1c9d0edd4 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 895608e54..610d703f9 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 9c5023f13..314e58924 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 c18c3a241..4239b87ca 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 000000000..6b922dcd7 --- /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 86ff67c1d..4847f5de7 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 1f8f2e17f..b89587daf 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 634ec4282..d2d92939a 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 000000000..5638f1f13 --- /dev/null +++ b/platform/switch @@ -0,0 +1 @@ +Subproject commit 5638f1f138228ba619ca3f51170aea36528bb613 diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 543f5879f..dabe1a444 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 56d2101c2..02320106b 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 000000000..3a518e4ee --- /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 000000000..b10e51e27 --- /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 000000000..fec0af897 --- /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 edebb1600..18be771c6 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 From 6a9577630af49627918c2404a5655d2b1ff944b9 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An Date: Fri, 15 Nov 2024 16:39:01 +0100 Subject: [PATCH 02/20] Update vita_builds.yml --- .github/workflows/vita_builds.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/vita_builds.yml b/.github/workflows/vita_builds.yml index 023c02842..315b57329 100644 --- a/.github/workflows/vita_builds.yml +++ b/.github/workflows/vita_builds.yml @@ -14,20 +14,12 @@ concurrency: jobs: vita-template: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-24.04" name: Template (target=release, tools=no) steps: - uses: actions/checkout@v4 - # Azure repositories are not reliable, we need to prevent azure giving us packages. - - name: Make apt sources.list use the default Ubuntu repositories - run: | - sudo rm -f /etc/apt/sources.list.d/* - sudo cp -f misc/ci/sources.list /etc/apt/sources.list - sudo apt-get update - sudo apt-get install gcc-multilib - - name: Restore Godot build cache uses: ./.github/actions/godot-cache-restore continue-on-error: true @@ -64,4 +56,4 @@ jobs: continue-on-error: true - name: Upload artifact - uses: ./.github/actions/upload-artifact + uses: ./.github/actions/upload-artifact \ No newline at end of file From e0a87c02557baa168e5ef2ff57470fe660485a57 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:11:46 +0100 Subject: [PATCH 03/20] Update dir_access_unix.cpp --- drivers/unix/dir_access_unix.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index e38d57f14..4b3ad0386 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -442,14 +442,13 @@ String DirAccessUnix::read_link(String p_file) { link.parse_utf8(buf, len); } return link; -#endif // !HORIZON_ENABLED +#endif } Error DirAccessUnix::create_link(String p_source, String p_target) { -#ifdef VITA_ENABLED +#ifdef VITA_ENABLED || HORIZON_ENABLED return FAILED; #else -#ifndef HORIZON_ENABLED if (p_target.is_rel_path()) p_target = get_current_dir().plus_file(p_target); From 143e02b8250c7b9c7e260310a3048c74f8f7e115 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:30:51 +0100 Subject: [PATCH 04/20] Create switch_builds.yml --- .github/workflows/switch_builds.yml | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/switch_builds.yml diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml new file mode 100644 index 000000000..4000c8f4e --- /dev/null +++ b/.github/workflows/switch_builds.yml @@ -0,0 +1,44 @@ +name: 🎮 Switch Builds +on: [push, pull_request] + +# Global Settings +env: + GODOT_BASE_BRANCH: 3.x + SCONSFLAGS: verbose=no warnings=no werror=no debug_symbols=no use_rtti=True disable_gles3=False + +concurrency: + group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-switch + cancel-in-progress: true + +jobs: + switch-template: + runs-on: ubuntu-latest + container: devkitpro/devkita64 + name: Template (target=release, tools=no) + + steps: + - uses: actions/checkout@v4 + + - name: Restore Godot build cache + uses: ./.github/actions/godot-cache-restore + continue-on-error: true + + - name: Setup python and scons + uses: ./.github/actions/godot-deps + + - name: Compilation + uses: ./.github/actions/godot-build + with: + sconsflags: ${{ env.SCONSFLAGS }} + platform: switch + target: release + tools: false + + - name: Save Godot build cache + uses: ./.github/actions/godot-cache-save + with: + cache-name: ${{ matrix.cache-name }} + continue-on-error: true + + - name: Upload artifact + uses: ./.github/actions/upload-artifact From e4218024cc3294f6bf0c664db1a80f5bb37c2ffe Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:32:50 +0100 Subject: [PATCH 05/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 60 +++++++++++++++-------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 4000c8f4e..5353e7226 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -1,44 +1,48 @@ -name: 🎮 Switch Builds -on: [push, pull_request] +name: 🔄 Switch Builds +on: + workflow_call: -# Global Settings +# Global Cache Settings env: - GODOT_BASE_BRANCH: 3.x - SCONSFLAGS: verbose=no warnings=no werror=no debug_symbols=no use_rtti=True disable_gles3=False - -concurrency: - group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-switch - cancel-in-progress: true + GODOT_BASE_BRANCH: 3.5 + SCONS_CACHE_LIMIT: 4096 jobs: switch-template: runs-on: ubuntu-latest container: devkitpro/devkita64 + name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - - name: Restore Godot build cache - uses: ./.github/actions/godot-cache-restore - continue-on-error: true + # Upload cache on completion and check it out now + - name: Load .scons_cache directory + id: switch-template-cache + uses: actions/cache@v2 + with: + path: ${{github.workspace}}/.scons_cache/ + key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} + restore-keys: | + ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} + ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} + ${{github.job}}-${{env.GODOT_BASE_BRANCH}} - - name: Setup python and scons - uses: ./.github/actions/godot-deps + - name: Install scons from pip + run: | + sudo apt-get update + sudo apt-get -y install python3-pip + sudo python3 -m pip install scons - name: Compilation - uses: ./.github/actions/godot-build - with: - sconsflags: ${{ env.SCONSFLAGS }} - platform: switch - target: release - tools: false + env: + SCONS_CACHE: ${{github.workspace}}/.scons_cache/ + run: | + scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no - - name: Save Godot build cache - uses: ./.github/actions/godot-cache-save + - uses: actions/upload-artifact@v2 with: - cache-name: ${{ matrix.cache-name }} - continue-on-error: true - - - name: Upload artifact - uses: ./.github/actions/upload-artifact + name: ${{ github.job }} + path: bin/* + retention-days: 14 From a80a68dd81d824fe114ae97a88b46756d59d75ba Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:38:57 +0100 Subject: [PATCH 06/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 5353e7226..869ca9fef 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -1,6 +1,5 @@ name: 🔄 Switch Builds -on: - workflow_call: +on: [push, pull_request] # Global Cache Settings env: @@ -15,7 +14,7 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # Upload cache on completion and check it out now - name: Load .scons_cache directory @@ -39,7 +38,7 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no + scons -j2 verbose=no warnings=no werror=no debug_symbols=no platform=switch target=release tools=no use_rtti=True disable_gles3=False - uses: actions/upload-artifact@v2 with: From 234b73251b5229016171da91b3e8a20c3de1841e Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:43:43 +0100 Subject: [PATCH 07/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 46 +++++++++++++---------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 869ca9fef..3bedf1c84 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Cache Settings env: GODOT_BASE_BRANCH: 3.5 - SCONS_CACHE_LIMIT: 4096 + SCONSFLAGS: verbose=no warnings=no werror=no debug_symbols=no use_rtti=True disable_gles3=False jobs: switch-template: @@ -16,32 +16,26 @@ jobs: steps: - uses: actions/checkout@v4 - # Upload cache on completion and check it out now - - name: Load .scons_cache directory - id: switch-template-cache - uses: actions/cache@v2 - with: - path: ${{github.workspace}}/.scons_cache/ - key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} - restore-keys: | - ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} - ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} - ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + - name: Restore Pandemonium build cache + uses: ./.github/actions/godot-cache-restore + continue-on-error: true - - name: Install scons from pip - run: | - sudo apt-get update - sudo apt-get -y install python3-pip - sudo python3 -m pip install scons + - name: Setup python and scons + uses: ./.github/actions/godot-deps - name: Compilation - env: - SCONS_CACHE: ${{github.workspace}}/.scons_cache/ - run: | - scons -j2 verbose=no warnings=no werror=no debug_symbols=no platform=switch target=release tools=no use_rtti=True disable_gles3=False - - - uses: actions/upload-artifact@v2 + uses: ./.github/actions/godot-build with: - name: ${{ github.job }} - path: bin/* - retention-days: 14 + sconsflags: ${{ env.SCONSFLAGS }} + platform: switch + target: release + tools: false + + - name: Save Godot build cache + uses: ./.github/actions/godot-cache-save + with: + cache-name: ${{ matrix.cache-name }} + continue-on-error: true + + - name: Upload artifact + uses: ./.github/actions/upload-artifact From 25082d657e3e79fad52858e091647fbb90d6a057 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:45:55 +0100 Subject: [PATCH 08/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 3bedf1c84..b29881932 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -20,8 +20,11 @@ jobs: uses: ./.github/actions/godot-cache-restore continue-on-error: true - - name: Setup python and scons - uses: ./.github/actions/godot-deps + - name: Install scons from pip + run: | + sudo apt-get update + sudo apt-get -y install python3-pip + sudo python3 -m pip install scons - name: Compilation uses: ./.github/actions/godot-build From 5d5535e50b66c4ce2f0d6f6c0d51343d5bad7248 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:00:33 +0100 Subject: [PATCH 09/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index b29881932..2b0719abd 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -27,12 +27,8 @@ jobs: sudo python3 -m pip install scons - name: Compilation - uses: ./.github/actions/godot-build - with: - sconsflags: ${{ env.SCONSFLAGS }} - platform: switch - target: release - tools: false + run: | + scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no - name: Save Godot build cache uses: ./.github/actions/godot-cache-save From 052718535cd977aefbcfc2b42f130b4f7b0dd123 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:25:50 +0100 Subject: [PATCH 10/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 2b0719abd..6e7811c99 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -14,7 +14,10 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive # Fetch all submodules - name: Restore Pandemonium build cache uses: ./.github/actions/godot-cache-restore From 85871deaf7be41287bb53a497c5b9c0c465c81ea Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:43:53 +0000 Subject: [PATCH 11/20] update --- drivers/unix/net_socket_posix.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index b17fa3ed5..6920f50ec 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -282,22 +282,18 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St memcpy(&greq.imr_multiaddr, p_ip.get_ipv4(), 4); memcpy(&greq.imr_interface, if_ip.get_ipv4(), 4); ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); - } else { - #if defined(VITA_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)); - #elif defined(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 - } + } else { + #ifndef VITA_ENABLED + #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 + #endif + } ERR_FAIL_COND_V(ret != 0, FAILED); return OK; From 8c40e357046706d8ee679c32ae7b1b3d9417f4da Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 14:21:30 +0000 Subject: [PATCH 12/20] update --- drivers/gles2/rasterizer_storage_gles2.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 9fc86846a..a9d703536 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -108,8 +108,6 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #elif defined(ANDROID_ENABLED) || defined(HORIZON_ENABLED) -#include // needed to load extensions - #include PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; From 60548646b9f0c777a72e96a2cc5aae8052de5705 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:00:58 +0100 Subject: [PATCH 13/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index 6e7811c99..bbc49b93a 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -33,11 +33,8 @@ jobs: run: | scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no - - name: Save Godot build cache - uses: ./.github/actions/godot-cache-save + - uses: actions/upload-artifact@v2 with: - cache-name: ${{ matrix.cache-name }} - continue-on-error: true - - - name: Upload artifact - uses: ./.github/actions/upload-artifact + name: ${{ github.job }} + path: bin/* + retention-days: 14 From 54f13fbceb2ffa834221fbef5709fbe90e2dccb1 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:02:15 +0100 Subject: [PATCH 14/20] Update switch_builds.yml --- .github/workflows/switch_builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/switch_builds.yml b/.github/workflows/switch_builds.yml index bbc49b93a..f805c8625 100644 --- a/.github/workflows/switch_builds.yml +++ b/.github/workflows/switch_builds.yml @@ -33,7 +33,7 @@ jobs: run: | scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: ${{ github.job }} path: bin/* From 3acaf3b39672c074bda34a6db5a7cef53a0be08f Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:04:41 +0000 Subject: [PATCH 15/20] correct vita --- drivers/unix/dir_access_unix.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 4b3ad0386..dbbe02e41 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -446,25 +446,25 @@ String DirAccessUnix::read_link(String p_file) { } Error DirAccessUnix::create_link(String p_source, String p_target) { -#ifdef VITA_ENABLED || HORIZON_ENABLED - return FAILED; +#if defined(VITA_ENABLED) || defined(HORIZON_ENABLED) + return FAILED; #else - if (p_target.is_rel_path()) - p_target = get_current_dir().plus_file(p_target); + if (p_target.is_rel_path()) { + p_target = get_current_dir().plus_file(p_target); + } - p_source = fix_path(p_source); - p_target = fix_path(p_target); + p_source = fix_path(p_source); + p_target = fix_path(p_target); - if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) { - return OK; - } else -#endif // !HORIZON_ENABLED - { - return FAILED; - } + if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) { + return OK; + } else { + return FAILED; + } #endif } + uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS struct statvfs vfs; From fdf1e062ecfadf8d604677435c9ecbd58d48f678 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:55:25 +0000 Subject: [PATCH 16/20] correct unexpected end-of-file found --- drivers/unix/dir_access_unix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index dbbe02e41..bfb3e3c4c 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -458,7 +458,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 + { return FAILED; } #endif From 6ebb78c5bad17b9e9345606893b7fc9e641a45d5 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Thu, 27 Feb 2025 19:28:56 +0000 Subject: [PATCH 17/20] submodules: recursive to download the sub module --- .github/workflows/android_builds.yml | 5 ++++- .github/workflows/javascript_builds.yml | 5 ++++- .github/workflows/vita_builds.yml | 5 ++++- .github/workflows/windows_builds.yml | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 1ec943f87..bbe5b08fd 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -17,7 +17,10 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive # Fetch all submodules - name: Set up Java 17 uses: actions/setup-java@v4 diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml index 95b8af8a1..7c328d1f5 100644 --- a/.github/workflows/javascript_builds.yml +++ b/.github/workflows/javascript_builds.yml @@ -18,7 +18,10 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive # Fetch all submodules - name: Set up Emscripten latest uses: mymindstorm/setup-emsdk@v14 diff --git a/.github/workflows/vita_builds.yml b/.github/workflows/vita_builds.yml index 315b57329..3452f7c6d 100644 --- a/.github/workflows/vita_builds.yml +++ b/.github/workflows/vita_builds.yml @@ -18,7 +18,10 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive # Fetch all submodules - name: Restore Godot build cache uses: ./.github/actions/godot-cache-restore diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 0a756bd02..6432527a2 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -34,7 +34,10 @@ jobs: tools: false steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive # Fetch all submodules - name: Restore Godot build cache uses: ./.github/actions/godot-cache-restore From 100a0f50e2090cf348e1c4f283408337255f0c59 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Fri, 28 Feb 2025 09:49:25 +0000 Subject: [PATCH 18/20] correct for VITA --- drivers/unix/dir_access_unix.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index bfb3e3c4c..56ea8f9e2 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -447,7 +447,7 @@ String DirAccessUnix::read_link(String p_file) { Error DirAccessUnix::create_link(String p_source, String p_target) { #if defined(VITA_ENABLED) || defined(HORIZON_ENABLED) - return FAILED; + return FAILED; // If Vita or Horizon, just return FAILED and do nothing else #else if (p_target.is_rel_path()) { p_target = get_current_dir().plus_file(p_target); @@ -458,15 +458,14 @@ 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 -#endif - { + } else { return FAILED; } #endif } + uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS struct statvfs vfs; From 3ea9bf04a1f29a4899385ab9eb7c54fb798be5f4 Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Fri, 28 Feb 2025 09:57:36 +0000 Subject: [PATCH 19/20] correct for both vita and horizon --- drivers/unix/dir_access_unix.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 56ea8f9e2..f4b3ddae0 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -446,8 +446,10 @@ String DirAccessUnix::read_link(String p_file) { } Error DirAccessUnix::create_link(String p_source, String p_target) { -#if defined(VITA_ENABLED) || defined(HORIZON_ENABLED) - return FAILED; // If Vita or Horizon, just return FAILED and do nothing else +#ifdef VITA_ENABLED + return FAILED; +#elif defined(HORIZON_ENABLED) + return FAILED; #else if (p_target.is_rel_path()) { p_target = get_current_dir().plus_file(p_target); @@ -465,7 +467,6 @@ Error DirAccessUnix::create_link(String p_source, String p_target) { } - uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS struct statvfs vfs; From 4a1fbe48ba05e9bae42423ee54a97d9ee3b621af Mon Sep 17 00:00:00 2001 From: Nguyen Truong An <79207918+flashshare@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:07:50 +0000 Subject: [PATCH 20/20] add missing endif --- drivers/unix/dir_access_unix.cpp | 552 +++++++++++++++---------------- 1 file changed, 276 insertions(+), 276 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index f4b3ddae0..27231d6c5 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -56,398 +56,399 @@ #endif Error DirAccessUnix::list_dir_begin() { - list_dir_end(); //close any previous dir opening! + list_dir_end(); //close any previous dir opening! - //char real_current_dir_name[2048]; //is this enough?! - //getcwd(real_current_dir_name,2048); - //chdir(current_path.utf8().get_data()); - dir_stream = opendir(current_dir.utf8().get_data()); - //chdir(real_current_dir_name); - if (!dir_stream) { - return ERR_CANT_OPEN; //error! - } + //char real_current_dir_name[2048]; //is this enough?! + //getcwd(real_current_dir_name,2048); + //chdir(current_path.utf8().get_data()); + dir_stream = opendir(current_dir.utf8().get_data()); + //chdir(real_current_dir_name); + if (!dir_stream) { + return ERR_CANT_OPEN; //error! + } - return OK; + return OK; } bool DirAccessUnix::file_exists(String p_file) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION - if (p_file.is_rel_path()) { - p_file = current_dir.plus_file(p_file); - } + if (p_file.is_rel_path()) { + p_file = current_dir.plus_file(p_file); + } - p_file = fix_path(p_file); + p_file = fix_path(p_file); - struct stat flags; - bool success = (stat(p_file.utf8().get_data(), &flags) == 0); + struct stat flags; + bool success = (stat(p_file.utf8().get_data(), &flags) == 0); - if (success && S_ISDIR(flags.st_mode)) { - success = false; - } + if (success && S_ISDIR(flags.st_mode)) { + success = false; + } - return success; + return success; } bool DirAccessUnix::dir_exists(String p_dir) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION - if (p_dir.is_rel_path()) { - p_dir = get_current_dir().plus_file(p_dir); - } + if (p_dir.is_rel_path()) { + p_dir = get_current_dir().plus_file(p_dir); + } - p_dir = fix_path(p_dir); + p_dir = fix_path(p_dir); - struct stat flags; - bool success = (stat(p_dir.utf8().get_data(), &flags) == 0); + struct stat flags; + bool success = (stat(p_dir.utf8().get_data(), &flags) == 0); - return (success && S_ISDIR(flags.st_mode)); + return (success && S_ISDIR(flags.st_mode)); } uint64_t DirAccessUnix::get_modified_time(String p_file) { - if (p_file.is_rel_path()) { - p_file = current_dir.plus_file(p_file); - } + if (p_file.is_rel_path()) { + p_file = current_dir.plus_file(p_file); + } - p_file = fix_path(p_file); + p_file = fix_path(p_file); - struct stat flags; - bool success = (stat(p_file.utf8().get_data(), &flags) == 0); + struct stat flags; + bool success = (stat(p_file.utf8().get_data(), &flags) == 0); - if (success) { - return flags.st_mtime; - } else { - ERR_FAIL_V(0); - }; - return 0; + if (success) { + return flags.st_mtime; + } else { + ERR_FAIL_V(0); + }; + return 0; }; String DirAccessUnix::get_next() { - if (!dir_stream) { - return ""; - } + if (!dir_stream) { + return ""; + } - dirent *entry = readdir(dir_stream); + dirent *entry = readdir(dir_stream); - if (entry == nullptr) { - list_dir_end(); - return ""; - } + if (entry == nullptr) { + list_dir_end(); + return ""; + } - String fname = fix_unicode_name(entry->d_name); + String fname = fix_unicode_name(entry->d_name); - // Look at d_type to determine if the entry is a directory, unless - // its type is unknown (the file system does not support it) or if - // the type is a link, in that case we want to resolve the link to - // known if it points to a directory. stat() will resolve the link - // for us. + // Look at d_type to determine if the entry is a directory, unless + // its type is unknown (the file system does not support it) or if + // the type is a link, in that case we want to resolve the link to + // known if it points to a directory. stat() will resolve the link + // for us. #ifdef VITA_ENABLED -#define SCE_SO_ISDIR(m) (((m)&SCE_SO_IFMT) == SCE_SO_IFDIR) - _cisdir = SCE_SO_ISDIR(entry->d_stat.st_attr); + #define SCE_SO_ISDIR(m) (((m)&SCE_SO_IFMT) == SCE_SO_IFDIR) + _cisdir = SCE_SO_ISDIR(entry->d_stat.st_attr); #else - if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) { - String f = current_dir.plus_file(fname); + if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) { + String f = current_dir.plus_file(fname); - struct stat flags; - if (stat(f.utf8().get_data(), &flags) == 0) { - _cisdir = S_ISDIR(flags.st_mode); - } else { - _cisdir = false; - } - } else { - _cisdir = (entry->d_type == DT_DIR); - } + struct stat flags; + if (stat(f.utf8().get_data(), &flags) == 0) { + _cisdir = S_ISDIR(flags.st_mode); + } else { + _cisdir = false; + } + } else { + _cisdir = (entry->d_type == DT_DIR); + } #endif - _cishidden = is_hidden(fname); + _cishidden = is_hidden(fname); - return fname; + return fname; } bool DirAccessUnix::current_is_dir() const { - return _cisdir; + return _cisdir; } bool DirAccessUnix::current_is_hidden() const { - return _cishidden; + return _cishidden; } void DirAccessUnix::list_dir_end() { - if (dir_stream) { - closedir(dir_stream); - } - dir_stream = nullptr; - _cisdir = false; + if (dir_stream) { + closedir(dir_stream); + } + dir_stream = nullptr; + _cisdir = false; } #if defined(HAVE_MNTENT) && defined(X11_ENABLED) static bool _filter_drive(struct mntent *mnt) { - // Ignore devices that don't point to /dev - if (strncmp(mnt->mnt_fsname, "/dev", 4) != 0) { - return false; - } + // Ignore devices that don't point to /dev + if (strncmp(mnt->mnt_fsname, "/dev", 4) != 0) { + return false; + } - // Accept devices mounted at common locations - if (strncmp(mnt->mnt_dir, "/media", 6) == 0 || - strncmp(mnt->mnt_dir, "/mnt", 4) == 0 || - strncmp(mnt->mnt_dir, "/home", 5) == 0 || - strncmp(mnt->mnt_dir, "/run/media", 10) == 0) { - return true; - } + // Accept devices mounted at common locations + if (strncmp(mnt->mnt_dir, "/media", 6) == 0 || + strncmp(mnt->mnt_dir, "/mnt", 4) == 0 || + strncmp(mnt->mnt_dir, "/home", 5) == 0 || + strncmp(mnt->mnt_dir, "/run/media", 10) == 0) { + return true; + } - // Ignore everything else - return false; + // Ignore everything else + return false; } #endif static void _get_drives(List *list) { - list->push_back("/"); + list->push_back("/"); #if defined(HAVE_MNTENT) && defined(X11_ENABLED) - // Check /etc/mtab for the list of mounted partitions - FILE *mtab = setmntent("/etc/mtab", "r"); - if (mtab) { - struct mntent mnt; - char strings[4096]; + // Check /etc/mtab for the list of mounted partitions + FILE *mtab = setmntent("/etc/mtab", "r"); + if (mtab) { + struct mntent mnt; + char strings[4096]; - while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) { - if (mnt.mnt_dir != nullptr && _filter_drive(&mnt)) { - // Avoid duplicates - if (!list->find(mnt.mnt_dir)) { - list->push_back(mnt.mnt_dir); - } - } - } + while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) { + if (mnt.mnt_dir != nullptr && _filter_drive(&mnt)) { + // Avoid duplicates + if (!list->find(mnt.mnt_dir)) { + list->push_back(mnt.mnt_dir); + } + } + } - endmntent(mtab); - } + endmntent(mtab); + } #endif - // Add $HOME - const char *home = getenv("HOME"); - if (home) { - // Only add if it's not a duplicate - if (!list->find(home)) { - list->push_back(home); - } + // Add $HOME + const char *home = getenv("HOME"); + if (home) { + // Only add if it's not a duplicate + if (!list->find(home)) { + list->push_back(home); + } - // Check $HOME/.config/gtk-3.0/bookmarks - char path[1024]; - snprintf(path, 1024, "%s/.config/gtk-3.0/bookmarks", home); - FILE *fd = fopen(path, "r"); - if (fd) { - char string[1024]; - while (fgets(string, 1024, fd)) { - // Parse only file:// links - if (strncmp(string, "file://", 7) == 0) { - // Strip any unwanted edges on the strings and push_back if it's not a duplicate - String fpath = String(string + 7).strip_edges().split_spaces()[0].percent_decode(); - if (!list->find(fpath)) { - list->push_back(fpath); - } - } - } + // Check $HOME/.config/gtk-3.0/bookmarks + char path[1024]; + snprintf(path, 1024, "%s/.config/gtk-3.0/bookmarks", home); + FILE *fd = fopen(path, "r"); + if (fd) { + char string[1024]; + while (fgets(string, 1024, fd)) { + // Parse only file:// links + if (strncmp(string, "file://", 7) == 0) { + // Strip any unwanted edges on the strings and push_back if it's not a duplicate + String fpath = String(string + 7).strip_edges().split_spaces()[0].percent_decode(); + if (!list->find(fpath)) { + list->push_back(fpath); + } + } + } - fclose(fd); - } - } + fclose(fd); + } + } - list->sort(); + list->sort(); } int DirAccessUnix::get_drive_count() { - List list; - _get_drives(&list); + List list; + _get_drives(&list); - return list.size(); + return list.size(); } String DirAccessUnix::get_drive(int p_drive) { - List list; - _get_drives(&list); + List list; + _get_drives(&list); - ERR_FAIL_INDEX_V(p_drive, list.size(), ""); + ERR_FAIL_INDEX_V(p_drive, list.size(), ""); - return list[p_drive]; + return list[p_drive]; } int DirAccessUnix::get_current_drive() { - int drive = 0; - int max_length = -1; - const String path = get_current_dir().to_lower(); - for (int i = 0; i < get_drive_count(); i++) { - const String d = get_drive(i).to_lower(); - if (max_length < d.length() && path.begins_with(d)) { - max_length = d.length(); - drive = i; - } - } - return drive; + int drive = 0; + int max_length = -1; + const String path = get_current_dir().to_lower(); + for (int i = 0; i < get_drive_count(); i++) { + const String d = get_drive(i).to_lower(); + if (max_length < d.length() && path.begins_with(d)) { + max_length = d.length(); + drive = i; + } + } + return drive; } bool DirAccessUnix::drives_are_shortcuts() { - return true; + return true; } Error DirAccessUnix::make_dir(String p_dir) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION - if (p_dir.is_rel_path()) { - p_dir = get_current_dir().plus_file(p_dir); - } + if (p_dir.is_rel_path()) { + p_dir = get_current_dir().plus_file(p_dir); + } - p_dir = fix_path(p_dir); + p_dir = fix_path(p_dir); - bool success = (mkdir(p_dir.utf8().get_data(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0); - int err = errno; + bool success = (mkdir(p_dir.utf8().get_data(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0); + int err = errno; - if (success) { - return OK; - }; + if (success) { + return OK; + }; - if (err == EEXIST) { - return ERR_ALREADY_EXISTS; - }; + if (err == EEXIST) { + return ERR_ALREADY_EXISTS; + }; - return ERR_CANT_CREATE; + return ERR_CANT_CREATE; } Error DirAccessUnix::change_dir(String p_dir) { - GLOBAL_LOCK_FUNCTION + GLOBAL_LOCK_FUNCTION - p_dir = fix_path(p_dir); + p_dir = fix_path(p_dir); - // prev_dir is the directory we are changing out of - String prev_dir; - char real_current_dir_name[2048]; - ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG); - if (prev_dir.parse_utf8(real_current_dir_name)) { - prev_dir = real_current_dir_name; //no utf8, maybe latin? - } + // prev_dir is the directory we are changing out of + String prev_dir; + char real_current_dir_name[2048]; + ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG); + if (prev_dir.parse_utf8(real_current_dir_name)) { + prev_dir = real_current_dir_name; //no utf8, maybe latin? + } - // try_dir is the directory we are trying to change into - String try_dir = ""; - if (p_dir.is_rel_path()) { - String next_dir = current_dir.plus_file(p_dir); - next_dir = next_dir.simplify_path(); - try_dir = next_dir; - } else { - try_dir = p_dir; - } + // try_dir is the directory we are trying to change into + String try_dir = ""; + if (p_dir.is_rel_path()) { + String next_dir = current_dir.plus_file(p_dir); + next_dir = next_dir.simplify_path(); + try_dir = next_dir; + } else { + try_dir = p_dir; + } - bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8 - if (!worked) { - return ERR_INVALID_PARAMETER; - } + bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8 + if (!worked) { + return ERR_INVALID_PARAMETER; + } - String base = _get_root_path(); - if (base != String() && !try_dir.begins_with(base)) { - ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG); - String new_dir; - new_dir.parse_utf8(real_current_dir_name); + String base = _get_root_path(); + if (base != String() && !try_dir.begins_with(base)) { + ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG); + String new_dir; + new_dir.parse_utf8(real_current_dir_name); - if (!new_dir.begins_with(base)) { - try_dir = current_dir; //revert - } - } + if (!new_dir.begins_with(base)) { + try_dir = current_dir; //revert + } + } - // the directory exists, so set current_dir to try_dir - current_dir = try_dir; - ERR_FAIL_COND_V(chdir(prev_dir.utf8().get_data()) != 0, ERR_BUG); - return OK; + // the directory exists, so set current_dir to try_dir + current_dir = try_dir; + ERR_FAIL_COND_V(chdir(prev_dir.utf8().get_data()) != 0, ERR_BUG); + return OK; } String DirAccessUnix::get_current_dir() { - String base = _get_root_path(); - if (base != "") { - String bd = current_dir.replace_first(base, ""); - if (bd.begins_with("/")) { - return _get_root_string() + bd.substr(1, bd.length()); - } else { - return _get_root_string() + bd; - } - } - return current_dir; + String base = _get_root_path(); + if (base != "") { + String bd = current_dir.replace_first(base, ""); + if (bd.begins_with("/")) { + return _get_root_string() + bd.substr(1, bd.length()); + } else { + return _get_root_string() + bd; + } + } + return current_dir; } Error DirAccessUnix::rename(String p_path, String p_new_path) { - if (p_path.is_rel_path()) { - p_path = get_current_dir().plus_file(p_path); - } + if (p_path.is_rel_path()) { + p_path = get_current_dir().plus_file(p_path); + } - p_path = fix_path(p_path); + p_path = fix_path(p_path); - if (p_new_path.is_rel_path()) { - p_new_path = get_current_dir().plus_file(p_new_path); - } + if (p_new_path.is_rel_path()) { + p_new_path = get_current_dir().plus_file(p_new_path); + } - p_new_path = fix_path(p_new_path); + p_new_path = fix_path(p_new_path); - return ::rename(p_path.utf8().get_data(), p_new_path.utf8().get_data()) == 0 ? OK : FAILED; + return ::rename(p_path.utf8().get_data(), p_new_path.utf8().get_data()) == 0 ? OK : FAILED; } Error DirAccessUnix::remove(String p_path) { - if (p_path.is_rel_path()) { - p_path = get_current_dir().plus_file(p_path); - } + if (p_path.is_rel_path()) { + p_path = get_current_dir().plus_file(p_path); + } - p_path = fix_path(p_path); + p_path = fix_path(p_path); - struct stat flags; - if ((stat(p_path.utf8().get_data(), &flags) != 0)) { - return FAILED; - } + struct stat flags; + if ((stat(p_path.utf8().get_data(), &flags) != 0)) { + return FAILED; + } - if (S_ISDIR(flags.st_mode)) { - return ::rmdir(p_path.utf8().get_data()) == 0 ? OK : FAILED; - } else { - return ::unlink(p_path.utf8().get_data()) == 0 ? OK : FAILED; - } + if (S_ISDIR(flags.st_mode)) { + return ::rmdir(p_path.utf8().get_data()) == 0 ? OK : FAILED; + } else { + return ::unlink(p_path.utf8().get_data()) == 0 ? OK : FAILED; + } } bool DirAccessUnix::is_link(String p_file) { #ifdef VITA_ENABLED - return false; + return false; #else - if (p_file.is_rel_path()) - p_file = get_current_dir().plus_file(p_file); + if (p_file.is_rel_path()) + p_file = get_current_dir().plus_file(p_file); - p_file = fix_path(p_file); + p_file = fix_path(p_file); - struct stat flags; - if ((lstat(p_file.utf8().get_data(), &flags) != 0)) - return FAILED; + struct stat flags; + if ((lstat(p_file.utf8().get_data(), &flags) != 0)) + return FAILED; - return S_ISLNK(flags.st_mode); + return S_ISLNK(flags.st_mode); #endif } String DirAccessUnix::read_link(String p_file) { #ifdef VITA_ENABLED - return p_file; + return p_file; #else - if (p_file.is_rel_path()) - p_file = get_current_dir().plus_file(p_file); + if (p_file.is_rel_path()) + p_file = get_current_dir().plus_file(p_file); - p_file = fix_path(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)); - String link; - if (len > 0) { - link.parse_utf8(buf, len); - } - return link; + char buf[256]; + memset(buf, 0, 256); + ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf)); + String link; + if (len > 0) { + link.parse_utf8(buf, len); + } + return link; +#endif #endif } Error DirAccessUnix::create_link(String p_source, String p_target) { #ifdef VITA_ENABLED - return FAILED; + return FAILED; #elif defined(HORIZON_ENABLED) return FAILED; #else @@ -466,47 +467,46 @@ Error DirAccessUnix::create_link(String p_source, String p_target) { #endif } - uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS - struct statvfs vfs; - if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) { - return 0; - }; + struct statvfs vfs; + if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) { + return 0; + }; - return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize; + return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize; #else - // FIXME: Implement this. - return 0; + // FIXME: Implement this. + return 0; #endif }; String DirAccessUnix::get_filesystem_type() const { - return ""; //TODO this should be implemented + return ""; //TODO this should be implemented } bool DirAccessUnix::is_hidden(const String &p_name) { - return p_name != "." && p_name != ".." && p_name.begins_with("."); + return p_name != "." && p_name != ".." && p_name.begins_with("."); } DirAccessUnix::DirAccessUnix() { - dir_stream = nullptr; - _cisdir = false; + dir_stream = nullptr; + _cisdir = false; - /* determine drive count */ + /* determine drive count */ - // set current directory to an absolute path of the current directory - char real_current_dir_name[2048]; - ERR_FAIL_COND(getcwd(real_current_dir_name, 2048) == nullptr); - if (current_dir.parse_utf8(real_current_dir_name)) { - current_dir = real_current_dir_name; - } + // set current directory to an absolute path of the current directory + char real_current_dir_name[2048]; + ERR_FAIL_COND(getcwd(real_current_dir_name, 2048) == nullptr); + if (current_dir.parse_utf8(real_current_dir_name)) { + current_dir = real_current_dir_name; + } - change_dir(current_dir); + change_dir(current_dir); } DirAccessUnix::~DirAccessUnix() { - list_dir_end(); + list_dir_end(); } -#endif //posix_enabled +#endif //posix_enabled \ No newline at end of file