diff --git a/audio/drivers/switch_nx_thread_audio.c b/audio/drivers/switch_nx_thread_audio.c
index d6acaa73ce..72a8fc4869 100644
--- a/audio/drivers/switch_nx_thread_audio.c
+++ b/audio/drivers/switch_nx_thread_audio.c
@@ -1,358 +1,358 @@
-/*  RetroArch - A frontend for libretro.
- *  Copyright (C) 2018      - misson2000
- *  Copyright (C) 2018      - m4xw
- *  Copyright (C) 2018      - lifajucejo
- *
- *  RetroArch is free software: you can redistribute it and/or modify it under the terms
- *  of the GNU General Public License as published by the Free Software Found-
- *  ation, either version 3 of the License, or (at your option) any later version.
- *
- *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- *  PURPOSE.  See the GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along with RetroArch.
- *  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include <stdint.h>
-#include <sys/unistd.h>
-
-#include <switch.h>
-
-#include <queues/fifo_queue.h>
-#include "../audio_driver.h"
-#include "../../verbosity.h"
-
-#include "../../tasks/tasks_internal.h"
-
-#define THREAD_STACK_SIZE (1024 * 8)
-
-#define AUDIO_THREAD_CPU 2
-
-#define CHANNELCOUNT 2
-#define BYTESPERSAMPLE sizeof(uint16_t)
-#define SAMPLE_SIZE (CHANNELCOUNT * BYTESPERSAMPLE)
-
-#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;
-
-      size_t fifoSize;
-
-      volatile bool running;
-      bool nonblocking;
-      bool is_paused;
-
-      AudioOutBuffer buffer[AUDIO_BUFFER_COUNT];
-      Thread thread;
-
-      unsigned latency;
-      uint32_t sampleRate;
-} switch_thread_audio_t;
-
-static void mainLoop(void* data)
-{
-   switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
-
-   if (!swa)
-      return;
-
-   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;
-   Result rc;
-
-   while (swa->running)
-   {
-      if (!released_out_buffer)
-      {
-         rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, U64_MAX);
-         if (R_FAILED(rc))
-         {
-            swa->running = false;
-            RARCH_LOG("[Audio]: audoutGetReleasedAudioOutBuffer failed: %d\n", (int)rc);
-            break;
-         }
-         released_out_buffer->data_size = 0;
-      }
-
-      size_t bufAvail = released_out_buffer->buffer_size - released_out_buffer->data_size;
-
-      lockMutex(&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);
-
-      mutexUnlock(&swa->fifoLock);
-      condvarWakeAll(&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);
-         if (R_FAILED(rc))
-         {
-            RARCH_LOG("[Audio]: audoutAppendAudioOutBuffer failed: %d\n", (int)rc);
-         }
-         released_out_buffer = NULL;
-      }
-      else
-         svcSleepThread(16000000); /* 16ms */
-   }
-}
-
-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));
-
-   if (!swa)
-      return NULL;
-
-   swa->running = true;
-   swa->nonblocking = true;
-   swa->is_paused = true;
-   swa->latency = MAX(latency, 8);
-
-   Result rc = audoutInitialize();
-   if (R_FAILED(rc))
-   {
-      RARCH_LOG("[Audio]: audio init failed %d\n", (int)rc);
-      return NULL;
-   }
-
-   rc = audoutStartAudioOut();
-   if (R_FAILED(rc))
-   {
-      RARCH_LOG("[Audio]: audio start init failed: %d\n", (int)rc);
-      return NULL;
-   }
-
-   swa->sampleRate = audoutGetSampleRate();
-   *new_rate = swa->sampleRate;
-
-   mutexInit(&swa->fifoLock);
-   swa->fifoSize = (swa->sampleRate * SAMPLE_SIZE * swa->latency) / 1000;
-   swa->fifo = fifo_new(swa->fifoSize);
-
-   condvarInit(&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);
-
-   if (R_FAILED(rc))
-   {
-      RARCH_LOG("[Audio]: thread creation failed create %u\n", swa->thread.handle);
-      swa->running = false;
-      return NULL;
-   }
-
-   if (R_FAILED(threadStart(&swa->thread)))
-   {
-      RARCH_LOG("[Audio]: thread creation failed start %u\n", swa->thread.handle);
-      threadClose(&swa->thread);
-      swa->running = false;
-      return NULL;
-   }
-
-   return swa;
-}
-
-static bool switch_thread_audio_start(void *data, bool is_shutdown)
-{
-   /* RARCH_LOG("[Audio]: switch_thread_audio_start\n"); */
-   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-   if (!swa)
-      return false;
-
-   swa->is_paused = false;
-   return true;
-}
-
-static bool switch_thread_audio_stop(void *data)
-{
-   switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
-
-   if (!swa)
-      return false;
-
-   swa->is_paused = true;
-   return true;
-}
-
-static void switch_thread_audio_free(void *data)
-{
-   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-   if (!swa)
-      return;
-
-   if (swa->running)
-   {
-      swa->running = false;
-      threadWaitForExit(&swa->thread);
-      threadClose(&swa->thread);
-   }
-
-   audoutStopAudioOut();
-   audoutExit();
-
-   if (swa->fifo)
-   {
-      fifo_free(swa->fifo);
-      swa->fifo = NULL;
-   }
-
-   for (int i = 0; i < AUDIO_BUFFER_COUNT; i++)
-      free(swa->buffer[i].buffer);
-
-   free(swa);
-   swa = NULL;
-}
-
-static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t size)
-{
-      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-      if (!swa || !swa->running)
-            return 0;
-
-      size_t avail;
-      size_t written;
-
-      if (swa->nonblocking)
-      {
-            lockMutex(&swa->fifoLock);
-            avail = fifo_write_avail(swa->fifo);
-            written = MIN(avail, size);
-            if (written > 0)
-            {
-                  fifo_write(swa->fifo, buf, written);
-            }
-            mutexUnlock(&swa->fifoLock);
-      }
-      else
-      {
-            written = 0;
-            while (written < size && swa->running)
-            {
-                  lockMutex(&swa->fifoLock);
-                  avail = fifo_write_avail(swa->fifo);
-                  if (avail == 0)
-                  {
-                        mutexUnlock(&swa->fifoLock);
-                        lockMutex(&swa->condLock);
-                        if (swa->running)
-                              condvarWait(&swa->cond, &swa->condLock);
-                        mutexUnlock(&swa->condLock);
-                  }
-                  else
-                  {
-                        size_t write_amt = MIN(size - written, avail);
-                        fifo_write(swa->fifo, (const char*)buf + written, write_amt);
-                        mutexUnlock(&swa->fifoLock);
-                        written += write_amt;
-                  }
-            }
-      }
-
-      return written;
-}
-
-static bool switch_thread_audio_alive(void *data)
-{
-      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-      if (!swa)
-            return false;
-
-      return !swa->is_paused;
-}
-
-static void switch_thread_audio_set_nonblock_state(void *data, bool state)
-{
-   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-   if (swa)
-      swa->nonblocking = state;
-}
-
-static bool switch_thread_audio_use_float(void *data)
-{
-   (void)data;
-   return false;
-}
-
-static size_t switch_thread_audio_write_avail(void *data)
-{
-      switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
-
-      lockMutex(&swa->fifoLock);
-      size_t val = fifo_write_avail(swa->fifo);
-      mutexUnlock(&swa->fifoLock);
-
-      return val;
-}
-
-size_t switch_thread_audio_buffer_size(void *data)
-{
-      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
-
-      if (!swa)
-            return 0;
-
-      return swa->fifoSize;
-}
-
-audio_driver_t audio_switch_thread = {
-      switch_thread_audio_init,
-      switch_thread_audio_write,
-      switch_thread_audio_stop,
-      switch_thread_audio_start,
-      switch_thread_audio_alive,
-      switch_thread_audio_set_nonblock_state,
-      switch_thread_audio_free,
-      switch_thread_audio_use_float,
-      "switch_thread",
-      NULL, /* device_list_new */
-      NULL, /* device_list_free */
-      switch_thread_audio_write_avail,
-      switch_thread_audio_buffer_size
-};
-
-/* vim: set ts=6 sw=6 sts=6: */
+/*  RetroArch - A frontend for libretro.
+ *  Copyright (C) 2018      - misson2000
+ *  Copyright (C) 2018      - m4xw
+ *  Copyright (C) 2018      - lifajucejo
+ *
+ *  RetroArch is free software: you can redistribute it and/or modify it under the terms
+ *  of the GNU General Public License as published by the Free Software Found-
+ *  ation, either version 3 of the License, or (at your option) any later version.
+ *
+ *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *  PURPOSE.  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with RetroArch.
+ *  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <sys/unistd.h>
+
+#include <switch.h>
+
+#include <queues/fifo_queue.h>
+#include "../audio_driver.h"
+#include "../../verbosity.h"
+
+#include "../../tasks/tasks_internal.h"
+
+#define THREAD_STACK_SIZE (1024 * 8)
+
+#define AUDIO_THREAD_CPU 2
+
+#define CHANNELCOUNT 2
+#define BYTESPERSAMPLE sizeof(uint16_t)
+#define SAMPLE_SIZE (CHANNELCOUNT * BYTESPERSAMPLE)
+
+#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;
+
+      size_t fifoSize;
+
+      volatile bool running;
+      bool nonblocking;
+      bool is_paused;
+
+      AudioOutBuffer buffer[AUDIO_BUFFER_COUNT];
+      Thread thread;
+
+      unsigned latency;
+      uint32_t sampleRate;
+} switch_thread_audio_t;
+
+static void mainLoop(void* data)
+{
+   switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
+
+   if (!swa)
+      return;
+
+   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;
+   Result rc;
+
+   while (swa->running)
+   {
+      if (!released_out_buffer)
+      {
+         rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, U64_MAX);
+         if (R_FAILED(rc))
+         {
+            swa->running = false;
+            RARCH_LOG("[Audio]: audoutGetReleasedAudioOutBuffer failed: %d\n", (int)rc);
+            break;
+         }
+         released_out_buffer->data_size = 0;
+      }
+
+      size_t bufAvail = released_out_buffer->buffer_size - released_out_buffer->data_size;
+
+      lockMutex(&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);
+
+      mutexUnlock(&swa->fifoLock);
+      condvarWakeAll(&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);
+         if (R_FAILED(rc))
+         {
+            RARCH_LOG("[Audio]: audoutAppendAudioOutBuffer failed: %d\n", (int)rc);
+         }
+         released_out_buffer = NULL;
+      }
+      else
+         svcSleepThread(16000000); /* 16ms */
+   }
+}
+
+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));
+
+   if (!swa)
+      return NULL;
+
+   swa->running = true;
+   swa->nonblocking = true;
+   swa->is_paused = true;
+   swa->latency = MAX(latency, 8);
+
+   Result rc = audoutInitialize();
+   if (R_FAILED(rc))
+   {
+      RARCH_LOG("[Audio]: audio init failed %d\n", (int)rc);
+      return NULL;
+   }
+
+   rc = audoutStartAudioOut();
+   if (R_FAILED(rc))
+   {
+      RARCH_LOG("[Audio]: audio start init failed: %d\n", (int)rc);
+      return NULL;
+   }
+
+   swa->sampleRate = audoutGetSampleRate();
+   *new_rate = swa->sampleRate;
+
+   mutexInit(&swa->fifoLock);
+   swa->fifoSize = (swa->sampleRate * SAMPLE_SIZE * swa->latency) / 1000;
+   swa->fifo = fifo_new(swa->fifoSize);
+
+   condvarInit(&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);
+
+   if (R_FAILED(rc))
+   {
+      RARCH_LOG("[Audio]: thread creation failed create %u\n", swa->thread.handle);
+      swa->running = false;
+      return NULL;
+   }
+
+   if (R_FAILED(threadStart(&swa->thread)))
+   {
+      RARCH_LOG("[Audio]: thread creation failed start %u\n", swa->thread.handle);
+      threadClose(&swa->thread);
+      swa->running = false;
+      return NULL;
+   }
+
+   return swa;
+}
+
+static bool switch_thread_audio_start(void *data, bool is_shutdown)
+{
+   /* RARCH_LOG("[Audio]: switch_thread_audio_start\n"); */
+   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+   if (!swa)
+      return false;
+
+   swa->is_paused = false;
+   return true;
+}
+
+static bool switch_thread_audio_stop(void *data)
+{
+   switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
+
+   if (!swa)
+      return false;
+
+   swa->is_paused = true;
+   return true;
+}
+
+static void switch_thread_audio_free(void *data)
+{
+   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+   if (!swa)
+      return;
+
+   if (swa->running)
+   {
+      swa->running = false;
+      threadWaitForExit(&swa->thread);
+      threadClose(&swa->thread);
+   }
+
+   audoutStopAudioOut();
+   audoutExit();
+
+   if (swa->fifo)
+   {
+      fifo_free(swa->fifo);
+      swa->fifo = NULL;
+   }
+
+   for (int i = 0; i < AUDIO_BUFFER_COUNT; i++)
+      free(swa->buffer[i].buffer);
+
+   free(swa);
+   swa = NULL;
+}
+
+static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t size)
+{
+      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+      if (!swa || !swa->running)
+            return 0;
+
+      size_t avail;
+      size_t written;
+
+      if (swa->nonblocking)
+      {
+            lockMutex(&swa->fifoLock);
+            avail = fifo_write_avail(swa->fifo);
+            written = MIN(avail, size);
+            if (written > 0)
+            {
+                  fifo_write(swa->fifo, buf, written);
+            }
+            mutexUnlock(&swa->fifoLock);
+      }
+      else
+      {
+            written = 0;
+            while (written < size && swa->running)
+            {
+                  lockMutex(&swa->fifoLock);
+                  avail = fifo_write_avail(swa->fifo);
+                  if (avail == 0)
+                  {
+                        mutexUnlock(&swa->fifoLock);
+                        lockMutex(&swa->condLock);
+                        if (swa->running)
+                              condvarWait(&swa->cond, &swa->condLock);
+                        mutexUnlock(&swa->condLock);
+                  }
+                  else
+                  {
+                        size_t write_amt = MIN(size - written, avail);
+                        fifo_write(swa->fifo, (const char*)buf + written, write_amt);
+                        mutexUnlock(&swa->fifoLock);
+                        written += write_amt;
+                  }
+            }
+      }
+
+      return written;
+}
+
+static bool switch_thread_audio_alive(void *data)
+{
+      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+      if (!swa)
+            return false;
+
+      return !swa->is_paused;
+}
+
+static void switch_thread_audio_set_nonblock_state(void *data, bool state)
+{
+   switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+   if (swa)
+      swa->nonblocking = state;
+}
+
+static bool switch_thread_audio_use_float(void *data)
+{
+   (void)data;
+   return false;
+}
+
+static size_t switch_thread_audio_write_avail(void *data)
+{
+      switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
+
+      lockMutex(&swa->fifoLock);
+      size_t val = fifo_write_avail(swa->fifo);
+      mutexUnlock(&swa->fifoLock);
+
+      return val;
+}
+
+size_t switch_thread_audio_buffer_size(void *data)
+{
+      switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
+
+      if (!swa)
+            return 0;
+
+      return swa->fifoSize;
+}
+
+audio_driver_t audio_switch_thread = {
+      switch_thread_audio_init,
+      switch_thread_audio_write,
+      switch_thread_audio_stop,
+      switch_thread_audio_start,
+      switch_thread_audio_alive,
+      switch_thread_audio_set_nonblock_state,
+      switch_thread_audio_free,
+      switch_thread_audio_use_float,
+      "switch_thread",
+      NULL, /* device_list_new */
+      NULL, /* device_list_free */
+      switch_thread_audio_write_avail,
+      switch_thread_audio_buffer_size
+};
+
+/* vim: set ts=6 sw=6 sts=6: */
diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c
index e1250481f9..6c77b6d1d2 100644
--- a/frontend/drivers/platform_switch.c
+++ b/frontend/drivers/platform_switch.c
@@ -1,737 +1,737 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <boolean.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <dirent.h>
-
-#include <file/nbio.h>
-#include <formats/rpng.h>
-#include <formats/image.h>
-
-#include <switch.h>
-
-#include <file/file_path.h>
-
-#ifdef HAVE_CONFIG_H
-#include "../../config.h"
-#endif
-
-#ifndef IS_SALAMANDER
-#include <lists/file_list.h>
-#endif
-
-#include "../frontend_driver.h"
-#include "../../verbosity.h"
-#include "../../defaults.h"
-#include "../../paths.h"
-#include "../../retroarch.h"
-#include "../../file_path_special.h"
-#include "../../audio/audio_driver.h"
-
-#ifndef IS_SALAMANDER
-#ifdef HAVE_MENU
-#include "../../menu/menu_driver.h"
-#endif
-#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);
-
-// 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);
-
-static void get_first_valid_core(char *path_return)
-{
-   DIR *dir;
-   struct dirent *ent;
-   const char *extension = ".nro";
-
-   path_return[0] = '\0';
-
-   dir = opendir("/retroarch/cores");
-   if (dir != NULL)
-   {
-      while (ent = readdir(dir))
-      {
-         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");
-            strcat(path_return, "/");
-            strcat(path_return, ent->d_name);
-            break;
-         }
-      }
-      closedir(dir);
-   }
-}
-
-static void frontend_switch_get_environment_settings(int *argc, char *argv[], void *args, void *params_data)
-{
-   (void)args;
-
-#ifndef IS_SALAMANDER
-#if defined(HAVE_LOGGER)
-   logger_init();
-#elif defined(HAVE_FILE_LOGGER)
-   retro_main_log_file_init("/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]));
-   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],
-                      "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "media", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE],
-                      "info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], g_defaults.dirs[DEFAULT_DIR_CORE],
-                      "savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], g_defaults.dirs[DEFAULT_DIR_CORE],
-                      "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], g_defaults.dirs[DEFAULT_DIR_CORE],
-                      "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_CORE],
-                      "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "config/remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE]));
-
-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT],
-                      "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR]));
-
-   fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT],
-                      file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config));
-}
-
-static void frontend_switch_deinit(void *data)
-{
-   (void)data;
-
-#if defined(HAVE_LIBNX) && defined(NXLINK) // Else freeze on exit
-   socketExit();
-#endif
-
-   // Splash
-   if (splashData)
-   {
-      free(splashData);
-      splashData = NULL;
-   }
-
-   gfxExit();
-}
-
-static void frontend_switch_exec(const char *path, bool should_load_game)
-{
-   char game_path[PATH_MAX];
-   const char *arg_data[3];
-   char error_string[200 + PATH_MAX];
-   int args = 0;
-   int error = 0;
-
-   game_path[0] = NULL;
-   arg_data[0] = NULL;
-
-   arg_data[args] = elf_path_cst;
-   arg_data[args + 1] = NULL;
-   args++;
-
-   RARCH_LOG("Attempt to load core: [%s].\n", path);
-#ifndef IS_SALAMANDER
-   if (should_load_game && !path_is_empty(RARCH_PATH_CONTENT))
-   {
-      strcpy(game_path, path_get(RARCH_PATH_CONTENT));
-      arg_data[args] = game_path;
-      arg_data[args + 1] = NULL;
-      args++;
-      RARCH_LOG("content path: [%s].\n", path_get(RARCH_PATH_CONTENT));
-   }
-#endif
-
-   if (path && path[0])
-   {
-#ifdef IS_SALAMANDER
-      struct stat sbuff;
-      bool file_exists;
-
-      file_exists = stat(path, &sbuff) == 0;
-      if (!file_exists)
-      {
-         char core_path[PATH_MAX];
-
-         /* find first valid core and load it if the target core doesnt exist */
-         get_first_valid_core(&core_path[0]);
-
-         if (core_path[0] == '\0')
-         {
-            /*errorInit(&error_dialog, ERROR_TEXT, CFG_LANGUAGE_EN);
-                errorText(&error_dialog, "There are no cores installed, install a core to continue.");
-                errorDisp(&error_dialog);*/
-            svcExitProcess();
-         }
-      }
-#endif
-      char *argBuffer = (char *)malloc(PATH_MAX);
-      if (should_load_game)
-      {
-         snprintf(argBuffer, PATH_MAX, "%s \"%s\"", path, game_path);
-      }
-      else
-      {
-         snprintf(argBuffer, PATH_MAX, "%s", path);
-      }
-
-      envSetNextLoad(path, argBuffer);
-   }
-}
-
-#ifndef IS_SALAMANDER
-static bool frontend_switch_set_fork(enum frontend_fork fork_mode)
-{
-   switch (fork_mode)
-   {
-   case FRONTEND_FORK_CORE:
-      RARCH_LOG("FRONTEND_FORK_CORE\n");
-      switch_fork_mode = fork_mode;
-      break;
-   case FRONTEND_FORK_CORE_WITH_ARGS:
-      RARCH_LOG("FRONTEND_FORK_CORE_WITH_ARGS\n");
-      switch_fork_mode = fork_mode;
-      break;
-   case FRONTEND_FORK_RESTART:
-      RARCH_LOG("FRONTEND_FORK_RESTART\n");
-      /*  NOTE: We don't implement Salamander, so just turn
-             this into FRONTEND_FORK_CORE. */
-      switch_fork_mode = FRONTEND_FORK_CORE;
-      break;
-   case FRONTEND_FORK_NONE:
-   default:
-      return false;
-   }
-
-   return true;
-}
-#endif
-
-static void frontend_switch_exitspawn(char *s, size_t len)
-{
-   bool should_load_game = false;
-#ifndef IS_SALAMANDER
-   if (switch_fork_mode == FRONTEND_FORK_NONE)
-      return;
-
-   switch (switch_fork_mode)
-   {
-   case FRONTEND_FORK_CORE_WITH_ARGS:
-      should_load_game = true;
-      break;
-   default:
-      break;
-   }
-#endif
-   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
-   for (uint32_t h = 0; h < height; h++)
-   {
-      for (uint32_t w = 0; w < width; w++)
-      {
-         uint32_t offset = (h * width) + w;
-         uint32_t c = buff[offset];
-
-         uint32_t a = (uint32_t)((c & 0xff000000) >> 24);
-         uint32_t r = (uint32_t)((c & 0x00ff0000) >> 16);
-         uint32_t g = (uint32_t)((c & 0x0000ff00) >> 8);
-         uint32_t b = (uint32_t)(c & 0x000000ff);
-
-         buff[offset] = RGBA8(r, g, b, a);
-      }
-   }
-}
-
-void frontend_switch_showsplash()
-{
-   printf("[Splash] Showing splashScreen\n");
-
-   if (splashData)
-   {
-      uint32_t width, height;
-      width = height = 0;
-
-      uint32_t *frambuffer = (uint32_t *)gfxGetFramebuffer(&width, &height);
-
-      gfx_slow_swizzling_blit(frambuffer, splashData, width, height, 0, 0, false);
-
-      gfxFlushBuffers();
-      gfxSwapBuffers();
-      gfxWaitForVsync();
-   }
-}
-
-// From rpng_test.c
-bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height)
-{
-   int retval;
-   size_t file_len;
-   bool ret = true;
-   rpng_t *rpng = NULL;
-   void *ptr = NULL;
-
-   struct nbio_t *handle = (struct nbio_t *)nbio_open(path, NBIO_READ);
-
-   if (!handle)
-      goto end;
-
-   nbio_begin_read(handle);
-
-   while (!nbio_iterate(handle))
-      svcSleepThread(3);
-
-   ptr = nbio_get_ptr(handle, &file_len);
-
-   if (!ptr)
-   {
-      ret = false;
-      goto end;
-   }
-
-   rpng = rpng_alloc();
-
-   if (!rpng)
-   {
-      ret = false;
-      goto end;
-   }
-
-   if (!rpng_set_buf_ptr(rpng, (uint8_t *)ptr))
-   {
-      ret = false;
-      goto end;
-   }
-
-   if (!rpng_start(rpng))
-   {
-      ret = false;
-      goto end;
-   }
-
-   while (rpng_iterate_image(rpng))
-      svcSleepThread(3);
-
-   if (!rpng_is_valid(rpng))
-   {
-      ret = false;
-      goto end;
-   }
-
-   do
-   {
-      retval = rpng_process_image(rpng, (void **)data, file_len, width, height);
-      svcSleepThread(3);
-   } while (retval == IMAGE_PROCESS_NEXT);
-
-   if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END)
-      ret = false;
-
-end:
-   if (handle)
-      nbio_free(handle);
-
-   if (rpng)
-      rpng_free(rpng);
-
-   rpng = NULL;
-
-   if (!ret)
-      free(*data);
-
-   return ret;
-}
-
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
-{
-   svcSleepThread(rqtp->tv_nsec + (rqtp->tv_sec * 1000000000));
-   return 0;
-}
-
-long sysconf(int name)
-{
-   switch (name)
-   {
-   case 8:
-      return 0x1000;
-   }
-   return -1;
-}
-
-ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
-{
-   return -1;
-}
-
-// Taken from glibc
-char *realpath(const char *name, char *resolved)
-{
-   char *rpath, *dest, *extra_buf = NULL;
-   const char *start, *end, *rpath_limit;
-   long int path_max;
-   int num_links = 0;
-
-   if (name == NULL)
-   {
-      /* As per Single Unix Specification V2 we must return an error if
-	 either parameter is a null pointer.  We extend this to allow
-	 the RESOLVED parameter to be NULL in case the we are expected to
-	 allocate the room for the return value.  */
-      return NULL;
-   }
-
-   if (name[0] == '\0')
-   {
-      /* As per Single Unix Specification V2 we must return an error if
-	 the name argument points to an empty string.  */
-      return NULL;
-   }
-
-#ifdef PATH_MAX
-   path_max = PATH_MAX;
-#else
-   path_max = pathconf(name, _PC_PATH_MAX);
-   if (path_max <= 0)
-      path_max = 1024;
-#endif
-
-   if (resolved == NULL)
-   {
-      rpath = malloc(path_max);
-      if (rpath == NULL)
-         return NULL;
-   }
-   else
-      rpath = resolved;
-   rpath_limit = rpath + path_max;
-
-   if (name[0] != '/')
-   {
-      if (!getcwd(rpath, path_max))
-      {
-         rpath[0] = '\0';
-         goto error;
-      }
-      dest = memchr(rpath, '\0', path_max);
-   }
-   else
-   {
-      rpath[0] = '/';
-      dest = rpath + 1;
-   }
-
-   for (start = end = name; *start; start = end)
-   {
-      int n;
-
-      /* Skip sequence of multiple path-separators.  */
-      while (*start == '/')
-         ++start;
-
-      /* Find end of path component.  */
-      for (end = start; *end && *end != '/'; ++end)
-         /* Nothing.  */;
-
-      if (end - start == 0)
-         break;
-      else if (end - start == 1 && start[0] == '.')
-         /* nothing */;
-      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
-      {
-         /* Back up to previous component, ignore if at root already.  */
-         if (dest > rpath + 1)
-            while ((--dest)[-1] != '/')
-               ;
-      }
-      else
-      {
-         size_t new_size;
-
-         if (dest[-1] != '/')
-            *dest++ = '/';
-
-         if (dest + (end - start) >= rpath_limit)
-         {
-            ptrdiff_t dest_offset = dest - rpath;
-            char *new_rpath;
-
-            if (resolved)
-            {
-               if (dest > rpath + 1)
-                  dest--;
-               *dest = '\0';
-               goto error;
-            }
-            new_size = rpath_limit - rpath;
-            if (end - start + 1 > path_max)
-               new_size += end - start + 1;
-            else
-               new_size += path_max;
-            new_rpath = (char *)realloc(rpath, new_size);
-            if (new_rpath == NULL)
-               goto error;
-            rpath = new_rpath;
-            rpath_limit = rpath + new_size;
-
-            dest = rpath + dest_offset;
-         }
-
-         dest = memcpy(dest, start, end - start);
-         *dest = '\0';
-      }
-   }
-   if (dest > rpath + 1 && dest[-1] == '/')
-      --dest;
-   *dest = '\0';
-
-   return rpath;
-
-error:
-   if (resolved == NULL)
-      free(rpath);
-   return NULL;
-}
-
-// runloop_get_system_info isnt initialized that early..
-extern void retro_get_system_info(struct retro_system_info *info);
-
-static void frontend_switch_init(void *data)
-{
-   (void)data;
-
-   // Init Resolution before initDefault
-   gfxInitResolution(1280, 720);
-
-   gfxInitDefault();
-   gfxSetMode(GfxMode_TiledDouble);
-
-   gfxConfigureTransform(0);
-
-#if defined(HAVE_LIBNX) && defined(NXLINK)
-   socketInitializeDefault();
-   nxlinkStdio();
-#ifndef IS_SALAMANDER
-   verbosity_enable();
-#endif
-#endif
-
-   rarch_system_info_t *sys_info = runloop_get_system_info();
-   retro_get_system_info(sys_info);
-
-   const char *core_name = NULL;
-
-   printf("[Video]: Video initialized\n");
-
-   uint32_t width, height;
-   width = height = 0;
-
-   // Load splash
-   if (!splashData)
-   {
-      if (sys_info)
-      {
-         core_name = sys_info->info.library_name;
-         char *full_core_splash_path = (char *)malloc(PATH_MAX);
-         snprintf(full_core_splash_path, PATH_MAX, "/retroarch/rgui/splash/%s.png", core_name);
-
-         rpng_load_image_argb((const char *)full_core_splash_path, &splashData, &width, &height);
-         if (splashData)
-         {
-            argb_to_rgba8(splashData, height, width);
-            frontend_switch_showsplash();
-         }
-         else
-         {
-            rpng_load_image_argb("/retroarch/rgui/splash/RetroArch.png", &splashData, &width, &height);
-            if (splashData)
-            {
-               argb_to_rgba8(splashData, height, width);
-               frontend_switch_showsplash();
-            }
-         }
-
-         free(full_core_splash_path);
-      }
-      else
-      {
-         rpng_load_image_argb("/retroarch/rgui/splash/RetroArch.png", &splashData, &width, &height);
-         if (splashData)
-         {
-            argb_to_rgba8(splashData, height, width);
-            frontend_switch_showsplash();
-         }
-      }
-   }
-   else
-   {
-      frontend_switch_showsplash();
-   }
-}
-
-static int frontend_switch_get_rating(void)
-{
-   return 1000;
-}
-
-enum frontend_architecture frontend_switch_get_architecture(void)
-{
-   return FRONTEND_ARCH_ARMV8;
-}
-
-static int frontend_switch_parse_drive_list(void *data, bool load_content)
-{
-#ifndef IS_SALAMANDER
-   file_list_t *list = (file_list_t *)data;
-   enum msg_hash_enums enum_idx = load_content ? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR : MSG_UNKNOWN;
-
-   if (!list)
-      return -1;
-
-   menu_entries_append_enum(list, "/", msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
-                            enum_idx,
-                            FILE_TYPE_DIRECTORY, 0, 0);
-#endif
-
-   return 0;
-}
-
-static uint64_t frontend_switch_get_mem_total(void)
-{
-   uint64_t memoryTotal = 0;
-   svcGetInfo(&memoryTotal, 6, CUR_PROCESS_HANDLE, 0); // avaiable
-   memoryTotal += frontend_switch_get_mem_used();
-
-   return memoryTotal;
-}
-
-static uint64_t frontend_switch_get_mem_used(void)
-{
-   uint64_t memoryUsed = 0;
-   svcGetInfo(&memoryUsed, 7, CUR_PROCESS_HANDLE, 0); // used
-
-   return memoryUsed;
-}
-
-static enum frontend_powerstate frontend_switch_get_powerstate(int *seconds, int *percent)
-{
-   // This is fine monkaS
-   return FRONTEND_POWERSTATE_CHARGED;
-}
-
-static void frontend_switch_get_os(char *s, size_t len, int *major, int *minor)
-{
-   strlcpy(s, "Horizon OS", len);
-
-   // There is pretty sure a better way, but this will do just fine
-   if (kernelAbove500())
-   {
-      *major = 5;
-      *minor = 0;
-   }
-   else if (kernelAbove400())
-   {
-      *major = 4;
-      *minor = 0;
-   }
-   else if (kernelAbove300())
-   {
-      *major = 3;
-      *minor = 0;
-   }
-   else if (kernelAbove200())
-   {
-      *major = 2;
-      *minor = 0;
-   }
-   else
-   {
-      // either 1.0 or > 5.x
-      *major = 1;
-      *minor = 0;
-   }
-}
-
-static void frontend_switch_get_name(char *s, size_t len)
-{
-   // TODO: Add Mariko at some point
-   strlcpy(s, "Nintendo Switch", len);
-}
-
-frontend_ctx_driver_t frontend_ctx_switch =
-    {
-        frontend_switch_get_environment_settings,
-        frontend_switch_init,
-        frontend_switch_deinit,
-        frontend_switch_exitspawn,
-        NULL, /* process_args */
-        frontend_switch_exec,
-#ifdef IS_SALAMANDER
-        NULL,
-#else
-        frontend_switch_set_fork,
-#endif
-        frontend_switch_shutdown,
-        frontend_switch_get_name,
-        frontend_switch_get_os,
-        frontend_switch_get_rating,
-        NULL, /* load_content */
-        frontend_switch_get_architecture,
-        frontend_switch_get_powerstate,
-        frontend_switch_parse_drive_list,
-        frontend_switch_get_mem_total,
-        frontend_switch_get_mem_used,
-        NULL, /* install_signal_handler */
-        NULL, /* get_signal_handler_state */
-        NULL, /* set_signal_handler_state */
-        NULL, /* destroy_signal_handler_state */
-        NULL, /* attach_console */
-        NULL, /* detach_console */
-        NULL, /* watch_path_for_changes */
-        NULL, /* check_for_path_changes */
-        NULL, /* set_sustained_performance_mode */
-        "switch",
-};
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include <boolean.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include <file/nbio.h>
+#include <formats/rpng.h>
+#include <formats/image.h>
+
+#include <switch.h>
+
+#include <file/file_path.h>
+
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+#ifndef IS_SALAMANDER
+#include <lists/file_list.h>
+#endif
+
+#include "../frontend_driver.h"
+#include "../../verbosity.h"
+#include "../../defaults.h"
+#include "../../paths.h"
+#include "../../retroarch.h"
+#include "../../file_path_special.h"
+#include "../../audio/audio_driver.h"
+
+#ifndef IS_SALAMANDER
+#ifdef HAVE_MENU
+#include "../../menu/menu_driver.h"
+#endif
+#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);
+
+// 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);
+
+static void get_first_valid_core(char *path_return)
+{
+   DIR *dir;
+   struct dirent *ent;
+   const char *extension = ".nro";
+
+   path_return[0] = '\0';
+
+   dir = opendir("/retroarch/cores");
+   if (dir != NULL)
+   {
+      while (ent = readdir(dir))
+      {
+         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");
+            strcat(path_return, "/");
+            strcat(path_return, ent->d_name);
+            break;
+         }
+      }
+      closedir(dir);
+   }
+}
+
+static void frontend_switch_get_environment_settings(int *argc, char *argv[], void *args, void *params_data)
+{
+   (void)args;
+
+#ifndef IS_SALAMANDER
+#if defined(HAVE_LOGGER)
+   logger_init();
+#elif defined(HAVE_FILE_LOGGER)
+   retro_main_log_file_init("/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]));
+   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],
+                      "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "media", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE],
+                      "info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], g_defaults.dirs[DEFAULT_DIR_CORE],
+                      "savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], g_defaults.dirs[DEFAULT_DIR_CORE],
+                      "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], g_defaults.dirs[DEFAULT_DIR_CORE],
+                      "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_CORE],
+                      "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "config/remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE]));
+
+   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT],
+                      "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR]));
+
+   fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT],
+                      file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config));
+}
+
+static void frontend_switch_deinit(void *data)
+{
+   (void)data;
+
+#if defined(HAVE_LIBNX) && defined(NXLINK) // Else freeze on exit
+   socketExit();
+#endif
+
+   // Splash
+   if (splashData)
+   {
+      free(splashData);
+      splashData = NULL;
+   }
+
+   gfxExit();
+}
+
+static void frontend_switch_exec(const char *path, bool should_load_game)
+{
+   char game_path[PATH_MAX];
+   const char *arg_data[3];
+   char error_string[200 + PATH_MAX];
+   int args = 0;
+   int error = 0;
+
+   game_path[0] = NULL;
+   arg_data[0] = NULL;
+
+   arg_data[args] = elf_path_cst;
+   arg_data[args + 1] = NULL;
+   args++;
+
+   RARCH_LOG("Attempt to load core: [%s].\n", path);
+#ifndef IS_SALAMANDER
+   if (should_load_game && !path_is_empty(RARCH_PATH_CONTENT))
+   {
+      strcpy(game_path, path_get(RARCH_PATH_CONTENT));
+      arg_data[args] = game_path;
+      arg_data[args + 1] = NULL;
+      args++;
+      RARCH_LOG("content path: [%s].\n", path_get(RARCH_PATH_CONTENT));
+   }
+#endif
+
+   if (path && path[0])
+   {
+#ifdef IS_SALAMANDER
+      struct stat sbuff;
+      bool file_exists;
+
+      file_exists = stat(path, &sbuff) == 0;
+      if (!file_exists)
+      {
+         char core_path[PATH_MAX];
+
+         /* find first valid core and load it if the target core doesnt exist */
+         get_first_valid_core(&core_path[0]);
+
+         if (core_path[0] == '\0')
+         {
+            /*errorInit(&error_dialog, ERROR_TEXT, CFG_LANGUAGE_EN);
+                errorText(&error_dialog, "There are no cores installed, install a core to continue.");
+                errorDisp(&error_dialog);*/
+            svcExitProcess();
+         }
+      }
+#endif
+      char *argBuffer = (char *)malloc(PATH_MAX);
+      if (should_load_game)
+      {
+         snprintf(argBuffer, PATH_MAX, "%s \"%s\"", path, game_path);
+      }
+      else
+      {
+         snprintf(argBuffer, PATH_MAX, "%s", path);
+      }
+
+      envSetNextLoad(path, argBuffer);
+   }
+}
+
+#ifndef IS_SALAMANDER
+static bool frontend_switch_set_fork(enum frontend_fork fork_mode)
+{
+   switch (fork_mode)
+   {
+   case FRONTEND_FORK_CORE:
+      RARCH_LOG("FRONTEND_FORK_CORE\n");
+      switch_fork_mode = fork_mode;
+      break;
+   case FRONTEND_FORK_CORE_WITH_ARGS:
+      RARCH_LOG("FRONTEND_FORK_CORE_WITH_ARGS\n");
+      switch_fork_mode = fork_mode;
+      break;
+   case FRONTEND_FORK_RESTART:
+      RARCH_LOG("FRONTEND_FORK_RESTART\n");
+      /*  NOTE: We don't implement Salamander, so just turn
+             this into FRONTEND_FORK_CORE. */
+      switch_fork_mode = FRONTEND_FORK_CORE;
+      break;
+   case FRONTEND_FORK_NONE:
+   default:
+      return false;
+   }
+
+   return true;
+}
+#endif
+
+static void frontend_switch_exitspawn(char *s, size_t len)
+{
+   bool should_load_game = false;
+#ifndef IS_SALAMANDER
+   if (switch_fork_mode == FRONTEND_FORK_NONE)
+      return;
+
+   switch (switch_fork_mode)
+   {
+   case FRONTEND_FORK_CORE_WITH_ARGS:
+      should_load_game = true;
+      break;
+   default:
+      break;
+   }
+#endif
+   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
+   for (uint32_t h = 0; h < height; h++)
+   {
+      for (uint32_t w = 0; w < width; w++)
+      {
+         uint32_t offset = (h * width) + w;
+         uint32_t c = buff[offset];
+
+         uint32_t a = (uint32_t)((c & 0xff000000) >> 24);
+         uint32_t r = (uint32_t)((c & 0x00ff0000) >> 16);
+         uint32_t g = (uint32_t)((c & 0x0000ff00) >> 8);
+         uint32_t b = (uint32_t)(c & 0x000000ff);
+
+         buff[offset] = RGBA8(r, g, b, a);
+      }
+   }
+}
+
+void frontend_switch_showsplash()
+{
+   printf("[Splash] Showing splashScreen\n");
+
+   if (splashData)
+   {
+      uint32_t width, height;
+      width = height = 0;
+
+      uint32_t *frambuffer = (uint32_t *)gfxGetFramebuffer(&width, &height);
+
+      gfx_slow_swizzling_blit(frambuffer, splashData, width, height, 0, 0, false);
+
+      gfxFlushBuffers();
+      gfxSwapBuffers();
+      gfxWaitForVsync();
+   }
+}
+
+// From rpng_test.c
+bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height)
+{
+   int retval;
+   size_t file_len;
+   bool ret = true;
+   rpng_t *rpng = NULL;
+   void *ptr = NULL;
+
+   struct nbio_t *handle = (struct nbio_t *)nbio_open(path, NBIO_READ);
+
+   if (!handle)
+      goto end;
+
+   nbio_begin_read(handle);
+
+   while (!nbio_iterate(handle))
+      svcSleepThread(3);
+
+   ptr = nbio_get_ptr(handle, &file_len);
+
+   if (!ptr)
+   {
+      ret = false;
+      goto end;
+   }
+
+   rpng = rpng_alloc();
+
+   if (!rpng)
+   {
+      ret = false;
+      goto end;
+   }
+
+   if (!rpng_set_buf_ptr(rpng, (uint8_t *)ptr))
+   {
+      ret = false;
+      goto end;
+   }
+
+   if (!rpng_start(rpng))
+   {
+      ret = false;
+      goto end;
+   }
+
+   while (rpng_iterate_image(rpng))
+      svcSleepThread(3);
+
+   if (!rpng_is_valid(rpng))
+   {
+      ret = false;
+      goto end;
+   }
+
+   do
+   {
+      retval = rpng_process_image(rpng, (void **)data, file_len, width, height);
+      svcSleepThread(3);
+   } while (retval == IMAGE_PROCESS_NEXT);
+
+   if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END)
+      ret = false;
+
+end:
+   if (handle)
+      nbio_free(handle);
+
+   if (rpng)
+      rpng_free(rpng);
+
+   rpng = NULL;
+
+   if (!ret)
+      free(*data);
+
+   return ret;
+}
+
+int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
+   svcSleepThread(rqtp->tv_nsec + (rqtp->tv_sec * 1000000000));
+   return 0;
+}
+
+long sysconf(int name)
+{
+   switch (name)
+   {
+   case 8:
+      return 0x1000;
+   }
+   return -1;
+}
+
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
+{
+   return -1;
+}
+
+// Taken from glibc
+char *realpath(const char *name, char *resolved)
+{
+   char *rpath, *dest, *extra_buf = NULL;
+   const char *start, *end, *rpath_limit;
+   long int path_max;
+   int num_links = 0;
+
+   if (name == NULL)
+   {
+      /* As per Single Unix Specification V2 we must return an error if
+	 either parameter is a null pointer.  We extend this to allow
+	 the RESOLVED parameter to be NULL in case the we are expected to
+	 allocate the room for the return value.  */
+      return NULL;
+   }
+
+   if (name[0] == '\0')
+   {
+      /* As per Single Unix Specification V2 we must return an error if
+	 the name argument points to an empty string.  */
+      return NULL;
+   }
+
+#ifdef PATH_MAX
+   path_max = PATH_MAX;
+#else
+   path_max = pathconf(name, _PC_PATH_MAX);
+   if (path_max <= 0)
+      path_max = 1024;
+#endif
+
+   if (resolved == NULL)
+   {
+      rpath = malloc(path_max);
+      if (rpath == NULL)
+         return NULL;
+   }
+   else
+      rpath = resolved;
+   rpath_limit = rpath + path_max;
+
+   if (name[0] != '/')
+   {
+      if (!getcwd(rpath, path_max))
+      {
+         rpath[0] = '\0';
+         goto error;
+      }
+      dest = memchr(rpath, '\0', path_max);
+   }
+   else
+   {
+      rpath[0] = '/';
+      dest = rpath + 1;
+   }
+
+   for (start = end = name; *start; start = end)
+   {
+      int n;
+
+      /* Skip sequence of multiple path-separators.  */
+      while (*start == '/')
+         ++start;
+
+      /* Find end of path component.  */
+      for (end = start; *end && *end != '/'; ++end)
+         /* Nothing.  */;
+
+      if (end - start == 0)
+         break;
+      else if (end - start == 1 && start[0] == '.')
+         /* nothing */;
+      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
+      {
+         /* Back up to previous component, ignore if at root already.  */
+         if (dest > rpath + 1)
+            while ((--dest)[-1] != '/')
+               ;
+      }
+      else
+      {
+         size_t new_size;
+
+         if (dest[-1] != '/')
+            *dest++ = '/';
+
+         if (dest + (end - start) >= rpath_limit)
+         {
+            ptrdiff_t dest_offset = dest - rpath;
+            char *new_rpath;
+
+            if (resolved)
+            {
+               if (dest > rpath + 1)
+                  dest--;
+               *dest = '\0';
+               goto error;
+            }
+            new_size = rpath_limit - rpath;
+            if (end - start + 1 > path_max)
+               new_size += end - start + 1;
+            else
+               new_size += path_max;
+            new_rpath = (char *)realloc(rpath, new_size);
+            if (new_rpath == NULL)
+               goto error;
+            rpath = new_rpath;
+            rpath_limit = rpath + new_size;
+
+            dest = rpath + dest_offset;
+         }
+
+         dest = memcpy(dest, start, end - start);
+         *dest = '\0';
+      }
+   }
+   if (dest > rpath + 1 && dest[-1] == '/')
+      --dest;
+   *dest = '\0';
+
+   return rpath;
+
+error:
+   if (resolved == NULL)
+      free(rpath);
+   return NULL;
+}
+
+// runloop_get_system_info isnt initialized that early..
+extern void retro_get_system_info(struct retro_system_info *info);
+
+static void frontend_switch_init(void *data)
+{
+   (void)data;
+
+   // Init Resolution before initDefault
+   gfxInitResolution(1280, 720);
+
+   gfxInitDefault();
+   gfxSetMode(GfxMode_TiledDouble);
+
+   gfxConfigureTransform(0);
+
+#if defined(HAVE_LIBNX) && defined(NXLINK)
+   socketInitializeDefault();
+   nxlinkStdio();
+#ifndef IS_SALAMANDER
+   verbosity_enable();
+#endif
+#endif
+
+   rarch_system_info_t *sys_info = runloop_get_system_info();
+   retro_get_system_info(sys_info);
+
+   const char *core_name = NULL;
+
+   printf("[Video]: Video initialized\n");
+
+   uint32_t width, height;
+   width = height = 0;
+
+   // Load splash
+   if (!splashData)
+   {
+      if (sys_info)
+      {
+         core_name = sys_info->info.library_name;
+         char *full_core_splash_path = (char *)malloc(PATH_MAX);
+         snprintf(full_core_splash_path, PATH_MAX, "/retroarch/rgui/splash/%s.png", core_name);
+
+         rpng_load_image_argb((const char *)full_core_splash_path, &splashData, &width, &height);
+         if (splashData)
+         {
+            argb_to_rgba8(splashData, height, width);
+            frontend_switch_showsplash();
+         }
+         else
+         {
+            rpng_load_image_argb("/retroarch/rgui/splash/RetroArch.png", &splashData, &width, &height);
+            if (splashData)
+            {
+               argb_to_rgba8(splashData, height, width);
+               frontend_switch_showsplash();
+            }
+         }
+
+         free(full_core_splash_path);
+      }
+      else
+      {
+         rpng_load_image_argb("/retroarch/rgui/splash/RetroArch.png", &splashData, &width, &height);
+         if (splashData)
+         {
+            argb_to_rgba8(splashData, height, width);
+            frontend_switch_showsplash();
+         }
+      }
+   }
+   else
+   {
+      frontend_switch_showsplash();
+   }
+}
+
+static int frontend_switch_get_rating(void)
+{
+   return 1000;
+}
+
+enum frontend_architecture frontend_switch_get_architecture(void)
+{
+   return FRONTEND_ARCH_ARMV8;
+}
+
+static int frontend_switch_parse_drive_list(void *data, bool load_content)
+{
+#ifndef IS_SALAMANDER
+   file_list_t *list = (file_list_t *)data;
+   enum msg_hash_enums enum_idx = load_content ? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR : MSG_UNKNOWN;
+
+   if (!list)
+      return -1;
+
+   menu_entries_append_enum(list, "/", msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
+                            enum_idx,
+                            FILE_TYPE_DIRECTORY, 0, 0);
+#endif
+
+   return 0;
+}
+
+static uint64_t frontend_switch_get_mem_total(void)
+{
+   uint64_t memoryTotal = 0;
+   svcGetInfo(&memoryTotal, 6, CUR_PROCESS_HANDLE, 0); // avaiable
+   memoryTotal += frontend_switch_get_mem_used();
+
+   return memoryTotal;
+}
+
+static uint64_t frontend_switch_get_mem_used(void)
+{
+   uint64_t memoryUsed = 0;
+   svcGetInfo(&memoryUsed, 7, CUR_PROCESS_HANDLE, 0); // used
+
+   return memoryUsed;
+}
+
+static enum frontend_powerstate frontend_switch_get_powerstate(int *seconds, int *percent)
+{
+   // This is fine monkaS
+   return FRONTEND_POWERSTATE_CHARGED;
+}
+
+static void frontend_switch_get_os(char *s, size_t len, int *major, int *minor)
+{
+   strlcpy(s, "Horizon OS", len);
+
+   // There is pretty sure a better way, but this will do just fine
+   if (kernelAbove500())
+   {
+      *major = 5;
+      *minor = 0;
+   }
+   else if (kernelAbove400())
+   {
+      *major = 4;
+      *minor = 0;
+   }
+   else if (kernelAbove300())
+   {
+      *major = 3;
+      *minor = 0;
+   }
+   else if (kernelAbove200())
+   {
+      *major = 2;
+      *minor = 0;
+   }
+   else
+   {
+      // either 1.0 or > 5.x
+      *major = 1;
+      *minor = 0;
+   }
+}
+
+static void frontend_switch_get_name(char *s, size_t len)
+{
+   // TODO: Add Mariko at some point
+   strlcpy(s, "Nintendo Switch", len);
+}
+
+frontend_ctx_driver_t frontend_ctx_switch =
+    {
+        frontend_switch_get_environment_settings,
+        frontend_switch_init,
+        frontend_switch_deinit,
+        frontend_switch_exitspawn,
+        NULL, /* process_args */
+        frontend_switch_exec,
+#ifdef IS_SALAMANDER
+        NULL,
+#else
+        frontend_switch_set_fork,
+#endif
+        frontend_switch_shutdown,
+        frontend_switch_get_name,
+        frontend_switch_get_os,
+        frontend_switch_get_rating,
+        NULL, /* load_content */
+        frontend_switch_get_architecture,
+        frontend_switch_get_powerstate,
+        frontend_switch_parse_drive_list,
+        frontend_switch_get_mem_total,
+        frontend_switch_get_mem_used,
+        NULL, /* install_signal_handler */
+        NULL, /* get_signal_handler_state */
+        NULL, /* set_signal_handler_state */
+        NULL, /* destroy_signal_handler_state */
+        NULL, /* attach_console */
+        NULL, /* detach_console */
+        NULL, /* watch_path_for_changes */
+        NULL, /* check_for_path_changes */
+        NULL, /* set_sustained_performance_mode */
+        "switch",
+};
diff --git a/gfx/common/switch_common.h b/gfx/common/switch_common.h
index d3858cb975..205f8ab68d 100644
--- a/gfx/common/switch_common.h
+++ b/gfx/common/switch_common.h
@@ -1,59 +1,59 @@
-#ifndef SWITCH_COMMON_H__
-#define SWITCH_COMMON_H__
-
-#include <switch.h>
-#include <gfx/scaler/scaler.h>
-
-typedef struct
-{
-   bool vsync;
-   bool rgb32;
-   bool smooth; // bilinear
-   unsigned width, height;
-   unsigned rotation;
-   struct video_viewport vp;
-   struct texture_image *overlay;
-   bool overlay_enabled;
-   bool in_menu;
-   struct
-   {
-      bool enable;
-      bool fullscreen;
-
-      uint32_t *pixels;
-
-      uint32_t width;
-      uint32_t height;
-
-      unsigned tgtw;
-      unsigned tgth;
-
-      struct scaler_ctx scaler;
-   } menu_texture;
-
-   struct
-   {
-      uint32_t width;
-      uint32_t height;
-      uint32_t x_offset;
-   } hw_scale;
-
-   uint32_t image[1280 * 720];
-   uint32_t tmp_image[1280 * 720];
-   u32 cnt;
-   struct scaler_ctx scaler;
-   uint32_t last_width;
-   uint32_t last_height;
-   bool keep_aspect;
-   bool should_resize;
-   bool need_clear;
-   bool is_threaded;
-
-   bool o_size;
-   uint32_t o_height;
-   uint32_t o_width;
-} switch_video_t;
-
-void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend);
-
-#endif
+#ifndef SWITCH_COMMON_H__
+#define SWITCH_COMMON_H__
+
+#include <switch.h>
+#include <gfx/scaler/scaler.h>
+
+typedef struct
+{
+   bool vsync;
+   bool rgb32;
+   bool smooth; // bilinear
+   unsigned width, height;
+   unsigned rotation;
+   struct video_viewport vp;
+   struct texture_image *overlay;
+   bool overlay_enabled;
+   bool in_menu;
+   struct
+   {
+      bool enable;
+      bool fullscreen;
+
+      uint32_t *pixels;
+
+      uint32_t width;
+      uint32_t height;
+
+      unsigned tgtw;
+      unsigned tgth;
+
+      struct scaler_ctx scaler;
+   } menu_texture;
+
+   struct
+   {
+      uint32_t width;
+      uint32_t height;
+      uint32_t x_offset;
+   } hw_scale;
+
+   uint32_t image[1280 * 720];
+   uint32_t tmp_image[1280 * 720];
+   u32 cnt;
+   struct scaler_ctx scaler;
+   uint32_t last_width;
+   uint32_t last_height;
+   bool keep_aspect;
+   bool should_resize;
+   bool need_clear;
+   bool is_threaded;
+
+   bool o_size;
+   uint32_t o_height;
+   uint32_t o_width;
+} switch_video_t;
+
+void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend);
+
+#endif
diff --git a/gfx/drivers/switch_nx_gfx.c b/gfx/drivers/switch_nx_gfx.c
index 3674852544..f207db442f 100644
--- a/gfx/drivers/switch_nx_gfx.c
+++ b/gfx/drivers/switch_nx_gfx.c
@@ -1,772 +1,772 @@
-/*  RetroArch - A frontend for libretro.
- *  Copyright (C) 2018      - misson2000
- *  Copyright (C) 2018      - m4xw
- *
- *  RetroArch is free software: you can redistribute it and/or modify it under the terms
- *  of the GNU General Public License as published by the Free Software Found-
- *  ation, either version 3 of the License, or (at your option) any later version.
- *
- *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- *  PURPOSE.  See the GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along with RetroArch.
- *  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-
-#include <retro_inline.h>
-#include <retro_math.h>
-#include <formats/image.h>
-
-#include <formats/image.h>
-#include <gfx/scaler/scaler.h>
-#include <gfx/scaler/pixconv.h>
-#include <gfx/video_frame.h>
-
-#include <switch.h>
-
-#ifdef HAVE_CONFIG_H
-#include "../../config.h"
-#endif
-
-#ifdef HAVE_MENU
-#include "../../menu/menu_driver.h"
-#endif
-
-#include "../font_driver.h"
-
-#include "../../configuration.h"
-#include "../../command.h"
-#include "../../driver.h"
-
-#include "../../retroarch.h"
-#include "../../verbosity.h"
-
-#include "../common/switch_common.h"
-
-#ifndef HAVE_THREADS
-#include "../../tasks/tasks_internal.h"
-#endif
-
-#ifdef HAVE_NXRGUI
-extern uint32_t *nx_backgroundImage;
-// Temp Overlay // KILL IT WITH FIRE
-extern uint32_t *tmp_overlay;
-#endif
-
-// (C) libtransistor
-static int pdep(uint32_t mask, uint32_t value)
-{
-    uint32_t out = 0;
-    for (int shift = 0; shift < 32; shift++)
-    {
-        uint32_t bit = 1u << shift;
-        if (mask & bit)
-        {
-            if (value & 1)
-                out |= bit;
-            value >>= 1;
-        }
-    }
-    return out;
-}
-
-static uint32_t swizzle_x(uint32_t v) { return pdep(~0x7B4u, v); }
-static uint32_t swizzle_y(uint32_t v) { return pdep(0x7B4, v); }
-
-void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend)
-{
-    uint32_t *dest = buffer;
-    uint32_t *src = image;
-    int x0 = tx;
-    int y0 = ty;
-    int x1 = x0 + w;
-    int y1 = y0 + h;
-    const uint32_t tile_height = 128;
-    const uint32_t padded_width = 128 * 10;
-
-    // we're doing this in pixels - should just shift the swizzles instead
-    uint32_t offs_x0 = swizzle_x(x0);
-    uint32_t offs_y = swizzle_y(y0);
-    uint32_t x_mask = swizzle_x(~0u);
-    uint32_t y_mask = swizzle_y(~0u);
-    uint32_t incr_y = swizzle_x(padded_width);
-
-    // step offs_x0 to the right row of tiles
-    offs_x0 += incr_y * (y0 / tile_height);
-
-    uint32_t x, y;
-    for (y = y0; y < y1; y++)
-    {
-        uint32_t *dest_line = dest + offs_y;
-        uint32_t offs_x = offs_x0;
-
-        for (x = x0; x < x1; x++)
-        {
-            uint32_t pixel = *src++;
-            if (blend) // supercheap masking
-            {
-                uint32_t dst = dest_line[offs_x];
-                uint8_t src_a = ((pixel & 0xFF000000) >> 24);
-
-                if (src_a > 0)
-                    pixel &= 0x00FFFFFF;
-                else
-                    pixel = dst;
-            }
-
-            dest_line[offs_x] = pixel;
-
-            offs_x = (offs_x - x_mask) & x_mask;
-        }
-
-        offs_y = (offs_y - y_mask) & y_mask;
-        if (!offs_y)
-            offs_x0 += incr_y; // wrap into next tile row
-    }
-}
-
-// needed to clear surface completely as hw scaling doesn't always scale to full resoution perflectly
-static void clear_screen(switch_video_t *sw)
-{
-    gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height);
-
-    uint32_t *out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
-
-    memset(out_buffer, 0, gfxGetFramebufferSize());
-
-    gfxFlushBuffers();
-    gfxSwapBuffers();
-    gfxWaitForVsync();
-}
-
-static void *switch_init(const video_info_t *video,
-                         const input_driver_t **input, void **input_data)
-{
-    void  *switchinput = NULL;
-    switch_video_t *sw = (switch_video_t *)calloc(1, sizeof(*sw));
-    if (!sw)
-        return NULL;
-
-    printf("loading switch gfx driver, width: %d, height: %d threaded: %d smooth %d\n", video->width, video->height, video->is_threaded, video->smooth);
-    sw->vp.x = 0;
-    sw->vp.y = 0;
-    sw->vp.width = sw->o_width = video->width;
-    sw->vp.height = sw->o_height = video->height;
-    sw->overlay_enabled = false;
-    sw->overlay = NULL;
-    sw->in_menu = false;
-
-    sw->vp.full_width = 1280;
-    sw->vp.full_height = 720;
-
-    // Sanity check
-    sw->vp.width = MIN(sw->vp.width, sw->vp.full_width);
-    sw->vp.height = MIN(sw->vp.height, sw->vp.full_height);
-
-    sw->vsync = video->vsync;
-    sw->rgb32 = video->rgb32;
-    sw->keep_aspect = true;
-    sw->should_resize = true;
-    sw->o_size = true;
-    sw->is_threaded = video->is_threaded;
-    sw->smooth = video->smooth;
-    sw->menu_texture.enable = false;
-
-    // Autoselect driver
-    if (input && input_data)
-    {
-        settings_t *settings = config_get_ptr();
-        switchinput = input_switch.init(settings->arrays.input_joypad_driver);
-        *input = switchinput ? &input_switch : NULL;
-        *input_data = switchinput;
-    }
-
-    font_driver_init_osd(sw, false,
-                         video->is_threaded,
-                         FONT_DRIVER_RENDER_SWITCH);
-
-    clear_screen(sw);
-
-    return sw;
-}
-
-static void switch_update_viewport(switch_video_t *sw,
-            video_frame_info_t *video_info)
-{
-    settings_t *settings = config_get_ptr();
-    int x                = 0;
-    int y                = 0;
-    float desired_aspect = 0.0f;
-    float width          = sw->vp.full_width;
-    float height         = sw->vp.full_height;
-
-    if (sw->o_size)
-    {
-        width = sw->o_width;
-        height = sw->o_height;
-        sw->vp.x = (int)(((float)sw->vp.full_width - width)) / 2;
-        sw->vp.y = (int)(((float)sw->vp.full_height - height)) / 2;
-
-        sw->vp.width = width;
-        sw->vp.height = height;
-
-        return;
-    }
-
-    desired_aspect = video_driver_get_aspect_ratio();
-
-    /* We crash if >1.0f */
-    printf("[Video] Aspect: %f\n", desired_aspect);
-    /*if (desired_aspect > 1.8f)
-            desired_aspect = 1.7778f;
-
-      if (desired_aspect < 1.2f && desired_aspect != 0.0f)
-            desired_aspect = 1.0f;*/
-
-    if (settings->bools.video_scale_integer)
-    {
-        video_viewport_get_scaled_integer(&sw->vp, sw->vp.full_width, sw->vp.full_height, desired_aspect, sw->keep_aspect);
-    }
-    else if (sw->keep_aspect)
-    {
-#if defined(HAVE_MENU)
-        if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
-        {
-            sw->vp.x = sw->vp.y = 0;
-            sw->vp.width = width;
-            sw->vp.height = height;
-        }
-        else
-#endif
-        {
-            float delta;
-            float device_aspect = ((float)sw->vp.full_width) / sw->vp.full_height;
-
-            if (fabsf(device_aspect - desired_aspect) < 0.0001f)
-            {
-                /* 
-                    * If the aspect ratios of screen and desired aspect
-                    * ratio are sufficiently equal (floating point stuff),
-                    * assume they are actually equal.
-                */
-            }
-            else if (device_aspect > desired_aspect)
-            {
-                delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
-                x = (int)roundf(width * (0.5f - delta));
-                width = (unsigned)roundf(2.0f * width * delta);
-            }
-            else
-            {
-                delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
-                y = (int)roundf(height * (0.5f - delta));
-                height = (unsigned)roundf(2.0f * height * delta);
-            }
-        }
-
-        sw->vp.x = x;
-        sw->vp.y = y;
-
-        sw->vp.width = width;
-        sw->vp.height = height;
-    }
-    else
-    {
-        sw->vp.x = sw->vp.y = 0;
-        sw->vp.width = width;
-        sw->vp.height = height;
-    }
-}
-
-static void switch_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
-{
-    switch_video_t *sw = (switch_video_t *)data;
-
-    if (!sw)
-        return;
-
-    sw->keep_aspect = true;
-    sw->o_size = false;
-
-    settings_t *settings = config_get_ptr();
-
-    switch (aspect_ratio_idx)
-    {
-    case ASPECT_RATIO_SQUARE:
-        video_driver_set_viewport_square_pixel();
-        break;
-
-    case ASPECT_RATIO_CORE:
-        video_driver_set_viewport_core();
-        sw->o_size = true;
-        sw->keep_aspect = false;
-        break;
-
-    case ASPECT_RATIO_CONFIG:
-        video_driver_set_viewport_config();
-        break;
-
-    case ASPECT_RATIO_CUSTOM:
-        if (settings->bools.video_scale_integer)
-        {
-            video_driver_set_viewport_core();
-            sw->o_size = true;
-            sw->keep_aspect = false;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value);
-
-    sw->should_resize = true;
-}
-
-static bool switch_frame(void *data, const void *frame,
-                         unsigned width, unsigned height,
-                         uint64_t frame_count, unsigned pitch,
-                         const char *msg, video_frame_info_t *video_info)
-{
-    switch_video_t   *sw = data;
-    uint32_t *out_buffer = NULL;
-    bool       ffwd_mode = video_info->input_driver_nonblock_state;
-
-    if (!frame)
-        return true;
-
-    if (ffwd_mode && !sw->is_threaded)
-    {
-        // render every 4th frame when in ffwd mode and not threaded
-        if ((frame_count % 4) != 0)
-            return true;
-    }
-
-    if (sw->should_resize || width != sw->last_width || height != sw->last_height)
-    {
-        printf("[Video] Requesting new size: width %i height %i\n", width, height);
-        printf("[Video] fw: %i fh: %i w: %i h: %i x: %i y: %i\n", sw->vp.full_width, sw->vp.full_height, sw->vp.width, sw->vp.height, sw->vp.x, sw->vp.y);
-        switch_update_viewport(sw, video_info);
-        printf("[Video] fw: %i fh: %i w: %i h: %i x: %i y: %i\n", sw->vp.full_width, sw->vp.full_height, sw->vp.width, sw->vp.height, sw->vp.x, sw->vp.y);
-
-        // Sanity check
-        sw->vp.width = MIN(sw->vp.width, sw->vp.full_width);
-        sw->vp.height = MIN(sw->vp.height, sw->vp.full_height);
-
-        scaler_ctx_gen_reset(&sw->scaler);
-
-        sw->scaler.in_width = width;
-        sw->scaler.in_height = height;
-        sw->scaler.in_stride = pitch;
-        sw->scaler.in_fmt = sw->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
-
-        if (!sw->smooth)
-        {
-            sw->scaler.out_width = sw->vp.width;
-            sw->scaler.out_height = sw->vp.height;
-            sw->scaler.out_stride = sw->vp.full_width * sizeof(uint32_t);
-        }
-        else
-        {
-            sw->scaler.out_width = width;
-            sw->scaler.out_height = height;
-            sw->scaler.out_stride = width * sizeof(uint32_t);
-
-            float screen_ratio = (float)sw->vp.full_width / sw->vp.full_height;
-            float tgt_ratio = (float)sw->vp.width / sw->vp.height;
-
-            sw->hw_scale.width = ceil(screen_ratio / tgt_ratio * sw->scaler.out_width);
-            sw->hw_scale.height = sw->scaler.out_height;
-            sw->hw_scale.x_offset = ceil((sw->hw_scale.width - sw->scaler.out_width) / 2.0);
-            if (!video_info->menu_is_alive)
-            {
-                clear_screen(sw);
-                gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
-            }
-        }
-        sw->scaler.out_fmt = SCALER_FMT_ABGR8888;
-
-        sw->scaler.scaler_type = SCALER_TYPE_POINT;
-
-        if (!scaler_ctx_gen_filter(&sw->scaler))
-        {
-            printf("failed to generate scaler for main image\n");
-            return false;
-        }
-
-        sw->last_width = width;
-        sw->last_height = height;
-
-        sw->should_resize = false;
-    }
-
-    out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
-
-    if (sw->in_menu && !video_info->menu_is_alive && sw->smooth)
-    {
-        memset(out_buffer, 0, sw->vp.full_width * sw->vp.full_height * 4);
-        gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
-    }
-    sw->in_menu = video_info->menu_is_alive;
-
-    if (sw->menu_texture.enable)
-    {
-        menu_driver_frame(video_info);
-
-        if (sw->menu_texture.pixels)
-        {
-#ifdef HAVE_NXRGUI
-            gfx_slow_swizzling_blit(out_buffer, nx_backgroundImage, sw->vp.full_width, sw->vp.full_height, 0, 0, false);
-#else
-            memset(out_buffer, 0, gfxGetFramebufferSize());
-#endif
-            scaler_ctx_scale(&sw->menu_texture.scaler, sw->tmp_image + ((sw->vp.full_height - sw->menu_texture.tgth) / 2) * sw->vp.full_width + ((sw->vp.full_width - sw->menu_texture.tgtw) / 2), sw->menu_texture.pixels);
-            gfx_slow_swizzling_blit(out_buffer, sw->tmp_image, sw->vp.full_width, sw->vp.full_height, 0, 0, true);
-        }
-    }
-    else if (sw->smooth) // bilinear
-    {
-        struct scaler_ctx *ctx = &sw->scaler;
-        scaler_ctx_scale_direct(ctx, sw->image, frame);
-        int w = sw->scaler.out_width;
-        int h = sw->scaler.out_height;
-        for (int y = 0; y < h; y++)
-            for (int x = 0; x < w; x++)
-                out_buffer[gfxGetFramebufferDisplayOffset(x + sw->hw_scale.x_offset, y)] = sw->image[y * w + x];
-    }
-    else
-    {
-        struct scaler_ctx *ctx = &sw->scaler;
-        scaler_ctx_scale(ctx, sw->image + (sw->vp.y * sw->vp.full_width) + sw->vp.x, frame);
-        gfx_slow_swizzling_blit(out_buffer, sw->image, sw->vp.full_width, sw->vp.full_height, 0, 0, false);
-#ifdef HAVE_NXRGUI
-        if (tmp_overlay)
-        {
-            gfx_slow_swizzling_blit(out_buffer, tmp_overlay, sw->vp.full_width, sw->vp.full_height, 0, 0, true);
-        }
-#endif
-    }
-
-    if (video_info->statistics_show && !sw->smooth)
-    {
-        struct font_params *osd_params = (struct font_params *)&video_info->osd_stat_params;
-
-        if (osd_params)
-            font_driver_render_msg(video_info, NULL, video_info->stat_text,
-                                   (const struct font_params *)&video_info->osd_stat_params);
-    }
-
-    if (msg)
-        font_driver_render_msg(video_info, NULL, msg, NULL);
-
-    gfxFlushBuffers();
-    gfxSwapBuffers();
-    if (sw->vsync || video_info->menu_is_alive)
-        gfxWaitForVsync();
-
-    return true;
-}
-
-static void switch_set_nonblock_state(void *data, bool toggle)
-{
-    switch_video_t *sw = data;
-    sw->vsync = !toggle;
-}
-
-static bool switch_alive(void *data)
-{
-    (void)data;
-    return true;
-}
-
-static bool switch_focus(void *data)
-{
-    (void)data;
-    return true;
-}
-
-static bool switch_suppress_screensaver(void *data, bool enable)
-{
-    (void)data;
-    (void)enable;
-    return false;
-}
-
-static bool switch_has_windowed(void *data)
-{
-    (void)data;
-    return false;
-}
-
-static void switch_free(void *data)
-{
-    switch_video_t *sw = data;
-    if (sw->menu_texture.pixels)
-        free(sw->menu_texture.pixels);
-
-    free(sw);
-}
-
-static bool switch_set_shader(void *data,
-                              enum rarch_shader_type type, const char *path)
-{
-    (void)data;
-    (void)type;
-    (void)path;
-
-    return false;
-}
-
-static void switch_set_rotation(void *data, unsigned rotation)
-{
-    switch_video_t *sw = data;
-    if (!sw)
-        return;
-    sw->rotation = rotation;
-}
-
-static void switch_viewport_info(void *data, struct video_viewport *vp)
-{
-    switch_video_t *sw = data;
-    *vp = sw->vp;
-}
-
-static bool switch_read_viewport(void *data, uint8_t *buffer, bool is_idle)
-{
-    (void)data;
-    (void)buffer;
-
-    return true;
-}
-
-static void switch_set_texture_frame(
-    void *data, const void *frame, bool rgb32,
-    unsigned width, unsigned height, float alpha)
-{
-    switch_video_t *sw = data;
-    size_t sz = width * height * (rgb32 ? 4 : 2);
-
-    if (!sw->menu_texture.pixels ||
-        sw->menu_texture.width != width ||
-        sw->menu_texture.height != height)
-    {
-        if (sw->menu_texture.pixels)
-            realloc(sw->menu_texture.pixels, sz);
-        else
-            sw->menu_texture.pixels = malloc(sz);
-
-        if (!sw->menu_texture.pixels)
-        {
-            printf("failed to allocate buffer for menu texture\n");
-            return;
-        }
-
-        int xsf = 1280 / width;
-        int ysf = 720 / height;
-        int sf = xsf;
-
-        if (ysf < sf)
-            sf = ysf;
-
-        sw->menu_texture.width = width;
-        sw->menu_texture.height = height;
-        sw->menu_texture.tgtw = width * sf;
-        sw->menu_texture.tgth = height * sf;
-
-        struct scaler_ctx *sctx = &sw->menu_texture.scaler;
-        scaler_ctx_gen_reset(sctx);
-
-        sctx->in_width = width;
-        sctx->in_height = height;
-        sctx->in_stride = width * (rgb32 ? 4 : 2);
-        sctx->in_fmt = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
-        sctx->out_width = sw->menu_texture.tgtw;
-        sctx->out_height = sw->menu_texture.tgth;
-        sctx->out_stride = 1280 * 4;
-        sctx->out_fmt = SCALER_FMT_ABGR8888;
-
-        sctx->scaler_type = SCALER_TYPE_POINT;
-
-        if (!scaler_ctx_gen_filter(sctx))
-        {
-            printf("failed to generate scaler for menu texture\n");
-            return;
-        }
-    }
-
-    memcpy(sw->menu_texture.pixels, frame, sz);
-}
-
-static void switch_apply_state_changes(void *data)
-{
-    (void)data;
-}
-
-static void switch_set_texture_enable(void *data, bool enable, bool full_screen)
-{
-    switch_video_t *sw = data;
-
-    if (!sw->menu_texture.enable && enable)
-        gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height);
-    else if (!enable && sw->menu_texture.enable && sw->smooth)
-    {
-        clear_screen(sw);
-        gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
-    }
-
-    sw->menu_texture.enable = enable;
-    sw->menu_texture.fullscreen = full_screen;
-}
-
-static void switch_set_osd_msg(void *data,
-                               video_frame_info_t *video_info,
-                               const char *msg,
-                               const void *params, void *font)
-{
-    switch_video_t *sw = (switch_video_t *)data;
-
-    if (sw)
-        font_driver_render_msg(video_info, font, msg, params);
-}
-
-#ifdef HAVE_OVERLAY
-static void switch_overlay_enable(void *data, bool state)
-{
-    printf("[Video] Enabled Overlay\n");
-
-    switch_video_t *swa = (switch_video_t *)data;
-
-    if (!swa)
-        return;
-
-    swa->overlay_enabled = state;
-}
-
-static bool switch_overlay_load(void *data,
-                                const void *image_data, unsigned num_images)
-{
-    switch_video_t *swa = (switch_video_t *)data;
-
-    struct texture_image *images = (struct texture_image *)image_data;
-
-    if (!swa)
-        return false;
-
-    swa->overlay = images;
-    swa->overlay_enabled = true;
-
-    return true;
-}
-
-static void switch_overlay_tex_geom(void *data,
-                                    unsigned idx, float x, float y, float w, float h)
-{
-    switch_video_t *swa = (switch_video_t *)data;
-
-    if (!swa)
-        return;
-}
-
-static void switch_overlay_vertex_geom(void *data,
-                                       unsigned idx, float x, float y, float w, float h)
-{
-    switch_video_t *swa = (switch_video_t *)data;
-
-    if (!swa)
-        return;
-}
-
-static void switch_overlay_full_screen(void *data, bool enable)
-{
-    (void)data;
-    (void)enable;
-}
-
-static void switch_overlay_set_alpha(void *data, unsigned idx, float mod)
-{
-    (void)data;
-    (void)idx;
-    (void)mod;
-}
-
-static const video_overlay_interface_t switch_overlay = {
-    switch_overlay_enable,
-    switch_overlay_load,
-    switch_overlay_tex_geom,
-    switch_overlay_vertex_geom,
-    switch_overlay_full_screen,
-    switch_overlay_set_alpha,
-};
-
-void switch_overlay_interface(void *data, const video_overlay_interface_t **iface)
-{
-    switch_video_t *swa = (switch_video_t *)data;
-    if (!swa)
-        return;
-    *iface = &switch_overlay;
-}
-
-#endif
-
-static const video_poke_interface_t switch_poke_interface = {
-    NULL,                       /* get_flags */
-    NULL,                       /* set_coords */
-    NULL,                       /* set_mvp */
-    NULL,                       /* load_texture */
-    NULL,                       /* unload_texture */
-    NULL,                       /* set_video_mode */
-    NULL,                       /* get_refresh_rate */
-    NULL,                       /* set_filtering */
-    NULL,                       /* get_video_output_size */
-    NULL,                       /* get_video_output_prev */
-    NULL,                       /* get_video_output_next */
-    NULL,                       /* get_current_framebuffer */
-    NULL,                       /* get_proc_address */
-    switch_set_aspect_ratio,    /* set_aspect_ratio */
-    switch_apply_state_changes, /* apply_state_changes */
-    switch_set_texture_frame,
-    switch_set_texture_enable,
-    switch_set_osd_msg,
-    NULL, /* show_mouse */
-    NULL, /* grab_mouse_toggle */
-    NULL, /* get_current_shader */
-    NULL, /* get_current_software_framebuffer */
-    NULL, /* get_hw_render_interface */
-};
-
-static void switch_get_poke_interface(void *data,
-                                      const video_poke_interface_t **iface)
-{
-    (void)data;
-    *iface = &switch_poke_interface;
-}
-
-video_driver_t video_switch = {
-    switch_init,
-    switch_frame,
-    switch_set_nonblock_state,
-    switch_alive,
-    switch_focus,
-    switch_suppress_screensaver,
-    switch_has_windowed,
-    switch_set_shader,
-    switch_free,
-    "switch",
-    NULL, /* set_viewport */
-    switch_set_rotation,
-    switch_viewport_info,
-    switch_read_viewport,
-    NULL, /* read_frame_raw */
-#ifdef HAVE_OVERLAY
-    switch_overlay_interface, /* switch_overlay_interface */
-#endif
-    switch_get_poke_interface,
-};
-
-/* vim: set ts=6 sw=6 sts=6: */
+/*  RetroArch - A frontend for libretro.
+ *  Copyright (C) 2018      - misson2000
+ *  Copyright (C) 2018      - m4xw
+ *
+ *  RetroArch is free software: you can redistribute it and/or modify it under the terms
+ *  of the GNU General Public License as published by the Free Software Found-
+ *  ation, either version 3 of the License, or (at your option) any later version.
+ *
+ *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *  PURPOSE.  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with RetroArch.
+ *  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+
+#include <retro_inline.h>
+#include <retro_math.h>
+#include <formats/image.h>
+
+#include <formats/image.h>
+#include <gfx/scaler/scaler.h>
+#include <gfx/scaler/pixconv.h>
+#include <gfx/video_frame.h>
+
+#include <switch.h>
+
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+#ifdef HAVE_MENU
+#include "../../menu/menu_driver.h"
+#endif
+
+#include "../font_driver.h"
+
+#include "../../configuration.h"
+#include "../../command.h"
+#include "../../driver.h"
+
+#include "../../retroarch.h"
+#include "../../verbosity.h"
+
+#include "../common/switch_common.h"
+
+#ifndef HAVE_THREADS
+#include "../../tasks/tasks_internal.h"
+#endif
+
+#ifdef HAVE_NXRGUI
+extern uint32_t *nx_backgroundImage;
+// Temp Overlay // KILL IT WITH FIRE
+extern uint32_t *tmp_overlay;
+#endif
+
+// (C) libtransistor
+static int pdep(uint32_t mask, uint32_t value)
+{
+    uint32_t out = 0;
+    for (int shift = 0; shift < 32; shift++)
+    {
+        uint32_t bit = 1u << shift;
+        if (mask & bit)
+        {
+            if (value & 1)
+                out |= bit;
+            value >>= 1;
+        }
+    }
+    return out;
+}
+
+static uint32_t swizzle_x(uint32_t v) { return pdep(~0x7B4u, v); }
+static uint32_t swizzle_y(uint32_t v) { return pdep(0x7B4, v); }
+
+void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend)
+{
+    uint32_t *dest = buffer;
+    uint32_t *src = image;
+    int x0 = tx;
+    int y0 = ty;
+    int x1 = x0 + w;
+    int y1 = y0 + h;
+    const uint32_t tile_height = 128;
+    const uint32_t padded_width = 128 * 10;
+
+    // we're doing this in pixels - should just shift the swizzles instead
+    uint32_t offs_x0 = swizzle_x(x0);
+    uint32_t offs_y = swizzle_y(y0);
+    uint32_t x_mask = swizzle_x(~0u);
+    uint32_t y_mask = swizzle_y(~0u);
+    uint32_t incr_y = swizzle_x(padded_width);
+
+    // step offs_x0 to the right row of tiles
+    offs_x0 += incr_y * (y0 / tile_height);
+
+    uint32_t x, y;
+    for (y = y0; y < y1; y++)
+    {
+        uint32_t *dest_line = dest + offs_y;
+        uint32_t offs_x = offs_x0;
+
+        for (x = x0; x < x1; x++)
+        {
+            uint32_t pixel = *src++;
+            if (blend) // supercheap masking
+            {
+                uint32_t dst = dest_line[offs_x];
+                uint8_t src_a = ((pixel & 0xFF000000) >> 24);
+
+                if (src_a > 0)
+                    pixel &= 0x00FFFFFF;
+                else
+                    pixel = dst;
+            }
+
+            dest_line[offs_x] = pixel;
+
+            offs_x = (offs_x - x_mask) & x_mask;
+        }
+
+        offs_y = (offs_y - y_mask) & y_mask;
+        if (!offs_y)
+            offs_x0 += incr_y; // wrap into next tile row
+    }
+}
+
+// needed to clear surface completely as hw scaling doesn't always scale to full resoution perflectly
+static void clear_screen(switch_video_t *sw)
+{
+    gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height);
+
+    uint32_t *out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
+
+    memset(out_buffer, 0, gfxGetFramebufferSize());
+
+    gfxFlushBuffers();
+    gfxSwapBuffers();
+    gfxWaitForVsync();
+}
+
+static void *switch_init(const video_info_t *video,
+                         const input_driver_t **input, void **input_data)
+{
+    void  *switchinput = NULL;
+    switch_video_t *sw = (switch_video_t *)calloc(1, sizeof(*sw));
+    if (!sw)
+        return NULL;
+
+    printf("loading switch gfx driver, width: %d, height: %d threaded: %d smooth %d\n", video->width, video->height, video->is_threaded, video->smooth);
+    sw->vp.x = 0;
+    sw->vp.y = 0;
+    sw->vp.width = sw->o_width = video->width;
+    sw->vp.height = sw->o_height = video->height;
+    sw->overlay_enabled = false;
+    sw->overlay = NULL;
+    sw->in_menu = false;
+
+    sw->vp.full_width = 1280;
+    sw->vp.full_height = 720;
+
+    // Sanity check
+    sw->vp.width = MIN(sw->vp.width, sw->vp.full_width);
+    sw->vp.height = MIN(sw->vp.height, sw->vp.full_height);
+
+    sw->vsync = video->vsync;
+    sw->rgb32 = video->rgb32;
+    sw->keep_aspect = true;
+    sw->should_resize = true;
+    sw->o_size = true;
+    sw->is_threaded = video->is_threaded;
+    sw->smooth = video->smooth;
+    sw->menu_texture.enable = false;
+
+    // Autoselect driver
+    if (input && input_data)
+    {
+        settings_t *settings = config_get_ptr();
+        switchinput = input_switch.init(settings->arrays.input_joypad_driver);
+        *input = switchinput ? &input_switch : NULL;
+        *input_data = switchinput;
+    }
+
+    font_driver_init_osd(sw, false,
+                         video->is_threaded,
+                         FONT_DRIVER_RENDER_SWITCH);
+
+    clear_screen(sw);
+
+    return sw;
+}
+
+static void switch_update_viewport(switch_video_t *sw,
+            video_frame_info_t *video_info)
+{
+    settings_t *settings = config_get_ptr();
+    int x                = 0;
+    int y                = 0;
+    float desired_aspect = 0.0f;
+    float width          = sw->vp.full_width;
+    float height         = sw->vp.full_height;
+
+    if (sw->o_size)
+    {
+        width = sw->o_width;
+        height = sw->o_height;
+        sw->vp.x = (int)(((float)sw->vp.full_width - width)) / 2;
+        sw->vp.y = (int)(((float)sw->vp.full_height - height)) / 2;
+
+        sw->vp.width = width;
+        sw->vp.height = height;
+
+        return;
+    }
+
+    desired_aspect = video_driver_get_aspect_ratio();
+
+    /* We crash if >1.0f */
+    printf("[Video] Aspect: %f\n", desired_aspect);
+    /*if (desired_aspect > 1.8f)
+            desired_aspect = 1.7778f;
+
+      if (desired_aspect < 1.2f && desired_aspect != 0.0f)
+            desired_aspect = 1.0f;*/
+
+    if (settings->bools.video_scale_integer)
+    {
+        video_viewport_get_scaled_integer(&sw->vp, sw->vp.full_width, sw->vp.full_height, desired_aspect, sw->keep_aspect);
+    }
+    else if (sw->keep_aspect)
+    {
+#if defined(HAVE_MENU)
+        if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
+        {
+            sw->vp.x = sw->vp.y = 0;
+            sw->vp.width = width;
+            sw->vp.height = height;
+        }
+        else
+#endif
+        {
+            float delta;
+            float device_aspect = ((float)sw->vp.full_width) / sw->vp.full_height;
+
+            if (fabsf(device_aspect - desired_aspect) < 0.0001f)
+            {
+                /* 
+                    * If the aspect ratios of screen and desired aspect
+                    * ratio are sufficiently equal (floating point stuff),
+                    * assume they are actually equal.
+                */
+            }
+            else if (device_aspect > desired_aspect)
+            {
+                delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
+                x = (int)roundf(width * (0.5f - delta));
+                width = (unsigned)roundf(2.0f * width * delta);
+            }
+            else
+            {
+                delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
+                y = (int)roundf(height * (0.5f - delta));
+                height = (unsigned)roundf(2.0f * height * delta);
+            }
+        }
+
+        sw->vp.x = x;
+        sw->vp.y = y;
+
+        sw->vp.width = width;
+        sw->vp.height = height;
+    }
+    else
+    {
+        sw->vp.x = sw->vp.y = 0;
+        sw->vp.width = width;
+        sw->vp.height = height;
+    }
+}
+
+static void switch_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
+{
+    switch_video_t *sw = (switch_video_t *)data;
+
+    if (!sw)
+        return;
+
+    sw->keep_aspect = true;
+    sw->o_size = false;
+
+    settings_t *settings = config_get_ptr();
+
+    switch (aspect_ratio_idx)
+    {
+    case ASPECT_RATIO_SQUARE:
+        video_driver_set_viewport_square_pixel();
+        break;
+
+    case ASPECT_RATIO_CORE:
+        video_driver_set_viewport_core();
+        sw->o_size = true;
+        sw->keep_aspect = false;
+        break;
+
+    case ASPECT_RATIO_CONFIG:
+        video_driver_set_viewport_config();
+        break;
+
+    case ASPECT_RATIO_CUSTOM:
+        if (settings->bools.video_scale_integer)
+        {
+            video_driver_set_viewport_core();
+            sw->o_size = true;
+            sw->keep_aspect = false;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value);
+
+    sw->should_resize = true;
+}
+
+static bool switch_frame(void *data, const void *frame,
+                         unsigned width, unsigned height,
+                         uint64_t frame_count, unsigned pitch,
+                         const char *msg, video_frame_info_t *video_info)
+{
+    switch_video_t   *sw = data;
+    uint32_t *out_buffer = NULL;
+    bool       ffwd_mode = video_info->input_driver_nonblock_state;
+
+    if (!frame)
+        return true;
+
+    if (ffwd_mode && !sw->is_threaded)
+    {
+        // render every 4th frame when in ffwd mode and not threaded
+        if ((frame_count % 4) != 0)
+            return true;
+    }
+
+    if (sw->should_resize || width != sw->last_width || height != sw->last_height)
+    {
+        printf("[Video] Requesting new size: width %i height %i\n", width, height);
+        printf("[Video] fw: %i fh: %i w: %i h: %i x: %i y: %i\n", sw->vp.full_width, sw->vp.full_height, sw->vp.width, sw->vp.height, sw->vp.x, sw->vp.y);
+        switch_update_viewport(sw, video_info);
+        printf("[Video] fw: %i fh: %i w: %i h: %i x: %i y: %i\n", sw->vp.full_width, sw->vp.full_height, sw->vp.width, sw->vp.height, sw->vp.x, sw->vp.y);
+
+        // Sanity check
+        sw->vp.width = MIN(sw->vp.width, sw->vp.full_width);
+        sw->vp.height = MIN(sw->vp.height, sw->vp.full_height);
+
+        scaler_ctx_gen_reset(&sw->scaler);
+
+        sw->scaler.in_width = width;
+        sw->scaler.in_height = height;
+        sw->scaler.in_stride = pitch;
+        sw->scaler.in_fmt = sw->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
+
+        if (!sw->smooth)
+        {
+            sw->scaler.out_width = sw->vp.width;
+            sw->scaler.out_height = sw->vp.height;
+            sw->scaler.out_stride = sw->vp.full_width * sizeof(uint32_t);
+        }
+        else
+        {
+            sw->scaler.out_width = width;
+            sw->scaler.out_height = height;
+            sw->scaler.out_stride = width * sizeof(uint32_t);
+
+            float screen_ratio = (float)sw->vp.full_width / sw->vp.full_height;
+            float tgt_ratio = (float)sw->vp.width / sw->vp.height;
+
+            sw->hw_scale.width = ceil(screen_ratio / tgt_ratio * sw->scaler.out_width);
+            sw->hw_scale.height = sw->scaler.out_height;
+            sw->hw_scale.x_offset = ceil((sw->hw_scale.width - sw->scaler.out_width) / 2.0);
+            if (!video_info->menu_is_alive)
+            {
+                clear_screen(sw);
+                gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
+            }
+        }
+        sw->scaler.out_fmt = SCALER_FMT_ABGR8888;
+
+        sw->scaler.scaler_type = SCALER_TYPE_POINT;
+
+        if (!scaler_ctx_gen_filter(&sw->scaler))
+        {
+            printf("failed to generate scaler for main image\n");
+            return false;
+        }
+
+        sw->last_width = width;
+        sw->last_height = height;
+
+        sw->should_resize = false;
+    }
+
+    out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
+
+    if (sw->in_menu && !video_info->menu_is_alive && sw->smooth)
+    {
+        memset(out_buffer, 0, sw->vp.full_width * sw->vp.full_height * 4);
+        gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
+    }
+    sw->in_menu = video_info->menu_is_alive;
+
+    if (sw->menu_texture.enable)
+    {
+        menu_driver_frame(video_info);
+
+        if (sw->menu_texture.pixels)
+        {
+#ifdef HAVE_NXRGUI
+            gfx_slow_swizzling_blit(out_buffer, nx_backgroundImage, sw->vp.full_width, sw->vp.full_height, 0, 0, false);
+#else
+            memset(out_buffer, 0, gfxGetFramebufferSize());
+#endif
+            scaler_ctx_scale(&sw->menu_texture.scaler, sw->tmp_image + ((sw->vp.full_height - sw->menu_texture.tgth) / 2) * sw->vp.full_width + ((sw->vp.full_width - sw->menu_texture.tgtw) / 2), sw->menu_texture.pixels);
+            gfx_slow_swizzling_blit(out_buffer, sw->tmp_image, sw->vp.full_width, sw->vp.full_height, 0, 0, true);
+        }
+    }
+    else if (sw->smooth) // bilinear
+    {
+        struct scaler_ctx *ctx = &sw->scaler;
+        scaler_ctx_scale_direct(ctx, sw->image, frame);
+        int w = sw->scaler.out_width;
+        int h = sw->scaler.out_height;
+        for (int y = 0; y < h; y++)
+            for (int x = 0; x < w; x++)
+                out_buffer[gfxGetFramebufferDisplayOffset(x + sw->hw_scale.x_offset, y)] = sw->image[y * w + x];
+    }
+    else
+    {
+        struct scaler_ctx *ctx = &sw->scaler;
+        scaler_ctx_scale(ctx, sw->image + (sw->vp.y * sw->vp.full_width) + sw->vp.x, frame);
+        gfx_slow_swizzling_blit(out_buffer, sw->image, sw->vp.full_width, sw->vp.full_height, 0, 0, false);
+#ifdef HAVE_NXRGUI
+        if (tmp_overlay)
+        {
+            gfx_slow_swizzling_blit(out_buffer, tmp_overlay, sw->vp.full_width, sw->vp.full_height, 0, 0, true);
+        }
+#endif
+    }
+
+    if (video_info->statistics_show && !sw->smooth)
+    {
+        struct font_params *osd_params = (struct font_params *)&video_info->osd_stat_params;
+
+        if (osd_params)
+            font_driver_render_msg(video_info, NULL, video_info->stat_text,
+                                   (const struct font_params *)&video_info->osd_stat_params);
+    }
+
+    if (msg)
+        font_driver_render_msg(video_info, NULL, msg, NULL);
+
+    gfxFlushBuffers();
+    gfxSwapBuffers();
+    if (sw->vsync || video_info->menu_is_alive)
+        gfxWaitForVsync();
+
+    return true;
+}
+
+static void switch_set_nonblock_state(void *data, bool toggle)
+{
+    switch_video_t *sw = data;
+    sw->vsync = !toggle;
+}
+
+static bool switch_alive(void *data)
+{
+    (void)data;
+    return true;
+}
+
+static bool switch_focus(void *data)
+{
+    (void)data;
+    return true;
+}
+
+static bool switch_suppress_screensaver(void *data, bool enable)
+{
+    (void)data;
+    (void)enable;
+    return false;
+}
+
+static bool switch_has_windowed(void *data)
+{
+    (void)data;
+    return false;
+}
+
+static void switch_free(void *data)
+{
+    switch_video_t *sw = data;
+    if (sw->menu_texture.pixels)
+        free(sw->menu_texture.pixels);
+
+    free(sw);
+}
+
+static bool switch_set_shader(void *data,
+                              enum rarch_shader_type type, const char *path)
+{
+    (void)data;
+    (void)type;
+    (void)path;
+
+    return false;
+}
+
+static void switch_set_rotation(void *data, unsigned rotation)
+{
+    switch_video_t *sw = data;
+    if (!sw)
+        return;
+    sw->rotation = rotation;
+}
+
+static void switch_viewport_info(void *data, struct video_viewport *vp)
+{
+    switch_video_t *sw = data;
+    *vp = sw->vp;
+}
+
+static bool switch_read_viewport(void *data, uint8_t *buffer, bool is_idle)
+{
+    (void)data;
+    (void)buffer;
+
+    return true;
+}
+
+static void switch_set_texture_frame(
+    void *data, const void *frame, bool rgb32,
+    unsigned width, unsigned height, float alpha)
+{
+    switch_video_t *sw = data;
+    size_t sz = width * height * (rgb32 ? 4 : 2);
+
+    if (!sw->menu_texture.pixels ||
+        sw->menu_texture.width != width ||
+        sw->menu_texture.height != height)
+    {
+        if (sw->menu_texture.pixels)
+            realloc(sw->menu_texture.pixels, sz);
+        else
+            sw->menu_texture.pixels = malloc(sz);
+
+        if (!sw->menu_texture.pixels)
+        {
+            printf("failed to allocate buffer for menu texture\n");
+            return;
+        }
+
+        int xsf = 1280 / width;
+        int ysf = 720 / height;
+        int sf = xsf;
+
+        if (ysf < sf)
+            sf = ysf;
+
+        sw->menu_texture.width = width;
+        sw->menu_texture.height = height;
+        sw->menu_texture.tgtw = width * sf;
+        sw->menu_texture.tgth = height * sf;
+
+        struct scaler_ctx *sctx = &sw->menu_texture.scaler;
+        scaler_ctx_gen_reset(sctx);
+
+        sctx->in_width = width;
+        sctx->in_height = height;
+        sctx->in_stride = width * (rgb32 ? 4 : 2);
+        sctx->in_fmt = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
+        sctx->out_width = sw->menu_texture.tgtw;
+        sctx->out_height = sw->menu_texture.tgth;
+        sctx->out_stride = 1280 * 4;
+        sctx->out_fmt = SCALER_FMT_ABGR8888;
+
+        sctx->scaler_type = SCALER_TYPE_POINT;
+
+        if (!scaler_ctx_gen_filter(sctx))
+        {
+            printf("failed to generate scaler for menu texture\n");
+            return;
+        }
+    }
+
+    memcpy(sw->menu_texture.pixels, frame, sz);
+}
+
+static void switch_apply_state_changes(void *data)
+{
+    (void)data;
+}
+
+static void switch_set_texture_enable(void *data, bool enable, bool full_screen)
+{
+    switch_video_t *sw = data;
+
+    if (!sw->menu_texture.enable && enable)
+        gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height);
+    else if (!enable && sw->menu_texture.enable && sw->smooth)
+    {
+        clear_screen(sw);
+        gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height);
+    }
+
+    sw->menu_texture.enable = enable;
+    sw->menu_texture.fullscreen = full_screen;
+}
+
+static void switch_set_osd_msg(void *data,
+                               video_frame_info_t *video_info,
+                               const char *msg,
+                               const void *params, void *font)
+{
+    switch_video_t *sw = (switch_video_t *)data;
+
+    if (sw)
+        font_driver_render_msg(video_info, font, msg, params);
+}
+
+#ifdef HAVE_OVERLAY
+static void switch_overlay_enable(void *data, bool state)
+{
+    printf("[Video] Enabled Overlay\n");
+
+    switch_video_t *swa = (switch_video_t *)data;
+
+    if (!swa)
+        return;
+
+    swa->overlay_enabled = state;
+}
+
+static bool switch_overlay_load(void *data,
+                                const void *image_data, unsigned num_images)
+{
+    switch_video_t *swa = (switch_video_t *)data;
+
+    struct texture_image *images = (struct texture_image *)image_data;
+
+    if (!swa)
+        return false;
+
+    swa->overlay = images;
+    swa->overlay_enabled = true;
+
+    return true;
+}
+
+static void switch_overlay_tex_geom(void *data,
+                                    unsigned idx, float x, float y, float w, float h)
+{
+    switch_video_t *swa = (switch_video_t *)data;
+
+    if (!swa)
+        return;
+}
+
+static void switch_overlay_vertex_geom(void *data,
+                                       unsigned idx, float x, float y, float w, float h)
+{
+    switch_video_t *swa = (switch_video_t *)data;
+
+    if (!swa)
+        return;
+}
+
+static void switch_overlay_full_screen(void *data, bool enable)
+{
+    (void)data;
+    (void)enable;
+}
+
+static void switch_overlay_set_alpha(void *data, unsigned idx, float mod)
+{
+    (void)data;
+    (void)idx;
+    (void)mod;
+}
+
+static const video_overlay_interface_t switch_overlay = {
+    switch_overlay_enable,
+    switch_overlay_load,
+    switch_overlay_tex_geom,
+    switch_overlay_vertex_geom,
+    switch_overlay_full_screen,
+    switch_overlay_set_alpha,
+};
+
+void switch_overlay_interface(void *data, const video_overlay_interface_t **iface)
+{
+    switch_video_t *swa = (switch_video_t *)data;
+    if (!swa)
+        return;
+    *iface = &switch_overlay;
+}
+
+#endif
+
+static const video_poke_interface_t switch_poke_interface = {
+    NULL,                       /* get_flags */
+    NULL,                       /* set_coords */
+    NULL,                       /* set_mvp */
+    NULL,                       /* load_texture */
+    NULL,                       /* unload_texture */
+    NULL,                       /* set_video_mode */
+    NULL,                       /* get_refresh_rate */
+    NULL,                       /* set_filtering */
+    NULL,                       /* get_video_output_size */
+    NULL,                       /* get_video_output_prev */
+    NULL,                       /* get_video_output_next */
+    NULL,                       /* get_current_framebuffer */
+    NULL,                       /* get_proc_address */
+    switch_set_aspect_ratio,    /* set_aspect_ratio */
+    switch_apply_state_changes, /* apply_state_changes */
+    switch_set_texture_frame,
+    switch_set_texture_enable,
+    switch_set_osd_msg,
+    NULL, /* show_mouse */
+    NULL, /* grab_mouse_toggle */
+    NULL, /* get_current_shader */
+    NULL, /* get_current_software_framebuffer */
+    NULL, /* get_hw_render_interface */
+};
+
+static void switch_get_poke_interface(void *data,
+                                      const video_poke_interface_t **iface)
+{
+    (void)data;
+    *iface = &switch_poke_interface;
+}
+
+video_driver_t video_switch = {
+    switch_init,
+    switch_frame,
+    switch_set_nonblock_state,
+    switch_alive,
+    switch_focus,
+    switch_suppress_screensaver,
+    switch_has_windowed,
+    switch_set_shader,
+    switch_free,
+    "switch",
+    NULL, /* set_viewport */
+    switch_set_rotation,
+    switch_viewport_info,
+    switch_read_viewport,
+    NULL, /* read_frame_raw */
+#ifdef HAVE_OVERLAY
+    switch_overlay_interface, /* switch_overlay_interface */
+#endif
+    switch_get_poke_interface,
+};
+
+/* vim: set ts=6 sw=6 sts=6: */
diff --git a/libretro-common/rthreads/switch_pthread.h b/libretro-common/rthreads/switch_pthread.h
index 5d51194666..7dc32adfca 100644
--- a/libretro-common/rthreads/switch_pthread.h
+++ b/libretro-common/rthreads/switch_pthread.h
@@ -1,207 +1,207 @@
-/* Copyright  (C) 2018 - M4xw <m4x@m4xw.net>, RetroArch Team
- *
- * ---------------------------------------------------------------------------------------
- * The following license statement only applies to this file (switch_pthread.h).
- * ---------------------------------------------------------------------------------------
- *
- * Permission is hereby granted, free of charge,
- * to any person obtaining a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _SWITCH_PTHREAD_WRAP_
-#define _SWITCH_PTHREAD_WRAP_
-
-#include <time.h>
-#include <stdio.h>
-#include <switch.h>
-#include <errno.h>
-
-#include "../include/retro_inline.h"
-#include "../../verbosity.h"
-
-#define THREADVARS_MAGIC 0x21545624 // !TV$
-
-// This structure is exactly 0x20 bytes, if more is needed modify getThreadVars() below
-typedef struct
-{
-   // Magic value used to check if the struct is initialized
-   u32 magic;
-
-   // Thread handle, for mutexes
-   Handle handle;
-
-   // Pointer to the current thread (if exists)
-   Thread *thread_ptr;
-
-   // Pointer to this thread's newlib state
-   struct _reent *reent;
-
-   // Pointer to this thread's thread-local segment
-   void *tls_tp; // !! Offset needs to be TLS+0x1F8 for __aarch64_read_tp !!
-} ThreadVars;
-
-static INLINE ThreadVars *getThreadVars(void)
-{
-   return (ThreadVars *)((u8 *)armGetTls() + 0x1E0);
-}
-
-#define STACKSIZE (8 * 1024)
-
-/* libnx threads return void but pthreads return void pointer */
-
-static uint32_t threadCounter = 1;
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
-{
-   u32 prio = 0;
-   Thread new_switch_thread;
-
-   svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
-
-   // Launch threads on Core 1
-   int rc = threadCreate(&new_switch_thread, (void (*)(void *))start_routine, arg, STACKSIZE, prio - 1, 1);
-
-   if (R_FAILED(rc))
-   {
-      return EAGAIN;
-   }
-
-   printf("[Threading]: Starting Thread(#%i)\n", threadCounter);
-   if (R_FAILED(threadStart(&new_switch_thread)))
-   {
-      threadClose(&new_switch_thread);
-      return -1;
-   }
-
-   *thread = new_switch_thread;
-
-   return 0;
-}
-
-void pthread_exit(void *retval)
-{
-   (void)retval;
-   printf("[Threading]: Exiting Thread\n");
-   svcExitThread();
-}
-
-static INLINE Thread threadGetCurrent(void)
-{
-   ThreadVars *tv = getThreadVars();
-   return *tv->thread_ptr;
-}
-
-static INLINE pthread_t pthread_self(void)
-{
-   return threadGetCurrent();
-}
-
-static INLINE int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
-{
-   mutexInit(mutex);
-
-   return 0;
-}
-
-INLINE int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
-   // Nothing
-   *mutex = 0;
-
-   return 0;
-}
-
-static INLINE int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
-   mutexLock(mutex);
-   return 0;
-}
-
-static INLINE int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
-   mutexUnlock(mutex);
-
-   return 0;
-}
-
-INLINE int pthread_detach(pthread_t thread)
-{
-   (void)thread;
-   // Nothing for now
-   return 0;
-}
-
-static INLINE int pthread_join(pthread_t thread, void **retval)
-{
-   printf("[Threading]: Waiting for Thread Exit\n");
-   threadWaitForExit(&thread);
-   threadClose(&thread);
-
-   return 0;
-}
-
-static INLINE int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
-   return mutexTryLock(mutex) ? 0 : 1;
-}
-
-static INLINE int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
-   condvarWait(cond, mutex);
-
-   return 0;
-}
-
-static INLINE int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
-{
-   condvarWaitTimeout(cond, mutex, abstime->tv_nsec);
-
-   return 0;
-}
-
-static INLINE int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
-{
-   condvarInit(cond);
-
-   return 0;
-}
-
-static INLINE int pthread_cond_signal(pthread_cond_t *cond)
-{
-   condvarWakeOne(cond);
-   return 0;
-}
-
-static INLINE int pthread_cond_broadcast(pthread_cond_t *cond)
-{
-   condvarWakeAll(cond);
-   return 0;
-}
-
-INLINE int pthread_cond_destroy(pthread_cond_t *cond)
-{
-   // Nothing
-   return 0;
-}
-
-INLINE int pthread_equal(pthread_t t1, pthread_t t2)
-{
-   if (t1.handle == t2.handle)
-      return 1;
-
-   return 0;
-}
-
-#endif
+/* Copyright  (C) 2018 - M4xw <m4x@m4xw.net>, RetroArch Team
+ *
+ * ---------------------------------------------------------------------------------------
+ * The following license statement only applies to this file (switch_pthread.h).
+ * ---------------------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _SWITCH_PTHREAD_WRAP_
+#define _SWITCH_PTHREAD_WRAP_
+
+#include <time.h>
+#include <stdio.h>
+#include <switch.h>
+#include <errno.h>
+
+#include "../include/retro_inline.h"
+#include "../../verbosity.h"
+
+#define THREADVARS_MAGIC 0x21545624 // !TV$
+
+// This structure is exactly 0x20 bytes, if more is needed modify getThreadVars() below
+typedef struct
+{
+   // Magic value used to check if the struct is initialized
+   u32 magic;
+
+   // Thread handle, for mutexes
+   Handle handle;
+
+   // Pointer to the current thread (if exists)
+   Thread *thread_ptr;
+
+   // Pointer to this thread's newlib state
+   struct _reent *reent;
+
+   // Pointer to this thread's thread-local segment
+   void *tls_tp; // !! Offset needs to be TLS+0x1F8 for __aarch64_read_tp !!
+} ThreadVars;
+
+static INLINE ThreadVars *getThreadVars(void)
+{
+   return (ThreadVars *)((u8 *)armGetTls() + 0x1E0);
+}
+
+#define STACKSIZE (8 * 1024)
+
+/* libnx threads return void but pthreads return void pointer */
+
+static uint32_t threadCounter = 1;
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
+{
+   u32 prio = 0;
+   Thread new_switch_thread;
+
+   svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
+
+   // Launch threads on Core 1
+   int rc = threadCreate(&new_switch_thread, (void (*)(void *))start_routine, arg, STACKSIZE, prio - 1, 1);
+
+   if (R_FAILED(rc))
+   {
+      return EAGAIN;
+   }
+
+   printf("[Threading]: Starting Thread(#%i)\n", threadCounter);
+   if (R_FAILED(threadStart(&new_switch_thread)))
+   {
+      threadClose(&new_switch_thread);
+      return -1;
+   }
+
+   *thread = new_switch_thread;
+
+   return 0;
+}
+
+void pthread_exit(void *retval)
+{
+   (void)retval;
+   printf("[Threading]: Exiting Thread\n");
+   svcExitThread();
+}
+
+static INLINE Thread threadGetCurrent(void)
+{
+   ThreadVars *tv = getThreadVars();
+   return *tv->thread_ptr;
+}
+
+static INLINE pthread_t pthread_self(void)
+{
+   return threadGetCurrent();
+}
+
+static INLINE int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+   mutexInit(mutex);
+
+   return 0;
+}
+
+INLINE int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+   // Nothing
+   *mutex = 0;
+
+   return 0;
+}
+
+static INLINE int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+   mutexLock(mutex);
+   return 0;
+}
+
+static INLINE int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+   mutexUnlock(mutex);
+
+   return 0;
+}
+
+INLINE int pthread_detach(pthread_t thread)
+{
+   (void)thread;
+   // Nothing for now
+   return 0;
+}
+
+static INLINE int pthread_join(pthread_t thread, void **retval)
+{
+   printf("[Threading]: Waiting for Thread Exit\n");
+   threadWaitForExit(&thread);
+   threadClose(&thread);
+
+   return 0;
+}
+
+static INLINE int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+   return mutexTryLock(mutex) ? 0 : 1;
+}
+
+static INLINE int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+   condvarWait(cond, mutex);
+
+   return 0;
+}
+
+static INLINE int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+   condvarWaitTimeout(cond, mutex, abstime->tv_nsec);
+
+   return 0;
+}
+
+static INLINE int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+   condvarInit(cond);
+
+   return 0;
+}
+
+static INLINE int pthread_cond_signal(pthread_cond_t *cond)
+{
+   condvarWakeOne(cond);
+   return 0;
+}
+
+static INLINE int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+   condvarWakeAll(cond);
+   return 0;
+}
+
+INLINE int pthread_cond_destroy(pthread_cond_t *cond)
+{
+   // Nothing
+   return 0;
+}
+
+INLINE int pthread_equal(pthread_t t1, pthread_t t2)
+{
+   if (t1.handle == t2.handle)
+      return 1;
+
+   return 0;
+}
+
+#endif