SWITCH: first commit, missing audio, input... (#1)

* SWITCH: first commit, missing audio, input...
This commit is contained in:
Cpasjuste 2018-03-10 22:02:38 +01:00 committed by Dave Murphy
parent 9a27289760
commit 005829b775
17 changed files with 977 additions and 2 deletions

78
CMakeLists.switch Normal file
View File

@ -0,0 +1,78 @@
cmake_minimum_required(VERSION 3.0)
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_SYSTEM_NAME "Generic")
set(DEVKITPRO $ENV{DEVKITPRO})
set(CMAKE_SYSTEM_PROCESSOR "armv8-a")
set(CMAKE_C_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc")
set(CMAKE_CXX_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++")
set(CMAKE_ASM_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-as")
set(CMAKE_AR "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ar" CACHE STRING "")
set(CMAKE_RANLIB "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ranlib" CACHE STRING "")
set(CMAKE_C_FLAGS "-O2 -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec -I${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include" CACHE STRING "C flags")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fpermissive -fno-rtti -fno-exceptions -std=gnu++11" CACHE STRING "C++ flags")
set(CMAKE_FIND_ROOT_PATH ${DEVKITPRO} ${DEVKITPRO}/devkitA64 ${DEVKITPRO}/libnx ${DEVKITPRO}/portlibs/switch)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available")
project(SDL2)
set(SRC_DIRS
src
src/atomic
src/audio
#src/audio/switch
src/audio/dummy
src/cpuinfo
src/events
src/file
src/filesystem/dummy
src/haptic
src/haptic/dummy
src/joystick
#src/joystick/switch
src/joystick/dummy
src/libm
src/power
src/render
src/render/software
src/stdlib
src/thread
src/thread/switch
src/timer
src/timer/switch
src/video
src/video/yuv2rgb
src/video/switch
)
set(SRC_FILES )
foreach (DIR ${SRC_DIRS})
file(GLOB FILES ${DIR}/*.c*)
list(APPEND SRC_FILES ${FILES})
endforeach (DIR)
# SDL2 library
add_library(${PROJECT_NAME} STATIC ${SRC_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC ${SRC_DIRS} include)
target_compile_options(${PROJECT_NAME} PUBLIC -O3 -DSWITCH)
# SDL2 test
add_executable(${PROJECT_NAME}.elf test/testswitch.c)
target_include_directories(${PROJECT_NAME}.elf PRIVATE include)
#target_include_directories(${PROJECT_NAME}.elf PRIVATE ${DEVKITPRO}/portlibs/switch/include)
target_compile_options(${PROJECT_NAME}.elf PRIVATE -O3 -DSWITCH)
target_link_libraries(${PROJECT_NAME}.elf
${PROJECT_NAME}
#${DEVKITPRO}/portlibs/switch/lib/libSDL2.a
${DEVKITPRO}/libnx/lib/libnx.a
m
)
set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_FLAGS "-specs=${DEVKITPRO}/libnx/switch.specs")
add_custom_target(${PROJECT_NAME}.nro
DEPENDS ${PROJECT_NAME}.elf
COMMAND elf2nro ${PROJECT_NAME}.elf ${PROJECT_NAME}.nro)

View File

@ -4233,6 +4233,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
aarch64-none-elf*)
ARCH=switch
EXTRA_CFLAGS="$EXTRA_CFLAGS -isystem${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include -D__SWITCH__=1"
EXTRA_CFLAGS="$EXTRA_CFLAGS -g -O2 -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec"
CheckDeclarationAfterStatement
CheckDiskAudio
CheckDummyAudio

View File

@ -0,0 +1,140 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <switch.h>
#include "../../SDL_internal.h"
#if SDL_THREAD_SWITCH
/* An implementation of condition variables using semaphores and mutexes */
/*
This implementation borrows heavily from the BeOS condition variable
implementation, written by Christopher Tate and Owen Smith. Thanks!
*/
#include "SDL_thread.h"
struct SDL_cond
{
Mutex mutex;
CondVar var;
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (cond) {
mutexInit(&cond->mutex);
condvarInit(&cond->var, &cond->mutex);
}
else {
SDL_OutOfMemory();
}
return (cond);
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond *cond)
{
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
condvarWakeOne(&cond->var);
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond *cond)
{
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
condvarWakeAll(&cond->var);
return 0;
}
/* Wait on the condition variable for at most 'ms' milliseconds.
The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait.
Typical use:
Thread A:
SDL_LockMutex(lock);
while ( ! condition ) {
SDL_CondWait(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
/* Unlock the mutex, as is required by condition variable semantics */
SDL_UnlockMutex(mutex);
condvarWaitTimeout(&cond->var, ms * 1000000);
/* Lock the mutex, as is required by condition variable semantics */
SDL_LockMutex(mutex);
return 0;
}
/* Wait on the condition variable forever */
int
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_SWITCH */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,122 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_THREAD_SWITCH
/* An implementation of mutexes using semaphores */
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
struct SDL_mutex
{
int recursive;
Uint32 owner;
Mutex mutex;
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
{
SDL_mutex *mutex;
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
if (mutex) {
mutexInit(&mutex->mutex);
mutex->recursive = 0;
mutex->owner = 0;
}
else {
SDL_OutOfMemory();
}
return mutex;
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
SDL_free(mutex);
}
}
/* Lock the semaphore */
int
SDL_mutexP(SDL_mutex *mutex)
{
Uint32 this_thread;
if (mutex == NULL) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
this_thread = (Uint32) SDL_ThreadID();
if (mutex->owner == this_thread) {
++mutex->recursive;
}
else {
/* The order of operations is important.
We set the locking thread id after we obtain the lock
so unlocks from other threads will fail.
*/
mutexLock(&mutex->mutex);
mutex->owner = this_thread;
mutex->recursive = 0;
}
return 0;
}
/* Unlock the mutex */
int
SDL_mutexV(SDL_mutex *mutex)
{
if (mutex == NULL) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
/* If we don't own the mutex, we can't unlock it */
if (SDL_ThreadID() != mutex->owner) {
SDL_SetError("mutex not owned by this thread");
return -1;
}
if (mutex->recursive) {
--mutex->recursive;
}
else {
/* The order of operations is important.
First reset the owner so another thread doesn't lock
the mutex and set the ownership before we reset it,
then release the lock semaphore.
*/
mutex->owner = 0;
mutexUnlock(&mutex->mutex);
}
return 0;
}
#endif /* SDL_THREAD_SWITCH */

View File

@ -0,0 +1,22 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

View File

@ -0,0 +1,172 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_THREAD_SWITCH
/* Semaphore functions for the VITA. */
#include <stdio.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_timer.h"
struct SDL_semaphore
{
Uint32 count;
Uint32 waiters_count;
SDL_mutex *count_lock;
SDL_cond *count_nonzero;
};
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
if (!sem) {
SDL_OutOfMemory();
return NULL;
}
sem->count = initial_value;
sem->waiters_count = 0;
sem->count_lock = SDL_CreateMutex();
sem->count_nonzero = SDL_CreateCond();
if (!sem->count_lock || !sem->count_nonzero) {
SDL_DestroySemaphore(sem);
return NULL;
}
return sem;
}
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem) {
sem->count = 0xFFFFFFFF;
while (sem->waiters_count > 0) {
SDL_CondSignal(sem->count_nonzero);
SDL_Delay(10);
}
SDL_DestroyCond(sem->count_nonzero);
if (sem->count_lock) {
SDL_mutexP(sem->count_lock);
SDL_mutexV(sem->count_lock);
SDL_DestroyMutex(sem->count_lock);
}
SDL_free(sem);
}
}
/* TODO: This routine is a bit overloaded.
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
* is specified, convert it to microseconds. */
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if (!sem) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
/* A timeout of 0 is an easy case */
if (timeout == 0) {
return SDL_SemTryWait(sem);
}
SDL_LockMutex(sem->count_lock);
++sem->waiters_count;
retval = 0;
while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
retval = SDL_CondWaitTimeout(sem->count_nonzero, sem->count_lock, timeout);
}
--sem->waiters_count;
if (retval == 0) {
--sem->count;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
}
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if (!sem) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = SDL_MUTEX_TIMEDOUT;
SDL_LockMutex(sem->count_lock);
if (sem->count > 0) {
--sem->count;
retval = 0;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem)
{
Uint32 value;
value = 0;
if (sem) {
SDL_LockMutex(sem->count_lock);
value = sem->count;
SDL_UnlockMutex(sem->count_lock);
}
return value;
}
int SDL_SemPost(SDL_sem *sem)
{
if (!sem) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
SDL_LockMutex(sem->count_lock);
if (sem->waiters_count > 0) {
SDL_CondSignal(sem->count_nonzero);
}
++sem->count;
SDL_UnlockMutex(sem->count_lock);
return 0;
}
#endif /* SDL_THREAD_SWITCH */

View File

@ -0,0 +1,87 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_THREAD_SWITCH
/* SWITCH thread management routines for SDL */
#include <stdio.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#define STACK_SIZE 0x2000
static void ThreadEntry(void *argp)
{
SDL_RunThread(*(void **) argp);
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
Result res = threadCreate(&thread->handle, ThreadEntry, args, STACK_SIZE, 0x2C, -2);
if (res != 0) {
return SDL_SetError("threadCreate() failed: 0x%08X", res);
}
res = threadStart(&thread->handle);
if (res != 0) {
return SDL_SetError("threadStart() failed: 0x%08X", res);
}
return 0;
}
void SDL_SYS_SetupThread(const char *name)
{
/* Do nothing. */
}
SDL_threadID SDL_ThreadID(void)
{
return (SDL_threadID) 0;
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
threadWaitForExit(&thread->handle);
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
// TODO ?
threadClose(&thread->handle);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
// TODO ?
threadClose(&thread->handle);
}
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
return 0;
}
#endif /* SDL_THREAD_SWITCH */

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -21,4 +21,4 @@
#include <switch.h>
typedef Thread* SYS_ThreadHandle;
typedef Thread SYS_ThreadHandle;

View File

@ -0,0 +1,34 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_thread_c.h"
SDL_TLSData *
SDL_SYS_GetTLSData(void)
{
return SDL_Generic_GetTLSData();
}
int
SDL_SYS_SetTLSData(SDL_TLSData *data)
{
return SDL_Generic_SetTLSData(data);
}

View File

@ -0,0 +1,78 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_TIMER_SWITCH
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#include <switch.h>
static bool started = false;
static Uint64 start = 0;
void
SDL_TicksInit(void)
{
if (started) {
return;
}
start = SDL_GetPerformanceCounter();
started = true;
}
void
SDL_TicksQuit(void)
{
started = false;
}
Uint32 SDL_GetTicks(void)
{
if (!started) {
SDL_TicksInit();
}
return (Uint32) ((SDL_GetPerformanceCounter() - start) * 1000 / SDL_GetPerformanceFrequency());
}
Uint64
SDL_GetPerformanceCounter(void)
{
return svcGetSystemTick();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 19200000;
}
void
SDL_Delay(Uint32 ms)
{
svcSleepThread((Uint64) ms * 1000000);
}
#endif /* SDL_TIMER_SWITCH */

View File

@ -439,6 +439,7 @@ extern VideoBootStrap QNX_bootstrap;
extern VideoBootStrap OFFSCREEN_bootstrap;
extern VideoBootStrap OS2DIVE_bootstrap;
extern VideoBootStrap OS2VMAN_bootstrap;
extern VideoBootStrap SWITCH_bootstrap;
extern SDL_VideoDevice *SDL_GetVideoDevice(void);
extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);

View File

@ -117,6 +117,9 @@ static VideoBootStrap *bootstrap[] = {
&OS2DIVE_bootstrap,
&OS2VMAN_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_SWITCH
&SWITCH_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
#endif

View File

@ -0,0 +1,168 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_SWITCH
/* SDL internals */
#include "../SDL_sysvideo.h"
#include <switch.h>
#define SWITCH_DATA "_SDL_SwitchData"
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
static int SWITCH_VideoInit(_THIS);
static int SWITCH_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
static void SWITCH_VideoQuit(_THIS);
static void SWITCH_PumpEvents(_THIS);
static int SWITCH_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch);
static int SWITCH_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects);
static void SWITCH_DestroyWindowFramebuffer(_THIS, SDL_Window *window);
static int SWITCH_Available(void)
{
return 1;
}
static void SWITCH_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device);
}
static SDL_VideoDevice *SWITCH_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return NULL;
}
device->VideoInit = SWITCH_VideoInit;
device->VideoQuit = SWITCH_VideoQuit;
device->SetDisplayMode = SWITCH_SetDisplayMode;
device->PumpEvents = SWITCH_PumpEvents;
device->CreateWindowFramebuffer = SWITCH_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = SWITCH_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = SWITCH_DestroyWindowFramebuffer;
device->free = SWITCH_DeleteDevice;
return device;
}
VideoBootStrap SWITCH_bootstrap = {
"Switch", "Video driver for Nintendo Switch (libnx)",
SWITCH_Available, SWITCH_CreateDevice
};
static int SWITCH_VideoInit(_THIS)
{
SDL_DisplayMode mode;
gfxInitResolution(SCREEN_WIDTH, SCREEN_HEIGHT);
gfxInitDefault();
gfxSetMode(GfxMode_LinearDouble);
mode.format = SDL_PIXELFORMAT_ARGB8888;
mode.w = SCREEN_WIDTH;
mode.h = SCREEN_HEIGHT;
mode.refresh_rate = 60;
mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
SDL_AddDisplayMode(&_this->displays[0], &mode);
return 0;
}
static void SWITCH_VideoQuit(_THIS)
{
gfxExit();
}
static int SWITCH_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
{
// TODO: use gfxConfigureResolution
return 0;
}
static void SWITCH_PumpEvents(_THIS)
{
// TODO
}
typedef struct
{
} SWITCH_WindowData;
static int SWITCH_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
{
int w, h;
//SWITCH_WindowData *data = SDL_calloc(1, sizeof(SWITCH_WindowData));
//SDL_SetWindowData(window, SWITCH_DATA, data);
SDL_GetWindowSize(window, &w, &h);
gfxConfigureResolution(w, h);
*pitch = w * 4;
*format = SDL_PIXELFORMAT_ABGR8888;
*pixels = gfxGetFramebuffer(NULL, NULL);
return 0;
}
static int SWITCH_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
{
//SWITCH_WindowData *data = (SWITCH_WindowData *) SDL_GetWindowData(window, SWITCH_DATA);
//if (!data) {
// return SDL_SetError("Couldn't find switch data for window");
//}
gfxFlushBuffers();
gfxSwapBuffers();
gfxWaitForVsync();
// update fb ptr for double buffering
window->surface->pixels = gfxGetFramebuffer(NULL, NULL);
return 0;
}
static void SWITCH_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
{
//SWITCH_WindowData *data = (SWITCH_WindowData *) SDL_GetWindowData(window, SWITCH_DATA);
//SDL_free(data);
}
#endif /* SDL_VIDEO_DRIVER_SWITCH */

69
test/testswitch.c Normal file
View File

@ -0,0 +1,69 @@
/*
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include <stdlib.h>
#include <stdio.h>
#include <switch.h>
#include "SDL2/SDL.h"
#define WINDOW_WIDTH 1280
#define WINDOW_HEIGHT 720
SDL_Renderer *renderer = NULL;
int done = 0;
int main(int argc, char *argv[])
{
consoleDebugInit(debugDevice_SVC);
stdout = stderr;
SDL_Window *window;
if (SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer) < 0) {
printf("SDL_CreateWindowAndRenderer: %s\n", SDL_GetError());
return -1;
}
SDL_Event event;
printf("entering main loop\n");
while (!done) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT || event.type == SDL_KEYDOWN) {
done = 1;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_Rect r = {0, 0, 64, 64};
SDL_RenderFillRect(renderer, &r);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_Rect g = {64, 0, 64, 64};
SDL_RenderFillRect(renderer, &g);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_Rect b = {128, 0, 64, 64};
SDL_RenderFillRect(renderer, &b);
SDL_RenderPresent(renderer);
}
return 0;
}