Initial support for Nintendo WiiU

This commit is contained in:
rw-r-r-0644
2018-10-28 19:14:23 +01:00
committed by Ash Logan
parent c7b8b49ef8
commit 560fd9cba6
21 changed files with 1108 additions and 15 deletions

83
Makefile.wiiu Normal file
View File

@@ -0,0 +1,83 @@
#---------------------------------------------------------------------------------
# Setup compile environment
#---------------------------------------------------------------------------------
$(call assert,$(call seq,$(strip $(DEVKITPPC)),),Please set DEVKITPPC in your environment.)
$(call assert,$(call seq,$(strip $(WUT_ROOT)),),Please set WUT_ROOT in your environment.)
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
export PATH := $(WUT_ROOT)/bin:$(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
AS = powerpc-eabi-as
CC = powerpc-eabi-gcc
CXX = powerpc-eabi-g++
AR = powerpc-eabi-ar
#---------------------------------------------------------------------------------
# Build options
#---------------------------------------------------------------------------------
TARGET = libSDL2.a
SOURCES = \
src/*.c \
src/atomic/*.c \
src/audio/*.c \
src/audio/dummy/*.c \
src/cpuinfo/*.c \
src/events/*.c \
src/file/*.c \
src/haptic/*.c \
src/haptic/dummy/*.c \
src/joystick/*.c \
src/joystick/wiiu/*.c \
src/joystick/dummy/*.c \
src/loadso/dummy/*.c \
src/power/*.c \
src/filesystem/dummy/*.c \
src/render/*.c \
src/render/software/*.c \
src/stdlib/*.c \
src/thread/*.c \
src/thread/wiiu/*.c \
src/thread/generic/*.c \
src/timer/*.c \
src/timer/wiiu/*.c \
src/timer/dummy/*.c \
src/video/*.c \
src/video/wiiu/*.c \
src/video/yuv2rgb/*.c \
src/video/dummy/*.c
OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')
INCLUDE = -I./include -I$(WUT_ROOT)/include -I$(PORTLIBS)/include
#---------------------------------------------------------------------------------
# Compile flags
#---------------------------------------------------------------------------------
CFLAGS := -O3 -D__WIIU__ -D__WUT__ -mcpu=750 -meabi -mhard-float $(INCLUDE)
CXXFLAGS := $(CFLAGS)
ASFLAGS := -g
#---------------------------------------------------------------------------------
# Build rules
#---------------------------------------------------------------------------------
.PHONY: clean install
$(TARGET): $(OBJECTS)
rm -f $@
$(AR) rcs $@ $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.m
$(CC) $(OBJCFLAGS) -c $< -o $@
%.o: %.s
$(CC) -x assembler-with-cpp $(ASFLAGS) -c $< -o $@
%.o: %.S
$(CC) -x assembler-with-cpp $(ASFLAGS) -c $< -o $@
install: $(TARGET)
mkdir -p $(PORTLIBS)/lib
mkdir -p $(PORTLIBS)/include/SDL2
cp $(TARGET) $(PORTLIBS)/lib/
cp -f ./include/*.h $(PORTLIBS)/include/SDL2/
clean:
rm -rf $(OBJECTS) $(TARGET)

View File

@@ -43,6 +43,8 @@
#include "SDL_config_psp.h"
#elif defined(__OS2__)
#include "SDL_config_os2.h"
#elif defined(__WIIU__)
#include "SDL_config_wiiu.h"
#else
/* This is a minimal configuration just to get SDL running on new platforms. */
#include "SDL_config_minimal.h"

157
include/SDL_config_wiiu.h Normal file
View File

@@ -0,0 +1,157 @@
/*
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.
*/
#ifndef SDL_config_wiiu_h_
#define SDL_config_wiiu_h_
#define SDL_config_h_
#include "SDL_platform.h"
#ifdef __GNUC__
#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1
#endif
#define HAVE_GCC_ATOMICS 1
#define STDC_HEADERS 1
#define HAVE_ALLOCA_H 1
#define HAVE_CTYPE_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_LIMITS_H 1
#define HAVE_MATH_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_STDINT_H 1
#define HAVE_STDIO_H 1
#define HAVE_STRING_H 1
#define HAVE_SYS_TYPES_H 1
/* C library functions */
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
#define HAVE_ALLOCA 1
#define HAVE_GETENV 1
#define HAVE_SETENV 1
#define HAVE_PUTENV 1
#define HAVE_SETENV 1
#define HAVE_UNSETENV 1
#define HAVE_QSORT 1
#define HAVE_ABS 1
#define HAVE_BCOPY 1
#define HAVE_MEMSET 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_MEMCMP 1
#define HAVE_STRLEN 1
#define HAVE_STRLCPY 1
#define HAVE_STRLCAT 1
#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE_STRTOLL 1
#define HAVE_STRTOULL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_VSSCANF 1
#define HAVE_VSNPRINTF 1
#define HAVE_M_PI 1
#define HAVE_ACOS 1
#define HAVE_ACOSF 1
#define HAVE_ASIN 1
#define HAVE_ASINF 1
#define HAVE_ATAN 1
#define HAVE_ATANF 1
#define HAVE_ATAN2 1
#define HAVE_ATAN2F 1
#define HAVE_CEIL 1
#define HAVE_CEILF 1
#define HAVE_COPYSIGN 1
#define HAVE_COPYSIGNF 1
#define HAVE_COS 1
#define HAVE_COSF 1
#define HAVE_FABS 1
#define HAVE_FABSF 1
#define HAVE_FLOOR 1
#define HAVE_FLOORF 1
#define HAVE_FMOD 1
#define HAVE_FMODF 1
#define HAVE_LOG 1
#define HAVE_LOGF 1
#define HAVE_LOG10 1
#define HAVE_LOG10F 1
#define HAVE_POW 1
#define HAVE_POWF 1
#define HAVE_SCALBN 1
#define HAVE_SCALBNF 1
#define HAVE_SIN 1
#define HAVE_SINF 1
#define HAVE_SQRT 1
#define HAVE_SQRTF 1
#define HAVE_TAN 1
#define HAVE_TANF 1
#define HAVE_SETJMP 1
#define HAVE_NANOSLEEP 1
/* #define HAVE_SYSCONF 1 */
/* #define HAVE_SIGACTION 1 */
/* Wii U isn't that sophisticated */
#define LACKS_SYS_MMAN_H 1
/* Wii U thread support (src/thread/wiiu/\*.c) */
#define SDL_THREAD_WIIU 1
/* Wii U timer support (src/timer/wiiu/\*.c) */
#define SDL_TIMER_WIIU 1
/* Wii U joystick driver (src/joystick/wiiu/\*.c) */
#define SDL_JOYSTICK_WIIU 1
/* Enable the stub audio driver (src/audio/dummy/\*.c) */
#define SDL_AUDIO_DRIVER_DUMMY 1
/* Wii U video dirver */
#define SDL_VIDEO_DRIVER_WIIU 1
/* There's no battery for the console unit */
#define SDL_POWER_DISABLED 1
/* !!! FIXME: what does Wii U do for filesystem stuff? */
#define SDL_FILESYSTEM_DUMMY 1
/* Wii U does have an haptic device, but it's not ported to sdl yet (src/haptic/dummy/\*.c) */
#define SDL_HAPTIC_DISABLED 1
/* Wii U can't load shared object (src/loadso/dummy/\*.c) */
#define SDL_LOADSO_DISABLED 1
#endif /* SDL_config_wiiu_h_ */

View File

@@ -158,6 +158,10 @@
#undef __PSP__
#define __PSP__ 1
#endif
#if defined(__WIIU__)
#undef __WIIU__
#define __WIIU__ 1
#endif
/* The NACL compiler defines __native_client__ and __pnacl__
* Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi

View File

@@ -37,6 +37,9 @@
#if defined(__PSP__)
#define DEFAULT_WINDOW_WIDTH 480
#define DEFAULT_WINDOW_HEIGHT 272
#elif defined(__WIIU__)
#define DEFAULT_WINDOW_WIDTH 1280
#define DEFAULT_WINDOW_HEIGHT 720
#else
#define DEFAULT_WINDOW_WIDTH 640
#define DEFAULT_WINDOW_HEIGHT 480

View File

@@ -474,6 +474,8 @@ SDL_GetPlatform()
return "iOS";
#elif __PSP__
return "PlayStation Portable";
#elif __WIIU__
return "Wii U";
#else
return "Unknown (see SDL_platform.h)";
#endif

View File

@@ -37,6 +37,10 @@
#include <android/log.h>
#endif
#if defined(__WIIU__)
#include <coreinit/debug.h>
#endif
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
@@ -327,7 +331,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
BOOL attachResult;
DWORD attachError;
unsigned long charsWritten;
unsigned long charsWritten;
DWORD consoleMode;
/* Maybe attach console and get stderr handle */
@@ -342,7 +346,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
} else if (attachError == ERROR_GEN_FAILURE) {
OutputDebugString(TEXT("Could not attach to console of parent process\r\n"));
consoleAttached = -1;
} else if (attachError == ERROR_ACCESS_DENIED) {
} else if (attachError == ERROR_ACCESS_DENIED) {
/* Already attached */
consoleAttached = 1;
} else {
@@ -369,10 +373,10 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
output = SDL_small_alloc(char, length, &isstack);
SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message);
tstr = WIN_UTF8ToString(output);
/* Output to debugger */
OutputDebugString(tstr);
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
/* Screen output to stderr, if console was attached. */
if (consoleAttached == 1) {
@@ -415,6 +419,10 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
return;
}
}
#elif defined(__WIIU__)
{
OSReport("SDL: %s: %s\n", SDL_priority_prefixes[priority], message);
}
#elif defined(__PSP__)
{
FILE* pFile;

View File

@@ -32,6 +32,10 @@
#include <atomic.h>
#endif
#if defined(__WIIU__)
#include <stdatomic.h>
#endif
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#include <xmmintrin.h>
#endif
@@ -114,6 +118,10 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
/* Used for Solaris with non-gcc compilers. */
return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
#elif defined(__WIIU__)
uint64_t val = 0;
return (SDL_bool) atomic_compare_exchange_strong((volatile _Atomic uint64_t*)lock, &val, 1);
#else
#error Please implement for your platform.
return SDL_FALSE;

View File

@@ -53,6 +53,8 @@
#define SDL_DYNAMIC_API 0
#elif defined(__PSP__) && __PSP__
#define SDL_DYNAMIC_API 0
#elif defined(__WIIU__) && __WIIU__
#define SDL_DYNAMIC_API 0
#elif defined(__clang_analyzer__)
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
#endif

View File

@@ -0,0 +1,166 @@
/*
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_JOYSTICK_WIIU
#include <vpad/input.h>
#include <coreinit/debug.h>
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#include "SDL_assert.h"
#include "SDL_events.h"
static VPADButtons button_map[] = {
VPAD_BUTTON_A, VPAD_BUTTON_B, VPAD_BUTTON_X, VPAD_BUTTON_Y,
VPAD_BUTTON_STICK_L, VPAD_BUTTON_STICK_R,
VPAD_BUTTON_L, VPAD_BUTTON_R,
VPAD_BUTTON_ZL, VPAD_BUTTON_ZR,
VPAD_BUTTON_PLUS, VPAD_BUTTON_MINUS,
VPAD_BUTTON_LEFT, VPAD_BUTTON_UP, VPAD_BUTTON_RIGHT, VPAD_BUTTON_DOWN,
VPAD_STICK_L_EMULATION_LEFT, VPAD_STICK_L_EMULATION_UP, VPAD_STICK_L_EMULATION_RIGHT, VPAD_STICK_L_EMULATION_DOWN,
VPAD_STICK_R_EMULATION_LEFT, VPAD_STICK_R_EMULATION_UP, VPAD_STICK_R_EMULATION_RIGHT, VPAD_STICK_R_EMULATION_DOWN
};
/* Function to scan the system for joysticks.
* Joystick 0 should be the system default joystick.
* This function should return the number of available joysticks, or -1
* on an unrecoverable fatal error.
*/
int SDL_SYS_JoystickInit(void) {
return 1;
}
/* Function to return the number of joystick devices plugged in right now */
int SDL_SYS_NumJoysticks(void) {
return 1;
}
/* Function to cause any queued joystick insertions to be processed */
void SDL_SYS_JoystickDetect(void) { }
/* Function to get the device-dependent name of a joystick */
const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index) {
return "Nintendo Wii U Gamepad";
}
/* Function to get the current instance id of the joystick located at device_index */
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) {
return device_index;
}
/* Function to open a joystick for use.
The joystick to open is specified by the device index.
This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error.
*/
int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) {
joystick->nbuttons = sizeof(button_map) / sizeof(VPADButtons);
joystick->naxes = 4;
joystick->nhats = 0;
return 0;
}
/* Function to query if the joystick is currently attached
* It returns SDL_TRUE if attached, SDL_FALSE otherwise.
*/
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick) {
return SDL_TRUE;
}
/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
* and update joystick device state.
*/
void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) {
static int16_t x1_old = 0;
static int16_t y1_old = 0;
static int16_t x2_old = 0;
static int16_t y2_old = 0;
VPADStatus vpad;
VPADReadError error;
VPADRead(0, &vpad, 1, &error);
int16_t x1 = (int16_t) ((vpad.leftStick.x) * 0x7ff0);
int16_t y1 = (int16_t) ((vpad.leftStick.y) * 0x7ff0);
int16_t x2 = (int16_t) ((vpad.rightStick.x) * 0x7ff0);
int16_t y2 = (int16_t) ((vpad.rightStick.y) * 0x7ff0);
if(x1 != x1_old) {
SDL_PrivateJoystickAxis(joystick, 0, x1);
x1_old = x1;
}
if(y1 != y1_old) {
SDL_PrivateJoystickAxis(joystick, 1, y1);
y1_old = y1;
}
if(x2 != x2_old) {
SDL_PrivateJoystickAxis(joystick, 2, x2);
x2_old = x2;
}
if(y2 != y2_old) {
SDL_PrivateJoystickAxis(joystick, 3, y2);
y2_old = y2;
}
int i;
for(i = 0; i < joystick->nbuttons; i++) {
SDL_PrivateJoystickButton(
joystick, i,
(vpad.hold & button_map[i]) ?
SDL_PRESSED : SDL_RELEASED
);
}
}
/* Function to return the stable GUID for a plugged in device */
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) {
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
return guid;
}
/* Function to return the stable GUID for a plugged in device */
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) {
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = joystick->name;
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
return guid;
}
/* Function to close a joystick after use */
void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { }
/* Function to perform any system-specific joystick related cleanup */
void SDL_SYS_JoystickQuit(void) { }
#endif

View File

@@ -27,7 +27,7 @@
#define libm_hidden_def(x)
#define strong_alias(x, y)
#ifndef __HAIKU__ /* already defined in a system header. */
#if !defined(__HAIKU__) && !defined(__WIIU__) /* already defined in a system header. */
typedef unsigned int u_int32_t;
#endif

View File

@@ -510,6 +510,12 @@ DEFAULT_MMAP_THRESHOLD default: 256K
#define LACKS_SYS_MMAN_H
#endif /* __OS2__ */
#ifdef __WIIU__
#define HAVE_MMAP 0
#define LACKS_SYS_MMAN_H
#define USE_LOCKS 0 // TODO: use locks
#endif /* __WIIU__ */
#if defined(DARWIN) || defined(_DARWIN)
/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
#ifndef HAVE_MORECORE

View File

@@ -36,6 +36,8 @@
#include "psp/SDL_systhread_c.h"
#elif SDL_THREAD_STDCPP
#include "stdcpp/SDL_systhread_c.h"
#elif SDL_THREAD_WIIU
#include "wiiu/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
#include "generic/SDL_systhread_c.h"

View File

@@ -0,0 +1,110 @@
/*
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_THREAD_WIIU
#include "SDL_thread.h"
#include <coreinit/condition.h>
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
{
OSCondition *cond;
cond = (OSCondition *) SDL_malloc(sizeof(OSCondition));
if (cond) {
OSInitCond(cond);
} else {
SDL_OutOfMemory();
}
return (SDL_cond *)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)
{
return SDL_CondBroadcast(cond);
}
/* 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");
}
OSSignalCond((OSCondition *)cond);
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)
{
return -1;
}
/* Wait on the condition variable forever */
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
{
OSWaitCond((OSCondition *)cond, (OSMutex *)mutex);
return 0;
}
#endif /* SDL_THREAD_WIIU */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,76 @@
/*
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"
#include <errno.h>
#include <coreinit/mutex.h>
#include "SDL_thread.h"
struct SDL_mutex
{
pthread_mutex_t id;
#if FAKE_RECURSIVE_MUTEX
int recursive;
pthread_t owner;
#endif
};
SDL_mutex *
SDL_CreateMutex(void)
{
OSMutex *mutex;
/* Allocate the structure */
mutex = (OSMutex *) SDL_calloc(1, sizeof(OSMutex));
OSInitMutex(mutex);
return (SDL_mutex *)mutex;
}
void
SDL_DestroyMutex(SDL_mutex * mutex)
{
if (mutex) {
SDL_free(mutex);
}
}
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
{
OSLockMutex((OSMutex *)mutex);
return 0;
}
int
SDL_TryLockMutex(SDL_mutex * mutex)
{
return OSTryLockMutex((OSMutex *)mutex) ? 0 : SDL_MUTEX_TIMEDOUT;
}
int
SDL_UnlockMutex(SDL_mutex * mutex)
{
OSUnlockMutex((OSMutex *)mutex);
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,122 @@
/*
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_THREAD_WIIU
/* WiiU thread management routines for SDL */
#include <stdio.h>
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#include "../SDL_thread_c.h"
#include <malloc.h>
#include <coreinit/thread.h>
static void
thread_deallocator(OSThread *thread, void *stack)
{
free(thread);
free(stack);
}
static void
thread_cleanup(OSThread *thread, void *stack)
{
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
unsigned int stackSize = thread->stacksize ? thread->stacksize : 0x8000;
int priority = OSGetThreadPriority(OSGetCurrentThread());
OSThread *handle = (OSThread *)memalign(16, sizeof(OSThread));
char *stack = (char *)memalign(16, stackSize);
memset(handle, 0, sizeof(OSThread));
if (!OSCreateThread(handle,
(OSThreadEntryPointFn)SDL_RunThread,
(int32_t)args,
NULL,
stack,
stackSize,
priority,
OS_THREAD_ATTRIB_AFFINITY_ANY))
{
return SDL_SetError("OSCreateThread() failed");
}
OSSetThreadDeallocator(handle, &thread_deallocator);
OSSetThreadCleanupCallback(handle, &thread_cleanup);
OSResumeThread(handle);
thread->handle = handle;
return 0;
}
void SDL_SYS_SetupThread(const char *name)
{
/* Do nothing. */
}
SDL_threadID SDL_ThreadID(void)
{
return (SDL_threadID) OSGetCurrentThread();
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
OSJoinThread(thread->handle, NULL);
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
OSDetachThread(thread->handle);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
OSCancelThread(thread->handle);
}
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
int value;
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = 17;
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = 15;
} else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
value = 14;
} else {
value = 16;
}
return OSSetThreadPriority(OSGetCurrentThread(), value);
}
#endif /* SDL_THREAD_WIIU */
/* vim: ts=4 sw=4
*/

View File

@@ -0,0 +1,27 @@
/*
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"
#include <coreinit/thread.h>
typedef OSThread *SYS_ThreadHandle;
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,84 @@
/*
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"
#ifdef SDL_TIMER_WIIU
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "SDL_error.h"
#include "../SDL_timer_c.h"
#include <coreinit/thread.h>
#include <coreinit/systeminfo.h>
#include <coreinit/time.h>
static OSTime start;
static SDL_bool ticks_started = SDL_FALSE;
void
SDL_TicksInit(void)
{
if (ticks_started) {
return;
}
ticks_started = SDL_TRUE;
start = OSGetSystemTime();
}
void
SDL_TicksQuit(void)
{
ticks_started = SDL_FALSE;
}
Uint32
SDL_GetTicks(void)
{
if (!ticks_started) {
SDL_TicksInit();
}
OSTime now = OSGetSystemTime();
return (Uint32)OSTicksToMilliseconds(now - start);
}
Uint64
SDL_GetPerformanceCounter(void)
{
return OSGetTime();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return OSTimerClockSpeed;
}
void
SDL_Delay(Uint32 ms)
{
OSSleepTicks(OSMillisecondsToTicks(ms));
}
#endif /* SDL_TIMER_WIIU */
/* vim: ts=4 sw=4
*/

View File

@@ -380,11 +380,11 @@ struct SDL_VideoDevice
/* Data private to this driver */
void *driverdata;
struct SDL_GLDriverData *gl_data;
#if SDL_VIDEO_OPENGL_EGL
struct SDL_EGL_VideoData *egl_data;
#endif
#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
struct SDL_PrivateGLESData *gles_data;
#endif
@@ -421,6 +421,7 @@ extern VideoBootStrap NACL_bootstrap;
extern VideoBootStrap VIVANTE_bootstrap;
extern VideoBootStrap Emscripten_bootstrap;
extern VideoBootStrap QNX_bootstrap;
extern VideoBootStrap WIIU_bootstrap;
extern SDL_VideoDevice *SDL_GetVideoDevice(void);
extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);

View File

@@ -109,6 +109,9 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_QNX
&QNX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WIIU
&WIIU_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
#endif
@@ -277,7 +280,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
}
}
}
if (!renderer) {
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
SDL_RendererInfo info;
@@ -1199,7 +1202,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)
return 0;
/* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
@@ -1912,7 +1915,7 @@ SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
/* Fullscreen windows are always at their display's origin */
if (window->flags & SDL_WINDOW_FULLSCREEN) {
int displayIndex;
if (x) {
*x = 0;
}
@@ -2275,7 +2278,7 @@ SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags)
if (SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)) == 0) {
return 0;
}
window->flags &= ~FULLSCREEN_MASK;
window->flags |= oldflags;
return -1;
@@ -2420,11 +2423,11 @@ SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window)
if (!_this->SetWindowModalFor) {
return SDL_Unsupported();
}
return _this->SetWindowModalFor(_this, modal_window, parent_window);
}
int
int
SDL_SetWindowInputFocus(SDL_Window * window)
{
CHECK_WINDOW_MAGIC(window, -1);
@@ -2432,7 +2435,7 @@ SDL_SetWindowInputFocus(SDL_Window * window)
if (!_this->SetWindowInputFocus) {
return SDL_Unsupported();
}
return _this->SetWindowInputFocus(_this, window);
}
@@ -3036,7 +3039,7 @@ SDL_GL_ExtensionSupported(const char *extension)
/* Deduce supported ES profile versions from the supported
ARB_ES*_compatibility extensions. There is no direct query.
This is normally only called when the OpenGL driver supports
{GLX,WGL}_EXT_create_context_es2_profile.
*/

View File

@@ -0,0 +1,227 @@
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_WIIU
/* SDL internals */
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
#include "SDL_loadso.h"
#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include <coreinit/memheap.h>
#include <coreinit/cache.h>
#include <coreinit/memfrmheap.h>
#include <coreinit/screen.h>
#include <string.h>
#define FRAME_HEAP_TAG (0x000DECAF)
static int WIIU_VideoInit(_THIS);
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
static void WIIU_VideoQuit(_THIS);
static void WIIU_PumpEvents(_THIS);
static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch);
static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects);
static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window);
static int WIIU_Available(void) {
return 1;
}
static void WIIU_DeleteDevice(SDL_VideoDevice *device) {
SDL_free(device);
}
static SDL_VideoDevice *WIIU_CreateDevice(int devindex) {
SDL_VideoDevice *device;
device = (SDL_VideoDevice*) SDL_calloc(1, sizeof(SDL_VideoDevice));
if(!device) {
SDL_OutOfMemory();
if(device) {
SDL_free(device);
}
return NULL;
}
device->VideoInit = WIIU_VideoInit;
device->VideoQuit = WIIU_VideoQuit;
device->SetDisplayMode = WIIU_SetDisplayMode;
device->PumpEvents = WIIU_PumpEvents;
device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer;
device->free = WIIU_DeleteDevice;
return device;
}
VideoBootStrap WIIU_bootstrap = {
"WiiU", "Video driver for Nintendo WiiU",
WIIU_Available, WIIU_CreateDevice
};
static int WIIU_VideoInit(_THIS) {
SDL_DisplayMode mode;
OSScreenInit();
mode.format = SDL_PIXELFORMAT_RGBA8888;
mode.w = 1280;
mode.h = 720;
mode.refresh_rate = 60;
mode.driverdata = NULL;
if(SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
SDL_AddDisplayMode(&_this->displays[0], &mode);
return 0;
}
static void WIIU_VideoQuit(_THIS) {
OSScreenShutdown();
}
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) {
return 0;
}
static void WIIU_PumpEvents(_THIS) {
// TODO
}
#define WIIU_DATA "_SDL_WiiUData"
typedef struct {
SDL_Surface *sdl_surface;
void *wiiu_surface;
int wiiu_work_fb;
} WIIU_WindowData;
static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) {
SDL_Surface *surface;
const Uint32 surface_format = SDL_PIXELFORMAT_RGBA8888;
int w, h;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
SDL_GetWindowSize(window, &w, &h);
surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
if(!surface) {
return -1;
}
WIIU_WindowData *data = SDL_calloc(1, sizeof(WIIU_WindowData));
data->sdl_surface = surface;
// Allocate the framebuffers
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
MEMRecordStateForFrmHeap(heap, FRAME_HEAP_TAG);
// Write "Look at the TV Screen" on the gamepad
void *sBufferDRC = MEMAllocFromFrmHeapEx(heap, OSScreenGetBufferSizeEx(SCREEN_DRC), 4);
OSScreenSetBufferEx(SCREEN_DRC, sBufferDRC);
OSScreenClearBufferEx(SCREEN_DRC, 0);
OSScreenPutFontEx(SCREEN_DRC, 0, 0, "Look at the TV Screen.");
DCFlushRange(sBufferDRC, OSScreenGetBufferSizeEx(SCREEN_DRC));
OSScreenFlipBuffersEx(SCREEN_DRC);
OSScreenEnableEx(SCREEN_DRC, 1);
// Allocate the framebuffer (TV will be used)
data->wiiu_work_fb = 1;
data->wiiu_surface = MEMAllocFromFrmHeapEx(heap, OSScreenGetBufferSizeEx(SCREEN_TV), 4);
OSScreenSetBufferEx(SCREEN_TV, data->wiiu_surface);
// Prepare the framebuffer
OSScreenClearBufferEx(SCREEN_TV, 0);
// Flush framebuffer
DCFlushRange(data->wiiu_surface, OSScreenGetBufferSizeEx(SCREEN_TV));
OSScreenFlipBuffersEx(SCREEN_TV);
data->wiiu_work_fb = !data->wiiu_work_fb;
// Enable the framebuffer
OSScreenEnableEx(SCREEN_TV, 1);
// Set surface data
SDL_SetWindowData(window, WIIU_DATA, data);
*format = surface_format;
*pixels = surface->pixels;
*pitch = surface->pitch;
// *hack*: if the window is not in focus joystick events will be
// ignored, so set the focus for the keyboard (actually the wiiu
// just doesn't have windows, so the focus concept doesn't really
// apply)
SDL_SetKeyboardFocus(window);
return 0;
}
static void WIIU_FBCopy(uint32_t *_dst, uint32_t *_src, uint32_t _w, uint32_t _h) {
register uint32_t *src = _src, *dst = _dst;
register uint32_t w = _w, h = _h;
register uint32_t a, b, c, d;
register uint32_t y, *xf;
for(y = 0; y < h; y++) {
xf = dst + w;
do {
a = src[0];
b = src[1];
c = src[2];
d = src[3];
dst[0] = a;
dst[1] = b;
dst[2] = c;
dst[3] = d;
src += 4;
dst += 4;
} while(dst != xf);
dst += 1280 - w;
}
}
static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) {
WIIU_WindowData *data;
data = (WIIU_WindowData*) SDL_GetWindowData(window, WIIU_DATA);
if(!data) {
return SDL_SetError("Couldn't find wiiu data for window");
}
SDL_Surface *sdl_surface = data->sdl_surface;
// Get buffers
uint32_t *src_buffer = (uint32_t *)sdl_surface->pixels;
uint32_t *dst_buffer = (uint32_t *)(data->wiiu_surface + (data->wiiu_work_fb * 1280 * 720 * 4));
WIIU_FBCopy(dst_buffer, src_buffer, sdl_surface->w, sdl_surface->h);
// Flush framebuffer
DCFlushRange(data->wiiu_surface, OSScreenGetBufferSizeEx(SCREEN_TV));
OSScreenFlipBuffersEx(SCREEN_TV);
data->wiiu_work_fb = !data->wiiu_work_fb;
return 0;
}
static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window) {
WIIU_WindowData *data;
data = (WIIU_WindowData*) SDL_GetWindowData(window, WIIU_DATA);
SDL_FreeSurface(data->sdl_surface);
SDL_free(data);
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
OSScreenEnableEx(SCREEN_DRC, 0);
OSScreenEnableEx(SCREEN_TV, 0);
MEMFreeByStateToFrmHeap(heap, FRAME_HEAP_TAG);
}
#endif /* SDL_VIDEO_DRIVER_WIIU */