diff --git a/Makefile.common b/Makefile.common index 2743726ef0..f7d4e47a8b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -836,7 +836,9 @@ ifeq ($(TARGET), retroarch_switch) OBJ += gfx/drivers/switch_gfx.o \ input/drivers/switch_input.o \ input/drivers_joypad/switch_joypad.o \ - audio/drivers/switch_audio.o + audio/drivers/switch_audio.o \ + audio/drivers/switch_nx_thread_audio.o \ + frontend/drivers/platform_switch.o endif endif diff --git a/Makefile.switch b/Makefile.switch index db887842c5..0e12f5a448 100644 --- a/Makefile.switch +++ b/Makefile.switch @@ -42,7 +42,7 @@ endif ifeq ($(strip $(LIBTRANSISTOR_HOME)),) -$(error "Please set LIBTRANSISTOR_HOME in your environment. export LIBTRANSISTOR_HOME=o libtransistor") +$(error "Please set LIBTRANSISTOR_HOME in your environment. export LIBTRANSISTOR_HOME=") endif include $(LIBTRANSISTOR_HOME)/libtransistor.mk @@ -52,7 +52,7 @@ LIBDIRS := -L. TARGETS := $(TARGET).nro -CFLAGS += $(INCDIRS) $(DEFINES) -Wunused-command-line-argument +CFLAGS += $(INCDIRS) $(DEFINES) -Wno-unused-command-line-argument -Werror-implicit-function-declaration all: $(TARGETS) diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 161b5989b4..9e083a54f4 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -125,9 +125,7 @@ static const audio_driver_t *audio_drivers[] = { #endif #ifdef SWITCH &audio_switch, -#ifdef HAVE_LIBNX &audio_switch_thread, -#endif #endif &audio_null, NULL, diff --git a/audio/drivers/switch_audio.c b/audio/drivers/switch_audio.c index 033dd2752c..5689ca511d 100644 --- a/audio/drivers/switch_audio.c +++ b/audio/drivers/switch_audio.c @@ -19,13 +19,7 @@ #include #include -#ifdef HAVE_LIBNX -#include -#else -#include -#include -#endif - +#include "switch_audio_compat.h" #include "../audio_driver.h" #include "../../verbosity.h" @@ -35,22 +29,6 @@ #define BUFFER_COUNT 3 #endif -#ifdef HAVE_LIBNX -#define switch_audio_ipc_init audoutInitialize -#define switch_audio_ipc_output_get_released_buffer(a, b) audoutGetReleasedAudioOutBuffer(&a->current_buffer, &b) -#define switch_audio_ipc_output_append_buffer(a, b) audoutAppendAudioOutBuffer(&b) -#define switch_audio_ipc_output_stop(a) audoutStopAudioOut() -#define switch_audio_ipc_output_start(a) audoutStartAudioOut() -#define audio_output_buffer_t AudioOutBuffer -#else -#define switch_audio_ipc_init audio_ipc_init -#define switch_audio_ipc_output_get_released_buffer(a, b) audio_ipc_output_get_released_buffer(&a->output, &b, &a->current_buffer) -#define switch_audio_ipc_output_append_buffer(a, b) audio_ipc_output_append_buffer(&a->output, &b) -#define switch_audio_ipc_output_stop(a) audio_ipc_output_stop(&a->output) -#define switch_audio_ipc_output_start(a) audio_ipc_output_start(&a->output) -#define audio_output_buffer_t audio_output_buffer_t -#endif - static const int sample_rate = 48000; static const int max_num_samples = sample_rate; static const int num_channels = 2; @@ -62,8 +40,8 @@ typedef struct bool is_paused; uint64_t last_append; unsigned latency; - audio_output_buffer_t buffers[BUFFER_COUNT]; - audio_output_buffer_t *current_buffer; + compat_audio_out_buffer buffers[BUFFER_COUNT]; + compat_audio_out_buffer *current_buffer; #ifndef HAVE_LIBNX audio_output_t output; @@ -155,13 +133,8 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size) if (swa->current_buffer->data_size > (48000 * swa->latency) / 1000) { - #ifdef HAVE_LIBNX - if (switch_audio_ipc_output_append_buffer(swa, *swa->current_buffer) != 0) - return -1; - #else if (switch_audio_ipc_output_append_buffer(swa, swa->current_buffer) != 0) return -1; - #endif swa->current_buffer = NULL; } @@ -339,7 +312,7 @@ static void *switch_audio_init(const char *device, goto fail_audio_output; #endif - if (switch_audio_ipc_output_append_buffer(swa, swa->buffers[i]) != 0) + if (switch_audio_ipc_output_append_buffer(swa, &swa->buffers[i]) != 0) goto fail_audio_output; } diff --git a/audio/drivers/switch_audio_compat.h b/audio/drivers/switch_audio_compat.h new file mode 100644 index 0000000000..976fa35250 --- /dev/null +++ b/audio/drivers/switch_audio_compat.h @@ -0,0 +1,90 @@ +#pragma once + +#ifdef HAVE_LIBNX +#include +#else +#include +#endif + +#ifdef HAVE_LIBNX + +// libnx definitions + +// threading +typedef Mutex compat_mutex; +typedef Thread compat_thread; +typedef CondVar compat_condvar; + +#define compat_thread_create(thread, func, data, stack_size, prio, cpu) \ + threadCreate(thread, func, data, stack_size, prio, cpu) +#define compat_thread_start(thread) \ + threadStart(thread) +#define compat_thread_join(thread) \ + threadWaitForExit(thread) +#define compat_thread_close(thread) \ + threadClose(thread) +#define compat_mutex_create(mutex) \ + mutexInit(mutex) +#define compat_mutex_lock(mutex) \ + mutexLock(mutex) +#define compat_mutex_unlock(mutex) \ + mutexUnlock(mutex) +#define compat_condvar_create(condvar) \ + condvarInit(condvar) +#define compat_condvar_wait(condvar, mutex) \ + condvarWait(condvar, mutex) +#define compat_condvar_wake_all(condvar) \ + condvarWakeAll(condvar) + +// audio +typedef AudioOutBuffer compat_audio_out_buffer; +#define switch_audio_ipc_init audoutInitialize +#define switch_audio_ipc_finalize audoutExit +#define switch_audio_ipc_output_get_released_buffer(a, b) audoutGetReleasedAudioOutBuffer(&a->current_buffer, &b) +#define switch_audio_ipc_output_append_buffer(a, b) audoutAppendAudioOutBuffer(b) +#define switch_audio_ipc_output_stop(a) audoutStopAudioOut() +#define switch_audio_ipc_output_start(a) audoutStartAudioOut() + +#else + +// libtransistor definitions + +typedef result_t Result; +#define R_FAILED(r) ((r) != RESULT_OK) + +// threading +typedef trn_mutex_t compat_mutex; +typedef trn_thread_t compat_thread; +typedef trn_condvar_t compat_condvar; + +#define compat_thread_create(thread, func, data, stack_size, prio, cpu) \ + trn_thread_create(thread, func, data, prio, cpu, stack_size, NULL) +#define compat_thread_start(thread) \ + trn_thread_start(thread) +#define compat_thread_join(thread) \ + trn_thread_join(thread, -1) +#define compat_thread_close(thread) \ + trn_thread_destroy(thread) +#define compat_mutex_create(mutex) \ + trn_mutex_create(mutex) +#define compat_mutex_lock(mutex) \ + trn_mutex_lock(mutex) +#define compat_mutex_unlock(mutex) \ + trn_mutex_unlock(mutex) +#define compat_condvar_create(condvar) \ + trn_condvar_create(condvar) +#define compat_condvar_wait(condvar, mutex) \ + trn_condvar_wait(condvar, mutex, -1) +#define compat_condvar_wake_all(condvar) \ + trn_condvar_signal(condvar, -1) + +// audio +typedef audio_output_buffer_t compat_audio_out_buffer; +#define switch_audio_ipc_init audio_ipc_init +#define switch_audio_ipc_finalize audio_ipc_finalize +#define switch_audio_ipc_output_get_released_buffer(a, b) audio_ipc_output_get_released_buffer(&a->output, &b, &a->current_buffer) +#define switch_audio_ipc_output_append_buffer(a, b) audio_ipc_output_append_buffer(&a->output, b) +#define switch_audio_ipc_output_stop(a) audio_ipc_output_stop(&a->output) +#define switch_audio_ipc_output_start(a) audio_ipc_output_start(&a->output) + +#endif diff --git a/audio/drivers/switch_nx_thread_audio.c b/audio/drivers/switch_nx_thread_audio.c index 72a8fc4869..508a150291 100644 --- a/audio/drivers/switch_nx_thread_audio.c +++ b/audio/drivers/switch_nx_thread_audio.c @@ -21,7 +21,11 @@ #include #include +#ifdef HAVE_LIBNX #include +#else +#include +#endif #include #include "../audio_driver.h" @@ -29,27 +33,22 @@ #include "../../tasks/tasks_internal.h" -#define THREAD_STACK_SIZE (1024 * 8) +#include "switch_audio_compat.h" -#define AUDIO_THREAD_CPU 2 - -#define CHANNELCOUNT 2 -#define BYTESPERSAMPLE sizeof(uint16_t) -#define SAMPLE_SIZE (CHANNELCOUNT * BYTESPERSAMPLE) +static const size_t thread_stack_size = 1024 * 8; +static const int thread_preferred_cpu = 2; +static const int channel_count = 2; +static const size_t sample_size = sizeof(uint16_t); +static const size_t frame_size = channel_count * sample_size; #define AUDIO_BUFFER_COUNT 2 -static inline void lockMutex(Mutex* mtx) -{ - mutexLock(mtx); -} - typedef struct { fifo_buffer_t* fifo; - Mutex fifoLock; - CondVar cond; - Mutex condLock; + compat_mutex fifoLock; + compat_condvar cond; + compat_mutex condLock; size_t fifoSize; @@ -57,11 +56,16 @@ typedef struct bool nonblocking; bool is_paused; - AudioOutBuffer buffer[AUDIO_BUFFER_COUNT]; - Thread thread; + compat_audio_out_buffer buffers[AUDIO_BUFFER_COUNT]; + compat_thread thread; unsigned latency; uint32_t sampleRate; + +#ifndef HAVE_LIBNX + audio_output_t output; + handle_t event; +#endif } switch_thread_audio_t; static void mainLoop(void* data) @@ -73,27 +77,23 @@ static void mainLoop(void* data) RARCH_LOG("[Audio]: start mainLoop cpu %u tid %u\n", svcGetCurrentProcessorNumber(), swa->thread.handle); - for (int i = 0; i < AUDIO_BUFFER_COUNT; i++) - { - swa->buffer[i].next = NULL; /* Unused */ - swa->buffer[i].buffer_size = swa->fifoSize; - swa->buffer[i].buffer = memalign(0x1000, swa->buffer[i].buffer_size); - swa->buffer[i].data_size = swa->buffer[i].buffer_size; - swa->buffer[i].data_offset = 0; - - memset(swa->buffer[i].buffer, 0, swa->buffer[i].buffer_size); - audoutAppendAudioOutBuffer(&swa->buffer[i]); - } - - AudioOutBuffer* released_out_buffer = NULL; - u32 released_out_count; + compat_audio_out_buffer* released_out_buffer = NULL; + uint32_t released_out_count; Result rc; while (swa->running) { if (!released_out_buffer) { +#ifdef HAVE_LIBNX rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, U64_MAX); +#else + uint32_t handle_idx = 0; + svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333); + svcResetSignal(swa->event); + + rc = audio_ipc_output_get_released_buffer(&swa->output, &released_out_count, &released_out_buffer); +#endif if (R_FAILED(rc)) { swa->running = false; @@ -105,20 +105,27 @@ static void mainLoop(void* data) size_t bufAvail = released_out_buffer->buffer_size - released_out_buffer->data_size; - lockMutex(&swa->fifoLock); + compat_mutex_lock(&swa->fifoLock); size_t avail = fifo_read_avail(swa->fifo); size_t to_write = MIN(avail, bufAvail); - if (to_write > 0) - fifo_read(swa->fifo, ((u8*)released_out_buffer->buffer) + released_out_buffer->data_size, to_write); + if (to_write > 0) { + uint8_t *base; +#ifdef HAVE_LIBNX + base = (uint8_t*) released_out_buffer->buffer; +#else + base = (uint8_t*) released_out_buffer->sample_data; +#endif + fifo_read(swa->fifo, base + released_out_buffer->data_size, to_write); + } - mutexUnlock(&swa->fifoLock); - condvarWakeAll(&swa->cond); + compat_mutex_unlock(&swa->fifoLock); + compat_condvar_wake_all(&swa->cond); released_out_buffer->data_size += to_write; if (released_out_buffer->data_size >= released_out_buffer->buffer_size / 2) { - rc = audoutAppendAudioOutBuffer(released_out_buffer); + rc = switch_audio_ipc_output_append_buffer(swa, released_out_buffer); if (R_FAILED(rc)) { RARCH_LOG("[Audio]: audoutAppendAudioOutBuffer failed: %d\n", (int)rc); @@ -132,9 +139,11 @@ static void mainLoop(void* data) static void *switch_thread_audio_init(const char *device, unsigned rate, unsigned latency, unsigned block_frames, unsigned *new_rate) { - (void)device; - - switch_thread_audio_t *swa = (switch_thread_audio_t *)calloc(1, sizeof(switch_thread_audio_t)); + (void)device; + + char names[8][0x20]; + uint32_t num_names = 0; + switch_thread_audio_t *swa = (switch_thread_audio_t *)calloc(1, sizeof(*swa)); if (!swa) return NULL; @@ -144,35 +153,101 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne swa->is_paused = true; swa->latency = MAX(latency, 8); - Result rc = audoutInitialize(); + Result rc = switch_audio_ipc_init(); if (R_FAILED(rc)) { RARCH_LOG("[Audio]: audio init failed %d\n", (int)rc); + free(swa); return NULL; } +#ifdef HAVE_LIBNX rc = audoutStartAudioOut(); if (R_FAILED(rc)) { RARCH_LOG("[Audio]: audio start init failed: %d\n", (int)rc); - return NULL; + goto fail_audio_ipc; } swa->sampleRate = audoutGetSampleRate(); +#else + if (audio_ipc_list_outputs(&names[0], 8, &num_names) != RESULT_OK) { + goto fail_audio_ipc; + } + + if (num_names != 1) { + RARCH_ERR("[Audio]: got back more than one AudioOut\n"); + goto fail_audio_ipc; + } + + if (audio_ipc_open_output(names[0], &swa->output) != RESULT_OK) { + goto fail_audio_ipc; + } + + swa->sampleRate = swa->output.sample_rate; + + if (swa->output.num_channels != 2) + { + RARCH_ERR("expected %d channels, got %d\n", 2, + swa->output.num_channels); + goto fail_audio_output; + } + + if (swa->output.sample_format != PCM_INT16) + { + RARCH_ERR("expected PCM_INT16, got %d\n", swa->output.sample_format); + goto fail_audio_output; + } + + if (audio_ipc_output_register_buffer_event(&swa->output, &swa->event) != 0) + goto fail_audio_output; +#endif + *new_rate = swa->sampleRate; - mutexInit(&swa->fifoLock); - swa->fifoSize = (swa->sampleRate * SAMPLE_SIZE * swa->latency) / 1000; + + for (int i = 0; i < AUDIO_BUFFER_COUNT; i++) + { +#ifdef HAVE_LIBNX + swa->buffers[i].next = NULL; /* Unused */ + swa->buffers[i].data_offset = 0; + swa->buffers[i].buffer_size = swa->fifoSize; + swa->buffers[i].data_size = swa->buffers[i].buffer_size; + swa->buffers[i].buffer = memalign(0x1000, swa->buffers[i].buffer_size); + + if (swa->buffers[i].buffer == NULL) + goto fail; + + memset(swa->buffers[i].buffer, 0, swa->buffers[i].buffer_size); +#else + swa->buffers[i].ptr = &swa->buffers[i].sample_data; + swa->buffers[i].unknown = 0; + swa->buffers[i].buffer_size = swa->fifoSize; + swa->buffers[i].data_size = swa->buffers[i].buffer_size; + swa->buffers[i].sample_data = alloc_pages(swa->buffers[i].buffer_size, swa->buffers[i].buffer_size, NULL); + + if (swa->buffers[i].sample_data == NULL) + goto fail_audio_output; + + memset(swa->buffers[i].sample_data, 0, swa->buffers[i].buffer_size); +#endif + + if (switch_audio_ipc_output_append_buffer(swa, &swa->buffers[i]) != 0) + goto fail_audio_output; + } + + compat_mutex_create(&swa->fifoLock); + swa->fifoSize = (swa->sampleRate * sample_size * swa->latency) / 1000; swa->fifo = fifo_new(swa->fifoSize); - condvarInit(&swa->cond); + compat_condvar_create(&swa->cond); RARCH_LOG("[Audio]: switch_thread_audio_init device %s requested rate %hu rate %hu latency %hu block_frames %hu fifoSize %lu\n", device, rate, swa->sampleRate, swa->latency, block_frames, swa->fifoSize); - u32 prio; - svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - rc = threadCreate(&swa->thread, &mainLoop, (void*)swa, THREAD_STACK_SIZE, prio + 1, AUDIO_THREAD_CPU); + uint32_t prio; + svcGetThreadPriority(&prio, 0xffff8000); + rc = compat_thread_create(&swa->thread, &mainLoop, (void*)swa, thread_stack_size, prio + 1, thread_preferred_cpu); if (R_FAILED(rc)) { @@ -181,15 +256,25 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne return NULL; } - if (R_FAILED(threadStart(&swa->thread))) + if (R_FAILED(compat_thread_start(&swa->thread))) { RARCH_LOG("[Audio]: thread creation failed start %u\n", swa->thread.handle); - threadClose(&swa->thread); + compat_thread_close(&swa->thread); swa->running = false; return NULL; } return swa; + +fail_audio_output: +#ifndef HAVE_LIBNX + audio_ipc_output_close(&swa->output); +#endif +fail_audio_ipc: + switch_audio_ipc_finalize(); +fail: + free(swa); // freeing a null ptr is valid + return NULL; } static bool switch_thread_audio_start(void *data, bool is_shutdown) @@ -225,12 +310,12 @@ static void switch_thread_audio_free(void *data) if (swa->running) { swa->running = false; - threadWaitForExit(&swa->thread); - threadClose(&swa->thread); + compat_thread_join(&swa->thread); + compat_thread_close(&swa->thread); } - audoutStopAudioOut(); - audoutExit(); + switch_audio_ipc_output_stop(swa); + switch_audio_ipc_finalize(); if (swa->fifo) { @@ -238,8 +323,13 @@ static void switch_thread_audio_free(void *data) swa->fifo = NULL; } - for (int i = 0; i < AUDIO_BUFFER_COUNT; i++) - free(swa->buffer[i].buffer); + for (int i = 0; i < sizeof(swa->buffers)/sizeof(swa->buffers[0]); i++) { +#ifdef HAVE_LIBNX + free(swa->buffers[i].buffer); +#else + free_pages(swa->buffers[i].sample_data); +#endif + } free(swa); swa = NULL; @@ -257,35 +347,35 @@ static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t siz if (swa->nonblocking) { - lockMutex(&swa->fifoLock); + compat_mutex_lock(&swa->fifoLock); avail = fifo_write_avail(swa->fifo); written = MIN(avail, size); if (written > 0) { fifo_write(swa->fifo, buf, written); } - mutexUnlock(&swa->fifoLock); + compat_mutex_unlock(&swa->fifoLock); } else { written = 0; while (written < size && swa->running) { - lockMutex(&swa->fifoLock); + compat_mutex_lock(&swa->fifoLock); avail = fifo_write_avail(swa->fifo); if (avail == 0) { - mutexUnlock(&swa->fifoLock); - lockMutex(&swa->condLock); + compat_mutex_unlock(&swa->fifoLock); + compat_mutex_lock(&swa->condLock); if (swa->running) - condvarWait(&swa->cond, &swa->condLock); - mutexUnlock(&swa->condLock); + compat_condvar_wait(&swa->cond, &swa->condLock); + compat_mutex_unlock(&swa->condLock); } else { size_t write_amt = MIN(size - written, avail); fifo_write(swa->fifo, (const char*)buf + written, write_amt); - mutexUnlock(&swa->fifoLock); + compat_mutex_unlock(&swa->fifoLock); written += write_amt; } } @@ -322,9 +412,9 @@ static size_t switch_thread_audio_write_avail(void *data) { switch_thread_audio_t* swa = (switch_thread_audio_t*)data; - lockMutex(&swa->fifoLock); + compat_mutex_lock(&swa->fifoLock); size_t val = fifo_write_avail(swa->fifo); - mutexUnlock(&swa->fifoLock); + compat_mutex_unlock(&swa->fifoLock); return val; } diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c index 6c77b6d1d2..7afdc9d365 100644 --- a/frontend/drivers/platform_switch.c +++ b/frontend/drivers/platform_switch.c @@ -11,7 +11,12 @@ #include #include +#ifdef HAVE_LIBNX #include +#else +#include +#include +#endif #include @@ -37,17 +42,27 @@ #endif #endif +#ifdef HAVE_LIBNX +#define SD_PREFIX +#else +#define SD_PREFIX "/sd" +#endif + static enum frontend_fork switch_fork_mode = FRONTEND_FORK_NONE; static const char *elf_path_cst = "/switch/retroarch_switch.nro"; static uint64_t frontend_switch_get_mem_used(void); +#ifdef HAVE_LIBNX + // Splash static uint32_t *splashData = NULL; // switch_gfx.c protypes, we really need a header extern void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend); +#endif // HAVE_LIBNX + static void get_first_valid_core(char *path_return) { DIR *dir; @@ -56,16 +71,16 @@ static void get_first_valid_core(char *path_return) path_return[0] = '\0'; - dir = opendir("/retroarch/cores"); + dir = opendir(SD_PREFIX "/retroarch/cores"); if (dir != NULL) { - while (ent = readdir(dir)) + while ((ent = readdir(dir)) != NULL) { if (ent == NULL) break; if (strlen(ent->d_name) > strlen(extension) && !strcmp(ent->d_name + strlen(ent->d_name) - strlen(extension), extension)) { - strcpy(path_return, "/retroarch/cores"); + strcpy(path_return, SD_PREFIX "/retroarch/cores"); strcat(path_return, "/"); strcat(path_return, ent->d_name); break; @@ -83,11 +98,11 @@ static void frontend_switch_get_environment_settings(int *argc, char *argv[], vo #if defined(HAVE_LOGGER) logger_init(); #elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("/retroarch-log.txt"); + retro_main_log_file_init(SD_PREFIX "/retroarch-log.txt"); #endif #endif - fill_pathname_basedir(g_defaults.dirs[DEFAULT_DIR_PORT], "/retroarch/retroarch_switch.nro", sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); + fill_pathname_basedir(g_defaults.dirs[DEFAULT_DIR_PORT], SD_PREFIX "/retroarch/retroarch_switch.nro", sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); RARCH_LOG("port dir: [%s]\n", g_defaults.dirs[DEFAULT_DIR_PORT]); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], g_defaults.dirs[DEFAULT_DIR_PORT], @@ -137,7 +152,8 @@ static void frontend_switch_deinit(void *data) { (void)data; -#if defined(HAVE_LIBNX) && defined(NXLINK) // Else freeze on exit +#ifdef HAVE_LIBNX +#if defined(SWITCH) && defined(NXLINK) socketExit(); #endif @@ -149,8 +165,10 @@ static void frontend_switch_deinit(void *data) } gfxExit(); +#endif } +#ifdef HAVE_LIBNX static void frontend_switch_exec(const char *path, bool should_load_game) { char game_path[PATH_MAX]; @@ -262,11 +280,6 @@ static void frontend_switch_exitspawn(char *s, size_t len) frontend_switch_exec(s, should_load_game); } -static void frontend_switch_shutdown(bool unused) -{ - (void)unused; -} - void argb_to_rgba8(uint32_t *buff, uint32_t height, uint32_t width) { // Convert @@ -536,6 +549,13 @@ error: return NULL; } +#endif // HAVE_LIBNX + +static void frontend_switch_shutdown(bool unused) +{ + (void)unused; +} + // runloop_get_system_info isnt initialized that early.. extern void retro_get_system_info(struct retro_system_info *info); @@ -543,6 +563,7 @@ static void frontend_switch_init(void *data) { (void)data; +#ifdef HAVE_LIBNX // splash // Init Resolution before initDefault gfxInitResolution(1280, 720); @@ -551,13 +572,13 @@ static void frontend_switch_init(void *data) gfxConfigureTransform(0); -#if defined(HAVE_LIBNX) && defined(NXLINK) +#ifdef NXLINK socketInitializeDefault(); nxlinkStdio(); #ifndef IS_SALAMANDER verbosity_enable(); #endif -#endif +#endif // NXLINK rarch_system_info_t *sys_info = runloop_get_system_info(); retro_get_system_info(sys_info); @@ -610,6 +631,7 @@ static void frontend_switch_init(void *data) { frontend_switch_showsplash(); } +#endif // HAVE_LIBNX (splash) } static int frontend_switch_get_rating(void) @@ -642,7 +664,7 @@ static int frontend_switch_parse_drive_list(void *data, bool load_content) static uint64_t frontend_switch_get_mem_total(void) { uint64_t memoryTotal = 0; - svcGetInfo(&memoryTotal, 6, CUR_PROCESS_HANDLE, 0); // avaiable + svcGetInfo(&memoryTotal, 6, 0xffff8001, 0); // avaiable memoryTotal += frontend_switch_get_mem_used(); return memoryTotal; @@ -651,7 +673,7 @@ static uint64_t frontend_switch_get_mem_total(void) static uint64_t frontend_switch_get_mem_used(void) { uint64_t memoryUsed = 0; - svcGetInfo(&memoryUsed, 7, CUR_PROCESS_HANDLE, 0); // used + svcGetInfo(&memoryUsed, 7, 0xffff8001, 0); // used return memoryUsed; } @@ -666,6 +688,7 @@ static void frontend_switch_get_os(char *s, size_t len, int *major, int *minor) { strlcpy(s, "Horizon OS", len); +#ifdef HAVE_LIBNX // There is pretty sure a better way, but this will do just fine if (kernelAbove500()) { @@ -693,6 +716,37 @@ static void frontend_switch_get_os(char *s, size_t len, int *major, int *minor) *major = 1; *minor = 0; } +#else + // defaults in case we error out + *major = 0; + *minor = 0; + + char firmware_version[0x100]; + + result_t r; // used by LIB_ASSERT_OK macros + LIB_ASSERT_OK(fail, sm_init()); + + ipc_object_t set_sys; + LIB_ASSERT_OK(fail_sm, sm_get_service(&set_sys, "set:sys")); + + ipc_request_t rq = ipc_make_request(3); + ipc_buffer_t buffers[] = { + ipc_make_buffer(firmware_version, 0x100, 0x1a), + }; + ipc_msg_set_buffers(rq, buffers, buffer_ptrs); + + LIB_ASSERT_OK(fail_object, ipc_send(set_sys, &rq, &ipc_default_response_fmt)); + + int patch; + sscanf(firmware_version + 0x68, "%d.%d.%d", major, minor, &patch); + +fail_object: + ipc_close(set_sys); +fail_sm: + sm_finalize(); +fail: + return; +#endif } static void frontend_switch_get_name(char *s, size_t len) @@ -706,6 +760,7 @@ frontend_ctx_driver_t frontend_ctx_switch = frontend_switch_get_environment_settings, frontend_switch_init, frontend_switch_deinit, +#ifdef HAVE_LIBNX frontend_switch_exitspawn, NULL, /* process_args */ frontend_switch_exec, @@ -714,6 +769,12 @@ frontend_ctx_driver_t frontend_ctx_switch = #else frontend_switch_set_fork, #endif +#else // HAVE_LIBNX + NULL, + NULL, + NULL, + NULL, +#endif // HAVE_LIBNX frontend_switch_shutdown, frontend_switch_get_name, frontend_switch_get_os, diff --git a/frontend/frontend_driver.c b/frontend/frontend_driver.c index e5b9b2557d..d846ed5928 100644 --- a/frontend/frontend_driver.c +++ b/frontend/frontend_driver.c @@ -70,6 +70,9 @@ static frontend_ctx_driver_t *frontend_ctx_drivers[] = { #endif #ifdef DJGPP &frontend_ctx_dos, +#endif +#ifdef SWITCH + &frontend_ctx_switch, #endif &frontend_ctx_null, NULL diff --git a/frontend/frontend_driver.h b/frontend/frontend_driver.h index 63fc0ae750..c6092ad7ef 100644 --- a/frontend/frontend_driver.h +++ b/frontend/frontend_driver.h @@ -126,6 +126,7 @@ extern frontend_ctx_driver_t frontend_ctx_win32; extern frontend_ctx_driver_t frontend_ctx_xenon; extern frontend_ctx_driver_t frontend_ctx_emscripten; extern frontend_ctx_driver_t frontend_ctx_dos; +extern frontend_ctx_driver_t frontend_ctx_switch; extern frontend_ctx_driver_t frontend_ctx_null; /** diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 6aa7fb293a..3443381bc7 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -391,7 +391,7 @@ int64_t retro_vfs_file_truncate_impl(libretro_vfs_implementation_file *stream, i #ifdef _WIN32 if(_chsize(_fileno(stream->fp), length) != 0) return -1; -#elif !defined(VITA) && !defined(PSP) +#elif !defined(VITA) && !defined(PSP) && (!defined(SWITCH) || defined(HAVE_LIBNX)) if(ftruncate(fileno(stream->fp), length) != 0) return -1; #endif