platforms c-source files updated
This commit is contained in:
parent
614ed9f942
commit
fc50e055c0
5 changed files with 981 additions and 685 deletions
|
@ -74,14 +74,14 @@ typedef struct {
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
extern CoreData CORE; // Global CORE state context
|
extern CoreData CORE; // Global CORE state context
|
||||||
|
extern bool isGpuReady; // Flag to note GPU has been initialized successfully
|
||||||
static PlatformData platform = { 0 }; // Platform specific data
|
static PlatformData platform = { 0 }; // Platform specific data
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Local Variables Definition
|
// Local Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#define KEYCODE_MAP_SIZE 162
|
#define KEYCODE_MAP_SIZE 162
|
||||||
static const KeyboardKey KeycodeMap[KEYCODE_MAP_SIZE] = {
|
static const KeyboardKey mapKeycode[KEYCODE_MAP_SIZE] = {
|
||||||
KEY_NULL, // AKEYCODE_UNKNOWN
|
KEY_NULL, // AKEYCODE_UNKNOWN
|
||||||
0, // AKEYCODE_SOFT_LEFT
|
0, // AKEYCODE_SOFT_LEFT
|
||||||
0, // AKEYCODE_SOFT_RIGHT
|
0, // AKEYCODE_SOFT_RIGHT
|
||||||
|
@ -267,8 +267,7 @@ static GamepadButton AndroidTranslateGamepadButton(int button);
|
||||||
|
|
||||||
// To allow easier porting to android, we allow the user to define a
|
// To allow easier porting to android, we allow the user to define a
|
||||||
// main function which we call from android_main, defined by ourselves
|
// main function which we call from android_main, defined by ourselves
|
||||||
//extern int main(int argc, char *argv[]);
|
extern int main(int argc, char *argv[]);
|
||||||
extern void android_run();
|
|
||||||
|
|
||||||
// Android main function
|
// Android main function
|
||||||
void android_main(struct android_app *app)
|
void android_main(struct android_app *app)
|
||||||
|
@ -276,21 +275,21 @@ void android_main(struct android_app *app)
|
||||||
char arg0[] = "raylib"; // NOTE: argv[] are mutable
|
char arg0[] = "raylib"; // NOTE: argv[] are mutable
|
||||||
platform.app = app;
|
platform.app = app;
|
||||||
|
|
||||||
(void)android_run();
|
|
||||||
// NOTE: Return from main is ignored
|
// NOTE: Return from main is ignored
|
||||||
//(void)main(1, (char *[]) { arg0, NULL });
|
(void)main(1, (char *[]) { arg0, NULL });
|
||||||
|
|
||||||
// Request to end the native activity
|
// Request to end the native activity
|
||||||
ANativeActivity_finish(app->activity);
|
ANativeActivity_finish(app->activity);
|
||||||
|
|
||||||
// Android ALooper_pollAll() variables
|
// Android ALooper_pollOnce() variables
|
||||||
int pollResult = 0;
|
int pollResult = 0;
|
||||||
int pollEvents = 0;
|
int pollEvents = 0;
|
||||||
|
|
||||||
// Waiting for application events before complete finishing
|
// Waiting for application events before complete finishing
|
||||||
while (!app->destroyRequested)
|
while (!app->destroyRequested)
|
||||||
{
|
{
|
||||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void **)&platform.source)) >= 0)
|
// Poll all events until we reach return value TIMEOUT, meaning no events left to process
|
||||||
|
while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, (void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)
|
||||||
{
|
{
|
||||||
if (platform.source != NULL) platform.source->process(app, platform.source);
|
if (platform.source != NULL) platform.source->process(app, platform.source);
|
||||||
}
|
}
|
||||||
|
@ -616,7 +615,7 @@ int SetGamepadMappings(const char *mappings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set gamepad vibration
|
// Set gamepad vibration
|
||||||
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
|
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
|
||||||
}
|
}
|
||||||
|
@ -634,6 +633,13 @@ void SetMouseCursor(int cursor)
|
||||||
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get physical key name.
|
||||||
|
const char *GetKeyName(int key)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// Register all input events
|
// Register all input events
|
||||||
void PollInputEvents(void)
|
void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
|
@ -677,27 +683,27 @@ void PollInputEvents(void)
|
||||||
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
|
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Android ALooper_pollAll() variables
|
// Android ALooper_pollOnce() variables
|
||||||
int pollResult = 0;
|
int pollResult = 0;
|
||||||
int pollEvents = 0;
|
int pollEvents = 0;
|
||||||
|
|
||||||
// Poll Events (registered events)
|
// Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll
|
||||||
// NOTE: Activity is paused if not enabled (platform.appEnabled)
|
// NOTE: Activity is paused if not enabled (platform.appEnabled)
|
||||||
while ((pollResult = ALooper_pollAll(platform.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT)
|
||||||
{
|
{
|
||||||
// Process this event
|
// Process this event
|
||||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||||
|
|
||||||
// NOTE: Never close window, native activity is controlled by the system!
|
// NOTE: Allow closing the window in case a configuration change happened.
|
||||||
|
// The android_main function should be allowed to return to its caller in order for the
|
||||||
|
// Android OS to relaunch the activity.
|
||||||
if (platform.app->destroyRequested != 0)
|
if (platform.app->destroyRequested != 0)
|
||||||
{
|
{
|
||||||
//CORE.Window.shouldClose = true;
|
CORE.Window.shouldClose = true;
|
||||||
//ANativeActivity_finish(platform.app->activity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -762,20 +768,20 @@ int InitPlatform(void)
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Initialized successfully");
|
||||||
|
|
||||||
// Android ALooper_pollAll() variables
|
// Android ALooper_pollOnce() variables
|
||||||
int pollResult = 0;
|
int pollResult = 0;
|
||||||
int pollEvents = 0;
|
int pollEvents = 0;
|
||||||
|
|
||||||
// Wait for window to be initialized (display and context)
|
// Wait for window to be initialized (display and context)
|
||||||
while (!CORE.Window.ready)
|
while (!CORE.Window.ready)
|
||||||
{
|
{
|
||||||
// Process events loop
|
// Process events until we reach TIMEOUT, which indicates no more events queued.
|
||||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT)
|
||||||
{
|
{
|
||||||
// Process this event
|
// Process this event
|
||||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||||
|
|
||||||
// NOTE: Never close window, native activity is controlled by the system!
|
// NOTE: It's highly likely destroyRequested will never be non-zero at the start of the activity lifecycle.
|
||||||
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,6 +812,12 @@ void ClosePlatform(void)
|
||||||
eglTerminate(platform.device);
|
eglTerminate(platform.device);
|
||||||
platform.device = EGL_NO_DISPLAY;
|
platform.device = EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Reset global state in case the activity is being relaunched.
|
||||||
|
if (platform.app->destroyRequested != 0) {
|
||||||
|
CORE = (CoreData){0};
|
||||||
|
platform = (PlatformData){0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize display device and framebuffer
|
||||||
|
@ -976,6 +988,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||||
// Initialize OpenGL context (states and resources)
|
// Initialize OpenGL context (states and resources)
|
||||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
||||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
|
isGpuReady = true;
|
||||||
|
|
||||||
// Setup default viewport
|
// Setup default viewport
|
||||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||||
|
@ -1135,9 +1148,9 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue(
|
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue(
|
||||||
event, AMOTION_EVENT_AXIS_RZ, 0);
|
event, AMOTION_EVENT_AXIS_RZ, 0);
|
||||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue(
|
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue(
|
||||||
event, AMOTION_EVENT_AXIS_BRAKE, 0) * 2.0f - 1.0f;
|
event, AMOTION_EVENT_AXIS_BRAKE, 0)*2.0f - 1.0f;
|
||||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue(
|
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue(
|
||||||
event, AMOTION_EVENT_AXIS_GAS, 0) * 2.0f - 1.0f;
|
event, AMOTION_EVENT_AXIS_GAS, 0)*2.0f - 1.0f;
|
||||||
|
|
||||||
// dpad is reported as an axis on android
|
// dpad is reported as an axis on android
|
||||||
float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
|
float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
|
||||||
|
@ -1203,7 +1216,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||||
return 1; // Handled gamepad button
|
return 1; // Handled gamepad button
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE) ? KeycodeMap[keycode] : KEY_NULL;
|
KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE)? mapKeycode[keycode] : KEY_NULL;
|
||||||
if (key != KEY_NULL)
|
if (key != KEY_NULL)
|
||||||
{
|
{
|
||||||
// Save current key and its state
|
// Save current key and its state
|
||||||
|
@ -1254,10 +1267,10 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||||
CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) };
|
CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) };
|
||||||
|
|
||||||
// Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
|
// Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
|
||||||
float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x) / (float)CORE.Window.display.width;
|
float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x)/(float)CORE.Window.display.width;
|
||||||
float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y) / (float)CORE.Window.display.height;
|
float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y)/(float)CORE.Window.display.height;
|
||||||
CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x * widthRatio - (float)CORE.Window.renderOffset.x / 2;
|
CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x*widthRatio - (float)CORE.Window.renderOffset.x/2;
|
||||||
CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y * heightRatio - (float)CORE.Window.renderOffset.y / 2;
|
CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y*heightRatio - (float)CORE.Window.renderOffset.y/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t action = AMotionEvent_getAction(event);
|
int32_t action = AMotionEvent_getAction(event);
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
typedef void *PVOID;
|
typedef void *PVOID;
|
||||||
typedef PVOID HANDLE;
|
typedef PVOID HANDLE;
|
||||||
|
#include "../external/win32_clipboard.h"
|
||||||
typedef HANDLE HWND;
|
typedef HANDLE HWND;
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#define GLFW_NATIVE_INCLUDE_NONE // To avoid some symbols re-definition in windows.h
|
#define GLFW_NATIVE_INCLUDE_NONE // To avoid some symbols re-definition in windows.h
|
||||||
|
@ -65,8 +66,9 @@
|
||||||
|
|
||||||
#if defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
#if defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||||
// NOTE: Those functions require linking with winmm library
|
// NOTE: Those functions require linking with winmm library
|
||||||
unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod);
|
//#pragma warning(disable: 4273)
|
||||||
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
__declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||||
|
//#pragma warning(default: 4273)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
|
@ -109,6 +111,7 @@ static void ErrorCallback(int error, const char *description);
|
||||||
|
|
||||||
// Window callbacks events
|
// Window callbacks events
|
||||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||||
|
static void WindowPosCallback(GLFWwindow* window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved
|
||||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||||
static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
||||||
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
||||||
|
@ -147,7 +150,7 @@ void ToggleFullscreen(void)
|
||||||
if (!CORE.Window.fullscreen)
|
if (!CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
// Store previous window position (in case we exit fullscreen)
|
// Store previous window position (in case we exit fullscreen)
|
||||||
glfwGetWindowPos(platform.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
CORE.Window.previousPosition = CORE.Window.position;
|
||||||
|
|
||||||
int monitorCount = 0;
|
int monitorCount = 0;
|
||||||
int monitorIndex = GetCurrentMonitor();
|
int monitorIndex = GetCurrentMonitor();
|
||||||
|
@ -179,7 +182,11 @@ void ToggleFullscreen(void)
|
||||||
CORE.Window.fullscreen = false;
|
CORE.Window.fullscreen = false;
|
||||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||||
|
|
||||||
|
// we update the window position right away
|
||||||
|
CORE.Window.position.x = CORE.Window.previousPosition.x;
|
||||||
|
CORE.Window.position.y = CORE.Window.previousPosition.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
||||||
|
@ -190,11 +197,11 @@ void ToggleFullscreen(void)
|
||||||
// Toggle borderless windowed mode
|
// Toggle borderless windowed mode
|
||||||
void ToggleBorderlessWindowed(void)
|
void ToggleBorderlessWindowed(void)
|
||||||
{
|
{
|
||||||
// Leave fullscreen before attempting to set borderless windowed mode and get screen position from it
|
// Leave fullscreen before attempting to set borderless windowed mode
|
||||||
bool wasOnFullscreen = false;
|
bool wasOnFullscreen = false;
|
||||||
if (CORE.Window.fullscreen)
|
if (CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
CORE.Window.previousPosition = CORE.Window.position;
|
// fullscreen already saves the previous position so it does not need to be set here again
|
||||||
ToggleFullscreen();
|
ToggleFullscreen();
|
||||||
wasOnFullscreen = true;
|
wasOnFullscreen = true;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +220,7 @@ void ToggleBorderlessWindowed(void)
|
||||||
{
|
{
|
||||||
// Store screen position and size
|
// Store screen position and size
|
||||||
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
||||||
if (!wasOnFullscreen) glfwGetWindowPos(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
|
if (!wasOnFullscreen) CORE.Window.previousPosition = CORE.Window.position;
|
||||||
CORE.Window.previousScreen = CORE.Window.screen;
|
CORE.Window.previousScreen = CORE.Window.screen;
|
||||||
|
|
||||||
// Set undecorated and topmost modes and flags
|
// Set undecorated and topmost modes and flags
|
||||||
|
@ -255,6 +262,9 @@ void ToggleBorderlessWindowed(void)
|
||||||
glfwFocusWindow(platform.handle);
|
glfwFocusWindow(platform.handle);
|
||||||
|
|
||||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||||
|
|
||||||
|
CORE.Window.position.x = CORE.Window.previousPosition.x;
|
||||||
|
CORE.Window.position.y = CORE.Window.previousPosition.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
|
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
|
||||||
|
@ -592,6 +602,9 @@ void SetWindowTitle(const char *title)
|
||||||
// Set window position on screen (windowed mode)
|
// Set window position on screen (windowed mode)
|
||||||
void SetWindowPosition(int x, int y)
|
void SetWindowPosition(int x, int y)
|
||||||
{
|
{
|
||||||
|
// Update CORE.Window.position as well
|
||||||
|
CORE.Window.position.x = x;
|
||||||
|
CORE.Window.position.y = y;
|
||||||
glfwSetWindowPos(platform.handle, x, y);
|
glfwSetWindowPos(platform.handle, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,8 +627,9 @@ void SetWindowMonitor(int monitor)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_INFO, "GLFW: Selected monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
TRACELOG(LOG_INFO, "GLFW: Selected monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
||||||
|
|
||||||
const int screenWidth = CORE.Window.screen.width;
|
// Here the render width has to be used again in case high dpi flag is enabled
|
||||||
const int screenHeight = CORE.Window.screen.height;
|
const int screenWidth = CORE.Window.render.width;
|
||||||
|
const int screenHeight = CORE.Window.render.height;
|
||||||
int monitorWorkareaX = 0;
|
int monitorWorkareaX = 0;
|
||||||
int monitorWorkareaY = 0;
|
int monitorWorkareaY = 0;
|
||||||
int monitorWorkareaWidth = 0;
|
int monitorWorkareaWidth = 0;
|
||||||
|
@ -666,6 +680,9 @@ void SetWindowMaxSize(int width, int height)
|
||||||
// Set window dimensions
|
// Set window dimensions
|
||||||
void SetWindowSize(int width, int height)
|
void SetWindowSize(int width, int height)
|
||||||
{
|
{
|
||||||
|
CORE.Window.screen.width = width;
|
||||||
|
CORE.Window.screen.height = height;
|
||||||
|
|
||||||
glfwSetWindowSize(platform.handle, width, height);
|
glfwSetWindowSize(platform.handle, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,6 +967,33 @@ const char *GetClipboardText(void)
|
||||||
return glfwGetClipboardString(platform.handle);
|
return glfwGetClipboardString(platform.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||||
|
// Get clipboard image
|
||||||
|
Image GetClipboardImage(void)
|
||||||
|
{
|
||||||
|
Image image = {0};
|
||||||
|
unsigned long long int dataSize = 0;
|
||||||
|
void* fileData = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int width, height;
|
||||||
|
fileData = (void*)Win32GetClipboardImageData(&width, &height, &dataSize);
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_GLFW doesn't implement `GetClipboardImage` for this OS");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fileData == NULL)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = LoadImageFromMemory(".bmp", fileData, (int)dataSize);
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
#endif // SUPPORT_CLIPBOARD_IMAGE
|
||||||
|
|
||||||
// Show mouse cursor
|
// Show mouse cursor
|
||||||
void ShowCursor(void)
|
void ShowCursor(void)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1089,7 @@ int SetGamepadMappings(const char *mappings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set gamepad vibration
|
// Set gamepad vibration
|
||||||
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
|
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform");
|
TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform");
|
||||||
}
|
}
|
||||||
|
@ -1072,6 +1116,12 @@ void SetMouseCursor(int cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get physical key name.
|
||||||
|
const char *GetKeyName(int key)
|
||||||
|
{
|
||||||
|
return glfwGetKeyName(key, glfwGetKeyScancode(key));
|
||||||
|
}
|
||||||
|
|
||||||
// Register all input events
|
// Register all input events
|
||||||
void PollInputEvents(void)
|
void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
|
@ -1144,7 +1194,7 @@ void PollInputEvents(void)
|
||||||
|
|
||||||
const unsigned char *buttons = state.buttons;
|
const unsigned char *buttons = state.buttons;
|
||||||
|
|
||||||
for (int k = 0; (buttons != NULL) && (k < GLFW_GAMEPAD_BUTTON_DPAD_LEFT + 1) && (k < MAX_GAMEPAD_BUTTONS); k++)
|
for (int k = 0; (buttons != NULL) && (k < MAX_GAMEPAD_BUTTONS); k++)
|
||||||
{
|
{
|
||||||
int button = -1; // GamepadButton enum values assigned
|
int button = -1; // GamepadButton enum values assigned
|
||||||
|
|
||||||
|
@ -1186,7 +1236,7 @@ void PollInputEvents(void)
|
||||||
// Get current axis state
|
// Get current axis state
|
||||||
const float *axes = state.axes;
|
const float *axes = state.axes;
|
||||||
|
|
||||||
for (int k = 0; (axes != NULL) && (k < GLFW_GAMEPAD_AXIS_LAST + 1) && (k < MAX_GAMEPAD_AXIS); k++)
|
for (int k = 0; (axes != NULL) && (k < GLFW_GAMEPAD_AXIS_LAST + 1); k++)
|
||||||
{
|
{
|
||||||
CORE.Input.Gamepad.axisState[i][k] = axes[k];
|
CORE.Input.Gamepad.axisState[i][k] = axes[k];
|
||||||
}
|
}
|
||||||
|
@ -1213,7 +1263,6 @@ void PollInputEvents(void)
|
||||||
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -1266,6 +1315,11 @@ int InitPlatform(void)
|
||||||
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
|
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
|
||||||
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
|
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
|
||||||
|
|
||||||
|
// Disable GlFW auto iconify behaviour
|
||||||
|
// Auto Iconify automatically minimizes (iconifies) the window if the window loses focus
|
||||||
|
// additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window
|
||||||
|
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
||||||
|
|
||||||
// Check window creation flags
|
// Check window creation flags
|
||||||
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
|
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
|
||||||
|
|
||||||
|
@ -1421,7 +1475,7 @@ int InitPlatform(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
||||||
|
|
||||||
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
|
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
|
||||||
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
|
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
|
||||||
|
@ -1443,15 +1497,7 @@ int InitPlatform(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No-fullscreen window creation
|
// No-fullscreen window creation
|
||||||
bool wantWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
|
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
|
||||||
|
|
||||||
// If we are windowed fullscreen, ensures that window does not minimize when focus is lost.
|
|
||||||
// This hinting code will not work if the user already specified the correct monitor dimensions;
|
|
||||||
// at this point we don't know the monitor's dimensions. (Though, how did the user then?)
|
|
||||||
if (wantWindowedFullscreen)
|
|
||||||
{
|
|
||||||
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to at least one pixel in size, as creation with a zero dimension is not allowed.
|
// Default to at least one pixel in size, as creation with a zero dimension is not allowed.
|
||||||
int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1;
|
int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1;
|
||||||
|
@ -1471,11 +1517,7 @@ int InitPlatform(void)
|
||||||
monitor = monitors[monitorIndex];
|
monitor = monitors[monitorIndex];
|
||||||
SetDimensionsFromMonitor(monitor);
|
SetDimensionsFromMonitor(monitor);
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "wantWindowed: %d, size: %dx%d", wantWindowedFullscreen, CORE.Window.screen.width, CORE.Window.screen.height);
|
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
|
||||||
if (wantWindowedFullscreen)
|
|
||||||
{
|
|
||||||
glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1567,11 +1609,16 @@ int InitPlatform(void)
|
||||||
int monitorHeight = 0;
|
int monitorHeight = 0;
|
||||||
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
|
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
|
||||||
|
|
||||||
int posX = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2;
|
// Here CORE.Window.render.width/height should be used instead of CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled.
|
||||||
int posY = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2;
|
int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2;
|
||||||
|
int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2;
|
||||||
if (posX < monitorX) posX = monitorX;
|
if (posX < monitorX) posX = monitorX;
|
||||||
if (posY < monitorY) posY = monitorY;
|
if (posY < monitorY) posY = monitorY;
|
||||||
SetWindowPosition(posX, posY);
|
SetWindowPosition(posX, posY);
|
||||||
|
|
||||||
|
// Update CORE.Window.position here so it is correct from the start
|
||||||
|
CORE.Window.position.x = posX;
|
||||||
|
CORE.Window.position.y = posY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load OpenGL extensions
|
// Load OpenGL extensions
|
||||||
|
@ -1583,6 +1630,7 @@ int InitPlatform(void)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Set window callback events
|
// Set window callback events
|
||||||
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||||
|
glfwSetWindowPosCallback(platform.handle, WindowPosCallback);
|
||||||
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
||||||
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
||||||
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
||||||
|
@ -1621,7 +1669,11 @@ int InitPlatform(void)
|
||||||
CORE.Storage.basePath = GetWorkingDirectory();
|
CORE.Storage.basePath = GetWorkingDirectory();
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
char* glfwPlatform = "";
|
#if defined(__NetBSD__)
|
||||||
|
// Workaround for NetBSD
|
||||||
|
char *glfwPlatform = "X11";
|
||||||
|
#else
|
||||||
|
char *glfwPlatform = "";
|
||||||
switch (glfwGetPlatform())
|
switch (glfwGetPlatform())
|
||||||
{
|
{
|
||||||
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
|
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
|
||||||
|
@ -1629,10 +1681,11 @@ int InitPlatform(void)
|
||||||
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
|
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
|
||||||
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
|
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
|
||||||
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
|
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform);
|
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW - %s): Initialized successfully", glfwPlatform);
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1668,27 +1721,18 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||||
if (IsWindowFullscreen()) return;
|
if (IsWindowFullscreen()) return;
|
||||||
|
|
||||||
// Set current screen size
|
// Set current screen size
|
||||||
#if defined(__APPLE__)
|
|
||||||
CORE.Window.screen.width = width;
|
|
||||||
CORE.Window.screen.height = height;
|
|
||||||
#else
|
|
||||||
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
|
|
||||||
{
|
|
||||||
Vector2 windowScaleDPI = GetWindowScaleDPI();
|
|
||||||
|
|
||||||
CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x);
|
|
||||||
CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CORE.Window.screen.width = width;
|
CORE.Window.screen.width = width;
|
||||||
CORE.Window.screen.height = height;
|
CORE.Window.screen.height = height;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// NOTE: Postprocessing texture is not scaled to new size
|
// NOTE: Postprocessing texture is not scaled to new size
|
||||||
}
|
}
|
||||||
|
static void WindowPosCallback(GLFWwindow* window, int x, int y)
|
||||||
|
{
|
||||||
|
// Set current window position
|
||||||
|
CORE.Window.position.x = x;
|
||||||
|
CORE.Window.position.y = y;
|
||||||
|
}
|
||||||
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
|
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
|
||||||
{
|
{
|
||||||
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
|
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
|
||||||
|
@ -1882,4 +1926,8 @@ static void JoystickCallback(int jid, int event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define WIN32_CLIPBOARD_IMPLEMENTATION
|
||||||
|
# include "../external/win32_clipboard.h"
|
||||||
|
#endif
|
||||||
// EOF
|
// EOF
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,7 @@
|
||||||
* Custom flag for rcore on target platform -not used-
|
* Custom flag for rcore on target platform -not used-
|
||||||
*
|
*
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* - SDL 2 (main library): Windowing and inputs management
|
* - SDL 2 or SLD 3 (main library): Windowing and inputs management
|
||||||
* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
|
* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -48,6 +48,10 @@
|
||||||
*
|
*
|
||||||
**********************************************************************************************/
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SDL_ENABLE_OLD_NAMES
|
||||||
|
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
|
||||||
|
#endif
|
||||||
#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
|
#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
@ -57,6 +61,20 @@
|
||||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#ifndef MAX_CLIPBOARD_BUFFER_LENGTH
|
||||||
|
#define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ((defined(SDL_MAJOR_VERSION) && SDL_MAJOR_VERSION == 3) && (defined(SDL_MINOR_VERSION) && SDL_MINOR_VERSION >= 1))
|
||||||
|
#ifndef PLATFORM_DESKTOP_SDL3
|
||||||
|
#define PLATFORM_DESKTOP_SDL3
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -64,7 +82,7 @@ typedef struct {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
|
|
||||||
SDL_Joystick *gamepad[MAX_GAMEPADS];
|
SDL_GameController *gamepad[MAX_GAMEPADS];
|
||||||
SDL_Cursor *cursor;
|
SDL_Cursor *cursor;
|
||||||
bool cursorRelative;
|
bool cursorRelative;
|
||||||
} PlatformData;
|
} PlatformData;
|
||||||
|
@ -80,7 +98,7 @@ static PlatformData platform = { 0 }; // Platform specific data
|
||||||
// Local Variables Definition
|
// Local Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#define SCANCODE_MAPPED_NUM 232
|
#define SCANCODE_MAPPED_NUM 232
|
||||||
static const KeyboardKey ScancodeToKey[SCANCODE_MAPPED_NUM] = {
|
static const KeyboardKey mapScancodeToKey[SCANCODE_MAPPED_NUM] = {
|
||||||
KEY_NULL, // SDL_SCANCODE_UNKNOWN
|
KEY_NULL, // SDL_SCANCODE_UNKNOWN
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -220,6 +238,190 @@ static const int CursorsLUT[] = {
|
||||||
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
|
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// SDL3 Migration Layer made to avoid `ifdefs` inside functions when we can.
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
|
||||||
|
// SDL3 Migration:
|
||||||
|
// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed,
|
||||||
|
// and you can call SDL_GetWindowFullscreenMode()
|
||||||
|
// to see whether an exclusive fullscreen mode will be used
|
||||||
|
// or the borderless fullscreen desktop mode will be used
|
||||||
|
#define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN
|
||||||
|
|
||||||
|
|
||||||
|
#define SDL_IGNORE false
|
||||||
|
#define SDL_DISABLE false
|
||||||
|
#define SDL_ENABLE true
|
||||||
|
|
||||||
|
// SDL3 Migration: SDL_INIT_TIMER - no longer needed before calling SDL_AddTimer()
|
||||||
|
#define SDL_INIT_TIMER 0x0 // It's a flag, so no problem in setting it to zero if we use in a bitor (|)
|
||||||
|
|
||||||
|
// SDL3 Migration: The SDL_WINDOW_SHOWN flag has been removed. Windows are shown by default and can be created hidden by using the SDL_WINDOW_HIDDEN flag.
|
||||||
|
#define SDL_WINDOW_SHOWN 0x0 // It's a flag, so no problem in setting it to zero if we use in a bitor (|)
|
||||||
|
|
||||||
|
//
|
||||||
|
// SDL3 Migration: Renamed
|
||||||
|
// IMPORTANT:
|
||||||
|
// Might need to call SDL_CleanupEvent somewhere see :https://github.com/libsdl-org/SDL/issues/3540#issuecomment-1793449852
|
||||||
|
//
|
||||||
|
#define SDL_DROPFILE SDL_EVENT_DROP_FILE
|
||||||
|
|
||||||
|
|
||||||
|
const char* SDL_GameControllerNameForIndex(int joystickIndex)
|
||||||
|
{
|
||||||
|
// NOTE: SDL3 uses the IDs itself (SDL_JoystickID) instead of SDL2 joystick_index
|
||||||
|
const char* name = NULL;
|
||||||
|
int numJoysticks = 0;
|
||||||
|
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks);
|
||||||
|
if (joysticks) {
|
||||||
|
if (joystickIndex < numJoysticks) {
|
||||||
|
SDL_JoystickID instance_id = joysticks[joystickIndex];
|
||||||
|
name = SDL_GetGamepadNameForID(instance_id);
|
||||||
|
}
|
||||||
|
SDL_free(joysticks);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDL_GetNumVideoDisplays(void)
|
||||||
|
{
|
||||||
|
int monitorCount = 0;
|
||||||
|
SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
|
||||||
|
// Safe because If `mem` is NULL, SDL_free does nothing.
|
||||||
|
SDL_free(displays);
|
||||||
|
|
||||||
|
return monitorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SLD3 Migration:
|
||||||
|
// To emulate SDL2 this function should return `SDL_DISABLE` or `SDL_ENABLE`
|
||||||
|
// representing the *processing state* of the event before this function makes any changes to it.
|
||||||
|
Uint8 SDL_EventState(Uint32 type, int state) {
|
||||||
|
|
||||||
|
Uint8 stateBefore = SDL_EventEnabled(type);
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case SDL_DISABLE: SDL_SetEventEnabled(type, false); break;
|
||||||
|
case SDL_ENABLE: SDL_SetEventEnabled(type, true); break;
|
||||||
|
default: TRACELOG(LOG_WARNING, "Event sate: unknow type");
|
||||||
|
}
|
||||||
|
return stateBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode* mode)
|
||||||
|
{
|
||||||
|
const SDL_DisplayMode* currMode = SDL_GetCurrentDisplayMode(displayID);
|
||||||
|
if (currMode == NULL)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "No current display mode");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*mode = *currMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDL3 Migration: Renamed
|
||||||
|
#define SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode_Adapter
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||||
|
{
|
||||||
|
return SDL_CreateSurface(width, height, SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask));
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDL3 Migration:
|
||||||
|
// SDL_GetDisplayDPI() -
|
||||||
|
// not reliable across platforms, approximately replaced by multiplying
|
||||||
|
// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms.
|
||||||
|
// returns 0 on success or a negative error code on failure
|
||||||
|
int SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi) {
|
||||||
|
float dpi = SDL_GetWindowDisplayScale(platform.window) * 96.0;
|
||||||
|
if (ddpi != NULL) *ddpi = dpi;
|
||||||
|
if (hdpi != NULL) *hdpi = dpi;
|
||||||
|
if (vdpi != NULL) *vdpi = dpi;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
|
||||||
|
{
|
||||||
|
return SDL_CreateSurface(width, height, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||||
|
{
|
||||||
|
return SDL_CreateSurfaceFrom(width, height, SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask), pixels, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
|
||||||
|
{
|
||||||
|
return SDL_CreateSurfaceFrom(width, height, format, pixels, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDL_NumJoysticks(void)
|
||||||
|
{
|
||||||
|
int numJoysticks;
|
||||||
|
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks);
|
||||||
|
SDL_free(joysticks);
|
||||||
|
return numJoysticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SDL_SetRelativeMouseMode
|
||||||
|
// returns 0 on success or a negative error code on failure
|
||||||
|
// If relative mode is not supported, this returns -1.
|
||||||
|
int SDL_SetRelativeMouseMode_Adapter(SDL_bool enabled)
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// SDL_SetWindowRelativeMouseMode(SDL_Window *window, bool enabled)
|
||||||
|
// \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
//
|
||||||
|
if (SDL_SetWindowRelativeMouseMode(platform.window, enabled))
|
||||||
|
{
|
||||||
|
return 0; // success
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1; // failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SDL_SetRelativeMouseMode SDL_SetRelativeMouseMode_Adapter
|
||||||
|
|
||||||
|
bool SDL_GetRelativeMouseMode_Adapter(void)
|
||||||
|
{
|
||||||
|
return SDL_GetWindowRelativeMouseMode(platform.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SDL_GetRelativeMouseMode SDL_GetRelativeMouseMode_Adapter
|
||||||
|
|
||||||
|
|
||||||
|
int SDL_GetNumTouchFingers(SDL_TouchID touchID)
|
||||||
|
{
|
||||||
|
// SDL_Finger **SDL_GetTouchFingers(SDL_TouchID touchID, int *count)
|
||||||
|
int count = 0;
|
||||||
|
SDL_Finger **fingers = SDL_GetTouchFingers(touchID, &count);
|
||||||
|
SDL_free(fingers);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // We're on SDL2
|
||||||
|
|
||||||
|
// Since SDL2 doesn't have this function we leave a stub
|
||||||
|
// SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3)
|
||||||
|
void* SDL_GetClipboardData(const char *mime_type, size_t *size) {
|
||||||
|
TRACELOG(LOG_WARNING, "Getting clipboard data that is not text is only available in SDL3");
|
||||||
|
// We could possibly implement it ourselves in this case for some easier platforms
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PLATFORM_DESKTOP_SDL3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// Module Internal Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -249,7 +451,12 @@ void ToggleFullscreen(void)
|
||||||
{
|
{
|
||||||
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
||||||
const int monitorCount = SDL_GetNumVideoDisplays();
|
const int monitorCount = SDL_GetNumVideoDisplays();
|
||||||
|
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
|
||||||
|
if ((monitor > 0) && (monitor <= monitorCount))
|
||||||
|
#else
|
||||||
if ((monitor >= 0) && (monitor < monitorCount))
|
if ((monitor >= 0) && (monitor < monitorCount))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)
|
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +479,11 @@ void ToggleBorderlessWindowed(void)
|
||||||
{
|
{
|
||||||
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
||||||
const int monitorCount = SDL_GetNumVideoDisplays();
|
const int monitorCount = SDL_GetNumVideoDisplays();
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
|
||||||
|
if ((monitor > 0) && (monitor <= monitorCount))
|
||||||
|
#else
|
||||||
if ((monitor >= 0) && (monitor < monitorCount))
|
if ((monitor >= 0) && (monitor < monitorCount))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)
|
if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)
|
||||||
{
|
{
|
||||||
|
@ -321,7 +532,11 @@ void SetWindowState(unsigned int flags)
|
||||||
{
|
{
|
||||||
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
||||||
const int monitorCount = SDL_GetNumVideoDisplays();
|
const int monitorCount = SDL_GetNumVideoDisplays();
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
|
||||||
|
if ((monitor > 0) && (monitor <= monitorCount))
|
||||||
|
#else
|
||||||
if ((monitor >= 0) && (monitor < monitorCount))
|
if ((monitor >= 0) && (monitor < monitorCount))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
|
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
|
||||||
CORE.Window.fullscreen = true;
|
CORE.Window.fullscreen = true;
|
||||||
|
@ -380,7 +595,11 @@ void SetWindowState(unsigned int flags)
|
||||||
{
|
{
|
||||||
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
const int monitor = SDL_GetWindowDisplayIndex(platform.window);
|
||||||
const int monitorCount = SDL_GetNumVideoDisplays();
|
const int monitorCount = SDL_GetNumVideoDisplays();
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
|
||||||
|
if ((monitor > 0) && (monitor <= monitorCount))
|
||||||
|
#else
|
||||||
if ((monitor >= 0) && (monitor < monitorCount))
|
if ((monitor >= 0) && (monitor < monitorCount))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
}
|
}
|
||||||
|
@ -476,9 +695,9 @@ void ClearWindowState(unsigned int flags)
|
||||||
// Set icon for window
|
// Set icon for window
|
||||||
void SetWindowIcon(Image image)
|
void SetWindowIcon(Image image)
|
||||||
{
|
{
|
||||||
SDL_Surface* iconSurface = NULL;
|
SDL_Surface *iconSurface = NULL;
|
||||||
|
|
||||||
Uint32 rmask, gmask, bmask, amask;
|
unsigned int rmask = 0, gmask = 0, bmask = 0, amask = 0;
|
||||||
int depth = 0; // Depth in bits
|
int depth = 0; // Depth in bits
|
||||||
int pitch = 0; // Pixel spacing (pitch) in bytes
|
int pitch = 0; // Pixel spacing (pitch) in bytes
|
||||||
|
|
||||||
|
@ -492,72 +711,67 @@ void SetWindowIcon(Image image)
|
||||||
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
|
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
|
||||||
rmask = 0xFF, gmask = 0xFF00;
|
rmask = 0xFF, gmask = 0xFF00;
|
||||||
bmask = 0, amask = 0;
|
bmask = 0, amask = 0;
|
||||||
depth = 16, pitch = image.width * 2;
|
depth = 16, pitch = image.width*2;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
|
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
|
||||||
rmask = 0xF800, gmask = 0x07E0;
|
rmask = 0xF800, gmask = 0x07E0;
|
||||||
bmask = 0x001F, amask = 0;
|
bmask = 0x001F, amask = 0;
|
||||||
depth = 16, pitch = image.width * 2;
|
depth = 16, pitch = image.width*2;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit
|
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit
|
||||||
rmask = 0x0000FF, gmask = 0x00FF00;
|
rmask = 0x0000FF, gmask = 0x00FF00;
|
||||||
bmask = 0xFF0000, amask = 0;
|
bmask = 0xFF0000, amask = 0;
|
||||||
depth = 24, pitch = image.width * 3;
|
depth = 24, pitch = image.width*3;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
|
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
|
||||||
rmask = 0xF800, gmask = 0x07C0;
|
rmask = 0xF800, gmask = 0x07C0;
|
||||||
bmask = 0x003E, amask = 0x0001;
|
bmask = 0x003E, amask = 0x0001;
|
||||||
depth = 16, pitch = image.width * 2;
|
depth = 16, pitch = image.width*2;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4:
|
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4:
|
||||||
rmask = 0xF000, gmask = 0x0F00;
|
rmask = 0xF000, gmask = 0x0F00;
|
||||||
bmask = 0x00F0, amask = 0x000F;
|
bmask = 0x00F0, amask = 0x000F;
|
||||||
depth = 16, pitch = image.width * 2;
|
depth = 16, pitch = image.width*2;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8:
|
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8:
|
||||||
rmask = 0xFF000000, gmask = 0x00FF0000;
|
rmask = 0xFF000000, gmask = 0x00FF0000;
|
||||||
bmask = 0x0000FF00, amask = 0x000000FF;
|
bmask = 0x0000FF00, amask = 0x000000FF;
|
||||||
depth = 32, pitch = image.width * 4;
|
depth = 32, pitch = image.width*4;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R32:
|
case PIXELFORMAT_UNCOMPRESSED_R32:
|
||||||
rmask = 0xFFFFFFFF, gmask = 0;
|
rmask = 0xFFFFFFFF, gmask = 0;
|
||||||
bmask = 0, amask = 0;
|
bmask = 0, amask = 0;
|
||||||
depth = 32, pitch = image.width * 4;
|
depth = 32, pitch = image.width*4;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
|
case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
|
||||||
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
|
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
|
||||||
bmask = 0xFFFFFFFF, amask = 0;
|
bmask = 0xFFFFFFFF, amask = 0;
|
||||||
depth = 96, pitch = image.width * 12;
|
depth = 96, pitch = image.width*12;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
|
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
|
||||||
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
|
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
|
||||||
bmask = 0xFFFFFFFF, amask = 0xFFFFFFFF;
|
bmask = 0xFFFFFFFF, amask = 0xFFFFFFFF;
|
||||||
depth = 128, pitch = image.width * 16;
|
depth = 128, pitch = image.width*16;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R16:
|
case PIXELFORMAT_UNCOMPRESSED_R16:
|
||||||
rmask = 0xFFFF, gmask = 0;
|
rmask = 0xFFFF, gmask = 0;
|
||||||
bmask = 0, amask = 0;
|
bmask = 0, amask = 0;
|
||||||
depth = 16, pitch = image.width * 2;
|
depth = 16, pitch = image.width*2;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
|
case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
|
||||||
rmask = 0xFFFF, gmask = 0xFFFF;
|
rmask = 0xFFFF, gmask = 0xFFFF;
|
||||||
bmask = 0xFFFF, amask = 0;
|
bmask = 0xFFFF, amask = 0;
|
||||||
depth = 48, pitch = image.width * 6;
|
depth = 48, pitch = image.width*6;
|
||||||
break;
|
break;
|
||||||
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
|
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
|
||||||
rmask = 0xFFFF, gmask = 0xFFFF;
|
rmask = 0xFFFF, gmask = 0xFFFF;
|
||||||
bmask = 0xFFFF, amask = 0xFFFF;
|
bmask = 0xFFFF, amask = 0xFFFF;
|
||||||
depth = 64, pitch = image.width * 8;
|
depth = 64, pitch = image.width*8;
|
||||||
break;
|
break;
|
||||||
default:
|
default: return; // Compressed formats are not supported
|
||||||
// Compressed formats are not supported
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iconSurface = SDL_CreateRGBSurfaceFrom(
|
iconSurface = SDL_CreateRGBSurfaceFrom( image.data, image.width, image.height, depth, pitch, rmask, gmask, bmask, amask );
|
||||||
image.data, image.width, image.height, depth, pitch,
|
|
||||||
rmask, gmask, bmask, amask
|
|
||||||
);
|
|
||||||
|
|
||||||
if (iconSurface)
|
if (iconSurface)
|
||||||
{
|
{
|
||||||
|
@ -599,12 +813,16 @@ void SetWindowMonitor(int monitor)
|
||||||
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
|
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
|
||||||
// see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba
|
// see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba
|
||||||
// 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again.
|
// 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again.
|
||||||
const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) ? true : false;
|
const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)? true : false;
|
||||||
|
|
||||||
const int screenWidth = CORE.Window.screen.width;
|
const int screenWidth = CORE.Window.screen.width;
|
||||||
const int screenHeight = CORE.Window.screen.height;
|
const int screenHeight = CORE.Window.screen.height;
|
||||||
SDL_Rect usableBounds;
|
SDL_Rect usableBounds;
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // Different style for success checking
|
||||||
|
if (SDL_GetDisplayUsableBounds(monitor, &usableBounds))
|
||||||
|
#else
|
||||||
if (SDL_GetDisplayUsableBounds(monitor, &usableBounds) == 0)
|
if (SDL_GetDisplayUsableBounds(monitor, &usableBounds) == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (wasFullscreen == 1) ToggleFullscreen(); // Leave fullscreen.
|
if (wasFullscreen == 1) ToggleFullscreen(); // Leave fullscreen.
|
||||||
|
|
||||||
|
@ -702,6 +920,7 @@ int GetCurrentMonitor(void)
|
||||||
{
|
{
|
||||||
int currentMonitor = 0;
|
int currentMonitor = 0;
|
||||||
|
|
||||||
|
// Be aware that this returns an ID in SDL3 and a Index in SDL2
|
||||||
currentMonitor = SDL_GetWindowDisplayIndex(platform.window);
|
currentMonitor = SDL_GetWindowDisplayIndex(platform.window);
|
||||||
|
|
||||||
return currentMonitor;
|
return currentMonitor;
|
||||||
|
@ -714,7 +933,11 @@ Vector2 GetMonitorPosition(int monitor)
|
||||||
if ((monitor >= 0) && (monitor < monitorCount))
|
if ((monitor >= 0) && (monitor < monitorCount))
|
||||||
{
|
{
|
||||||
SDL_Rect displayBounds;
|
SDL_Rect displayBounds;
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
if (SDL_GetDisplayUsableBounds(monitor, &displayBounds))
|
||||||
|
#else
|
||||||
if (SDL_GetDisplayUsableBounds(monitor, &displayBounds) == 0)
|
if (SDL_GetDisplayUsableBounds(monitor, &displayBounds) == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return (Vector2){ (float)displayBounds.x, (float)displayBounds.y };
|
return (Vector2){ (float)displayBounds.x, (float)displayBounds.y };
|
||||||
}
|
}
|
||||||
|
@ -842,10 +1065,16 @@ Vector2 GetWindowScaleDPI(void)
|
||||||
{
|
{
|
||||||
Vector2 scale = { 1.0f, 1.0f };
|
Vector2 scale = { 1.0f, 1.0f };
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DESKTOP_SDL3
|
||||||
// NOTE: SDL_GetWindowDisplayScale was only added on SDL3
|
// NOTE: SDL_GetWindowDisplayScale was only added on SDL3
|
||||||
// see https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale
|
// see https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale
|
||||||
// TODO: Implement the window scale factor calculation manually.
|
// TODO: Implement the window scale factor calculation manually.
|
||||||
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
|
||||||
|
#else
|
||||||
|
scale.x = SDL_GetWindowDisplayScale(platform.window);
|
||||||
|
scale.y = scale.x;
|
||||||
|
TRACELOG(LOG_INFO, "WindowScaleDPI is %f", scale.x);
|
||||||
|
#endif
|
||||||
|
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
@ -857,25 +1086,86 @@ void SetClipboardText(const char *text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get clipboard text content
|
// Get clipboard text content
|
||||||
// NOTE: returned string must be freed with SDL_free()
|
|
||||||
const char *GetClipboardText(void)
|
const char *GetClipboardText(void)
|
||||||
{
|
{
|
||||||
return SDL_GetClipboardText();
|
static char buffer[MAX_CLIPBOARD_BUFFER_LENGTH] = { 0 };
|
||||||
|
|
||||||
|
char *clipboard = SDL_GetClipboardText();
|
||||||
|
|
||||||
|
int clipboardSize = snprintf(buffer, sizeof(buffer), "%s", clipboard);
|
||||||
|
if (clipboardSize >= MAX_CLIPBOARD_BUFFER_LENGTH)
|
||||||
|
{
|
||||||
|
char *truncate = buffer + MAX_CLIPBOARD_BUFFER_LENGTH - 4;
|
||||||
|
sprintf(truncate, "...");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(clipboard);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||||
|
// Get clipboard image
|
||||||
|
Image GetClipboardImage(void)
|
||||||
|
{
|
||||||
|
// Let's hope compiler put these arrays in static memory
|
||||||
|
const char *image_formats[] = {
|
||||||
|
"image/bmp",
|
||||||
|
"image/png",
|
||||||
|
"image/jpg",
|
||||||
|
"image/tiff",
|
||||||
|
};
|
||||||
|
const char *image_extensions[] = {
|
||||||
|
".bmp",
|
||||||
|
".png",
|
||||||
|
".jpg",
|
||||||
|
".tiff",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Image image = {0};
|
||||||
|
size_t dataSize = 0;
|
||||||
|
void *fileData = NULL;
|
||||||
|
for (int i = 0; i < SDL_arraysize(image_formats); ++i)
|
||||||
|
{
|
||||||
|
// NOTE: This pointer should be free with SDL_free() at some point.
|
||||||
|
fileData = SDL_GetClipboardData(image_formats[i], &dataSize);
|
||||||
|
if (fileData) {
|
||||||
|
image = LoadImageFromMemory(image_extensions[i], fileData, dataSize);
|
||||||
|
if (IsImageValid(image))
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_INFO, "Clipboard image: Got image from clipboard as a `%s` successfully", image_extensions[i]);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data. %s", SDL_GetError());
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Show mouse cursor
|
// Show mouse cursor
|
||||||
void ShowCursor(void)
|
void ShowCursor(void)
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
SDL_ShowCursor();
|
||||||
|
#else
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
#endif
|
||||||
CORE.Input.Mouse.cursorHidden = false;
|
CORE.Input.Mouse.cursorHidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hides mouse cursor
|
// Hides mouse cursor
|
||||||
void HideCursor(void)
|
void HideCursor(void)
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
SDL_HideCursor();
|
||||||
|
#else
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
#endif
|
||||||
CORE.Input.Mouse.cursorHidden = true;
|
CORE.Input.Mouse.cursorHidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,7 +1173,13 @@ void HideCursor(void)
|
||||||
void EnableCursor(void)
|
void EnableCursor(void)
|
||||||
{
|
{
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
// SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
|
||||||
|
SDL_ShowCursor();
|
||||||
|
#else
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
#endif
|
||||||
|
|
||||||
platform.cursorRelative = false;
|
platform.cursorRelative = false;
|
||||||
CORE.Input.Mouse.cursorHidden = false;
|
CORE.Input.Mouse.cursorHidden = false;
|
||||||
|
@ -939,17 +1235,17 @@ int SetGamepadMappings(const char *mappings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set gamepad vibration
|
// Set gamepad vibration
|
||||||
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
|
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
|
||||||
{
|
{
|
||||||
//Limit input values to between 0.0f and 1.0f
|
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f))
|
||||||
leftMotor = (0.0f > leftMotor) ? 0.0f : leftMotor;
|
|
||||||
rightMotor = (0.0f > rightMotor) ? 0.0f : rightMotor;
|
|
||||||
leftMotor = (1.0f < leftMotor) ? 1.0f : leftMotor;
|
|
||||||
rightMotor = (1.0f < rightMotor) ? 1.0f : rightMotor;
|
|
||||||
|
|
||||||
if (IsGamepadAvailable(gamepad))
|
|
||||||
{
|
{
|
||||||
SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));
|
if (leftMotor < 0.0f) leftMotor = 0.0f;
|
||||||
|
if (leftMotor > 1.0f) leftMotor = 1.0f;
|
||||||
|
if (rightMotor < 0.0f) rightMotor = 0.0f;
|
||||||
|
if (rightMotor > 1.0f) rightMotor = 1.0f;
|
||||||
|
if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME;
|
||||||
|
|
||||||
|
SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(duration*1000.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,8 +1267,30 @@ void SetMouseCursor(int cursor)
|
||||||
CORE.Input.Mouse.cursor = cursor;
|
CORE.Input.Mouse.cursor = cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get physical key name.
|
||||||
|
const char *GetKeyName(int key)
|
||||||
|
{
|
||||||
|
return SDL_GetKeyName(key);
|
||||||
|
}
|
||||||
|
|
||||||
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
|
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3 // SDL3
|
||||||
|
int count = 0;
|
||||||
|
SDL_Finger **fingers = SDL_GetTouchFingers(event.touchID, &count);
|
||||||
|
CORE.Input.Touch.pointCount = count;
|
||||||
|
|
||||||
|
for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
|
||||||
|
{
|
||||||
|
SDL_Finger *finger = fingers[i];
|
||||||
|
CORE.Input.Touch.pointId[i] = finger->id;
|
||||||
|
CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width;
|
||||||
|
CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
|
||||||
|
CORE.Input.Touch.currentTouchState[i] = 1;
|
||||||
|
}
|
||||||
|
SDL_free(fingers);
|
||||||
|
#else // SDL2
|
||||||
|
|
||||||
CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
|
CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
|
||||||
|
|
||||||
for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
|
for (int i = 0; i < CORE.Input.Touch.pointCount; i++)
|
||||||
|
@ -983,6 +1301,7 @@ static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
|
||||||
CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
|
CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;
|
||||||
CORE.Input.Touch.currentTouchState[i] = 1;
|
CORE.Input.Touch.currentTouchState[i] = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i = CORE.Input.Touch.pointCount; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.currentTouchState[i] = 0;
|
for (int i = CORE.Input.Touch.pointCount; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.currentTouchState[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -1074,16 +1393,26 @@ void PollInputEvents(void)
|
||||||
CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *));
|
CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *));
|
||||||
|
|
||||||
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
|
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
// const char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
|
||||||
|
// Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed.
|
||||||
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
|
||||||
|
#else
|
||||||
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
||||||
SDL_free(event.drop.file);
|
SDL_free(event.drop.file);
|
||||||
|
#endif
|
||||||
|
|
||||||
CORE.Window.dropFileCount++;
|
CORE.Window.dropFileCount++;
|
||||||
}
|
}
|
||||||
else if (CORE.Window.dropFileCount < 1024)
|
else if (CORE.Window.dropFileCount < 1024)
|
||||||
{
|
{
|
||||||
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
|
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
|
||||||
|
#else
|
||||||
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
||||||
SDL_free(event.drop.file);
|
SDL_free(event.drop.file);
|
||||||
|
#endif
|
||||||
|
|
||||||
CORE.Window.dropFileCount++;
|
CORE.Window.dropFileCount++;
|
||||||
}
|
}
|
||||||
|
@ -1092,10 +1421,18 @@ void PollInputEvents(void)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Window events are also polled (Minimized, maximized, close...)
|
// Window events are also polled (Minimized, maximized, close...)
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DESKTOP_SDL3
|
||||||
|
// SDL3 states:
|
||||||
|
// The SDL_WINDOWEVENT_* events have been moved to top level events,
|
||||||
|
// and SDL_WINDOWEVENT has been removed.
|
||||||
|
// In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT
|
||||||
|
// and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event.
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
{
|
{
|
||||||
switch (event.window.event)
|
switch (event.window.event)
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
case SDL_WINDOWEVENT_RESIZED:
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
{
|
{
|
||||||
|
@ -1123,16 +1460,26 @@ void PollInputEvents(void)
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||||
case SDL_WINDOWEVENT_RESTORED:
|
case SDL_WINDOWEVENT_RESTORED:
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
break;
|
||||||
|
#else
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Keyboard events
|
// Keyboard events
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
// SDL3 Migration: The following structures have been removed: * SDL_Keysym
|
||||||
|
KeyboardKey key = ConvertScancodeToKey(event.key.scancode);
|
||||||
|
#else
|
||||||
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
|
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (key != KEY_NULL) {
|
if (key != KEY_NULL)
|
||||||
|
{
|
||||||
// If key was up, add it to the key pressed queue
|
// If key was up, add it to the key pressed queue
|
||||||
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
|
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
|
||||||
{
|
{
|
||||||
|
@ -1154,7 +1501,12 @@ void PollInputEvents(void)
|
||||||
|
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
KeyboardKey key = ConvertScancodeToKey(event.key.scancode);
|
||||||
|
#else
|
||||||
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
|
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
|
||||||
|
#endif
|
||||||
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1249,15 +1601,15 @@ void PollInputEvents(void)
|
||||||
|
|
||||||
if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))
|
if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))
|
||||||
{
|
{
|
||||||
platform.gamepad[jid] = SDL_JoystickOpen(jid);
|
platform.gamepad[jid] = SDL_GameControllerOpen(jid);
|
||||||
|
|
||||||
if (platform.gamepad[jid])
|
if (platform.gamepad[jid])
|
||||||
{
|
{
|
||||||
CORE.Input.Gamepad.ready[jid] = true;
|
CORE.Input.Gamepad.ready[jid] = true;
|
||||||
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(platform.gamepad[jid]);
|
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[jid]));
|
||||||
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
||||||
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
||||||
strncpy(CORE.Input.Gamepad.name[jid], SDL_JoystickName(platform.gamepad[jid]), 63);
|
strncpy(CORE.Input.Gamepad.name[jid], SDL_GameControllerNameForIndex(jid), 63);
|
||||||
CORE.Input.Gamepad.name[jid][63] = '\0';
|
CORE.Input.Gamepad.name[jid][63] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1270,15 +1622,15 @@ void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
int jid = event.jdevice.which;
|
int jid = event.jdevice.which;
|
||||||
|
|
||||||
if (jid == SDL_JoystickInstanceID(platform.gamepad[jid]))
|
if (jid == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid])))
|
||||||
{
|
{
|
||||||
SDL_JoystickClose(platform.gamepad[jid]);
|
SDL_GameControllerClose(platform.gamepad[jid]);
|
||||||
platform.gamepad[jid] = SDL_JoystickOpen(0);
|
platform.gamepad[jid] = SDL_GameControllerOpen(0);
|
||||||
CORE.Input.Gamepad.ready[jid] = false;
|
CORE.Input.Gamepad.ready[jid] = false;
|
||||||
memset(CORE.Input.Gamepad.name[jid], 0, 64);
|
memset(CORE.Input.Gamepad.name[jid], 0, 64);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
{
|
{
|
||||||
int button = -1;
|
int button = -1;
|
||||||
|
|
||||||
|
@ -1312,7 +1664,7 @@ void PollInputEvents(void)
|
||||||
CORE.Input.Gamepad.lastButtonPressed = button;
|
CORE.Input.Gamepad.lastButtonPressed = button;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
{
|
{
|
||||||
int button = -1;
|
int button = -1;
|
||||||
|
|
||||||
|
@ -1346,7 +1698,7 @@ void PollInputEvents(void)
|
||||||
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
|
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
{
|
{
|
||||||
int axis = -1;
|
int axis = -1;
|
||||||
|
|
||||||
|
@ -1364,13 +1716,13 @@ void PollInputEvents(void)
|
||||||
if (axis >= 0)
|
if (axis >= 0)
|
||||||
{
|
{
|
||||||
// SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range
|
// SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range
|
||||||
float value = event.jaxis.value / (float) 32767;
|
float value = event.jaxis.value/(float)32767;
|
||||||
CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value;
|
CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value;
|
||||||
|
|
||||||
// Register button state for triggers in addition to their axes
|
// Register button state for triggers in addition to their axes
|
||||||
if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
|
if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
|
||||||
{
|
{
|
||||||
int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER) ? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
|
int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
|
||||||
int pressed = (value > 0.1f);
|
int pressed = (value > 0.1f);
|
||||||
CORE.Input.Gamepad.currentButtonState[event.jaxis.which][button] = pressed;
|
CORE.Input.Gamepad.currentButtonState[event.jaxis.which][button] = pressed;
|
||||||
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
|
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
|
||||||
|
@ -1499,11 +1851,6 @@ int InitPlatform(void)
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CORE.Window.flags & FLAG_VSYNC_HINT)
|
|
||||||
{
|
|
||||||
SDL_GL_SetSwapInterval(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||||
{
|
{
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
|
@ -1511,7 +1858,11 @@ int InitPlatform(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init window
|
// Init window
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags);
|
||||||
|
#else
|
||||||
platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags);
|
platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init OpenGL context
|
// Init OpenGL context
|
||||||
platform.glContext = SDL_GL_CreateContext(platform.window);
|
platform.glContext = SDL_GL_CreateContext(platform.window);
|
||||||
|
@ -1537,6 +1888,9 @@ int InitPlatform(void)
|
||||||
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
|
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
|
||||||
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
||||||
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
||||||
|
|
||||||
|
if (CORE.Window.flags & FLAG_VSYNC_HINT) SDL_GL_SetSwapInterval(1);
|
||||||
|
else SDL_GL_SetSwapInterval(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1554,14 +1908,15 @@ int InitPlatform(void)
|
||||||
// Initialize gamepads
|
// Initialize gamepads
|
||||||
for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
|
for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
|
||||||
{
|
{
|
||||||
platform.gamepad[i] = SDL_JoystickOpen(i);
|
platform.gamepad[i] = SDL_GameControllerOpen(i);
|
||||||
|
|
||||||
if (platform.gamepad[i])
|
if (platform.gamepad[i])
|
||||||
{
|
{
|
||||||
CORE.Input.Gamepad.ready[i] = true;
|
CORE.Input.Gamepad.ready[i] = true;
|
||||||
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(platform.gamepad[i]);
|
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
|
||||||
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
|
||||||
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
|
||||||
strncpy(CORE.Input.Gamepad.name[i], SDL_JoystickName(platform.gamepad[i]), 63);
|
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), 63);
|
||||||
CORE.Input.Gamepad.name[i][63] = '\0';
|
CORE.Input.Gamepad.name[i][63] = '\0';
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
|
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
|
||||||
|
@ -1587,10 +1942,16 @@ int InitPlatform(void)
|
||||||
|
|
||||||
// Initialize storage system
|
// Initialize storage system
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
CORE.Storage.basePath = GetWorkingDirectory(); // Define base path for storage
|
// Define base path for storage
|
||||||
|
CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef PLATFORM_DESKTOP_SDL3
|
||||||
|
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL3): Initialized successfully");
|
||||||
|
#else
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1609,8 +1970,9 @@ static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode)
|
||||||
{
|
{
|
||||||
if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM)
|
if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM)
|
||||||
{
|
{
|
||||||
return ScancodeToKey[sdlScancode];
|
return mapScancodeToKey[sdlScancode];
|
||||||
}
|
}
|
||||||
|
|
||||||
return KEY_NULL; // No equivalent key in Raylib
|
return KEY_NULL; // No equivalent key in Raylib
|
||||||
}
|
}
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -89,7 +89,6 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
typedef unsigned int uint;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Display data
|
// Display data
|
||||||
|
@ -207,7 +206,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {
|
||||||
[BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,
|
[BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,
|
||||||
[BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,
|
[BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,
|
||||||
[BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
|
[BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
|
||||||
[BTN_TR2] GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
[BTN_TR2] = GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
||||||
[BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,
|
[BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,
|
||||||
[BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,
|
[BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,
|
||||||
[BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,
|
[BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,
|
||||||
|
@ -611,7 +610,7 @@ int SetGamepadMappings(const char *mappings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set gamepad vibration
|
// Set gamepad vibration
|
||||||
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
|
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
|
||||||
}
|
}
|
||||||
|
@ -629,6 +628,13 @@ void SetMouseCursor(int cursor)
|
||||||
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get physical key name.
|
||||||
|
const char *GetKeyName(int key)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// Register all input events
|
// Register all input events
|
||||||
void PollInputEvents(void)
|
void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
|
@ -758,7 +764,9 @@ int InitPlatform(void)
|
||||||
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
||||||
|
|
||||||
if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))
|
// In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected.
|
||||||
|
// This might be a hardware or software limitation like on Raspberry Pi Zero with composite output.
|
||||||
|
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
||||||
platform.connector = con;
|
platform.connector = con;
|
||||||
|
@ -1029,7 +1037,7 @@ int InitPlatform(void)
|
||||||
|
|
||||||
// If graphic device is no properly initialized, we end program
|
// If graphic device is no properly initialized, we end program
|
||||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
|
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
|
||||||
|
|
||||||
// Set some default window flags
|
// Set some default window flags
|
||||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
||||||
|
@ -1137,7 +1145,8 @@ void ClosePlatform(void)
|
||||||
|
|
||||||
// Close the evdev devices
|
// Close the evdev devices
|
||||||
|
|
||||||
if (platform.mouseFd != -1) {
|
if (platform.mouseFd != -1)
|
||||||
|
{
|
||||||
close(platform.mouseFd);
|
close(platform.mouseFd);
|
||||||
platform.mouseFd = -1;
|
platform.mouseFd = -1;
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1480,6 @@ static void ConfigureEvdevDevice(char *device)
|
||||||
TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
|
TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (TEST_BIT(evBits, EV_KEY))
|
if (TEST_BIT(evBits, EV_KEY))
|
||||||
{
|
{
|
||||||
// The first 32 keys as defined in input-event-codes.h are pretty much
|
// The first 32 keys as defined in input-event-codes.h are pretty much
|
||||||
|
@ -1614,7 +1622,7 @@ static void PollKeyboardEvents(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0) ? "UP " : "DOWN", event.code, keycode);
|
TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0)? "UP " : "DOWN", event.code, keycode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1641,7 +1649,7 @@ static void PollGamepadEvents(void)
|
||||||
{
|
{
|
||||||
short keycodeRaylib = linuxToRaylibMap[event.code];
|
short keycodeRaylib = linuxToRaylibMap[event.code];
|
||||||
|
|
||||||
TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0) ? "UP " : "DOWN", event.code, keycodeRaylib);
|
TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycodeRaylib);
|
||||||
|
|
||||||
if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS))
|
if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS))
|
||||||
{
|
{
|
||||||
|
@ -1666,7 +1674,7 @@ static void PollGamepadEvents(void)
|
||||||
int range = platform.gamepadAbsAxisRange[i][event.code][1];
|
int range = platform.gamepadAbsAxisRange[i][event.code][1];
|
||||||
|
|
||||||
// NOTE: Scaling of event.value to get values between -1..1
|
// NOTE: Scaling of event.value to get values between -1..1
|
||||||
CORE.Input.Gamepad.axisState[i][axisRaylib] = (2 * (float)(event.value - min) / range) - 1;
|
CORE.Input.Gamepad.axisState[i][axisRaylib] = (2*(float)(event.value - min)/range) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1925,9 +1933,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
||||||
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
|
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
|
||||||
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
|
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
|
||||||
|
|
||||||
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) {
|
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
|
||||||
nearestIndex = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nearestIndex;
|
return nearestIndex;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue