Compare commits

...

4 Commits

Author SHA1 Message Date
Alberto Mardegan
c467e205b7
Merge 7c224bcd71 into d1b87143bc 2025-07-10 19:50:11 +02:00
Camilla Löwy
d1b87143bc Win32: Remove support for original MinGW
The original MinGW distribution appears to no longer be maintained and
should not be used.  Anyone still using MinGW should consider switching
to the MinGW-w64 fork or another actively maintained toolchain.
MinGW-w64 supports 64-bit binaries and provides much newer compilers and
Win32 headers.

Fixes #2540
2025-07-10 17:59:12 +02:00
Alberto Mardegan
7c224bcd71 WIP: add GameCube & Wii support 2025-01-27 17:24:14 +03:00
Alberto Mardegan
bc0d63cf82 nuklear: fix big-endian image conversion
This has been submitted upstream as well.
2025-01-27 17:24:14 +03:00
35 changed files with 2972 additions and 2898 deletions

View File

@ -29,7 +29,7 @@ for:
only: only:
- GENERATOR: MinGW Makefiles - GENERATOR: MinGW Makefiles
build_script: build_script:
- set PATH=%PATH:C:\Program Files\Git\usr\bin=C:\MinGW\bin% - set PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin=%
- cmake -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% - cmake -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
- cmake --build build - cmake --build build
- -

View File

@ -41,12 +41,6 @@ indent_size = 2
indent_style = tab indent_style = tab
indent_size = unset indent_size = unset
[deps/mingw/*.h]
indent_style = space
indent_size = 4
tab_width = 8
trim_trailing_whitespace = false
[deps/getopt.{c,h}] [deps/getopt.{c,h}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2

View File

@ -24,8 +24,15 @@ if (DEFINED GLFW_USE_WAYLAND AND UNIX AND NOT APPLE)
"GLFW_USE_WAYLAND has been removed; delete the CMake cache and set GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 instead") "GLFW_USE_WAYLAND has been removed; delete the CMake cache and set GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 instead")
endif() endif()
IF(CMAKE_SYSTEM_NAME MATCHES "NintendoWii|NintendoGameCube")
SET(OGC ON)
ELSE()
SET(OGC OFF)
ENDIF()
cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF) cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF)
cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF) cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_OGC "Build support for Nintendo GameCube/Wii" ON "OGC" OFF)
cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF) cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland" ON "UNIX;NOT APPLE" OFF) cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland" ON "UNIX;NOT APPLE" OFF)
@ -49,7 +56,7 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
find_package(Threads REQUIRED) find_package(Threads)
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Report backend selection # Report backend selection

View File

@ -52,7 +52,7 @@ and window system. It does not need any additional headers for context creation
APIs (WGL, GLX, EGL, NSGL, OSMesa) or rendering APIs (OpenGL, OpenGL ES, Vulkan) APIs (WGL, GLX, EGL, NSGL, OSMesa) or rendering APIs (OpenGL, OpenGL ES, Vulkan)
to enable support for them. to enable support for them.
GLFW supports compilation on Windows with Visual C++ 2013 and later, MinGW and GLFW supports compilation on Windows with Visual C++ (2013 and later) and
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
and Clang. It will likely compile in other environments as well, but this is and Clang. It will likely compile in other environments as well, but this is
not regularly tested. not regularly tested.
@ -124,6 +124,7 @@ information on what to include when reporting a bug.
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
the limit of the mouse button tokens to be reported (#2423) the limit of the mouse button tokens to be reported (#2423)
- Updated minimum CMake version to 3.16 (#2541) - Updated minimum CMake version to 3.16 (#2541)
- Removed support for building with original MinGW (#2540)
- [Cocoa] Added `QuartzCore` framework as link-time dependency - [Cocoa] Added `QuartzCore` framework as link-time dependency
- [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506) - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Wayland] Bugfix: The fractional scaling related objects were not destroyed

View File

@ -1,117 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSSTRUCT) && \
!defined(NONAMELESSUNION)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSUNION) && \
!defined(NONAMELESSSTRUCT)
#define NONAMELESSSTRUCT 1
#endif
#if !defined(__GNU_EXTENSION)
#if defined(__GNUC__) || defined(__GNUG__)
#define __GNU_EXTENSION __extension__
#else
#define __GNU_EXTENSION
#endif
#endif /* __extension__ */
#ifndef __ANONYMOUS_DEFINED
#define __ANONYMOUS_DEFINED
#if defined(__GNUC__) || defined(__GNUG__)
#define _ANONYMOUS_UNION __extension__
#define _ANONYMOUS_STRUCT __extension__
#else
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif
#ifndef NONAMELESSUNION
#define _UNION_NAME(x)
#define _STRUCT_NAME(x)
#else /* NONAMELESSUNION */
#define _UNION_NAME(x) x
#define _STRUCT_NAME(x) x
#endif
#endif /* __ANONYMOUS_DEFINED */
#ifndef DUMMYUNIONNAME
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME u
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# define DUMMYUNIONNAME2 u2
# define DUMMYUNIONNAME3 u3
# define DUMMYUNIONNAME4 u4
# define DUMMYUNIONNAME5 u5
# define DUMMYUNIONNAME6 u6
# define DUMMYUNIONNAME7 u7
# define DUMMYUNIONNAME8 u8
# define DUMMYUNIONNAME9 u9
# else /* NONAMELESSUNION */
# define DUMMYUNIONNAME
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# define DUMMYUNIONNAME2
# define DUMMYUNIONNAME3
# define DUMMYUNIONNAME4
# define DUMMYUNIONNAME5
# define DUMMYUNIONNAME6
# define DUMMYUNIONNAME7
# define DUMMYUNIONNAME8
# define DUMMYUNIONNAME9
# endif
#endif /* DUMMYUNIONNAME */
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# else
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# endif
#endif /* DUMMYUNIONNAME1 */
#ifndef DUMMYSTRUCTNAME
# ifdef NONAMELESSUNION
# define DUMMYSTRUCTNAME s
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2 s2
# define DUMMYSTRUCTNAME3 s3
# define DUMMYSTRUCTNAME4 s4
# define DUMMYSTRUCTNAME5 s5
# else
# define DUMMYSTRUCTNAME
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2
# define DUMMYSTRUCTNAME3
# define DUMMYSTRUCTNAME4
# define DUMMYSTRUCTNAME5
# endif
#endif /* DUMMYSTRUCTNAME */
/* These are for compatibility with the Wine source tree */
#ifndef WINELIB_NAME_AW
# ifdef __MINGW_NAME_AW
# define WINELIB_NAME_AW __MINGW_NAME_AW
# else
# ifdef UNICODE
# define WINELIB_NAME_AW(func) func##W
# else
# define WINELIB_NAME_AW(func) func##A
# endif
# endif
#endif /* WINELIB_NAME_AW */
#ifndef DECL_WINELIB_TYPE_AW
# ifdef __MINGW_TYPEDEF_AW
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
# else
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
# endif
#endif /* DECL_WINELIB_TYPE_AW */

2467
deps/mingw/dinput.h vendored

File diff suppressed because it is too large Load Diff

239
deps/mingw/xinput.h vendored
View File

@ -1,239 +0,0 @@
/*
* The Wine project - Xinput Joystick Library
* Copyright 2008 Andrew Fenn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_XINPUT_H
#define __WINE_XINPUT_H
#include <windef.h>
/*
* Bitmasks for the joysticks buttons, determines what has
* been pressed on the joystick, these need to be mapped
* to whatever device you're using instead of an xbox 360
* joystick
*/
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#define XINPUT_GAMEPAD_START 0x0010
#define XINPUT_GAMEPAD_BACK 0x0020
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#define XINPUT_GAMEPAD_A 0x1000
#define XINPUT_GAMEPAD_B 0x2000
#define XINPUT_GAMEPAD_X 0x4000
#define XINPUT_GAMEPAD_Y 0x8000
/*
* Defines the flags used to determine if the user is pushing
* down on a button, not holding a button, etc
*/
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
#define XINPUT_KEYSTROKE_KEYUP 0x0002
#define XINPUT_KEYSTROKE_REPEAT 0x0004
/*
* Defines the codes which are returned by XInputGetKeystroke
*/
#define VK_PAD_A 0x5800
#define VK_PAD_B 0x5801
#define VK_PAD_X 0x5802
#define VK_PAD_Y 0x5803
#define VK_PAD_RSHOULDER 0x5804
#define VK_PAD_LSHOULDER 0x5805
#define VK_PAD_LTRIGGER 0x5806
#define VK_PAD_RTRIGGER 0x5807
#define VK_PAD_DPAD_UP 0x5810
#define VK_PAD_DPAD_DOWN 0x5811
#define VK_PAD_DPAD_LEFT 0x5812
#define VK_PAD_DPAD_RIGHT 0x5813
#define VK_PAD_START 0x5814
#define VK_PAD_BACK 0x5815
#define VK_PAD_LTHUMB_PRESS 0x5816
#define VK_PAD_RTHUMB_PRESS 0x5817
#define VK_PAD_LTHUMB_UP 0x5820
#define VK_PAD_LTHUMB_DOWN 0x5821
#define VK_PAD_LTHUMB_RIGHT 0x5822
#define VK_PAD_LTHUMB_LEFT 0x5823
#define VK_PAD_LTHUMB_UPLEFT 0x5824
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
#define VK_PAD_RTHUMB_UP 0x5830
#define VK_PAD_RTHUMB_DOWN 0x5831
#define VK_PAD_RTHUMB_RIGHT 0x5832
#define VK_PAD_RTHUMB_LEFT 0x5833
#define VK_PAD_RTHUMB_UPLEFT 0x5834
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
/*
* Deadzones are for analogue joystick controls on the joypad
* which determine when input should be assumed to be in the
* middle of the pad. This is a threshold to stop a joypad
* controlling the game when the player isn't touching the
* controls.
*/
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
/*
* Defines what type of abilities the type of joystick has
* DEVTYPE_GAMEPAD is available for all joysticks, however
* there may be more specific identifiers for other joysticks
* which are being used.
*/
#define XINPUT_DEVTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
/*
* These are used with the XInputGetCapabilities function to
* determine the abilities to the joystick which has been
* plugged in.
*/
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
#define XINPUT_FLAG_GAMEPAD 0x00000001
/*
* Defines the status of the battery if one is used in the
* attached joystick. The first two define if the joystick
* supports a battery. Disconnected means that the joystick
* isn't connected. Wired shows that the joystick is a wired
* joystick.
*/
#define BATTERY_DEVTYPE_GAMEPAD 0x00
#define BATTERY_DEVTYPE_HEADSET 0x01
#define BATTERY_TYPE_DISCONNECTED 0x00
#define BATTERY_TYPE_WIRED 0x01
#define BATTERY_TYPE_ALKALINE 0x02
#define BATTERY_TYPE_NIMH 0x03
#define BATTERY_TYPE_UNKNOWN 0xFF
#define BATTERY_LEVEL_EMPTY 0x00
#define BATTERY_LEVEL_LOW 0x01
#define BATTERY_LEVEL_MEDIUM 0x02
#define BATTERY_LEVEL_FULL 0x03
/*
* How many joysticks can be used with this library. Games that
* use the xinput library will not go over this number.
*/
#define XUSER_MAX_COUNT 4
#define XUSER_INDEX_ANY 0x000000FF
/*
* Defines the structure of an xbox 360 joystick.
*/
typedef struct _XINPUT_GAMEPAD {
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
typedef struct _XINPUT_STATE {
DWORD dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
} XINPUT_STATE, *PXINPUT_STATE;
/*
* Defines the structure of how much vibration is set on both the
* right and left motors in a joystick. If you're not using a 360
* joystick you will have to map these to your device.
*/
typedef struct _XINPUT_VIBRATION {
WORD wLeftMotorSpeed;
WORD wRightMotorSpeed;
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
/*
* Defines the structure for what kind of abilities the joystick has
* such abilities are things such as if the joystick has the ability
* to send and receive audio, if the joystick is in fact a driving
* wheel or perhaps if the joystick is some kind of dance pad or
* guitar.
*/
typedef struct _XINPUT_CAPABILITIES {
BYTE Type;
BYTE SubType;
WORD Flags;
XINPUT_GAMEPAD Gamepad;
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
/*
* Defines the structure for a joystick input event which is
* retrieved using the function XInputGetKeystroke
*/
typedef struct _XINPUT_KEYSTROKE {
WORD VirtualKey;
WCHAR Unicode;
WORD Flags;
BYTE UserIndex;
BYTE HidCode;
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
typedef struct _XINPUT_BATTERY_INFORMATION
{
BYTE BatteryType;
BYTE BatteryLevel;
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
#ifdef __cplusplus
extern "C" {
#endif
void WINAPI XInputEnable(WINBOOL);
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
#ifdef __cplusplus
}
#endif
#endif /* __WINE_XINPUT_H */

12
deps/nuklear.h vendored
View File

@ -12988,7 +12988,7 @@ nk_font_bake_convert(void *out_memory, int img_width, int img_height,
const void *in_memory) const void *in_memory)
{ {
int n = 0; int n = 0;
nk_rune *dst; nk_byte *dst;
const nk_byte *src; const nk_byte *src;
NK_ASSERT(out_memory); NK_ASSERT(out_memory);
@ -12997,10 +12997,14 @@ nk_font_bake_convert(void *out_memory, int img_width, int img_height,
NK_ASSERT(img_height); NK_ASSERT(img_height);
if (!out_memory || !in_memory || !img_height || !img_width) return; if (!out_memory || !in_memory || !img_height || !img_width) return;
dst = (nk_rune*)out_memory; dst = (nk_byte*)out_memory;
src = (const nk_byte*)in_memory; src = (const nk_byte*)in_memory;
for (n = (int)(img_width * img_height); n > 0; n--) for (n = (int)(img_width * img_height); n > 0; n--) {
*dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF; *dst++ = 0xff; // r
*dst++ = 0xff; // g
*dst++ = 0xff; // b
*dst++ = *src++; // a
}
} }
/* ------------------------------------------------------------- /* -------------------------------------------------------------

28
deps/tinycthread.c vendored
View File

@ -40,6 +40,8 @@ freely, subject to the following restrictions:
#elif defined(_TTHREAD_WIN32_) #elif defined(_TTHREAD_WIN32_)
#include <process.h> #include <process.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#endif #endif
/* Standard, good-to-have defines */ /* Standard, good-to-have defines */
@ -60,6 +62,8 @@ int mtx_init(mtx_t *mtx, int type)
mtx->mRecursive = type & mtx_recursive; mtx->mRecursive = type & mtx_recursive;
InitializeCriticalSection(&mtx->mHandle); InitializeCriticalSection(&mtx->mHandle);
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
int ret; int ret;
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -78,6 +82,7 @@ void mtx_destroy(mtx_t *mtx)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
DeleteCriticalSection(&mtx->mHandle); DeleteCriticalSection(&mtx->mHandle);
#elif defined(_TTHREAD_OGC_)
#else #else
pthread_mutex_destroy(mtx); pthread_mutex_destroy(mtx);
#endif #endif
@ -93,6 +98,8 @@ int mtx_lock(mtx_t *mtx)
mtx->mAlreadyLocked = TRUE; mtx->mAlreadyLocked = TRUE;
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -116,6 +123,8 @@ int mtx_trylock(mtx_t *mtx)
ret = thrd_busy; ret = thrd_busy;
} }
return ret; return ret;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
#endif #endif
@ -127,6 +136,8 @@ int mtx_unlock(mtx_t *mtx)
mtx->mAlreadyLocked = FALSE; mtx->mAlreadyLocked = FALSE;
LeaveCriticalSection(&mtx->mHandle); LeaveCriticalSection(&mtx->mHandle);
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
#endif #endif
@ -161,6 +172,8 @@ int cnd_init(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -178,6 +191,7 @@ void cnd_destroy(cnd_t *cond)
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
} }
DeleteCriticalSection(&cond->mWaitersCountLock); DeleteCriticalSection(&cond->mWaitersCountLock);
#elif defined(_TTHREAD_OGC_)
#else #else
pthread_cond_destroy(cond); pthread_cond_destroy(cond);
#endif #endif
@ -203,6 +217,8 @@ int cnd_signal(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -228,6 +244,8 @@ int cnd_broadcast(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -286,6 +304,8 @@ int cnd_wait(cnd_t *cond, mtx_t *mtx)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
return _cnd_timedwait_win32(cond, mtx, INFINITE); return _cnd_timedwait_win32(cond, mtx, INFINITE);
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -303,6 +323,8 @@ int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
} }
else else
return thrd_error; return thrd_error;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
int ret; int ret;
ret = pthread_cond_timedwait(cond, mtx, ts); ret = pthread_cond_timedwait(cond, mtx, ts);
@ -324,14 +346,14 @@ typedef struct {
/* Thread wrapper function. */ /* Thread wrapper function. */
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
static unsigned WINAPI _thrd_wrapper_function(void * aArg) static unsigned WINAPI _thrd_wrapper_function(void * aArg)
#elif defined(_TTHREAD_POSIX_) #else
static void * _thrd_wrapper_function(void * aArg) static void * _thrd_wrapper_function(void * aArg)
#endif #endif
{ {
thrd_start_t fun; thrd_start_t fun;
void *arg; void *arg;
int res; int res;
#if defined(_TTHREAD_POSIX_) #if defined(_TTHREAD_POSIX_) || defined(_TTHREAD_OGC_)
void *pres; void *pres;
#endif #endif
@ -394,6 +416,8 @@ thrd_t thrd_current(void)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
return GetCurrentThread(); return GetCurrentThread();
#elif defined(_TTHREAD_OGC_)
return LWP_GetSelf();
#else #else
return pthread_self(); return pthread_self();
#endif #endif

6
deps/tinycthread.h vendored
View File

@ -51,6 +51,8 @@ freely, subject to the following restrictions:
#if !defined(_TTHREAD_PLATFORM_DEFINED_) #if !defined(_TTHREAD_PLATFORM_DEFINED_)
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define _TTHREAD_WIN32_ #define _TTHREAD_WIN32_
#elif defined(GEKKO)
#define _TTHREAD_OGC_
#else #else
#define _TTHREAD_POSIX_ #define _TTHREAD_POSIX_
#endif #endif
@ -80,6 +82,8 @@ freely, subject to the following restrictions:
#if defined(_TTHREAD_POSIX_) #if defined(_TTHREAD_POSIX_)
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <pthread.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#elif defined(_TTHREAD_WIN32_) #elif defined(_TTHREAD_WIN32_)
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -313,6 +317,8 @@ int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
/* Thread */ /* Thread */
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
typedef HANDLE thrd_t; typedef HANDLE thrd_t;
#elif defined(_TTHREAD_OGC_)
typedef lwp_t thrd_t;
#else #else
typedef pthread_t thrd_t; typedef pthread_t thrd_t;
#endif #endif

View File

@ -36,9 +36,9 @@ specific to GLFW. It may be a useful companion to this one.
### Installing dependencies {#compile_deps} ### Installing dependencies {#compile_deps}
The C/C++ development environments in Visual Studio, Xcode and MinGW come with The C/C++ development environments in Visual Studio, Xcode and MinGW-w64 come
all necessary dependencies for compiling GLFW, but on Unix-like systems like with all necessary dependencies for compiling GLFW, but on Unix-like systems
Linux and FreeBSD you will need a few extra packages. like Linux and FreeBSD you will need a few extra packages.
#### Dependencies for Wayland and X11 {#compile_deps_wayland} #### Dependencies for Wayland and X11 {#compile_deps_wayland}
@ -180,7 +180,7 @@ cd path/to/build
make make
``` ```
With MinGW, it is `mingw32-make`. With MinGW-w64, it is `mingw32-make`.
```sh ```sh
cd path/to/build cd path/to/build
@ -299,12 +299,12 @@ library. This option is only available when compiling for Linux and other Unix-
systems other than macOS. This is enabled by default. systems other than macOS. This is enabled by default.
## Cross-compilation with CMake and MinGW {#compile_mingw_cross} ## Cross-compilation with CMake and MinGW-w64 {#compile_mingw_cross}
Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For Both Cygwin and many Linux distributions have MinGW-w64 packages. For example,
example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages for 32- and
for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives like Ubuntu
like Ubuntu have the `mingw-w64` package for both. have the `mingw-w64` package for both.
GLFW has CMake toolchain files in the `CMake` subdirectory that set up GLFW has CMake toolchain files in the `CMake` subdirectory that set up
cross-compilation of Windows binaries. To use these files you set the cross-compilation of Windows binaries. To use these files you set the
@ -315,9 +315,9 @@ configuring and generating the build files.
cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=path/to/file cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=path/to/file
``` ```
The exact toolchain file to use depends on the prefix used by the MinGW or The exact toolchain file to use depends on the prefix used by the MinGW-w64
MinGW-w64 binaries on your system. You can usually see this in the /usr binaries on your system. You can usually see this in the /usr directory. For
directory. For example, both the Ubuntu and Cygwin MinGW-w64 packages have example, both the Ubuntu and Cygwin MinGW-w64 packages have
`/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct invocation `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct invocation
would be: would be:

View File

@ -621,11 +621,11 @@ The format of the string is as follows:
- The names of the always supported context creation APIs EGL and OSMesa - The names of the always supported context creation APIs EGL and OSMesa
- Any additional compile-time options, APIs and (on Windows) what compiler was used - Any additional compile-time options, APIs and (on Windows) what compiler was used
For example, compiling GLFW 3.5 with MinGW as a DLL for Windows, may result in a version string For example, compiling GLFW 3.5 with MinGW-64 as a DLL for Windows, may result
like this: in a version string like this:
```c ```c
3.5.0 Win32 WGL Null EGL OSMesa MinGW DLL 3.5.0 Win32 WGL Null EGL OSMesa MinGW-w64 DLL
``` ```
Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may

View File

@ -20,6 +20,15 @@ this.
## Removals {#removals} ## Removals {#removals}
### Original MinGW support has been removed {#original_mingw}
Support for the now unmaintained original MinGW distribution has been removed.
This does not apply to the much more capable [MinGW-w64](https://www.mingw-w64.org/),
which remains fully supported. MinGW-w64 can build both 32- and 64-bit binaries, is
actively maintained and available on many platforms.
## New symbols {#new_symbols} ## New symbols {#new_symbols}
### New functions {#new_functions} ### New functions {#new_functions}

View File

@ -37,7 +37,9 @@ add_executable(triangle-opengles WIN32 MACOSX_BUNDLE triangle-opengles.c ${ICON}
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL}) add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
if (Threads_FOUND)
target_link_libraries(particles Threads::Threads) target_link_libraries(particles Threads::Threads)
endif()
if (RT_LIBRARY) if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}") target_link_libraries(particles "${RT_LIBRARY}")
endif() endif()

View File

@ -1342,6 +1342,7 @@ extern "C" {
#define GLFW_PLATFORM_WAYLAND 0x00060003 #define GLFW_PLATFORM_WAYLAND 0x00060003
#define GLFW_PLATFORM_X11 0x00060004 #define GLFW_PLATFORM_X11 0x00060004
#define GLFW_PLATFORM_NULL 0x00060005 #define GLFW_PLATFORM_NULL 0x00060005
#define GLFW_PLATFORM_OGC 0x00060006
/*! @} */ /*! @} */
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1

View File

@ -15,6 +15,9 @@ if (APPLE)
elseif (WIN32) elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c
win32_time.c win32_thread.c) win32_time.c win32_thread.c)
elseif (OGC)
target_sources(glfw PRIVATE ogc_time.h ogc_thread.h ogc_module.c
ogc_time.c ogc_thread.c)
else() else()
target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c
posix_time.c posix_thread.c) posix_time.c posix_thread.c)
@ -57,6 +60,13 @@ if (GLFW_BUILD_WAYLAND)
wl_monitor.c wl_window.c) wl_monitor.c wl_window.c)
endif() endif()
if (GLFW_BUILD_OGC)
target_compile_definitions(glfw PRIVATE _GLFW_OGC)
target_sources(glfw PRIVATE ogc_platform.h ogc_init.c ogc_joystick.c
ogc_monitor.c ogc_window.c ogc_context.c
ogc_cursor.h)
endif()
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND) if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c) target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
@ -136,7 +146,9 @@ target_include_directories(glfw PUBLIC
target_include_directories(glfw PRIVATE target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src" "${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src") "${GLFW_BINARY_DIR}/src")
if (Threads_FOUND)
target_link_libraries(glfw PRIVATE Threads::Threads) target_link_libraries(glfw PRIVATE Threads::Threads)
endif()
if (GLFW_BUILD_WIN32) if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32") list(APPEND glfw_PKG_LIBS "-lgdi32")
@ -213,6 +225,13 @@ if (GLFW_BUILD_X11)
target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}") target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}")
endif() endif()
if (GLFW_BUILD_OGC)
include(FindPkgConfig)
pkg_check_modules(Opengx REQUIRED IMPORTED_TARGET opengl)
target_link_libraries(glfw PRIVATE PkgConfig::Opengx wiikeyboard fat)
endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_library(RT_LIBRARY rt) find_library(RT_LIBRARY rt)
mark_as_advanced(RT_LIBRARY) mark_as_advanced(RT_LIBRARY)
@ -255,24 +274,6 @@ if (GLFW_BUILD_WIN32)
target_compile_definitions(glfw PRIVATE UNICODE _UNICODE) target_compile_definitions(glfw PRIVATE UNICODE _UNICODE)
endif() endif()
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
# the inclusion of stddef.h (by glfw3.h), which is itself included before
# win32_platform.h. We define them here until a saner solution can be found
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
if (MINGW)
target_compile_definitions(glfw PRIVATE WINVER=0x0501)
endif()
# Workaround for legacy MinGW not providing XInput and DirectInput
if (MINGW)
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
check_include_file(xinput.h XINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw")
endif()
endif()
# Workaround for the MS CRT deprecating parts of the standard library # Workaround for the MS CRT deprecating parts of the standard library
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC") if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
@ -286,10 +287,6 @@ endif()
if (GLFW_BUILD_SHARED_LIBRARY) if (GLFW_BUILD_SHARED_LIBRARY)
if (WIN32) if (WIN32)
if (MINGW) if (MINGW)
# Remove the dependency on the shared version of libgcc
# NOTE: MinGW-w64 has the correct default but MinGW needs this
target_link_libraries(glfw PRIVATE "-static-libgcc")
# Remove the lib prefix on the DLL (but not the import library) # Remove the lib prefix on the DLL (but not the import library)
set_target_properties(glfw PROPERTIES PREFIX "") set_target_properties(glfw PROPERTIES PREFIX "")

View File

@ -997,5 +997,13 @@ const char* _glfwDefaultMappings[] =
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
#endif // GLFW_BUILD_LINUX_JOYSTICK #endif // GLFW_BUILD_LINUX_JOYSTICK
#if defined(_GLFW_OGC)
"05002bf87e0500000105000001000000,Nintendo Wiimote 1,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500ea387e0500000106000001000000,Nintendo Wiimote 2,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500aa397e0500000107000001000000,Nintendo Wiimote 3,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"05006bf97e0500000108000001000000,Nintendo Wiimote 4,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500b98e7e0500000305000001000000,Nintendo Wii Classic 1,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
#endif
}; };

View File

@ -78,5 +78,9 @@ const char* _glfwDefaultMappings[] =
#if defined(GLFW_BUILD_LINUX_JOYSTICK) #if defined(GLFW_BUILD_LINUX_JOYSTICK)
@GLFW_LINUX_MAPPINGS@ @GLFW_LINUX_MAPPINGS@
#endif // GLFW_BUILD_LINUX_JOYSTICK #endif // GLFW_BUILD_LINUX_JOYSTICK
#if defined(_GLFW_OGC)
"05002bf87e0500000105000001000000,Nintendo Wiimote,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
#endif
}; };

204
src/ogc_context.c Normal file
View File

@ -0,0 +1,204 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <opengx.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
#ifdef __wii__
static void drawCursorRect(_GLFWcursor* cursor)
{
short xhot = cursor->ogc.xhot;
short yhot = cursor->ogc.yhot;
u16 width = GX_GetTexObjWidth(&cursor->ogc.texobj);
u16 height = GX_GetTexObjHeight(&cursor->ogc.texobj);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(-xhot, -yhot);
GX_TexCoord2u8(0, 0);
GX_Position2s16(width - xhot, -yhot);
GX_TexCoord2u8(1, 0);
GX_Position2s16(width - xhot, height - yhot);
GX_TexCoord2u8(1, 1);
GX_Position2s16(-xhot, height - yhot);
GX_TexCoord2u8(0, 1);
GX_End();
}
static void drawCursor(_GLFWwindow* window)
{
Mtx44 proj;
Mtx mv;
_GLFWcursor* cursor = window->ogc.currentCursor;
if (!cursor) return;
GX_LoadTexObj(&cursor->ogc.texobj, GX_TEXMAP0);
int width = window->ogc.width;
int height = window->ogc.height;
guOrtho(proj, 0, height, 0, width, 0, 1);
GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC);
guMtxIdentity(mv);
guMtxScaleApply(mv, mv,
width / 640.0f,
height / 480.0f, 1.0f);
if (cursor->ogc.canRotate) {
Mtx rot;
float angle;
WPADData *data = WPAD_Data(0);
angle = data->ir.angle;
guMtxRotDeg(rot, 'z', angle);
guMtxConcat(mv, rot, mv);
}
guMtxTransApply(mv, mv,
window->virtualCursorPosX,
window->virtualCursorPosY, 0);
GX_LoadPosMtxImm(mv, GX_PNMTX1);
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetNumTevStages(1);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetNumTexGens(1);
GX_SetCurrentMtx(GX_PNMTX1);
GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_FALSE);
GX_SetScissor(0, 0, width, height);
drawCursorRect(cursor);
GX_SetCurrentMtx(GX_PNMTX0);
GX_DrawDone();
}
#endif // __wii__
static void makeContextCurrentOgc(_GLFWwindow* window)
{
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static GLFWglproc getProcAddressOgc(const char* procname)
{
return (GLFWglproc) ogx_get_proc_address(procname);
}
static void destroyContextOgc(_GLFWwindow* window)
{
}
static void swapBuffersOgc(_GLFWwindow* window)
{
void *xfb;
u8 mustClear, mustWait;
if (ogx_prepare_swap_buffers() < 0) return;
#ifdef __wii__
if (window->ogc.hovered &&
(window->callbacks.mouseButton || window->callbacks.cursorPos))
drawCursor(window);
#endif // __wii__
if (window->doublebuffer) {
mustClear = GX_TRUE;
mustWait = GX_TRUE;
xfb = _glfw.ogc.xfb[_glfw.ogc.fbIndex];
_glfw.ogc.fbIndex ^= 1;
} else {
mustClear = GX_FALSE;
mustWait = GX_FALSE;
xfb = _glfw.ogc.xfb[0];
}
GX_CopyDisp(xfb, mustClear);
GX_DrawDone();
GX_Flush();
VIDEO_SetNextFramebuffer(xfb);
VIDEO_Flush();
if (mustWait)
VIDEO_WaitVSync();
}
static void swapIntervalOgc(int interval)
{
// No swap interval on Ogc
}
static int extensionSupportedOgc(const char* extension)
{
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
return strstr(extensions, extensions) != NULL;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateContextOgc(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Ogc: OpenGL ES is not available on Ogc");
return GLFW_FALSE;
}
ogx_enable_double_buffering(fbconfig->doublebuffer);
if (fbconfig->stencilBits > 0) {
OgxStencilFlags stencilFlags = OGX_STENCIL_NONE;
if (fbconfig->stencilBits > 4) stencilFlags |= OGX_STENCIL_8BIT;
ogx_stencil_create(stencilFlags);
}
window->context.makeCurrent = makeContextCurrentOgc;
window->context.swapBuffers = swapBuffersOgc;
window->context.swapInterval = swapIntervalOgc;
window->context.extensionSupported = extensionSupportedOgc;
window->context.getProcAddress = getProcAddressOgc;
window->context.destroy = destroyContextOgc;
return GLFW_TRUE;
}

487
src/ogc_cursor.h Normal file
View File

@ -0,0 +1,487 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <gctypes.h>
typedef struct {
u16 width;
u16 height;
u8 hot_x;
u8 hot_y;
u8 bytes_per_pixel;
u8 pixel_data[];
} _GLFWcursorDataOgc;
static const _GLFWcursorDataOgc OGC_cursor_hand = {
37, 52, 11, 0, 4,
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000Q\000"
"\000\000\262\000\000\000\337\000\000\000\345\000\000\000\313\000\000\000\203\000\000\000\032\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005"
"\000\000\000\224\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000"
"\000\000\330\000\000\000\062\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\177\000\000\000\377\000\000\000\377\026\026\026\377bbb\377ttt\377"
"<<<\377\000\000\000\377\000\000\000\377\000\000\000\334\000\000\000\030\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%\000\000\000\364\000\000\000\377...\377\327\327"
"\327\377\377\377\377\377\377\377\377\377\373\373\373\377\177\177\177\377"
"\000\000\000\377\000\000\000\377\000\000\000\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000n\000\000\000\377\005\005\005\377\277\277\277\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377BBB\377\000"
"\000\000\377\000\000\000\323\000\000\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\225\000\000\000\377###\377\366\366\366\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\206\206\206\377\000\000"
"\000\377\000\000\000\356\000\000\000\033\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\231\000\000\000\377+++\377\370\370\370\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\217\217\217\377\000\000\000\377"
"\000\000\000\361\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\230\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000"
"\000\000\360\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230"
"\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000"
"\360\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000"
"\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360"
"\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000"
"\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000"
"\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377"
"***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000\000\037"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377"
"\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000\000\037\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367"
"\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\357\000\000\000\026\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367\367"
"\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\370\000\000\000\244\000\000\000\223"
"\000\000\000e\000\000\000\032\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367\367"
"\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377\000\000\000\340\000\000\000Z\000\000\000\000\000\000\000\003\000\000\000\022\000\000\000\006\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367"
"\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\215\215\215\377\000\000\000\377\001\001\001\377%%%\377\036\036\036"
"\377\000\000\000\377\000\000\000\377\000\000\000\373\000\000\000\244\000\000\000\310\000\000\000\341\000\000\000\320"
"\000\000\000\220\000\000\000*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000"
"\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\210\210\210\377\022\022\022\377\270\270\270"
"\377\356\356\356\377\351\351\351\377\236\236\236\377\022\022\022\377\000\000\000\377"
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\357\000\000\000[\000\000\000"
"\030\000\000\000<\000\000\000B\000\000\000(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\227\000\000\000\377***\377\367\367\367\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\202\202\202\377\065\065\065\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\246\246\246\377\001\001\001\377\003\003\003\377@@@\377iii\377DD"
"D\377\002\002\002\377\000\000\000\377\000\000\000\372\000\000\000\342\000\000\000\375\000\000\000\377\000\000\000\360"
"\000\000\000\264\000\000\000:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\233\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061"
"\377\375\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\372"
"\372\372\377\036\036\036\377kkk\377\375\375\375\377\377\377\377\377\377\377"
"\377\377\253\253\253\377\015\015\015\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000"
"\377\000\000\000\377\000\000\000\377\000\000\000\366\000\000\000U\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016"
"\000\000\000n\000\000\000\272\000\000\000\360\000\000\000\377***\377\367\367\367\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\203"
"\203\203\377\061\061\061\377\375\375\375\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\376\376\376\377\063\063\063\377\211\211\211\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\177\177\177\377\000\000"
"\000\377AAA\377\236\236\236\377\256\256\256\377lll\377\011\011\011\377\000\000\000\377"
"\000\000\000\360\000\000\000)\000\000\000\000\000\000\000!\000\000\000\304\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061\377\375"
"\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375"
"\377\061\061\061\377\203\203\203\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\304\304\304\377\011\011\011\377\327\327\327\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\247\247\247\377\006\006\006\377\000"
"\000\000\377\000\000\000\225\000\000\000\016\000\000\000\312\000\000\000\377\000\000\000\377(((\377aaa\377\067"
"\067\067\377'''\377\366\366\366\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061\377\375"
"\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375"
"\377\061\061\061\377\203\203\203\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\313\313\313\377\015\015\015\377\323\323\323\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377NNN\377\000\000\000"
"\377\000\000\000\324\000\000\000s\000\000\000\377\000\000\000\377fff\377\357\357\357\377\377\377"
"\377\377\244\244\244\377###\377\365\365\365\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377|||\377&&&\377\375\375"
"\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375\377"
"&&&\377|||\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\306\306\306\377\001\001\001\377\317\317\317\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\200\200\200\377\000\000\000\377\000\000\000\345"
"\000\000\000\305\000\000\000\377\062\062\062\377\371\371\371\377\377\377\377\377\377\377"
"\377\377\235\235\235\377###\377\365\365\365\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\274\274\274\377\221"
"\221\221\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\376\376\376\377\221\221\221\377\274\274\274\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\342\342\340\377\200\200\200"
"\377\347\347\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\202\202\202\377\000\000\000\377\000\000\000\345\000\000\000\342\000\000\000\377www\377"
"\377\377\377\377\376\376\376\377\377\377\377\377\235\235\235\377!##\377\365"
"\365\365\377\377\377\377\377\374\376\376\377\374\376\376\377\374\376\376"
"\377\374\376\376\377\377\377\377\377\377\377\377\377\374\376\376\377\374"
"\376\376\377\374\376\376\377\374\376\376\377\374\376\376\377\377\377\377"
"\377\377\377\377\377\374\376\376\377\374\376\376\377\374\376\376\377\374"
"\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\374\376\376"
"\377\374\376\376\377\374\376\376\377\377\377\377\377\201\201\201\377\000\000"
"\000\377\000\000\000\345\000\000\000\346\000\000\000\377\203\203\203\377\377\377\377\377\375"
"\373\375\377\377\377\377\377\233\233\235\377!!#\377\363\363\365\377\377\377"
"\377\377\373\373\376\377\373\373\376\377\373\373\376\377\373\373\376\377"
"\373\373\376\377\373\373\376\377\373\373\376\377\373\373\375\377\373\373"
"\376\377\373\373\376\377\373\373\376\377\373\373\375\377\373\373\376\377"
"\373\373\376\377\373\373\376\377\373\373\376\377\373\373\376\377\373\373"
"\376\377\373\373\375\377\373\373\375\377\373\373\375\377\373\373\376\377"
"\373\374\376\377\377\377\377\377\201\201\201\377\000\000\000\377\000\000\000\345\000\000"
"\000\345\000\000\000\377\177\201\201\377\377\377\377\377\371\373\376\377\377\377"
"\377\377\233\233\235\377\"\"\"\377\361\363\366\377\375\377\377\377\371\373"
"\376\377\371\373\376\377\371\373\376\377\367\372\376\377\367\372\376\377"
"\371\371\376\377\371\371\376\377\371\373\376\377\371\373\376\377\371\373"
"\376\377\371\373\376\377\367\372\376\377\367\372\376\377\371\373\376\377"
"\367\372\376\377\367\372\376\377\371\373\376\377\367\372\376\377\371\373"
"\376\377\371\373\376\377\367\372\376\377\367\372\376\377\371\373\376\377"
"\377\377\377\377\177\201\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377"
"\177\177\201\377\377\377\377\377\365\370\377\377\377\377\377\377\234\234"
"\234\377\"\"\"\377\356\361\365\377\372\375\377\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377"
"\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377"
"\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\366\371\376\377\377\377\377\377"
"\177\177\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377}\200\202\377\377"
"\377\377\377\363\366\375\377\377\377\377\377\232\234\234\377\"\"\"\377\355"
"\357\364\377\370\372\377\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363"
"\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363"
"\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\364\367\376\377\377\377\377\377~\177\201\377\000\000\000\377"
"\000\000\000\345\000\000\000\345\000\000\000\377|~\201\377\377\377\377\377\357\362\374\377"
"\377\377\377\377\231\232\234\377\"\"\"\377\352\355\364\377\364\370\377\377"
"\357\362\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\362"
"\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364\374\377"
"\357\362\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364"
"\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364\374\377"
"\357\364\374\377\357\364\374\377\357\362\374\377\357\364\374\377\360\363"
"\375\377\377\377\377\377|~\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377"
"z|\201\377\377\377\377\377\353\360\374\377\375\377\377\377\230\232\235\377"
"\"\"\"\377\347\352\364\377\360\364\377\377\353\360\374\377\355\360\374\377"
"\355\360\374\377\355\360\374\377\353\360\374\377\355\360\374\377\353\360"
"\374\377\353\360\374\377\353\360\374\377\355\360\374\377\355\360\374\377"
"\355\360\374\377\355\362\374\377\355\360\374\377\353\360\374\377\353\360"
"\374\377\355\360\374\377\353\360\374\377\355\360\374\377\355\360\374\377"
"\355\360\374\377\353\360\374\377\355\362\374\377\377\377\377\377z|\201\377"
"\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377y{\201\377\377\377\377\377\351\356"
"\372\377\373\377\377\377\220\223\230\377\026\026\026\377\344\351\363\377\353"
"\362\377\377\350\357\374\377\350\357\372\377\350\357\372\377\350\357\374"
"\377\350\357\374\377\350\357\372\377\350\357\374\377\350\357\372\377\350"
"\357\372\377\350\357\374\377\350\357\374\377\350\357\374\377\350\357\372"
"\377\350\357\372\377\350\357\372\377\350\357\374\377\350\357\374\377\350"
"\357\372\377\350\357\372\377\350\357\372\377\350\357\372\377\350\357\372"
"\377\351\360\373\377\377\377\377\377y{\201\377\000\000\000\377\000\000\000\345\000\000\000"
"\345\000\000\000\377xz\200\377\375\377\377\377\346\354\373\377\352\362\376\377"
"\304\313\325\377\226\233\243\377\343\353\370\377\345\355\374\377\345\355"
"\372\377\345\355\372\377\345\353\372\377\345\353\372\377\345\355\372\377"
"\345\355\372\377\345\353\372\377\345\353\372\377\345\353\372\377\345\355"
"\372\377\345\355\372\377\345\353\372\377\345\353\372\377\345\353\372\377"
"\345\353\372\377\345\353\372\377\345\353\372\377\345\353\372\377\345\353"
"\372\377\345\353\372\377\345\353\372\377\345\353\372\377\344\354\373\377"
"\375\377\377\377xz\200\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377ux\201"
"\377\373\377\377\377\342\352\373\377\340\350\371\377\350\360\377\377\362"
"\370\377\377\341\351\373\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341"
"\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341"
"\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\342\352\373\377\373\377\377\377ux\201"
"\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377ty\200\377\367\375\377\377\336"
"\346\372\377\334\346\372\377\334\346\372\377\334\346\370\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335"
"\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\335\345\371\377\334\346\372\377\335"
"\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\334\346\372\377\335\345\371\377\335"
"\345\371\377\335\347\373\377\367\375\377\377ty\200\377\000\000\000\377\000\000\000\345"
"\000\000\000\345\000\000\000\377sx\200\377\366\373\377\377\334\344\372\377\331\344\370"
"\377\330\343\371\377\331\344\370\377\330\343\371\377\330\343\371\377\331"
"\344\370\377\331\344\370\377\331\344\370\377\331\344\370\377\330\343\371"
"\377\331\344\370\377\331\344\370\377\331\344\370\377\331\344\370\377\331"
"\344\370\377\330\343\371\377\330\343\371\377\330\343\371\377\331\344\370"
"\377\331\344\370\377\331\344\370\377\330\343\371\377\330\342\371\377\331"
"\344\370\377\331\343\370\377\331\344\370\377\331\343\370\377\334\344\370"
"\377\366\373\377\377sx\200\377\000\000\000\377\000\000\000\345\000\000\000\346\000\000\000\377QV"
"[\377\365\373\377\377\334\346\372\377\325\341\370\377\325\337\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\324\341\370\377\324\341\370\377\334\346\372\377\365\373\377\377PU\\"
"\377\000\000\000\377\000\000\000\346\000\000\000\314\000\000\000\377\012\012\014\377\254\264\301\377"
"\362\370\377\377\325\341\370\377\321\335\367\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\320\335\370\377\320\335\370\377\320\335\370\377"
"\320\335\370\377\320\335\370\377\321\335\367\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\320\335\370\377\320\335\370\377\321\335\367\377"
"\321\335\367\377\320\335\370\377\320\335\370\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\321\335\367\377\320\335\370\377\321\335\367\377"
"\326\340\371\377\362\370\377\377\254\264\301\377\012\012\014\377\000\000\000\377\000"
"\000\000\314\000\000\000d\000\000\000\377\000\000\000\377\024\025\027\377\262\274\314\377\355\365"
"\377\377\323\336\367\377\315\334\366\377\315\334\366\377\314\333\367\377"
"\315\334\366\377\314\333\367\377\314\333\367\377\314\333\367\377\314\333"
"\367\377\316\333\367\377\314\333\367\377\314\333\367\377\315\334\366\377"
"\315\334\366\377\315\334\366\377\316\333\367\377\316\333\367\377\314\333"
"\367\377\314\333\367\377\315\334\366\377\315\334\366\377\314\333\367\377"
"\314\333\367\377\314\333\367\377\323\340\367\377\356\365\377\377\262\274"
"\314\377\024\025\027\377\000\000\000\377\000\000\000\377\000\000\000d\000\000\000\002\000\000\000\220\000\000\000"
"\377\000\000\000\377\025\027\032\377\261\273\315\377\352\362\377\377\317\333\367\377"
"\311\326\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330"
"\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377"
"\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330"
"\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377"
"\311\330\366\377\311\330\366\377\311\330\366\377\317\333\367\377\352\362"
"\377\377\261\271\315\377\025\027\032\377\000\000\000\377\000\000\000\377\000\000\000\220\000\000\000"
"\002\000\000\000\000\000\000\000\002\000\000\000\224\000\000\000\377\000\000\000\377\025\030\032\377\257\272\320"
"\377\346\356\377\377\313\330\366\377\305\325\365\377\305\324\365\377\305"
"\324\365\377\305\325\365\377\305\324\365\377\305\324\365\377\305\325\365"
"\377\305\325\365\377\305\324\365\377\305\325\365\377\305\325\365\377\305"
"\324\365\377\305\325\365\377\305\325\365\377\305\325\365\377\305\325\365"
"\377\305\325\365\377\305\324\365\377\305\324\365\377\313\332\366\377\346"
"\356\377\377\257\272\320\377\025\027\032\377\000\000\000\377\000\000\000\377\000\000\000\224\000"
"\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\235\000\000\000\377\000\000\000\377\031\032"
"\034\377\267\304\335\377\327\345\377\377\307\326\365\377\302\322\365\377\302"
"\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365"
"\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302"
"\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365"
"\377\302\322\365\377\302\322\365\377\305\326\367\377\327\343\377\377\267"
"\304\335\377\031\032\034\377\000\000\000\377\000\000\000\377\000\000\000\235\000\000\000\004\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\241\000\000\000\377\000\000\000\377GJV\377"
"\327\345\377\377\311\330\367\377\275\317\365\377\276\317\365\377\276\320"
"\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377"
"\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320"
"\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377"
"\275\317\365\377\311\330\367\377\326\345\377\377GJV\377\000\000\000\377\000\000\000\377"
"\000\000\000\241\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\011\000\000\000\313\000\000\000\377\015\015\017\377\270\305\341\377\312\334\374"
"\377\271\315\364\377\272\314\364\377\272\316\364\377\272\316\364\377\272"
"\316\364\377\272\316\364\377\272\316\364\377\272\316\364\377\272\316\364"
"\377\272\316\364\377\272\316\364\377\272\316\364\377\272\316\364\377\272"
"\316\364\377\272\316\364\377\272\316\364\377\271\316\364\377\312\334\374"
"\377\270\305\341\377\015\015\017\377\000\000\000\377\000\000\000\313\000\000\000\011\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000s\000\000"
"\000\377\004\004\006\377\254\270\324\377\311\332\376\377\267\313\364\377\270\312"
"\363\377\270\314\363\377\270\314\363\377\270\314\363\377\270\314\363\377"
"\270\312\363\377\270\312\363\377\270\314\363\377\270\314\363\377\270\314"
"\363\377\270\314\363\377\270\312\363\377\270\314\363\377\270\314\363\377"
"\270\314\363\377\267\313\364\377\311\332\376\377\254\270\324\377\004\004\006\377"
"\000\000\000\377\000\000\000s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\377\005\005\007\377\253\270\324\377\306\332"
"\376\377\263\310\363\377\264\311\363\377\264\311\363\377\264\311\363\377"
"\264\311\363\377\264\311\363\377\264\311\364\377\264\311\364\377\264\311"
"\363\377\264\311\363\377\264\311\363\377\264\311\363\377\264\311\363\377"
"\264\311\363\377\264\311\364\377\264\311\364\377\263\310\363\377\306\332"
"\376\377\253\270\324\377\005\005\007\377\000\000\000\377\000\000\000a\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000d\000\000\000\377"
"\005\005\007\377\255\274\332\377\306\330\376\377\261\306\363\377\262\307\362\377"
"\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307"
"\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377"
"\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307"
"\362\377\261\306\363\377\306\330\376\377\255\274\332\377\005\005\007\377\000\000\000"
"\377\000\000\000d\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000W\000\000\000\377\002\002\002\377\205\220\251\377\341\354\377"
"\377\313\333\377\377\311\333\377\377\311\333\377\377\311\333\377\377\311"
"\333\377\377\311\333\377\377\311\333\377\377\311\333\377\377\311\333\377"
"\377\311\333\377\377\310\332\377\377\311\333\377\377\311\333\377\377\311"
"\333\377\377\310\332\377\377\310\332\377\377\313\333\377\377\340\354\377"
"\377\205\220\251\377\002\002\002\377\000\000\000\377\000\000\000W\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\034\000\000\000\354"
"\000\000\000\377\020\022\025\377RZi\377]ev\377Zdt\377Zdt\377[ct\377[ct\377Zdt\377"
"Zdt\377Zdt\377[ct\377[ct\377Zds\377[ct\377[ct\377Zdt\377[cr\377Zds\377]e"
"v\377RZi\377\020\022\025\377\000\000\000\377\000\000\000\354\000\000\000\034\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000f\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000"
"\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
"\000\377\000\000\000\377\000\000\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\000\000\275\000"
"\000\000\344\000\000\000\345\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000"
"\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000"
"\344\000\000\000\344\000\000\000\344\000\000\000\345\000\000\000\344\000\000\000\275\000\000\000R\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
};
static const _GLFWcursorDataOgc OGC_cursor_arrow = {
24, 31, 0, 0, 4,
"\002\002\002\337\000\000\000\224\000\000\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377"
"\005\005\005\321\000\000\000$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377ddd\377\037\037\037\373\003\003\003\364"
"\000\000\000V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\361\361\361\377VVV\376\000\000\000\377"
"\002\002\002\243\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\241"
"\241\241\377\007\007\007\375\005\005\005\322\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\315\315\315\377!!!\373\003\003\003\365\000\000\000Y\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\362\362\362\377"
"WWW\376\000\000\000\377\002\002\002\243\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\241\241\241\377\007\007\007\375\005"
"\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\316\316\316\377!!!\373\003\003\003\365\000\000\000Z"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\362\362\362\377XXX\376\000\000\000\377\002\002\002\243\000\000\000"
"\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\375\375\377\377\373\374\376\377\235\236\240\377\007\007\007\374\005"
"\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\377\377"
"\373\374\376\377\371\373\376\377\367\371\376\377\366\370\375\377\305\310"
"\314\377\037!\"\373\003\003\003\366\000\000\000[\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\375\375\377\377\373\374\376\377\371"
"\373\376\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375"
"\377\360\364\374\377\342\347\357\377QSW\376\000\000\000\377\002\002\002\243\000\000\000\012"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\375\375\377\377\373\374\376\377\371\373\376\377"
"\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377\360\364"
"\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357\373\377"
"\222\226\236\377\007\007\007\374\004\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\377\225\225\225\377\375\375\377\377\373\374\376\377\371\373\376"
"\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377\360"
"\364\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357\373"
"\377\347\356\373\377\345\354\373\377\343\353\372\377\275\303\321\377#%'\373"
"\003\003\003\366\000\000\000[\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\223\223\224\377\371\373"
"\376\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377"
"\360\364\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357"
"\373\377\347\356\373\377\345\354\373\377\343\353\372\377\342\352\372\377"
"\340\350\372\377\336\347\371\377\321\332\354\377LOW\376\000\000\000\377\002\002\002\243"
"\000\000\000\012\000\000\000\000\000\000\000\377\220\221\224\377\366\370\375\377\364\367\375\377"
"\362\365\375\377\360\364\374\377\356\363\374\377\354\362\374\377\353\360"
"\374\377\351\357\373\377\347\356\373\377\345\354\373\377\343\353\372\377"
"\342\352\372\377\340\350\372\377\336\347\371\377\334\346\371\377\332\344"
"\371\377\330\343\370\377\327\342\370\377\206\215\235\377\006\006\007\374\004\004\005"
"\332\000\000\000,\000\000\000\377\217\220\224\377\362\365\375\377\360\364\374\377\356"
"\363\374\377\354\361\374\377\353\360\374\377\351\357\373\377\347\356\373"
"\377\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372\377\336"
"\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342\370"
"\377\325\340\370\377\323\337\370\377\321\336\367\377pw\206\377\000\000\000\377"
"\001\001\001\347\000\000\000\377\214\217\223\377\356\363\374\377\354\361\374\377\353"
"\360\374\377\351\357\373\377\347\356\373\377\345\354\373\377\343\353\372"
"\377\342\352\372\377\340\350\372\377\336\347\371\377\334\346\371\377\332"
"\344\371\377\330\343\370\377\327\342\370\377\325\340\370\377\323\337\370"
"\377\321\336\367\377\225\236\261\377,/\065\374\000\000\000\377\004\004\005\316\000\000\000F"
"\000\000\000\377\212\215\223\377\353\360\374\377\351\357\373\377\347\356\373\377"
"\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372\377\336\347"
"\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342\370\377"
"\325\340\370\377\323\337\370\377\321\336\367\377\236\250\275\377\062\065<\374"
"\000\000\000\377\002\004\004\323\000\000\000U\000\000\000\001\000\000\000\000\000\000\000\377\210\214\223\377\347"
"\356\373\377\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372"
"\377\336\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327"
"\342\370\377\325\340\370\377\323\337\370\377\321\336\367\377\230\241\265"
"\377,/\064\374\000\000\000\377\002\004\004\323\000\000\000U\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\377\206\212\223\377\343\353\372\377\341\352\372\377\340\350\372\377"
"\336\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342"
"\370\377\325\340\370\377\323\337\370\377\321\336\367\377\317\334\367\377"
"DHQ\374\000\000\000\377\004\004\004\314\000\000\000J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377\203\211\222\377\340\350\372\377\336\347\371\377\334"
"\346\371\377\332\344\371\377\330\343\370\377\327\342\370\377\325\340\370"
"\377\323\337\370\377\321\336\367\377\317\334\367\377\315\333\367\377\314"
"\332\366\377JOZ\376\002\002\003\362\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\202\207\221\377\334\346\371\377\332\344"
"\371\377\330\343\370\377\327\342\370\377\325\340\370\377\323\337\370\377"
"\321\336\367\377\316\333\366\377\315\333\367\377\314\332\366\377\312\330"
"\366\377\310\327\366\377\250\266\320\377\002\002\002\376\000\000\000r\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\177\205\221\377\330\343"
"\370\377\327\342\370\377\325\340\370\377\323\337\370\377\321\336\367\377"
"\223\234\257\377),\062\374\036\040$\374\306\324\361\377\310\327\366\377\306"
"\326\365\377\304\324\365\377\303\323\365\377FLX\376\003\003\004\354\000\000\000\012\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377~\204\221\377\325"
"\340\370\377\323\337\370\377\321\336\367\377\222\233\256\377)-\063\374\000\000"
"\000\377\002\004\004\321\000\000\000\376y\203\226\377\304\324\365\377\303\323\365\377\301"
"\322\364\377\277\320\364\377\242\261\321\377\001\002\002\376\000\000\000s\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377{\202\221\377\321\336\367\377"
"\222\233\256\377),\062\374\000\000\000\377\004\004\005\313\000\000\000I\000\000\000\000\001\001\003\263\026"
"\030\034\373\275\316\357\377\277\320\364\377\275\317\364\377\273\316\364\377"
"\271\314\363\377CJY\376\003\003\004\354\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377INW\377)+\061\373\000\000\000\377\004\004\004\312\000\000\000H\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\062\000\000\000\376t\177\225\377\273\316\364\377\271\314\363"
"\377\270\313\363\377\212\232\271\377(,\066\375\000\000\000\377\000\000\000F\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\004\004\004\311\000\000\000H\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\003\003\262\025\027\034\373\264\307"
"\356\377\212\232\271\377.\063>\374\000\000\000\377\004\004\005\330\000\000\000V\000\000\000\001\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000t\000\000\000G\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\062\000\000\000\376\032\035$\375"
"\000\000\000\377\004\004\005\327\000\000\000V\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\003\003\247\004\004\005\325\000\000\000U\000\000\000\002\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
};

161
src/ogc_init.c Normal file
View File

@ -0,0 +1,161 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(_GLFW_OGC)
#include <assert.h>
#include <fat.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiikeyboard/keyboard.h>
#include <wiiuse/wpad.h>
#define FIFO_SIZE (256*1024)
char _glfwUnimplementedFmt[] = "Ogc: the platform does not support %s";
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwConnectOgc(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform ogc =
{
.platformID = GLFW_PLATFORM_OGC,
.init = _glfwInitOgc,
.terminate = _glfwTerminateOgc,
.getCursorPos = _glfwGetCursorPosOgc,
.setCursorPos = _glfwSetCursorPosOgc,
.setCursorMode = _glfwSetCursorModeOgc,
.setRawMouseMotion = _glfwSetRawMouseMotionOgc,
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedOgc,
.createCursor = _glfwCreateCursorOgc,
.createStandardCursor = _glfwCreateStandardCursorOgc,
.destroyCursor = _glfwDestroyCursorOgc,
.setCursor = _glfwSetCursorOgc,
.getScancodeName = _glfwGetScancodeNameOgc,
.getKeyScancode = _glfwGetKeyScancodeOgc,
.setClipboardString = _glfwSetClipboardStringOgc,
.getClipboardString = _glfwGetClipboardStringOgc,
.initJoysticks = _glfwInitJoysticksOgc,
.terminateJoysticks = _glfwTerminateJoysticksOgc,
.pollJoystick = _glfwPollJoystickOgc,
.getMappingName = _glfwGetMappingNameOgc,
.updateGamepadGUID = _glfwUpdateGamepadGUIDOgc,
.freeMonitor = _glfwFreeMonitorOgc,
.getMonitorPos = _glfwGetMonitorPosOgc,
.getMonitorContentScale = _glfwGetMonitorContentScaleOgc,
.getMonitorWorkarea = _glfwGetMonitorWorkareaOgc,
.getVideoModes = _glfwGetVideoModesOgc,
.getVideoMode = _glfwGetVideoModeOgc,
.getGammaRamp = _glfwGetGammaRampOgc,
.setGammaRamp = _glfwSetGammaRampOgc,
.createWindow = _glfwCreateWindowOgc,
.destroyWindow = _glfwDestroyWindowOgc,
.setWindowTitle = _glfwSetWindowTitleOgc,
.setWindowIcon = _glfwSetWindowIconOgc,
.getWindowPos = _glfwGetWindowPosOgc,
.setWindowPos = _glfwSetWindowPosOgc,
.getWindowSize = _glfwGetWindowSizeOgc,
.setWindowSize = _glfwSetWindowSizeOgc,
.setWindowSizeLimits = _glfwSetWindowSizeLimitsOgc,
.setWindowAspectRatio = _glfwSetWindowAspectRatioOgc,
.getFramebufferSize = _glfwGetFramebufferSizeOgc,
.getWindowFrameSize = _glfwGetWindowFrameSizeOgc,
.getWindowContentScale = _glfwGetWindowContentScaleOgc,
.iconifyWindow = _glfwIconifyWindowOgc,
.restoreWindow = _glfwRestoreWindowOgc,
.maximizeWindow = _glfwMaximizeWindowOgc,
.showWindow = _glfwShowWindowOgc,
.hideWindow = _glfwHideWindowOgc,
.requestWindowAttention = _glfwRequestWindowAttentionOgc,
.focusWindow = _glfwFocusWindowOgc,
.setWindowMonitor = _glfwSetWindowMonitorOgc,
.windowFocused = _glfwWindowFocusedOgc,
.windowIconified = _glfwWindowIconifiedOgc,
.windowVisible = _glfwWindowVisibleOgc,
.windowMaximized = _glfwWindowMaximizedOgc,
.windowHovered = _glfwWindowHoveredOgc,
.framebufferTransparent = _glfwFramebufferTransparentOgc,
.getWindowOpacity = _glfwGetWindowOpacityOgc,
.setWindowResizable = _glfwSetWindowResizableOgc,
.setWindowDecorated = _glfwSetWindowDecoratedOgc,
.setWindowFloating = _glfwSetWindowFloatingOgc,
.setWindowOpacity = _glfwSetWindowOpacityOgc,
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughOgc,
.pollEvents = _glfwPollEventsOgc,
.waitEvents = _glfwWaitEventsOgc,
.waitEventsTimeout = _glfwWaitEventsTimeoutOgc,
.postEmptyEvent = _glfwPostEmptyEventOgc,
.getEGLPlatform = _glfwGetEGLPlatformOgc,
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayOgc,
.getEGLNativeWindow = _glfwGetEGLNativeWindowOgc,
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsOgc,
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportOgc,
.createWindowSurface = _glfwCreateWindowSurfaceOgc
};
*platform = ogc;
return GLFW_TRUE;
}
int _glfwInitOgc(void)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
VIDEO_Init();
void *fifoBuffer = MEM_K0_TO_K1(memalign(32, FIFO_SIZE));
memset(fifoBuffer, 0, FIFO_SIZE);
GX_Init(fifoBuffer, FIFO_SIZE);
fatInitDefault();
PAD_Init();
KEYBOARD_Init(NULL);
#ifdef __wii__
WPAD_Init();
WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, 640, 480);
#endif
_glfwCreateMonitorOgc();
return GLFW_TRUE;
}
void _glfwTerminateOgc(void)
{
_glfwTerminateEGL();
_glfwTerminateOSMesa();
}
#endif // _GLFW_OGC

417
src/ogc_joystick.c Normal file
View File

@ -0,0 +1,417 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(_GLFW_OGC)
#include <ogc/lwp_watchdog.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
#define MAX_FAILED_GC_READS 10
#define MAX_GC_AXES 6
#define MAX_GC_BUTTONS 8
#define MAX_GC_HATS 1
/* PAD_ScanPads() returns 0 if no joystick is connected, but also if querying
* the hardware failed for whatever reason. This can occasionally happen at
* runtime; so, we want to ignore these events and only report the joystick
* disconnection if PAD_ScanPads() consistently returns 0.
*
* This function returns true if the scanPads value is reliable.
*/
static GLFWbool readGCJoysticks(u32 *scanPads)
{
static GLFWbool lastReadFailed = GLFW_FALSE;
static u64 firstDisconnectedTimestamp = 0;
u32 currScanPads;
u64 timestamp;
currScanPads = PAD_ScanPads();
if (currScanPads == 0) {
timestamp = gettime();
if (lastReadFailed) {
if (ticks_to_millisecs(timestamp - firstDisconnectedTimestamp) < 500)
return GLFW_FALSE;
} else {
firstDisconnectedTimestamp = timestamp;
lastReadFailed = GLFW_TRUE;
return GLFW_FALSE;
}
} else {
lastReadFailed = GLFW_FALSE;
}
*scanPads = currScanPads;
return GLFW_TRUE;
}
static void readGCJoystick(_GLFWjoystick* js)
{
u32 id = js->ogc.id;
u16 btns = PAD_ButtonsHeld(id);
js->buttons[0] = btns & PAD_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & PAD_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & PAD_BUTTON_X ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & PAD_BUTTON_Y ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & PAD_TRIGGER_L ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & PAD_TRIGGER_R ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & PAD_TRIGGER_Z ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[7] = btns & PAD_BUTTON_START ? GLFW_PRESS : GLFW_RELEASE;
js->axes[0] = PAD_StickX(id) / 100.0;
js->axes[1] = PAD_StickY(id) / 100.0;
js->axes[2] = PAD_SubStickX(id) / 100.0;
js->axes[3] = PAD_SubStickY(id) / 100.0;
js->axes[4] = PAD_TriggerL(id) / 200.0;
js->axes[5] = PAD_TriggerR(id) / 200.0;
unsigned char hat = 0;
if (btns & PAD_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & PAD_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
if (btns & PAD_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & PAD_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
_glfwInputJoystickHat(js, 0, hat);
}
/* CRC algorithm used by SDL */
static uint16_t crc16_for_byte(uint8_t r)
{
uint16_t crc = 0;
int i;
for (i = 0; i < 8; ++i) {
crc = ((crc ^ r) & 1 ? 0xA001 : 0) ^ crc >> 1;
r >>= 1;
}
return crc;
}
uint16_t SDL_crc16(uint16_t crc, const void *data, size_t len)
{
/* As an optimization we can precalculate a 256 entry table for each byte */
size_t i;
for (i = 0; i < len; ++i) {
crc = crc16_for_byte((uint8_t)crc ^ ((const uint8_t *)data)[i]) ^ crc >> 8;
}
return crc;
}
static _GLFWjoystick* addJoystick(int deviceId,
const char *name, const char* guid,
int axisCount, int buttonCount, int hatCount)
{
fprintf(stderr, "Add controller %d %s\n", deviceId, name);
_GLFWjoystick* js =
_glfwAllocJoystick(name, guid,
axisCount, buttonCount, hatCount);
js->ogc.id = deviceId;
_glfw.ogcjs.joystickIndex[deviceId] = js - _glfw.joysticks;
_glfwInputJoystick(js, GLFW_CONNECTED);
return js;
}
static void addGCJoystick(int deviceId)
{
char name[16], guid[33];
uint16_t nameCrc;
sprintf(name, "Gamecube %d", deviceId);
nameCrc = SDL_crc16(0, name, strlen(name));
sprintf(guid, "0000%02x%02x7e050000000%d000001000000",
nameCrc & 0xff, nameCrc >> 8, deviceId + 1);
addJoystick(deviceId, name, guid,
MAX_GC_AXES, MAX_GC_BUTTONS, MAX_GC_HATS);
}
#ifdef __wii__
static inline float readAxis(uint8_t pos, uint8_t center, uint8_t min, uint8_t max)
{
if (pos < center) {
return (pos - center) / (float)(center - min);
} else {
return (pos - center) / (float)(max - center);
}
}
static void readJoystickAxes(_GLFWjoystick* js, int index, const joystick_t *data)
{
js->axes[index] = readAxis(data->pos.x, data->center.x, data->min.x, data->max.x);
js->axes[index + 1] = readAxis(data->pos.y, data->center.y, data->min.y, data->max.y);
}
static inline float clampUnity(float value)
{
if (value < -1.0f) return -1.0f;
if (value > 1.0f) return 1.0f;
return value;
}
static void readOrientationAxes(_GLFWjoystick* js, int index, const orient_t *data)
{
/* Orientation fields range from -180 to 180 (they are measured in
* degrees), but in order to use them as joystick axes it's more reasonable
* to limit their range to -90/90. */
js->axes[index] = clampUnity(-data->pitch / 90.0f);
js->axes[index + 1] = clampUnity(data->roll / 90.0f);
js->axes[index + 2] = clampUnity(data->yaw / 90.0f);
}
static void readWiimote(_GLFWjoystick* js)
{
u32 id = js->ogc.id - MAX_GC_JOYSTICKS;
WPADData *data = WPAD_Data(id);
u32 btns = data->btns_h | data->btns_d;
unsigned char hat = 0;
GLFWbool readWiimote = GLFW_FALSE;
GLFWbool wiimotePointer = GLFW_FALSE;
int wiimoteFirstAxis = 0;
if (js->ogc.expansion == EXP_NUNCHUK) {
js->buttons[7] = btns & WPAD_NUNCHUK_BUTTON_Z ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[8] = btns & WPAD_NUNCHUK_BUTTON_C ? GLFW_PRESS : GLFW_RELEASE;
/* When a nunchuk is connected, we report its joystick as the first two axes,
* followed by three axes from the wiimote orientation, followed by
* three axes from the nunchuk orientation. */
readJoystickAxes(js, 0, &data->exp.nunchuk.js);
readWiimote = GLFW_TRUE;
wiimotePointer = GLFW_TRUE;
wiimoteFirstAxis = 2;
readOrientationAxes(js, wiimoteFirstAxis + 3, &data->exp.nunchuk.orient);
} else if (js->ogc.expansion == EXP_CLASSIC) {
if (btns & WPAD_CLASSIC_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_CLASSIC_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
if (btns & WPAD_CLASSIC_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & WPAD_CLASSIC_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
js->buttons[0] = btns & WPAD_CLASSIC_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & WPAD_CLASSIC_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & WPAD_CLASSIC_BUTTON_X ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & WPAD_CLASSIC_BUTTON_Y ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & WPAD_CLASSIC_BUTTON_FULL_L ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & WPAD_CLASSIC_BUTTON_FULL_R ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & WPAD_CLASSIC_BUTTON_ZL ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[7] = btns & WPAD_CLASSIC_BUTTON_ZR ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[8] = btns & WPAD_CLASSIC_BUTTON_MINUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[9] = btns & WPAD_CLASSIC_BUTTON_PLUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[10] = btns & WPAD_CLASSIC_BUTTON_HOME ? GLFW_PRESS : GLFW_RELEASE;
readJoystickAxes(js, 0, &data->exp.classic.ljs);
readJoystickAxes(js, 2, &data->exp.classic.rjs);
} else if (js->ogc.expansion == EXP_NONE) {
readWiimote = GLFW_TRUE;
wiimotePointer = data->ir.valid;
}
if (readWiimote) {
if (wiimotePointer) {
if (btns & WPAD_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
if (btns & WPAD_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & WPAD_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
} else {
if (btns & WPAD_BUTTON_LEFT) hat |= GLFW_HAT_DOWN;
if (btns & WPAD_BUTTON_RIGHT) hat |= GLFW_HAT_UP;
if (btns & WPAD_BUTTON_UP) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_BUTTON_DOWN) hat |= GLFW_HAT_RIGHT;
}
js->buttons[0] = btns & WPAD_BUTTON_1 ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & WPAD_BUTTON_2 ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & WPAD_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & WPAD_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & WPAD_BUTTON_MINUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & WPAD_BUTTON_PLUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & WPAD_BUTTON_HOME ? GLFW_PRESS : GLFW_RELEASE;
readOrientationAxes(js, wiimoteFirstAxis, &data->orient);
}
_glfwInputJoystickHat(js, 0, hat);
/* On the Wii, let's close the window when the HOME button is pressed,
* since that's the default behaviour for homebrew applications. The close
* event can anyway be overridden in the application, if this behaviour is
* not desired. */
if (btns & WPAD_BUTTON_HOME && _glfw.windowListHead) {
_glfwInputWindowCloseRequest(_glfw.windowListHead);
}
}
static void addWiimote(int deviceId, uint8_t expansion)
{
char name[64], guid[40];
uint16_t nameCrc;
int axisCount, buttonCount, hatCount;
/* These counters are for the bare Wiimote */
axisCount = 3;
buttonCount = 7;
hatCount = 1;
char *name_ptr = name;
name_ptr += sprintf(name_ptr, "Wiimote %d", deviceId - MAX_GC_JOYSTICKS);
switch (expansion) {
case WPAD_EXP_NUNCHUK:
strcpy(name_ptr, " + Nunchuk");
axisCount += 5;
buttonCount += 2;
break;
case WPAD_EXP_CLASSIC:
strcpy(name_ptr, " + Classic");
axisCount = 4;
buttonCount = 11;
hatCount = 1;
break;
case WPAD_EXP_GUITARHERO3:
strcpy(name_ptr, " + Guitar Hero 3");
break;
case WPAD_EXP_WIIBOARD:
strcpy(name_ptr, " + Balance board");
break;
}
nameCrc = SDL_crc16(0, name, strlen(name));
sprintf(guid, "0500%02x%02x7e0500000%d0%d000001000000",
nameCrc & 0xff, nameCrc >> 8, expansion + 1, deviceId + 1);
_GLFWjoystick *js = addJoystick(deviceId, name, guid,
axisCount, buttonCount, hatCount);
js->ogc.expansion = expansion;
}
#endif /* __wii__ */
static void removeJoystick(int deviceId)
{
_GLFWjoystick* js = JOYSTICK_FROM_DEVICE(deviceId);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
_glfwFreeJoystick(js);
_glfw.ogcjs.joystickIndex[deviceId] = -1;
fprintf(stderr, "Removed controller %d\n", deviceId);
}
static GLFWbool updateJoysticks()
{
u32 scanPads = 0;
if (_glfw.joysticksInitialized && readGCJoysticks(&scanPads)) {
for (int i = 0; i < MAX_GC_JOYSTICKS; i++) {
GLFWbool connected = !!(scanPads & (1 << i));
int joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(i);
GLFWbool wasConnected = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].connected : GLFW_FALSE;
if (connected != wasConnected) {
if (connected) {
addGCJoystick(i);
joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(i);
} else {
removeJoystick(i);
}
}
if (connected)
readGCJoystick(&_glfw.joysticks[joystickIndex]);
}
}
#ifdef __wii__
/* The WPAD data is also used for the mouse, so we read it even if
* joysticks haven't been initialized */
WPAD_ReadPending(WPAD_CHAN_ALL, NULL);
if (_glfw.joysticksInitialized) {
for (int i = 0; i < MAX_WIIMOTES; i++) {
int deviceId = i + MAX_GC_JOYSTICKS;
int joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(deviceId);
WPADData *data = WPAD_Data(i);
/* Ignore all reads where an error occurred */
if (data->err != WPAD_ERR_NONE) continue;
GLFWbool connected = data->data_present != 0;
uint8_t expansion = data->data_present & WPAD_DATA_EXPANSION ?
data->exp.type : EXP_NONE;
GLFWbool wasConnected = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].connected : GLFW_FALSE;
uint8_t hadExpansion = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].ogc.expansion : EXP_NONE;
if (connected != wasConnected || expansion != hadExpansion) {
if (wasConnected) {
removeJoystick(deviceId);
}
if (connected) {
addWiimote(deviceId, expansion);
joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(deviceId);
}
}
if (connected)
readWiimote(&_glfw.joysticks[joystickIndex]);
}
}
#endif
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPollJoysticksOgc(void)
{
return updateJoysticks();
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksOgc(void)
{
/* Hardware initialization done in ogc_init.c, since we want it to happen
* ASAP */
for (int i = 0; i < MAX_JOYSTICKS; i++) {
_glfw.ogcjs.joystickIndex[i] = -1;
}
return GLFW_TRUE;
}
void _glfwTerminateJoysticksOgc(void)
{
// TODO
}
GLFWbool _glfwPollJoystickOgc(_GLFWjoystick* js, int mode)
{
updateJoysticks();
return js->connected;
}
const char* _glfwGetMappingNameOgc(void)
{
return "Ogc";
}
void _glfwUpdateGamepadGUIDOgc(char* guid)
{
}
#endif // _GLFW_OGC

64
src/ogc_joystick.h Normal file
View File

@ -0,0 +1,64 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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.
//
//========================================================================
#define GLFW_OGC_JOYSTICK_STATE _GLFWjoystickOgc ogc;
#define GLFW_OGC_LIBRARY_JOYSTICK_STATE _GLFWlibraryJoystickOgc ogcjs;
#define MAX_GC_JOYSTICKS 4
#ifdef __wii__
#define MAX_WIIMOTES 4
#else
#define MAX_WIIMOTES 0
#endif
#define MAX_JOYSTICKS (MAX_GC_JOYSTICKS + MAX_WIIMOTES)
// Ogc-specific joystick data
//
typedef struct _GLFWjoystickOgc
{
int id;
uint8_t expansion;
} _GLFWjoystickOgc;
typedef struct _GLFWlibraryJoystickOgc
{
char joystickIndex[MAX_JOYSTICKS];
} _GLFWlibraryJoystickOgc;
#define JOYSTICK_INDEX_FROM_DEVICE(deviceId) \
((int)_glfw.ogcjs.joystickIndex[deviceId])
#define JOYSTICK_FROM_DEVICE(deviceId) \
(&_glfw.joysticks[JOYSTICK_INDEX_FROM_DEVICE(deviceId)])
GLFWbool _glfwPollJoysticksOgc(void);
GLFWbool _glfwInitJoysticksOgc(void);
void _glfwTerminateJoysticksOgc(void);
GLFWbool _glfwPollJoystickOgc(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameOgc(void);
void _glfwUpdateGamepadGUIDOgc(char* guid);

50
src/ogc_module.c Normal file
View File

@ -0,0 +1,50 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(GLFW_BUILD_OGC_MODULE)
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return NULL;
}
void _glfwPlatformFreeModule(void* module)
{
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return NULL;
}
#endif // GLFW_BUILD_OGC_MODULE

248
src/ogc_monitor.c Normal file
View File

@ -0,0 +1,248 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(_GLFW_OGC)
#include <ogc/color.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_OGC_MODES 4 /* - VIDEO_GetPreferredMode()
- 240p progressive mode
- 480p progressive mode
- 528p PAL progressive mode
*/
static GXRModeObj *s_videoModes[MAX_OGC_MODES + 1]; // +1 for the NULL entry
// Inverse of the VI_TVMODE macro
#define VI_FORMAT_FROM_MODE(tvmode) (tvmode >> 2)
static void setupXfb(_GLFWmonitor* monitor)
{
if (_glfw.ogc.xfb[0]) {
free(MEM_K1_TO_K0(_glfw.ogc.xfb[0]));
_glfw.ogc.xfb[0] = NULL;
}
if (_glfw.ogc.xfb[1]) {
free(MEM_K1_TO_K0(_glfw.ogc.xfb[1]));
_glfw.ogc.xfb[1] = NULL;
}
if (!_glfw.ogc.xfb[0]) {
_glfw.ogc.xfb[0] =
MEM_K0_TO_K1(SYS_AllocateFramebuffer(monitor->ogc.ogcMode));
}
if (monitor->window && monitor->window->doublebuffer) {
_glfw.ogc.xfb[1] =
MEM_K0_TO_K1(SYS_AllocateFramebuffer(monitor->ogc.ogcMode));
}
_glfw.ogc.fbIndex = 0;
}
static void ogcVideoModeToGlfw(const GXRModeObj *in, GLFWvidmode *out)
{
out->width = in->fbWidth;
out->height = in->efbHeight;
out->redBits = out->greenBits = out->blueBits = 8;
u32 format = VI_FORMAT_FROM_MODE(in->viTVMode);
switch (format) {
case VI_DEBUG:
case VI_NTSC:
case VI_EURGB60:
case VI_MPAL:
out->refreshRate = 60;
break;
case VI_PAL:
case VI_DEBUG_PAL:
out->refreshRate = 50;
break;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwCreateMonitorOgc()
{
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
void _glfwSetVideoModeOgc(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
int i;
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
fprintf(stderr, "%s:%d %s chosen %dx%d window %p\n", __FILE__, __LINE__, __func__,
best->width, best->height, monitor->window);
for (i = 0; i < monitor->modeCount; i++) {
GLFWvidmode tmp;
ogcVideoModeToGlfw(s_videoModes[i], &tmp);
if (_glfwCompareVideoModes(best, &tmp) == 0)
break;
}
/* In the unlikely case that this is not one of our modes, just pick our
* preferred one */
if (i >= monitor->modeCount) i = 0;
GXRModeObj *vmode = s_videoModes[i];
monitor->ogc.currentMode = i;
monitor->ogc.ogcMode = vmode;
setupXfb(monitor);
VIDEO_Configure(vmode);
VIDEO_ClearFrameBuffer(vmode, _glfw.ogc.xfb[0], COLOR_BLACK);
VIDEO_SetNextFramebuffer(_glfw.ogc.xfb[0]);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
float yscale = GX_GetYScaleFactor(vmode->efbHeight, vmode->xfbHeight);
GX_SetDispCopyYScale(yscale);
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorOgc(_GLFWmonitor* monitor)
{
}
void _glfwGetMonitorPosOgc(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
}
void _glfwGetMonitorContentScaleOgc(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.0f;
if (yscale)
*yscale = 1.0f;
}
void _glfwGetMonitorWorkareaOgc(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
if (width)
*width = monitor->modes[monitor->ogc.currentMode].width;
if (height)
*height = monitor->modes[monitor->ogc.currentMode].height;
}
GLFWvidmode* _glfwGetVideoModesOgc(_GLFWmonitor* monitor, int* found)
{
int i, count;
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
i = 0;
s_videoModes[i++] = VIDEO_GetPreferredMode(NULL);
/* Add more video modes, depending on the TV mode of the preferred mode
* (NTSC, PAL, etc.) */
switch (VI_FORMAT_FROM_MODE(s_videoModes[0]->viTVMode))
{
case VI_DEBUG:
case VI_NTSC:
s_videoModes[i++] = &TVNtsc240Ds;
s_videoModes[i++] = &TVNtsc480Prog;
break;
case VI_MPAL:
s_videoModes[i++] = &TVMpal240Ds;
s_videoModes[i++] = &TVMpal480Prog;
break;
case VI_EURGB60:
s_videoModes[i++] = &TVEurgb60Hz240Ds;
s_videoModes[i++] = &TVEurgb60Hz480Prog;
s_videoModes[i++] = &TVPal528Prog;
break;
case VI_PAL:
case VI_DEBUG_PAL:
s_videoModes[i++] = &TVPal264Ds;
s_videoModes[i++] = &TVPal576ProgScale; // EFB height is 480
s_videoModes[i++] = &TVPal528Prog;
break;
default:
return NULL;
}
s_videoModes[i] = NULL;
GLFWvidmode* modes = _glfw_calloc(i, sizeof(GLFWvidmode));
count = i;
for (int i = 0; i < count; i++)
{
ogcVideoModeToGlfw(s_videoModes[i], &modes[i]);
}
*found = count;
return modes;
}
GLFWbool _glfwGetVideoModeOgc(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
*mode = monitor->modes[monitor->ogc.currentMode];
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampOgc(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"gamma ramp");
return GLFW_FALSE;
}
void _glfwSetGammaRampOgc(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"gamma ramp");
}
#endif // _GLFW_OGC

252
src/ogc_platform.h Normal file
View File

@ -0,0 +1,252 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <ogc/gx.h>
#include <ogc/system.h>
#include <ogc/video.h>
#define GLFW_OGC_WINDOW_STATE _GLFWwindowOgc ogc;
#define GLFW_OGC_LIBRARY_WINDOW_STATE _GLFWlibraryOgc ogc;
#define GLFW_OGC_MONITOR_STATE _GLFWmonitorOgc ogc;
#define GLFW_OGC_CURSOR_STATE _GLFWcursorOgc ogc;
extern char _glfwUnimplementedFmt[];
#if 0
typedef struct ogc_cursor_theme* (* PFN_ogc_cursor_theme_load)(const char*, int, struct ogc_shm*);
typedef void (* PFN_ogc_cursor_theme_destroy)(struct ogc_cursor_theme*);
typedef struct ogc_cursor* (* PFN_ogc_cursor_theme_get_cursor)(struct ogc_cursor_theme*, const char*);
typedef struct ogc_buffer* (* PFN_ogc_cursor_image_get_buffer)(struct ogc_cursor_image*);
#define ogc_cursor_theme_load _glfw.ogc.cursor.theme_load
#define ogc_cursor_theme_destroy _glfw.ogc.cursor.theme_destroy
#define ogc_cursor_theme_get_cursor _glfw.ogc.cursor.theme_get_cursor
#define ogc_cursor_image_get_buffer _glfw.ogc.cursor.image_get_buffer
typedef struct ogc_egl_window* (* PFN_ogc_egl_window_create)(struct ogc_surface*, int, int);
typedef void (* PFN_ogc_egl_window_destroy)(struct ogc_egl_window*);
typedef void (* PFN_ogc_egl_window_resize)(struct ogc_egl_window*, int, int, int, int);
#define ogc_egl_window_create _glfw.ogc.egl.window_create
#define ogc_egl_window_destroy _glfw.ogc.egl.window_destroy
#define ogc_egl_window_resize _glfw.ogc.egl.window_resize
typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags);
typedef void (* PFN_xkb_context_unref)(struct xkb_context*);
typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
typedef uint32_t (* PFN_xkb_keysym_to_utf32)(xkb_keysym_t);
typedef int (* PFN_xkb_keysym_to_utf8)(xkb_keysym_t, char*, size_t);
#define xkb_context_new _glfw.ogc.xkb.context_new
#define xkb_context_unref _glfw.ogc.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.ogc.xkb.keymap_new_from_string
#define xkb_keymap_unref _glfw.ogc.xkb.keymap_unref
#define xkb_keymap_mod_get_index _glfw.ogc.xkb.keymap_mod_get_index
#define xkb_keymap_key_repeats _glfw.ogc.xkb.keymap_key_repeats
#define xkb_keymap_key_get_syms_by_level _glfw.ogc.xkb.keymap_key_get_syms_by_level
#define xkb_state_new _glfw.ogc.xkb.state_new
#define xkb_state_unref _glfw.ogc.xkb.state_unref
#define xkb_state_key_get_syms _glfw.ogc.xkb.state_key_get_syms
#define xkb_state_update_mask _glfw.ogc.xkb.state_update_mask
#define xkb_state_key_get_layout _glfw.ogc.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.ogc.xkb.state_mod_index_is_active
#define xkb_keysym_to_utf32 _glfw.ogc.xkb.keysym_to_utf32
#define xkb_keysym_to_utf8 _glfw.ogc.xkb.keysym_to_utf8
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*);
typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t);
typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*);
typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*);
#define xkb_compose_table_new_from_locale _glfw.ogc.xkb.compose_table_new_from_locale
#define xkb_compose_table_unref _glfw.ogc.xkb.compose_table_unref
#define xkb_compose_state_new _glfw.ogc.xkb.compose_state_new
#define xkb_compose_state_unref _glfw.ogc.xkb.compose_state_unref
#define xkb_compose_state_feed _glfw.ogc.xkb.compose_state_feed
#define xkb_compose_state_get_status _glfw.ogc.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.ogc.xkb.compose_state_get_one_sym
#endif
// Ogc-specific per-window data
//
typedef struct _GLFWwindowOgc
{
int width, height;
GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered;
GLFWbool transparent;
GLFWbool scaleFramebuffer;
struct ogc_surface* surface;
struct ogc_callback* callback;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
char* appId;
} _GLFWwindowOgc;
// Ogc-specific global data
//
typedef struct _GLFWlibraryOgc
{
void * xfb[2];
int fbIndex;
struct ogc_cursor_theme* cursorTheme;
struct ogc_cursor_theme* cursorThemeHiDPI;
struct ogc_surface* cursorSurface;
const char* cursorPreviousName;
int cursorTimerfd;
uint32_t serial;
uint32_t pointerEnterSerial;
int keyRepeatTimerfd;
int32_t keyRepeatRate;
int32_t keyRepeatDelay;
int keyRepeatScancode;
char* clipboardString;
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
} _GLFWlibraryOgc;
// Ogc-specific per-monitor data
//
typedef struct _GLFWmonitorOgc
{
int currentMode;
GXRModeObj* ogcMode;
} _GLFWmonitorOgc;
// Ogc-specific per-cursor data
//
typedef struct _GLFWcursorOgc
{
GXTexObj texobj;
short xhot, yhot;
GLFWbool canRotate;
} _GLFWcursorOgc;
GLFWbool _glfwConnectOgc(int platformID, _GLFWplatform* platform);
int _glfwInitOgc(void);
void _glfwTerminateOgc(void);
void _glfwCreateMonitorOgc(void);
void _glfwSetVideoModeOgc(_GLFWmonitor* monitor, const GLFWvidmode* desired);
GLFWbool _glfwCreateContextOgc(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
GLFWbool _glfwCreateWindowOgc(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowOgc(_GLFWwindow* window);
void _glfwSetWindowTitleOgc(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconOgc(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosOgc(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosOgc(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeOgc(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeOgc(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsOgc(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioOgc(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeOgc(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeOgc(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleOgc(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowOgc(_GLFWwindow* window);
void _glfwRestoreWindowOgc(_GLFWwindow* window);
void _glfwMaximizeWindowOgc(_GLFWwindow* window);
void _glfwShowWindowOgc(_GLFWwindow* window);
void _glfwHideWindowOgc(_GLFWwindow* window);
void _glfwRequestWindowAttentionOgc(_GLFWwindow* window);
void _glfwFocusWindowOgc(_GLFWwindow* window);
void _glfwSetWindowMonitorOgc(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleOgc(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredOgc(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentOgc(_GLFWwindow* window);
void _glfwSetWindowResizableOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingOgc(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityOgc(_GLFWwindow* window);
void _glfwSetWindowOpacityOgc(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionOgc(_GLFWwindow* window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedOgc(void);
void _glfwPollEventsOgc(void);
void _glfwWaitEventsOgc(void);
void _glfwWaitEventsTimeoutOgc(double timeout);
void _glfwPostEmptyEventOgc(void);
void _glfwGetCursorPosOgc(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosOgc(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeOgc(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameOgc(int scancode);
int _glfwGetKeyScancodeOgc(int key);
GLFWbool _glfwCreateCursorOgc(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorOgc(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorOgc(_GLFWcursor* cursor);
void _glfwSetCursorOgc(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringOgc(const char* string);
const char* _glfwGetClipboardStringOgc(void);
EGLenum _glfwGetEGLPlatformOgc(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayOgc(void);
EGLNativeWindowType _glfwGetEGLNativeWindowOgc(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsOgc(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportOgc(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceOgc(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorOgc(_GLFWmonitor* monitor);
void _glfwGetMonitorPosOgc(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleOgc(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaOgc(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesOgc(_GLFWmonitor* monitor, int* count);
GLFWbool _glfwGetVideoModeOgc(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampOgc(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampOgc(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwAddOutputOgc(uint32_t name, uint32_t version);
void _glfwUpdateBufferScaleFromOutputsOgc(_GLFWwindow* window);

237
src/ogc_thread.c Normal file
View File

@ -0,0 +1,237 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(GLFW_BUILD_OGC_THREAD)
#include <assert.h>
#include <ogcsys.h>
#include <string.h>
#define MAX_THREADS 32
#define INITIAL_STORAGE_CAPACITY 64
#define INCREMENT_STORAGE_CAPACITY 64
typedef struct _GLFWthreadStorageOgc {
size_t capacity;
size_t used;
void *data[0]; /* Array of pointers to the stored data element */
} _GLFWthreadStorageOgc;
#define RESERVED_PTR ((void*)0x1)
typedef struct _GLFWthreadMapOgc {
lwp_t threadId;
_GLFWthreadStorageOgc *storage;
} _GLFWthreadMapOgc;
static _GLFWthreadMapOgc threadMap[MAX_THREADS];
static mutex_t threadMapMutex = 0; // TODO initialize!
static _GLFWthreadMapOgc *storageEntryForThread()
{
lwp_t currentThreadId = LWP_GetSelf();
/* We are not creating entries here and only our thread can modify our
* entry, so we don't need to lock the mutex here. */
for (int i = 0; i < MAX_THREADS; i++) {
_GLFWthreadMapOgc *entry = &threadMap[i];
if (entry->threadId == currentThreadId) {
return entry;
}
}
return NULL;
}
static inline _GLFWthreadStorageOgc *storageForThread()
{
_GLFWthreadMapOgc *entry = storageEntryForThread();
return entry ? entry->storage : NULL;
}
static _GLFWthreadMapOgc *createStorageEntryForThread()
{
size_t initialSize = sizeof(_GLFWthreadStorageOgc) +
INITIAL_STORAGE_CAPACITY * sizeof(void*);
_GLFWthreadStorageOgc *storage = _glfw_calloc(1, initialSize);
if (!storage) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to allocate TLS data");
return NULL;
}
storage->capacity = INITIAL_STORAGE_CAPACITY;
storage->used = 0;
if (!LWP_MutexLock(threadMapMutex)) {
_glfw_free(storage);
_glfwInputError(GLFW_PLATFORM_ERROR,
"OGC: Failed to lock TLS mutex");
return NULL;
}
_GLFWthreadMapOgc *entry = NULL;
lwp_t currentThreadId = LWP_GetSelf();
for (int i = 0; i < MAX_THREADS; i++) {
entry = &threadMap[i];
if (!entry->threadId) {
entry->threadId = currentThreadId;
entry->storage = storage;
break;
}
}
if (entry->threadId != currentThreadId) {
// We didn't find a free slot
entry = NULL;
}
LWP_MutexUnlock(threadMapMutex);
return entry;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->ogc.allocated == GLFW_FALSE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
if (!entry) {
entry = createStorageEntryForThread();
if (!entry) {
// The error has already been logged
return GLFW_FALSE;
}
}
_GLFWthreadStorageOgc *storage = entry->storage;
if (storage->used >= storage->capacity) {
size_t newSize = sizeof(_GLFWthreadStorageOgc) +
(storage->capacity + INCREMENT_STORAGE_CAPACITY) * sizeof(void*);
storage = _glfw_realloc(storage, newSize);
if (!storage) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to reallocate TLS data");
return GLFW_FALSE;
}
// No need to lock the map, since we are changing our own thread's
// entry
entry->storage = storage;
storage->capacity += INCREMENT_STORAGE_CAPACITY;
}
// Find the first free entry in the TLS data
int index = -1;
for (int i = 0; i < storage->capacity; i++) {
if (!storage->data[i]) {
index = i;
break;
}
}
/* We know that storage->capacity > storage->used, so there must be free
* slots */
assert(index >= 0);
storage->data[index] = RESERVED_PTR;
storage->used++;
tls->ogc.index = index;
tls->ogc.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->ogc.allocated) {
_GLFWthreadMapOgc *entry = storageEntryForThread();
if (entry) {
assert(entry->storage->capacity > tls->ogc.index);
assert(entry->storage->used > 0);
entry->storage->data[tls->ogc.index] = NULL;
entry->storage->used--;
}
}
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->ogc.allocated == GLFW_TRUE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
void *ptr = entry->storage->data[tls->ogc.index];
return ptr == RESERVED_PTR ? NULL : ptr;
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->posix.allocated == GLFW_TRUE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
entry->storage->data[tls->ogc.index] = value;
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_FALSE);
if (LWP_MutexInit(&mutex->ogc.handle, false) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "OGC: Failed to create mutex");
return GLFW_FALSE;
}
return mutex->ogc.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->ogc.allocated)
LWP_MutexDestroy(mutex->ogc.handle);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_TRUE);
LWP_MutexLock(mutex->ogc.handle);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_TRUE);
LWP_MutexUnlock(mutex->ogc.handle);
}
void _glfwThreadInitMutexOgc()
{
LWP_MutexInit(&threadMapMutex, false);
}
#endif // GLFW_BUILD_OGC_THREAD

49
src/ogc_thread.h Normal file
View File

@ -0,0 +1,49 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <ogc/mutex.h>
#define GLFW_OGC_TLS_STATE _GLFWtlsOgc ogc;
#define GLFW_OGC_MUTEX_STATE _GLFWmutexOgc ogc;
// POSIX-specific thread local storage data
//
typedef struct _GLFWtlsOgc
{
GLFWbool allocated;
int index;
} _GLFWtlsOgc;
// POSIX-specific mutex data
//
typedef struct _GLFWmutexOgc
{
GLFWbool allocated;
mutex_t handle;
} _GLFWmutexOgc;
void _glfwThreadInitMutexOgc();

52
src/ogc_time.c Normal file
View File

@ -0,0 +1,52 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 "internal.h"
#if defined(GLFW_BUILD_OGC_TIMER)
#include <ogc/lwp_watchdog.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
}
uint64_t _glfwPlatformGetTimerValue(void)
{
return gettime();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return secs_to_ticks(1);
}
#endif // GLFW_BUILD_OGC_TIMER

28
src/ogc_time.h Normal file
View File

@ -0,0 +1,28 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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.
//
//========================================================================
#define GLFW_OGC_LIBRARY_TIMER_STATE

564
src/ogc_window.c Normal file
View File

@ -0,0 +1,564 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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.
//
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
#if defined(_GLFW_OGC)
#include "ogc_cursor.h"
#include <assert.h>
#include <errno.h>
#include <malloc.h>
#include <opengx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiikeyboard/keyboard.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
static void keysym_to_utf8(uint16_t symbol, char *utf8)
{
/* ignore private symbols, used by wiikeyboard for special keys */
if ((symbol >= 0xE000 && symbol <= 0xF8FF) || symbol == 0xFFFF)
return;
/* convert UCS-2 to UTF-8 */
if (symbol < 0x80) {
utf8[0] = symbol;
} else if (symbol < 0x800) {
utf8[0] = 0xC0 | (symbol >> 6);
utf8[1] = 0x80 | (symbol & 0x3F);
} else {
utf8[0] = 0xE0 | (symbol >> 12);
utf8[1] = 0x80 | ((symbol >> 6) & 0x3F);
utf8[2] = 0x80 | (symbol & 0x3F);
}
}
static void acquireMonitor(_GLFWwindow* window)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
if (!window->monitor) {
window->monitor = _glfw.monitors[0];
}
_glfwInputMonitorWindow(window->monitor, window);
_glfwSetVideoModeOgc(window->monitor, &window->videoMode);
}
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
_glfwInputMonitorWindow(window->monitor, NULL);
}
/* Convert the RGBA pixels to the 4x4 tile ARGB texture used by GX */
static void setPixelToTextureARGB(char *texture, u32 offset, u32 color)
{
*(u16*)(texture + offset) = color >> 16;
*(u16*)(texture + offset + 32) = color;
}
static void setPixelToTextureRGBA(char *texture, u32 offset, u32 color)
{
setPixelToTextureARGB(texture, offset, (color << 24) | (color >> 8));
}
static void pixelsToTextureARGB(const void *pixels, s16 width, s16 height,
s16 pitch, void *texture)
{
s16 tex_pitch = (width + 3) / 4 * 4;
int row, col;
for (row = 0; row < height; row++) {
int y = row;
u32 *src = (u32 *)((u8 *)pixels + pitch * row);
for (col = 0; col < width; col++) {
int x = col;
u32 offset = (((y >> 2) << 4) * tex_pitch) +
((x >> 2) << 6) + (((y % 4 << 2) + x % 4) << 1);
setPixelToTextureRGBA(texture, offset, *src++);
}
}
}
static void* createRGBAtexture(const GLFWimage* image)
{
u32 textureSize;
void *texels;
textureSize = GX_GetTexBufferSize(image->width, image->height, GX_TF_RGBA8,
GX_FALSE, 0);
texels = memalign(32, textureSize);
if (!texels) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to allocate cursor texture");
return NULL;
}
pixelsToTextureARGB(image->pixels, image->width, image->height,
image->width * 4, texels);
DCStoreRange(texels, textureSize);
return texels;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateWindowOgc(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
fprintf(stderr, "%s:%d %s %p\n", __FILE__, __LINE__, __func__, window);
acquireMonitor(window);
window->ogc.width = window->monitor->ogc.ogcMode->fbWidth;
window->ogc.height = window->monitor->ogc.ogcMode->efbHeight;
if (ctxconfig->client != GLFW_NO_API)
{
ogx_initialize();
if (!_glfwCreateContextOgc(window, ctxconfig, fbconfig))
return GLFW_FALSE;
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
}
/* Set the default Wii cursor */
GLFWcursor *cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
_glfwSetCursorOgc(window, (_GLFWcursor*) cursor);
return GLFW_TRUE;
}
void _glfwDestroyWindowOgc(_GLFWwindow* window)
{
if (window->monitor)
releaseMonitor(window);
}
void _glfwSetWindowTitleOgc(_GLFWwindow* window, const char* title)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window title");
}
void _glfwSetWindowIconOgc(_GLFWwindow* window,
int count, const GLFWimage* images)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window icon");
}
void _glfwGetWindowPosOgc(_GLFWwindow* window, int* xpos, int* ypos)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"getting the window position");
}
void _glfwSetWindowPosOgc(_GLFWwindow* window, int xpos, int ypos)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window position");
}
void _glfwGetWindowSizeOgc(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->ogc.width;
if (height)
*height = window->ogc.height;
}
void _glfwSetWindowSizeOgc(_GLFWwindow* window, int width, int height)
{
fprintf(stderr, "%s:%d %s %dx%d\n", __FILE__, __LINE__, __func__, width, height);
if (window->monitor)
{
}
else
{
_glfwInputWindowDamage(window);
}
}
void _glfwSetWindowSizeLimitsOgc(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the size limits");
}
void _glfwSetWindowAspectRatioOgc(_GLFWwindow* window, int numer, int denom)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the aspect ratio");
}
void _glfwGetFramebufferSizeOgc(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->monitor->ogc.ogcMode->fbWidth;
if (height)
*height = window->monitor->ogc.ogcMode->efbHeight;;
}
void _glfwGetWindowFrameSizeOgc(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
*left = *top = *right = *bottom = 0;
}
void _glfwGetWindowContentScaleOgc(_GLFWwindow* window,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.0f;
if (yscale)
*yscale = 1.0f;
}
void _glfwIconifyWindowOgc(_GLFWwindow* window)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"iconifying the window");
}
void _glfwRestoreWindowOgc(_GLFWwindow* window)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"restoring the window");
}
void _glfwMaximizeWindowOgc(_GLFWwindow* window)
{
}
void _glfwShowWindowOgc(_GLFWwindow* window)
{
}
void _glfwHideWindowOgc(_GLFWwindow* window)
{
}
void _glfwRequestWindowAttentionOgc(_GLFWwindow* window)
{
}
void _glfwFocusWindowOgc(_GLFWwindow* window)
{
}
void _glfwSetWindowMonitorOgc(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
}
GLFWbool _glfwWindowFocusedOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowIconifiedOgc(_GLFWwindow* window)
{
return GLFW_FALSE;
}
GLFWbool _glfwWindowVisibleOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowMaximizedOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowHoveredOgc(_GLFWwindow* window)
{
return window->ogc.hovered;
}
GLFWbool _glfwFramebufferTransparentOgc(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwSetWindowResizableOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwSetWindowDecoratedOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwSetWindowFloatingOgc(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"making a window floating");
}
void _glfwSetWindowMousePassthroughOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
float _glfwGetWindowOpacityOgc(_GLFWwindow* window)
{
return 1.f;
}
void _glfwSetWindowOpacityOgc(_GLFWwindow* window, float opacity)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window opacity");
}
void _glfwSetRawMouseMotionOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
GLFWbool _glfwRawMouseMotionSupportedOgc(void)
{
return GLFW_FALSE;
}
#ifdef __wii__
static void handleWiimoteCursorOgc(_GLFWwindow* window)
{
WPADData *data = WPAD_Data(0);
float x, y;
GLFWbool mouseActive = !!data->ir.valid;
if (mouseActive != window->ogc.hovered) {
window->ogc.hovered = mouseActive;
_glfwInputCursorEnter(window, mouseActive);
}
if (!mouseActive) return;
x = data->ir.x * window->ogc.width / data->ir.vres[0];
y = data->ir.y * window->ogc.height / data->ir.vres[1];
_glfwInputCursorPos(window, x, y);
if (data->btns_d & WPAD_BUTTON_A)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_PRESS, 0);
if (data->btns_u & WPAD_BUTTON_A)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_RELEASE, 0);
if (data->btns_d & WPAD_BUTTON_B)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_2, GLFW_PRESS, 0);
if (data->btns_u & WPAD_BUTTON_B)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_2, GLFW_RELEASE, 0);
}
#endif
void _glfwPollEventsOgc(void)
{
//fprintf(stderr, "Polling for events %d\n", 0);
GLFWbool hasEvents = GLFW_FALSE;
if (_glfwPollJoysticksOgc()) {
hasEvents = GLFW_TRUE;
#ifdef __wii__
/* Use the first wiimote as mouse */
if (_glfw.windowListHead)
handleWiimoteCursorOgc(_glfw.windowListHead);
#endif
}
}
void _glfwWaitEventsOgc(void)
{
// TODO: check if events were produced or sleep?
_glfwPollEventsOgc();
}
void _glfwWaitEventsTimeoutOgc(double timeout)
{
// TODO: check if events were produced or sleep?
_glfwPollEventsOgc();
}
void _glfwPostEmptyEventOgc(void)
{
}
void _glfwGetCursorPosOgc(_GLFWwindow* window, double* xpos, double* ypos)
{
if (xpos)
*xpos = window->virtualCursorPosX;
if (ypos)
*ypos = window->virtualCursorPosY;
}
void _glfwSetCursorPosOgc(_GLFWwindow* window, double x, double y)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the cursor position");
}
void _glfwSetCursorModeOgc(_GLFWwindow* window, int mode)
{
// TODO
}
const char* _glfwGetScancodeNameOgc(int scancode)
{
static char name[10];
name[0] = name[1] = '\0';
switch (scancode) {
case KS_Return: name[0] = '\n'; break;
case KS_Escape: return "ESC";
default:
keysym_to_utf8(scancode, name);
}
return name;
}
int _glfwGetKeyScancodeOgc(int key)
{
return _glfw.ogc.scancodes[key];
}
GLFWbool _glfwCreateCursorOgc(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{
void* texels = createRGBAtexture(image);
if (!texels) return GLFW_FALSE;
cursor->ogc.xhot = xhot;
cursor->ogc.yhot = yhot;
GX_InvalidateTexAll();
GX_InitTexObj(&cursor->ogc.texobj, texels,
image->width, image->height,
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjLOD(&cursor->ogc.texobj, GX_LINEAR, GX_LINEAR,
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
return GLFW_TRUE;
}
GLFWbool _glfwCreateStandardCursorOgc(_GLFWcursor* cursor, int shape)
{
const _GLFWcursorDataOgc* cd = NULL;
switch (shape)
{
case GLFW_ARROW_CURSOR:
cd = &OGC_cursor_arrow;
break;
case GLFW_POINTING_HAND_CURSOR:
cd = &OGC_cursor_hand;
break;
default:
return GLFW_FALSE;
}
GLFWimage image = {
cd->width, cd->height, cd->pixel_data
};
return _glfwCreateCursorOgc(cursor, &image,
cd->hot_x, cd->hot_y);
}
void _glfwDestroyCursorOgc(_GLFWcursor* cursor)
{
void *data = GX_GetTexObjData(&cursor->ogc.texobj);
if (data != 0)
free(MEM_PHYSICAL_TO_K0(data));
}
void _glfwSetCursorOgc(_GLFWwindow* window, _GLFWcursor* cursor)
{
window->ogc.currentCursor = cursor;
}
void _glfwSetClipboardStringOgc(const char* string)
{
}
const char* _glfwGetClipboardStringOgc(void)
{
return NULL;
}
EGLenum _glfwGetEGLPlatformOgc(EGLint** attribs)
{
return EGL_PLATFORM_ANGLE_ANGLE;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayOgc(void)
{
return EGL_DEFAULT_DISPLAY;
}
EGLNativeWindowType _glfwGetEGLNativeWindowOgc(_GLFWwindow* window)
{
return 0;
}
void _glfwGetRequiredInstanceExtensionsOgc(char** extensions)
{
}
GLFWbool _glfwGetPhysicalDevicePresentationSupportOgc(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
}
VkResult _glfwCreateWindowSurfaceOgc(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
#endif // _GLFW_OGC

View File

@ -56,6 +56,9 @@ static const struct
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
{ GLFW_PLATFORM_X11, _glfwConnectX11 }, { GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif #endif
#if defined(_GLFW_OGC)
{ GLFW_PLATFORM_OGC, _glfwConnectOgc },
#endif
}; };
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
@ -68,6 +71,7 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
desiredID != GLFW_PLATFORM_COCOA && desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND && desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 && desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_OGC &&
desiredID != GLFW_PLATFORM_NULL) desiredID != GLFW_PLATFORM_NULL)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID); _glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);
@ -187,8 +191,6 @@ GLFWAPI const char* glfwGetVersionString(void)
" OSMesa" " OSMesa"
#if defined(__MINGW64_VERSION_MAJOR) #if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64" " MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
" VisualC" " VisualC"
#endif #endif

View File

@ -29,6 +29,8 @@
defined(GLFW_BUILD_WIN32_MODULE) || \ defined(GLFW_BUILD_WIN32_MODULE) || \
defined(GLFW_BUILD_WIN32_THREAD) || \ defined(GLFW_BUILD_WIN32_THREAD) || \
defined(GLFW_BUILD_COCOA_TIMER) || \ defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_OGC_MODULE) || \
defined(GLFW_BUILD_OGC_THREAD) || \
defined(GLFW_BUILD_POSIX_TIMER) || \ defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \ defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \ defined(GLFW_BUILD_POSIX_THREAD) || \
@ -90,6 +92,16 @@
#define GLFW_GLX_LIBRARY_CONTEXT_STATE #define GLFW_GLX_LIBRARY_CONTEXT_STATE
#endif #endif
#if defined(_GLFW_OGC)
#include "ogc_platform.h"
#define GLFW_EXPOSE_NATIVE_OGC
#else
#define GLFW_OGC_WINDOW_STATE
#define GLFW_OGC_MONITOR_STATE
#define GLFW_OGC_CURSOR_STATE
#define GLFW_OGC_LIBRARY_WINDOW_STATE
#endif
#include "null_joystick.h" #include "null_joystick.h"
#if defined(_GLFW_WIN32) #if defined(_GLFW_WIN32)
@ -106,6 +118,13 @@
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#endif #endif
#if defined(_GLFW_OGC)
#include "ogc_joystick.h"
#else
#define GLFW_OGC_JOYSTICK_STATE
#define GLFW_OGC_LIBRARY_JOYSTICK_STATE
#endif
#if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__) #if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)
#define GLFW_BUILD_LINUX_JOYSTICK #define GLFW_BUILD_LINUX_JOYSTICK
#endif #endif
@ -123,6 +142,7 @@
GLFW_WAYLAND_WINDOW_STATE \ GLFW_WAYLAND_WINDOW_STATE \
GLFW_X11_WINDOW_STATE \ GLFW_X11_WINDOW_STATE \
GLFW_NULL_WINDOW_STATE \ GLFW_NULL_WINDOW_STATE \
GLFW_OGC_WINDOW_STATE \
#define GLFW_PLATFORM_MONITOR_STATE \ #define GLFW_PLATFORM_MONITOR_STATE \
GLFW_WIN32_MONITOR_STATE \ GLFW_WIN32_MONITOR_STATE \
@ -130,6 +150,7 @@
GLFW_WAYLAND_MONITOR_STATE \ GLFW_WAYLAND_MONITOR_STATE \
GLFW_X11_MONITOR_STATE \ GLFW_X11_MONITOR_STATE \
GLFW_NULL_MONITOR_STATE \ GLFW_NULL_MONITOR_STATE \
GLFW_OGC_MONITOR_STATE \
#define GLFW_PLATFORM_CURSOR_STATE \ #define GLFW_PLATFORM_CURSOR_STATE \
GLFW_WIN32_CURSOR_STATE \ GLFW_WIN32_CURSOR_STATE \
@ -137,11 +158,13 @@
GLFW_WAYLAND_CURSOR_STATE \ GLFW_WAYLAND_CURSOR_STATE \
GLFW_X11_CURSOR_STATE \ GLFW_X11_CURSOR_STATE \
GLFW_NULL_CURSOR_STATE \ GLFW_NULL_CURSOR_STATE \
GLFW_OGC_CURSOR_STATE \
#define GLFW_PLATFORM_JOYSTICK_STATE \ #define GLFW_PLATFORM_JOYSTICK_STATE \
GLFW_WIN32_JOYSTICK_STATE \ GLFW_WIN32_JOYSTICK_STATE \
GLFW_COCOA_JOYSTICK_STATE \ GLFW_COCOA_JOYSTICK_STATE \
GLFW_LINUX_JOYSTICK_STATE GLFW_LINUX_JOYSTICK_STATE \
GLFW_OGC_JOYSTICK_STATE \
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \ #define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
GLFW_WIN32_LIBRARY_WINDOW_STATE \ GLFW_WIN32_LIBRARY_WINDOW_STATE \
@ -149,11 +172,13 @@
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \ GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
GLFW_X11_LIBRARY_WINDOW_STATE \ GLFW_X11_LIBRARY_WINDOW_STATE \
GLFW_NULL_LIBRARY_WINDOW_STATE \ GLFW_NULL_LIBRARY_WINDOW_STATE \
GLFW_OGC_LIBRARY_WINDOW_STATE \
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
GLFW_WIN32_LIBRARY_JOYSTICK_STATE \ GLFW_WIN32_LIBRARY_JOYSTICK_STATE \
GLFW_COCOA_LIBRARY_JOYSTICK_STATE \ GLFW_COCOA_LIBRARY_JOYSTICK_STATE \
GLFW_LINUX_LIBRARY_JOYSTICK_STATE GLFW_LINUX_LIBRARY_JOYSTICK_STATE \
GLFW_OGC_LIBRARY_JOYSTICK_STATE \
#define GLFW_PLATFORM_CONTEXT_STATE \ #define GLFW_PLATFORM_CONTEXT_STATE \
GLFW_WGL_CONTEXT_STATE \ GLFW_WGL_CONTEXT_STATE \
@ -167,6 +192,8 @@
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_THREAD #define GLFW_BUILD_WIN32_THREAD
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_THREAD
#else #else
#define GLFW_BUILD_POSIX_THREAD #define GLFW_BUILD_POSIX_THREAD
#endif #endif
@ -179,12 +206,18 @@
#include "posix_thread.h" #include "posix_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE #define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE
#elif defined(GLFW_BUILD_OGC_THREAD)
#include "ogc_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_OGC_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_OGC_MUTEX_STATE
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER #define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define GLFW_BUILD_COCOA_TIMER #define GLFW_BUILD_COCOA_TIMER
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_TIMER
#else #else
#define GLFW_BUILD_POSIX_TIMER #define GLFW_BUILD_POSIX_TIMER
#endif #endif
@ -198,10 +231,15 @@
#elif defined(GLFW_BUILD_POSIX_TIMER) #elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h" #include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_OGC_TIMER)
#include "ogc_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_OGC_LIBRARY_TIMER_STATE
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_MODULE #define GLFW_BUILD_WIN32_MODULE
#elif defined(__wii__) || defined(__gamecube)
#define GLFW_BUILD_OGC_MODULE
#else #else
#define GLFW_BUILD_POSIX_MODULE #define GLFW_BUILD_POSIX_MODULE
#endif #endif

View File

@ -83,24 +83,12 @@
#ifndef WM_COPYGLOBALDATA #ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049 #define WM_COPYGLOBALDATA 0x0049
#endif #endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_DPICHANGED #ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0 #define WM_DPICHANGED 0x02E0
#endif #endif
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
#endif
#ifndef EDS_ROTATEDMODE #ifndef EDS_ROTATEDMODE
#define EDS_ROTATEDMODE 0x00000004 #define EDS_ROTATEDMODE 0x00000004
#endif #endif
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE #ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0603 #define _WIN32_WINNT_WINBLUE 0x0603
#endif #endif
@ -113,9 +101,6 @@
#ifndef USER_DEFAULT_SCREEN_DPI #ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96 #define USER_DEFAULT_SCREEN_DPI 96
#endif #endif
#ifndef OCR_HAND
#define OCR_HAND 32649
#endif
#if WINVER < 0x0601 #if WINVER < 0x0601
typedef struct typedef struct

View File

@ -41,8 +41,10 @@ add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN}) add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL}) add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
if (Threads_FOUND)
target_link_libraries(empty Threads::Threads) target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads) target_link_libraries(threads Threads::Threads)
endif()
if (RT_LIBRARY) if (RT_LIBRARY)
target_link_libraries(empty "${RT_LIBRARY}") target_link_libraries(empty "${RT_LIBRARY}")
target_link_libraries(threads "${RT_LIBRARY}") target_link_libraries(threads "${RT_LIBRARY}")