118#if !defined(EXTERNAL_CONFIG_FLAGS)
124#define RLGL_IMPLEMENTATION
127#define RAYMATH_IMPLEMENTATION
130#if defined(SUPPORT_GESTURES_SYSTEM)
131 #define GESTURES_IMPLEMENTATION
135#if defined(SUPPORT_CAMERA_SYSTEM)
136 #define CAMERA_IMPLEMENTATION
140#if defined(SUPPORT_GIF_RECORDING)
141 #define MSF_GIF_MALLOC(contextPointer, newSize) RL_MALLOC(newSize)
142 #define MSF_GIF_REALLOC(contextPointer, oldMemory, oldSize, newSize) RL_REALLOC(oldMemory, newSize)
143 #define MSF_GIF_FREE(contextPointer, oldMemory, oldSize) RL_FREE(oldMemory)
149#if defined(SUPPORT_COMPRESSION_API)
150 #define SINFL_IMPLEMENTATION
151 #define SINFL_NO_SIMD
154 #define SDEFL_IMPLEMENTATION
158#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
159 #undef _POSIX_C_SOURCE
160 #define _POSIX_C_SOURCE 199309L
164#if defined (PLATFORM_DESKTOP)
167 #define MAX_PATH 1025
169 __declspec(dllimport)
unsigned long __stdcall GetModuleFileNameA(
void *hModule,
void *lpFilename,
unsigned long nSize);
170 __declspec(dllimport)
unsigned long __stdcall GetModuleFileNameW(
void *hModule,
void *lpFilename,
unsigned long nSize);
171 __declspec(dllimport)
int __stdcall WideCharToMultiByte(
unsigned int cp,
unsigned long flags,
void *widestr,
int cchwide,
void *str,
int cbmb,
void *defchar,
int *used_default);
172 #elif defined(__linux__)
174 #elif defined(__APPLE__)
175 #include <sys/syslimits.h>
176 #include <mach-o/dyld.h>
188#if defined(PLATFORM_DESKTOP) && defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__))
189 #define DIRENT_MALLOC RL_MALLOC
190 #define DIRENT_FREE RL_FREE
199 #define GETCWD _getcwd
204 #define GETCWD getcwd
208#if defined(PLATFORM_DESKTOP)
209 #define GLFW_INCLUDE_NONE
216 #define GLFW_EXPOSE_NATIVE_WIN32
219 #if defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
221 unsigned int __stdcall timeBeginPeriod(
unsigned int uPeriod);
222 unsigned int __stdcall timeEndPeriod(
unsigned int uPeriod);
225 #if defined(__linux__) || defined(__FreeBSD__)
226 #include <sys/time.h>
233 #if defined(__APPLE__)
241#if defined(PLATFORM_ANDROID)
243 #include <android/window.h>
244 #include <android_native_app_glue.h>
251#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
258 #include <sys/ioctl.h>
259 #include <linux/kd.h>
260 #include <linux/input.h>
261 #include <linux/joystick.h>
263#if defined(PLATFORM_RPI)
264 #include "bcm_host.h"
266#if defined(PLATFORM_DRM)
269 #include <xf86drmMode.h>
273 #include "EGL/eglext.h"
277#if defined(PLATFORM_WEB)
278 #define GLFW_INCLUDE_ES2
280 #include <sys/time.h>
282 #include <emscripten/emscripten.h>
283 #include <emscripten/html5.h>
289#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
290 #define USE_LAST_TOUCH_DEVICE
292 #define DEFAULT_GAMEPAD_DEV "/dev/input/js"
293 #define DEFAULT_EVDEV_PATH "/dev/input/"
296#ifndef MAX_FILEPATH_LENGTH
297 #if defined(__linux__)
298 #define MAX_FILEPATH_LENGTH 4096
300 #define MAX_FILEPATH_LENGTH 512
304#ifndef MAX_KEYBOARD_KEYS
305 #define MAX_KEYBOARD_KEYS 512
307#ifndef MAX_MOUSE_BUTTONS
308 #define MAX_MOUSE_BUTTONS 8
311 #define MAX_GAMEPADS 4
313#ifndef MAX_GAMEPAD_AXIS
314 #define MAX_GAMEPAD_AXIS 8
316#ifndef MAX_GAMEPAD_BUTTONS
317 #define MAX_GAMEPAD_BUTTONS 32
319#ifndef MAX_TOUCH_POINTS
320 #define MAX_TOUCH_POINTS 8
322#ifndef MAX_KEY_PRESSED_QUEUE
323 #define MAX_KEY_PRESSED_QUEUE 16
325#ifndef MAX_CHAR_PRESSED_QUEUE
326 #define MAX_CHAR_PRESSED_QUEUE 16
329#if defined(SUPPORT_DATA_STORAGE)
330 #ifndef STORAGE_DATA_FILE
331 #define STORAGE_DATA_FILE "storage.data"
335#ifndef MAX_DECOMPRESSION_SIZE
336 #define MAX_DECOMPRESSION_SIZE 64
340#define FLAG_SET(n, f) ((n) |= (f))
341#define FLAG_CLEAR(n, f) ((n) &= ~(f))
342#define FLAG_TOGGLE(n, f) ((n) ^= (f))
343#define FLAG_CHECK(n, f) ((n) & (f))
348#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
364typedef struct {
unsigned int width;
unsigned int height; }
Size;
369#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
372#if defined(PLATFORM_RPI)
373 EGL_DISPMANX_WINDOW_T handle;
375#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
376#if defined(PLATFORM_DRM)
378 drmModeConnector *connector;
381 struct gbm_device *gbmDevice;
382 struct gbm_surface *gbmSurface;
383 struct gbm_bo *prevBO;
410#if defined(PLATFORM_ANDROID)
413 struct android_app *app;
414 struct android_poll_source *source;
415 bool contextRebindRequired;
422#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
423 InputEventWorker eventWorker[10];
436#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
438#if defined(SUPPORT_SSH_KEYBOARD_RPI)
441 int defaultFileFlags;
442 struct termios defaultSettings;
460#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
480#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
493#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
494 unsigned long long base;
505static char **dirFilesPath =
NULL;
506static int dirFileCount = 0;
510#if defined(SUPPORT_SCREEN_CAPTURE)
511static int screenshotCounter = 0;
514#if defined(SUPPORT_GIF_RECORDING)
515static int gifFrameCounter = 0;
516static bool gifRecording =
false;
520#if defined(SUPPORT_EVENTS_AUTOMATION)
521#define MAX_CODE_AUTOMATION_EVENTS 16384
523typedef enum AutomationEventType {
530 INPUT_MOUSE_BUTTON_UP,
531 INPUT_MOUSE_BUTTON_DOWN,
532 INPUT_MOUSE_POSITION,
533 INPUT_MOUSE_WHEEL_MOTION,
534 INPUT_GAMEPAD_CONNECT,
535 INPUT_GAMEPAD_DISCONNECT,
536 INPUT_GAMEPAD_BUTTON_UP,
537 INPUT_GAMEPAD_BUTTON_DOWN,
538 INPUT_GAMEPAD_AXIS_MOTION,
541 INPUT_TOUCH_POSITION,
549 ACTION_TAKE_SCREENSHOT,
551} AutomationEventType;
556 EVENT_INPUT_KEYBOARD = 0,
557 EVENT_INPUT_MOUSE = 1,
558 EVENT_INPUT_GAMEPAD = 2,
559 EVENT_INPUT_TOUCH = 4,
560 EVENT_INPUT_GESTURE = 8,
565static const char *autoEventTypeName[] = {
570 "INPUT_KEY_RELEASED",
571 "INPUT_MOUSE_BUTTON_UP",
572 "INPUT_MOUSE_BUTTON_DOWN",
573 "INPUT_MOUSE_POSITION",
574 "INPUT_MOUSE_WHEEL_MOTION",
575 "INPUT_GAMEPAD_CONNECT",
576 "INPUT_GAMEPAD_DISCONNECT",
577 "INPUT_GAMEPAD_BUTTON_UP",
578 "INPUT_GAMEPAD_BUTTON_DOWN",
579 "INPUT_GAMEPAD_AXIS_MOTION",
582 "INPUT_TOUCH_POSITION",
588 "ACTION_TAKE_SCREENSHOT",
589 "ACTION_SETTARGETFPS"
593typedef struct AutomationEvent {
599static AutomationEvent *events =
NULL;
600static unsigned int eventCount = 0;
601static bool eventsPlaying =
false;
602static bool eventsRecording =
false;
611#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
619static void InitTimer(
void);
620static bool InitGraphicsDevice(
int width,
int height);
621static void SetupFramebuffer(
int width,
int height);
622static void SetupViewport(
int width,
int height);
624#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
625static void ErrorCallback(
int error,
const char *description);
627static void WindowSizeCallback(
GLFWwindow *window,
int width,
int height);
628#if !defined(PLATFORM_WEB)
629static void WindowMaximizeCallback(
GLFWwindow* window,
int maximized);
631static void WindowIconifyCallback(
GLFWwindow *window,
int iconified);
632static void WindowFocusCallback(
GLFWwindow *window,
int focused);
633static void WindowDropCallback(
GLFWwindow *window,
int count,
const char **paths);
635static void KeyCallback(
GLFWwindow *window,
int key,
int scancode,
int action,
int mods);
636static void CharCallback(
GLFWwindow *window,
unsigned int key);
637static void MouseButtonCallback(
GLFWwindow *window,
int button,
int action,
int mods);
638static void MouseCursorPosCallback(
GLFWwindow *window,
double x,
double y);
639static void MouseScrollCallback(
GLFWwindow *window,
double xoffset,
double yoffset);
640static void CursorEnterCallback(
GLFWwindow *window,
int enter);
643#if defined(PLATFORM_ANDROID)
644static void AndroidCommandCallback(
struct android_app *app,
int32_t cmd);
645static int32_t AndroidInputCallback(
struct android_app *app, AInputEvent *event);
648#if defined(PLATFORM_WEB)
649static EM_BOOL EmscriptenFullscreenChangeCallback(
int eventType,
const EmscriptenFullscreenChangeEvent *event,
void *userData);
650static EM_BOOL EmscriptenWindowResizedCallback(
int eventType,
const EmscriptenUiEvent *event,
void *userData);
651static EM_BOOL EmscriptenResizeCallback(
int eventType,
const EmscriptenUiEvent *event,
void *userData);
653static EM_BOOL EmscriptenMouseCallback(
int eventType,
const EmscriptenMouseEvent *mouseEvent,
void *userData);
654static EM_BOOL EmscriptenTouchCallback(
int eventType,
const EmscriptenTouchEvent *touchEvent,
void *userData);
655static EM_BOOL EmscriptenGamepadCallback(
int eventType,
const EmscriptenGamepadEvent *gamepadEvent,
void *userData);
658#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
659static void InitKeyboard(
void);
660static void RestoreKeyboard(
void);
661#if defined(SUPPORT_SSH_KEYBOARD_RPI)
662static void ProcessKeyboard(
void);
665static void InitEvdevInput(
void);
666static void ConfigureEvdevDevice(
char *device);
667static void PollKeyboardEvents(
void);
668static void *EventThread(
void *arg);
670static void InitGamepad(
void);
671static void *GamepadThread(
void *arg);
673#if defined(PLATFORM_DRM)
674static int FindMatchingConnectorMode(
const drmModeConnector *connector,
const drmModeModeInfo *mode);
675static int FindExactConnectorMode(
const drmModeConnector *connector, uint width, uint height, uint fps,
bool allowInterlaced);
676static int FindNearestConnectorMode(
const drmModeConnector *connector, uint width, uint height, uint fps,
bool allowInterlaced);
681#if defined(SUPPORT_EVENTS_AUTOMATION)
682static void LoadAutomationEvents(
const char *fileName);
683static void ExportAutomationEvents(
const char *fileName);
684static void RecordAutomationEvent(
unsigned int frame);
685static void PlayAutomationEvent(
unsigned int frame);
690void __stdcall Sleep(
unsigned long msTimeout);
693#if !defined(SUPPORT_MODULE_RTEXT)
700#if defined(PLATFORM_ANDROID)
703extern int main(
int argc,
char *argv[]);
705void android_main(
struct android_app *app)
707 char arg0[] =
"raylib";
708 CORE.Android.app = app;
711 (void)
main(1, (
char *[]) { arg0,
NULL });
715struct android_app *GetAndroidApp(
void)
717 return CORE.Android.app;
730#if defined(SUPPORT_MODULE_RSHAPES)
735#if defined(SUPPORT_MODULE_RTEXTURES)
740#if defined(SUPPORT_MODULE_RTEXT)
745#if defined(SUPPORT_MODULE_RMODELS)
750#if defined(SUPPORT_MODULE_RAUDIO)
765#if defined(PLATFORM_ANDROID)
772 ANativeActivity_setWindowFlags(CORE.Android.app->activity, AWINDOW_FLAG_FULLSCREEN, 0);
774 int orientation = AConfiguration_getOrientation(CORE.Android.app->config);
776 if (orientation == ACONFIGURATION_ORIENTATION_PORT)
TRACELOG(
LOG_INFO,
"ANDROID: Window orientation set as portrait");
777 else if (orientation == ACONFIGURATION_ORIENTATION_LAND)
TRACELOG(
LOG_INFO,
"ANDROID: Window orientation set as landscape");
782 AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_PORT);
787 AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_LAND);
798 CORE.Android.app->onAppCmd = AndroidCommandCallback;
801 CORE.Android.app->onInputEvent = AndroidInputCallback;
804 InitAssetManager(CORE.Android.app->activity->assetManager, CORE.Android.app->activity->internalDataPath);
819 while ((pollResult = ALooper_pollAll(0,
NULL, &pollEvents, (
void**)&CORE.Android.source)) >= 0)
822 if (CORE.Android.source !=
NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
829#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
832 CORE.
Window.
ready = InitGraphicsDevice(width, height);
845 srand((
unsigned int)time(
NULL));
850#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
854 #if defined(SUPPORT_MODULE_RSHAPES)
860 #if defined(SUPPORT_MODULE_RSHAPES)
867#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
877#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
884#if defined(PLATFORM_WEB)
886 emscripten_set_fullscreenchange_callback(
"#canvas",
NULL, 1, EmscriptenFullscreenChangeCallback);
901 emscripten_set_click_callback(
"#canvas",
NULL, 1, EmscriptenMouseCallback);
904 emscripten_set_touchstart_callback(
"#canvas",
NULL, 1, EmscriptenTouchCallback);
905 emscripten_set_touchend_callback(
"#canvas",
NULL, 1, EmscriptenTouchCallback);
906 emscripten_set_touchmove_callback(
"#canvas",
NULL, 1, EmscriptenTouchCallback);
907 emscripten_set_touchcancel_callback(
"#canvas",
NULL, 1, EmscriptenTouchCallback);
910 emscripten_set_gamepadconnected_callback(
NULL, 1, EmscriptenGamepadCallback);
911 emscripten_set_gamepaddisconnected_callback(
NULL, 1, EmscriptenGamepadCallback);
917#if defined(SUPPORT_EVENTS_AUTOMATION)
918 events = (AutomationEvent *)malloc(MAX_CODE_AUTOMATION_EVENTS*
sizeof(AutomationEvent));
928#if defined(SUPPORT_GIF_RECORDING)
933 gifRecording =
false;
937#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
943#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
948#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
952#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
975#if defined(PLATFORM_DRM)
984 gbm_surface_release_buffer(CORE.
Window.gbmSurface, CORE.
Window.prevBO);
988 if (CORE.
Window.gbmSurface)
990 gbm_surface_destroy(CORE.
Window.gbmSurface);
994 if (CORE.
Window.gbmDevice)
996 gbm_device_destroy(CORE.
Window.gbmDevice);
1002 if (CORE.
Window.connector)
1004 drmModeSetCrtc(CORE.
Window.fd, CORE.
Window.crtc->crtc_id, CORE.
Window.crtc->buffer_id,
1006 drmModeFreeConnector(CORE.
Window.connector);
1010 drmModeFreeCrtc(CORE.
Window.crtc);
1014 if (CORE.
Window.fd != -1)
1040#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
1054 for (
int i = 0; i <
sizeof(CORE.
Input.eventWorker)/
sizeof(InputEventWorker); ++i)
1056 if (CORE.
Input.eventWorker[i].threadId)
1058 pthread_join(CORE.
Input.eventWorker[i].threadId,
NULL);
1065#if defined(SUPPORT_EVENTS_AUTOMATION)
1076#if defined(PLATFORM_WEB)
1082 emscripten_sleep(16);
1086#if defined(PLATFORM_DESKTOP)
1102#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
1123#if defined(PLATFORM_DESKTOP)
1132#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
1142#if defined(PLATFORM_DESKTOP)
1152#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
1162#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
1178#if defined(PLATFORM_DESKTOP)
1185 int monitorCount = 0;
1190 GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] :
NULL;
1192 if (monitor ==
NULL)
1221#if defined(PLATFORM_WEB)
1289#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
1297#if defined(PLATFORM_DESKTOP)
1309#if defined(PLATFORM_DESKTOP)
1318#if defined(PLATFORM_DESKTOP)
1332#if defined(PLATFORM_DESKTOP)
1409 TRACELOG(
LOG_WARNING,
"WINDOW: Framebuffer transparency can only by configured before window initialization");
1415 TRACELOG(
LOG_WARNING,
"WINDOW: High DPI can only by configured before window initialization");
1421 TRACELOG(
LOG_WARNING,
"WINDOW: MSAA can only by configured before window initialization");
1427 TRACELOG(
LOG_WARNING,
"RPI: Interlaced mode can only by configured before window initialization");
1435#if defined(PLATFORM_DESKTOP)
1510 TRACELOG(
LOG_WARNING,
"WINDOW: Framebuffer transparency can only by configured before window initialization");
1516 TRACELOG(
LOG_WARNING,
"WINDOW: High DPI can only by configured before window initialization");
1522 TRACELOG(
LOG_WARNING,
"WINDOW: MSAA can only by configured before window initialization");
1528 TRACELOG(
LOG_WARNING,
"RPI: Interlaced mode can only by configured before window initialization");
1537#if defined(PLATFORM_DESKTOP)
1544 icon[0].
pixels = (
unsigned char *)image.
data;
1558#if defined(PLATFORM_DESKTOP)
1566#if defined(PLATFORM_DESKTOP)
1574#if defined(PLATFORM_DESKTOP)
1575 int monitorCount = 0;
1578 if ((monitor >= 0) && (monitor < monitorCount))
1592#if defined(PLATFORM_DESKTOP)
1601#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
1609#if defined(PLATFORM_DESKTOP)
1610 if (opacity >= 1.0f) opacity = 1.0f;
1611 else if (opacity <= 0.0f) opacity = 0.0f;
1643#if defined(PLATFORM_DESKTOP) && defined(_WIN32)
1647#if defined(__linux__)
1654#if defined(__APPLE__)
1665#if defined(PLATFORM_DESKTOP)
1668 return monitorCount;
1677#if defined(PLATFORM_DESKTOP)
1682 if (monitorCount == 1)
1688 for (
int i = 0; i < monitorCount; i++)
1690 if (monitors[i] == monitor)
1702 for (
int i = 0; i < monitorCount; i++)
1710 monitor = monitors[i];
1712 if (x >= mx && x <= (mx + width) && y >= my && y <= (my + height))
1725#if defined(PLATFORM_DESKTOP)
1729 if ((monitor >= 0) && (monitor < monitorCount))
1734 return (
Vector2){ (float)x, (
float)y };
1744#if defined(PLATFORM_DESKTOP)
1748 if ((monitor >= 0) && (monitor < monitorCount))
1754 if (count > 0)
return modes[count - 1].
width;
1765#if defined(PLATFORM_DESKTOP)
1769 if ((monitor >= 0) && (monitor < monitorCount))
1775 if (count > 0)
return modes[count - 1].
height;
1786#if defined(PLATFORM_DESKTOP)
1790 if ((monitor >= 0) && (monitor < monitorCount))
1794 return physicalWidth;
1804#if defined(PLATFORM_DESKTOP)
1808 if ((monitor >= 0) && (monitor < monitorCount))
1812 return physicalHeight;
1821#if defined(PLATFORM_DESKTOP)
1825 if ((monitor >= 0) && (monitor < monitorCount))
1832#if defined(PLATFORM_DRM)
1833 if ((CORE.
Window.connector) && (CORE.
Window.modeIndex >= 0))
1835 return CORE.
Window.connector->modes[CORE.
Window.modeIndex].vrefresh;
1846#if defined(PLATFORM_DESKTOP)
1849 return (
Vector2){ (float)x, (
float)y };
1855 Vector2 scale = { 1.0f, 1.0f };
1857#if defined(PLATFORM_DESKTOP)
1862 int monitorCount = 0;
1866 for (
int i = 0; i < monitorCount; i++)
1870 int xpos, ypos, width, height;
1873 if ((windowPos.
x >= xpos) && (windowPos.
x < xpos + width) &&
1874 (windowPos.
y >= ypos) && (windowPos.
y < ypos + height))
1889#if defined(PLATFORM_DESKTOP)
1893 if ((monitor >= 0) && (monitor < monitorCount))
1906#if defined(PLATFORM_DESKTOP)
1909#if defined(PLATFORM_WEB)
1910 return emscripten_run_script_string(
"navigator.clipboard.readText()");
1918#if defined(PLATFORM_DESKTOP)
1921#if defined(PLATFORM_WEB)
1922 emscripten_run_script(
TextFormat(
"navigator.clipboard.writeText('%s')", text));
1929#if defined(PLATFORM_DESKTOP)
1939#if defined(PLATFORM_DESKTOP)
1955#if defined(PLATFORM_DESKTOP)
1958#if defined(PLATFORM_WEB)
1959 emscripten_exit_pointerlock();
1968#if defined(PLATFORM_DESKTOP)
1971#if defined(PLATFORM_WEB)
1972 emscripten_request_pointerlock(
"#canvas", 1);
2013#if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MOUSE_CURSOR_POINT)
2022#if defined(SUPPORT_GIF_RECORDING)
2026 #define GIF_RECORD_FRAMERATE 10
2040 #if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MODULE_RTEXT)
2041 if (((gifFrameCounter/15)%2) == 1)
2052#if defined(SUPPORT_EVENTS_AUTOMATION)
2054 if (eventsRecording)
2058 if (((gifFrameCounter/15)%2) == 1)
2066 else if (eventsPlaying)
2070 if (((gifFrameCounter/15)%2) == 1)
2080#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
2105#if defined(SUPPORT_EVENTS_AUTOMATION)
2108 else if (eventsPlaying)
2158 double right = top*aspect;
2165 double top = camera.
fovy/2.0;
2166 double right = top*aspect;
2275#if defined(__APPLE__)
2337 float lensRadius = fabsf(-1.0f - 4.0f*lensShift);
2338 float lensRadiusSq = lensRadius*lensRadius;
2344 float normScreenWidth = 0.5f;
2345 float normScreenHeight = 1.0f;
2346 config.
scaleIn[0] = 2.0f/normScreenWidth;
2347 config.
scaleIn[1] = 2.0f/normScreenHeight/aspect;
2348 config.
scale[0] = normScreenWidth*0.5f/distortionScale;
2349 config.
scale[1] = normScreenHeight*0.5f*aspect/distortionScale;
2357 float projOffset = 4.0f*lensShift;
2400 char *vShaderStr =
NULL;
2401 char *fShaderStr =
NULL;
2527 Vector3 deviceCoords = { x, y, z };
2542 double top = camera.
fovy/2.0;
2543 double right = top*aspect;
2546 matProj =
MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
2579 Matrix matTransform = { 0 };
2601 return matTransform;
2609 return screenPosition;
2626 double top = camera.
fovy/2.0;
2627 double right = top*aspect;
2639 Quaternion worldPos = { position.
x, position.
y, position.
z, 1.0f };
2648 Vector3 ndcPos = { worldPos.
x/worldPos.
w, -worldPos.
y/worldPos.
w, worldPos.
z/worldPos.
w };
2651 Vector2 screenPosition = { (ndcPos.
x + 1.0f)/2.0f*(
float)width, (ndcPos.
y + 1.0f)/2.0f*(
float)height };
2653 return screenPosition;
2662 return (
Vector2){ transform.
x, transform.
y };
2671 return (
Vector2){ transform.
x, transform.
y };
2689#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
2690 #define FPS_CAPTURE_FRAMES_COUNT 30
2691 #define FPS_AVERAGE_TIME_SECONDS 0.5f
2692 #define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT)
2694 static int index = 0;
2696 static float average = 0, last = 0;
2699 if (fpsFrame == 0)
return 0;
2705 average -= history[index];
2707 average += history[index];
2710 fps = (int)roundf(1.0f/average);
2727#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
2731#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
2732 struct timespec ts = { 0 };
2733 clock_gettime(CLOCK_MONOTONIC, &ts);
2734 unsigned long long int time = (
unsigned long long int)ts.tv_sec*1000000000LLU + (
unsigned long long int)ts.tv_nsec;
2736 return (
double)(time - CORE.
Time.base)*1e-9;
2756#if defined(SUPPORT_MODULE_RTEXTURES)
2760 char path[2048] = { 0 };
2766#if defined(PLATFORM_WEB)
2788 return (rand()%(abs(max - min) + 1) + min);
2800 bool result =
false;
2803 if (_access(fileName, 0) != -1) result =
true;
2805 if (access(fileName, F_OK) != -1) result =
true;
2820 bool result =
false;
2823 if (fileExt !=
NULL)
2825#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_TEXT_MANIPULATION)
2827 const char **checkExts =
TextSplit(ext,
';', &extCount);
2829 char fileExtLower[16] = { 0 };
2832 for (
int i = 0; i < extCount; i++)
2834 if (strcmp(fileExtLower,
TextToLower(checkExts[i])) == 0)
2841 if (strcmp(fileExt, ext) == 0) result =
true;
2851 bool result =
false;
2869 FILE *file = fopen(fileName,
"rb");
2873 fseek(file, 0L, SEEK_END);
2874 size = (int)ftell(file);
2884 const char *dot = strrchr(fileName,
'.');
2886 if (!dot || dot == fileName)
return NULL;
2892static const char *strprbrk(
const char *s,
const char *charset)
2894 const char *latestMatch =
NULL;
2895 for (; s = strpbrk(s, charset), s !=
NULL; latestMatch = s++) { }
2902 const char *fileName =
NULL;
2903 if (filePath !=
NULL) fileName = strprbrk(filePath,
"\\/");
2905 if (!fileName)
return filePath;
2907 return fileName + 1;
2913 #define MAX_FILENAMEWITHOUTEXT_LENGTH 128
2920 int size = (int)strlen(fileName);
2924 if (fileName[i] ==
'.')
2947 const char *lastSlash =
NULL;
2953 if (filePath[1] !=
':' && filePath[0] !=
'\\' && filePath[0] !=
'/')
2961 lastSlash = strprbrk(filePath,
"\\/");
2964 if (lastSlash == filePath)
2967 dirPath[0] = filePath[0];
2973 memcpy(dirPath + (filePath[1] !=
':' && filePath[0] !=
'\\' && filePath[0] !=
'/' ? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1));
2974 dirPath[strlen(filePath) - strlen(lastSlash) + (filePath[1] !=
':' && filePath[0] !=
'\\' && filePath[0] !=
'/' ? 2 : 0)] =
'\0';
2986 int pathLen = (int)strlen(dirPath);
2988 if (pathLen <= 3) strcpy(prevDirPath, dirPath);
2990 for (
int i = (pathLen - 1); (i >= 0) && (pathLen > 3); i--)
2992 if ((dirPath[i] ==
'\\') || (dirPath[i] ==
'/'))
2995 if (((i == 2) && (dirPath[1] ==
':')) || (i == 0)) i++;
2997 strncpy(prevDirPath, dirPath, i);
3023#if defined (UNICODE)
3024 unsigned short widePath[MAX_PATH];
3025 len = GetModuleFileNameW(
NULL, widePath, MAX_PATH);
3026 len = WideCharToMultiByte(0, 0, widePath, len, appDir, MAX_PATH,
NULL,
NULL);
3028 len = GetModuleFileNameA(
NULL, appDir, MAX_PATH);
3032 for (
int i = len; i >= 0; --i)
3034 if (appDir[i] ==
'\\')
3036 appDir[i + 1] =
'\0';
3047#elif defined(__linux__)
3048 unsigned int size =
sizeof(appDir);
3049 ssize_t len = readlink(
"/proc/self/exe", appDir, size);
3053 for (
int i = len; i >= 0; --i)
3055 if (appDir[i] ==
'/')
3057 appDir[i + 1] =
'\0';
3067#elif defined(__APPLE__)
3070 if (_NSGetExecutablePath(appDir, &size) == 0)
3072 int len = strlen(appDir);
3073 for (
int i = len; i >= 0; --i)
3075 if (appDir[i] ==
'/')
3077 appDir[i + 1] =
'\0';
3105 while ((entity =
readdir(dir)) !=
NULL) counter++;
3107 dirFileCount = counter;
3108 *fileCount = dirFileCount;
3111 dirFilesPath = (
char **)
RL_MALLOC(dirFileCount*
sizeof(
char *));
3118 for (
int i = 0; (entity =
readdir(dir)) !=
NULL; i++) strcpy(dirFilesPath[i], entity->
d_name);
3124 return dirFilesPath;
3130 if (dirFileCount > 0)
3132 for (
int i = 0; i < dirFileCount; i++)
RL_FREE(dirFilesPath[i]);
3143 bool result =
CHDIR(dir);
3147 return (result == 0);
3180 struct stat result = { 0 };
3182 if (stat(fileName, &result) == 0)
3184 time_t mod = result.st_mtime;
3193unsigned char *
CompressData(
const unsigned char *data,
int dataSize,
int *compDataSize)
3195 #define COMPRESSION_QUALITY_DEFLATE 8
3197 unsigned char *compData =
NULL;
3199#if defined(SUPPORT_COMPRESSION_API)
3203 compData = (
unsigned char *)
RL_CALLOC(bounds, 1);
3206 TraceLog(
LOG_INFO,
"SYSTEM: Compress data: Original size: %i -> Comp. size: %i", dataSize, *compDataSize);
3213unsigned char *
DecompressData(
const unsigned char *compData,
int compDataSize,
int *dataSize)
3215 unsigned char *data =
NULL;
3217#if defined(SUPPORT_COMPRESSION_API)
3221 unsigned char *temp =
RL_REALLOC(data, length);
3223 if (temp !=
NULL) data = temp;
3224 else TRACELOG(
LOG_WARNING,
"SYSTEM: Failed to re-allocate required decompression memory");
3228 TraceLog(
LOG_INFO,
"SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, *dataSize);
3237 static const unsigned char base64encodeTable[] = {
3238 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
3239 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
3240 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'
3243 static const int modTable[] = { 0, 2, 1 };
3245 *outputSize = 4*((dataSize + 2)/3);
3247 char *encodedData =
RL_MALLOC(*outputSize);
3249 if (encodedData ==
NULL)
return NULL;
3251 for (
int i = 0, j = 0; i < dataSize;)
3253 unsigned int octetA = (i < dataSize)? (
unsigned char)data[i++] : 0;
3254 unsigned int octetB = (i < dataSize)? (
unsigned char)data[i++] : 0;
3255 unsigned int octetC = (i < dataSize)? (
unsigned char)data[i++] : 0;
3257 unsigned int triple = (octetA << 0x10) + (octetB << 0x08) + octetC;
3259 encodedData[j++] = base64encodeTable[(triple >> 3*6) & 0x3F];
3260 encodedData[j++] = base64encodeTable[(triple >> 2*6) & 0x3F];
3261 encodedData[j++] = base64encodeTable[(triple >> 1*6) & 0x3F];
3262 encodedData[j++] = base64encodeTable[(triple >> 0*6) & 0x3F];
3265 for (
int i = 0; i < modTable[dataSize%3]; i++) encodedData[*outputSize - 1 - i] =
'=';
3273 static const unsigned char base64decodeTable[] = {
3274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3275 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3276 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
3277 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
3282 for (
int i = 0; data[4*i] != 0; i++)
3284 if (data[4*i + 3] ==
'=')
3286 if (data[4*i + 2] ==
'=') outSize += 1;
3293 unsigned char *decodedData = (
unsigned char *)
RL_MALLOC(outSize);
3295 for (
int i = 0; i < outSize/3; i++)
3297 unsigned char a = base64decodeTable[(int)data[4*i]];
3298 unsigned char b = base64decodeTable[(int)data[4*i + 1]];
3299 unsigned char c = base64decodeTable[(int)data[4*i + 2]];
3300 unsigned char d = base64decodeTable[(int)data[4*i + 3]];
3302 decodedData[3*i] = (a << 2) | (b >> 4);
3303 decodedData[3*i + 1] = (b << 4) | (c >> 2);
3304 decodedData[3*i + 2] = (c << 6) | d;
3310 unsigned char a = base64decodeTable[(int)data[4*n]];
3311 unsigned char b = base64decodeTable[(int)data[4*n + 1]];
3312 decodedData[outSize - 1] = (a << 2) | (b >> 4);
3314 else if (outSize%3 == 2)
3317 unsigned char a = base64decodeTable[(int)data[4*n]];
3318 unsigned char b = base64decodeTable[(int)data[4*n + 1]];
3319 unsigned char c = base64decodeTable[(int)data[4*n + 2]];
3320 decodedData[outSize - 2] = (a << 2) | (b >> 4);
3321 decodedData[outSize - 1] = (b << 4) | (c >> 2);
3324 *outputSize = outSize;
3332 bool success =
false;
3334#if defined(SUPPORT_DATA_STORAGE)
3335 char path[512] = { 0 };
3338 unsigned int dataSize = 0;
3339 unsigned int newDataSize = 0;
3340 unsigned char *fileData =
LoadFileData(path, &dataSize);
3341 unsigned char *newFileData =
NULL;
3343 if (fileData !=
NULL)
3345 if (dataSize <= (position*
sizeof(
int)))
3348 newDataSize = (position + 1)*
sizeof(
int);
3349 newFileData = (
unsigned char *)
RL_REALLOC(fileData, newDataSize);
3351 if (newFileData !=
NULL)
3354 int *dataPtr = (
int *)newFileData;
3355 dataPtr[position] = value;
3360 TRACELOG(
LOG_WARNING,
"FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", path, dataSize, position*
sizeof(
int));
3363 newFileData = fileData;
3364 newDataSize = dataSize;
3370 newFileData = fileData;
3371 newDataSize = dataSize;
3374 int *dataPtr = (
int *)newFileData;
3375 dataPtr[position] = value;
3378 success =
SaveFileData(path, newFileData, newDataSize);
3387 dataSize = (position + 1)*
sizeof(
int);
3388 fileData = (
unsigned char *)
RL_MALLOC(dataSize);
3389 int *dataPtr = (
int *)fileData;
3390 dataPtr[position] = value;
3408#if defined(SUPPORT_DATA_STORAGE)
3409 char path[512] = { 0 };
3412 unsigned int dataSize = 0;
3413 unsigned char *fileData =
LoadFileData(path, &dataSize);
3415 if (fileData !=
NULL)
3417 if (dataSize < (position*4))
TRACELOG(
LOG_WARNING,
"FILEIO: [%s] Failed to find storage position: %i", path, position);
3420 int *dataPtr = (
int *)fileData;
3421 value = dataPtr[position];
3441 if (strchr(url,
'\'') !=
NULL)
3447#if defined(PLATFORM_DESKTOP)
3448 char *cmd = (
char *)
RL_CALLOC(strlen(url) + 10,
sizeof(char));
3450 sprintf(cmd,
"explorer \"%s\"", url);
3452 #if defined(__linux__) || defined(__FreeBSD__)
3453 sprintf(cmd,
"xdg-open '%s'", url);
3455 #if defined(__APPLE__)
3456 sprintf(cmd,
"open '%s'", url);
3458 int result = system(cmd);
3462#if defined(PLATFORM_WEB)
3463 emscripten_run_script(
TextFormat(
"window.open('%s', '_blank')", url));
3465#if defined(PLATFORM_ANDROID)
3467 JavaVM *vm = CORE.Android.app->activity->vm;
3468 (*vm)->AttachCurrentThread(vm, &env,
NULL);
3470 jstring urlString = (*env)->NewStringUTF(env, url);
3471 jclass uriClass = (*env)->FindClass(env,
"android/net/Uri");
3472 jmethodID uriParse = (*env)->GetStaticMethodID(env, uriClass,
"parse",
"(Ljava/lang/String;)Landroid/net/Uri;");
3473 jobject uri = (*env)->CallStaticObjectMethod(env, uriClass, uriParse, urlString);
3475 jclass intentClass = (*env)->FindClass(env,
"android/content/Intent");
3476 jfieldID actionViewId = (*env)->GetStaticFieldID(env, intentClass,
"ACTION_VIEW",
"Ljava/lang/String;");
3477 jobject actionView = (*env)->GetStaticObjectField(env, intentClass, actionViewId);
3478 jmethodID newIntent = (*env)->GetMethodID(env, intentClass,
"<init>",
"(Ljava/lang/String;Landroid/net/Uri;)V");
3479 jobject intent = (*env)->AllocObject(env, intentClass);
3481 (*env)->CallVoidMethod(env, intent, newIntent, actionView, uri);
3482 jclass activityClass = (*env)->FindClass(env,
"android/app/Activity");
3483 jmethodID startActivity = (*env)->GetMethodID(env, activityClass,
"startActivity",
"(Landroid/content/Intent;)V");
3484 (*env)->CallVoidMethod(env, CORE.Android.app->activity->clazz, startActivity, intent);
3486 (*vm)->DetachCurrentThread(vm);
3497 bool pressed =
false;
3514 bool released =
false;
3576#if !defined(PLATFORM_ANDROID)
3586 bool result =
false;
3596#if defined(PLATFORM_DESKTOP)
3600#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
3604#if defined(PLATFORM_WEB)
3613#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
3636 bool pressed =
false;
3647 bool result =
false;
3658 bool released =
false;
3669 bool result =
false;
3688#if defined(PLATFORM_DESKTOP)
3698 bool pressed =
false;
3724 bool released =
false;
3743#if defined(PLATFORM_ANDROID)
3753#if defined(PLATFORM_ANDROID)
3765#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
3790#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
3813#if defined(PLATFORM_ANDROID)
3816#if defined(PLATFORM_WEB)
3827#if defined(PLATFORM_DESKTOP)
3841#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
3851#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
3862 Vector2 position = { -1.0f, -1.0f };
3864#if defined(PLATFORM_DESKTOP)
3870#if defined(PLATFORM_ANDROID)
3885#if defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
3917static bool InitGraphicsDevice(
int width,
int height)
3926#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
3939#if defined(__APPLE__)
3950#if defined(PLATFORM_DESKTOP)
3968#if defined(PLATFORM_WEB)
4008#if defined(PLATFORM_DESKTOP)
4018 #if defined(__APPLE__)
4048#if defined(__APPLE__)
4061#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
4070#if defined(PLATFORM_DESKTOP)
4077#if defined(PLATFORM_DESKTOP)
4099 for (
int i = 0; i < count; i++)
4112#if defined(PLATFORM_DESKTOP)
4145#if defined(PLATFORM_DESKTOP)
4150 if (windowPosX < 0) windowPosX = 0;
4151 if (windowPosY < 0) windowPosY = 0;
4169#if !defined(PLATFORM_WEB)
4185#if !defined(PLATFORM_WEB)
4201#if defined(PLATFORM_DESKTOP)
4206 #if !defined(__APPLE__)
4231#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
4235#if defined(PLATFORM_RPI)
4238 DISPMANX_ELEMENT_HANDLE_T dispmanElement = { 0 };
4239 DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = { 0 };
4240 DISPMANX_UPDATE_HANDLE_T dispmanUpdate = { 0 };
4242 VC_RECT_T dstRect = { 0 };
4243 VC_RECT_T srcRect = { 0 };
4246#if defined(PLATFORM_DRM)
4249 CORE.
Window.modeIndex = -1;
4256#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
4257 CORE.
Window.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
4259 TRACELOG(
LOG_INFO,
"DISPLAY: No graphic card set, trying platform-gpu-card");
4260 CORE.
Window.fd = open(
"/dev/dri/by-path/platform-gpu-card", O_RDWR);
4262 if ((-1 == CORE.
Window.fd) || (drmModeGetResources(CORE.
Window.fd) ==
NULL))
4264 TRACELOG(
LOG_INFO,
"DISPLAY: Failed to open platform-gpu-card, trying card1");
4265 CORE.
Window.fd = open(
"/dev/dri/card1", O_RDWR);
4268 if ((-1 == CORE.
Window.fd) || (drmModeGetResources(CORE.
Window.fd) ==
NULL))
4271 CORE.
Window.fd = open(
"/dev/dri/card0", O_RDWR);
4274 if (-1 == CORE.
Window.fd)
4280 drmModeRes *res = drmModeGetResources(CORE.
Window.fd);
4288 for (
size_t i = 0; i < res->count_connectors; i++)
4291 drmModeConnector *con = drmModeGetConnector(CORE.
Window.fd, res->connectors[i]);
4293 if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))
4296 CORE.
Window.connector = con;
4302 drmModeFreeConnector(con);
4305 if (!CORE.
Window.connector)
4308 drmModeFreeResources(res);
4312 drmModeEncoder *enc = drmModeGetEncoder(CORE.
Window.fd, CORE.
Window.connector->encoder_id);
4316 drmModeFreeResources(res);
4320 CORE.
Window.crtc = drmModeGetCrtc(CORE.
Window.fd, enc->crtc_id);
4324 drmModeFreeEncoder(enc);
4325 drmModeFreeResources(res);
4332 TRACELOG(
LOG_TRACE,
"DISPLAY: Selecting DRM connector mode for current used mode...");
4334 CORE.
Window.modeIndex = FindMatchingConnectorMode(CORE.
Window.connector, &CORE.
Window.crtc->mode);
4336 if (CORE.
Window.modeIndex < 0)
4339 drmModeFreeEncoder(enc);
4340 drmModeFreeResources(res);
4353 if (CORE.
Window.modeIndex < 0)
4356 if (CORE.
Window.modeIndex < 0)
4359 if (CORE.
Window.modeIndex < 0)
4362 if (CORE.
Window.modeIndex < 0)
4365 drmModeFreeEncoder(enc);
4366 drmModeFreeResources(res);
4374 CORE.
Window.connector->modes[CORE.
Window.modeIndex].hdisplay, CORE.
Window.connector->modes[CORE.
Window.modeIndex].vdisplay,
4375 (CORE.
Window.connector->modes[CORE.
Window.modeIndex].
flags & DRM_MODE_FLAG_INTERLACE) ?
'i' :
'p',
4376 CORE.
Window.connector->modes[CORE.
Window.modeIndex].vrefresh);
4382 drmModeFreeEncoder(enc);
4385 drmModeFreeResources(res);
4388 CORE.
Window.gbmDevice = gbm_create_device(CORE.
Window.fd);
4389 if (!CORE.
Window.gbmDevice)
4395 CORE.
Window.gbmSurface = gbm_surface_create(CORE.
Window.gbmDevice, CORE.
Window.connector->modes[CORE.
Window.modeIndex].hdisplay,
4396 CORE.
Window.connector->modes[CORE.
Window.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
4397 if (!CORE.
Window.gbmSurface)
4413 const EGLint framebufferAttribs[] =
4416#if defined(PLATFORM_DRM)
4422#if defined(PLATFORM_DRM)
4428 EGL_SAMPLE_BUFFERS, sampleBuffer,
4433 const EGLint contextAttribs[] =
4439#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
4443#if defined(PLATFORM_DRM)
4462#if defined(PLATFORM_DRM)
4463 if (!eglChooseConfig(CORE.
Window.device,
NULL,
NULL, 0, &numConfigs))
4478 EGLint matchingNumConfigs = 0;
4479 if (!eglChooseConfig(CORE.
Window.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
4486 TRACELOG(
LOG_TRACE,
"DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
4490 for (
EGLint i = 0; i < matchingNumConfigs; ++i)
4499 if (GBM_FORMAT_ARGB8888 ==
id)
4502 CORE.
Window.config = configs[i];
4517 eglChooseConfig(CORE.
Window.device, framebufferAttribs, &CORE.
Window.config, 1, &numConfigs);
4534#if defined(PLATFORM_ANDROID)
4535 EGLint displayFormat = 0;
4554#if defined(PLATFORM_RPI)
4581 VC_DISPMANX_ALPHA_T alpha = { 0 };
4582 alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
4584 alpha.opacity = 255;
4587 dispmanDisplay = vc_dispmanx_display_open(0);
4588 dispmanUpdate = vc_dispmanx_update_start(0);
4590 dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay, 0, &dstRect, 0,
4591 &srcRect, DISPMANX_PROTECTION_NONE, &alpha, 0, DISPMANX_NO_ROTATE);
4593 CORE.
Window.handle.element = dispmanElement;
4596 vc_dispmanx_update_submit_sync(dispmanUpdate);
4601 if (renderer)
TRACELOG(
LOG_INFO,
"DISPLAY: Renderer name is: %s", renderer);
4606#if defined(PLATFORM_DRM)
4647#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
4663#if defined(PLATFORM_ANDROID)
4673static void SetupViewport(
int width,
int height)
4681#if defined(__APPLE__)
4682 float xScale = 1.0f, yScale = 1.0f;
4702static void SetupFramebuffer(
int width,
int height)
4713 if (widthRatio <= heightRatio)
4754 if (displayRatio <= screenRatio)
4779static void InitTimer(
void)
4785#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
4789#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
4790 struct timespec now = { 0 };
4792 if (clock_gettime(CLOCK_MONOTONIC, &now) == 0)
4794 CORE.
Time.base = (
unsigned long long int)now.tv_sec*1000000000LLU + (
unsigned long long int)now.tv_nsec;
4809#if defined(SUPPORT_BUSY_WAIT_LOOP)
4810 double previousTime =
GetTime();
4811 double currentTime = 0.0;
4814 while ((currentTime - previousTime) < ms/1000.0f) currentTime =
GetTime();
4816 #if defined(SUPPORT_PARTIALBUSY_WAIT_LOOP)
4817 double busyWait = ms*0.05;
4818 ms -= (float)busyWait;
4823 Sleep((
unsigned int)ms);
4825 #if defined(__linux__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)
4826 struct timespec req = { 0 };
4827 time_t sec = (int)(ms/1000.0f);
4830 req.tv_nsec = ms*1000000L;
4833 while (nanosleep(&req, &req) == -1)
continue;
4835 #if defined(__APPLE__)
4839 #if defined(SUPPORT_PARTIALBUSY_WAIT_LOOP)
4840 double previousTime =
GetTime();
4841 double currentTime = 0.0;
4844 while ((currentTime - previousTime) < (busyWait/1000.0f)) currentTime =
GetTime();
4852#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
4856#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
4859#if defined(PLATFORM_DRM)
4863 struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.
Window.gbmSurface);
4867 int result = drmModeAddFB(CORE.
Window.fd, CORE.
Window.connector->modes[CORE.
Window.modeIndex].hdisplay, CORE.
Window.connector->modes[CORE.
Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
4868 if (result != 0)
TRACELOG(
LOG_ERROR,
"DISPLAY: drmModeAddFB() failed with result: %d", result);
4870 result = drmModeSetCrtc(CORE.
Window.fd, CORE.
Window.crtc->crtc_id, fb, 0, 0, &CORE.
Window.connector->connector_id, 1, &CORE.
Window.connector->modes[CORE.
Window.modeIndex]);
4871 if (result != 0)
TRACELOG(
LOG_ERROR,
"DISPLAY: drmModeSetCrtc() failed with result: %d", result);
4875 result = drmModeRmFB(CORE.
Window.fd, CORE.
Window.prevFB);
4876 if (result != 0)
TRACELOG(
LOG_ERROR,
"DISPLAY: drmModeRmFB() failed with result: %d", result);
4881 if (CORE.
Window.prevBO) gbm_surface_release_buffer(CORE.
Window.gbmSurface, CORE.
Window.prevBO);
4892#if defined(SUPPORT_GESTURES_SYSTEM)
4902#if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM))
4908#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
4912 PollKeyboardEvents();
4934#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
4959#
if defined(PLATFORM_DESKTOP)
4982 const unsigned char *buttons = state.buttons;
5024 const float *axes = state.axes;
5041#if defined(SUPPORT_EVENTS_WAITING)
5048#if defined(PLATFORM_WEB)
5054#if defined(PLATFORM_WEB)
5056 int numGamepads = 0;
5057 if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS) numGamepads = emscripten_get_num_gamepads();
5059 for (
int i = 0; (i < numGamepads) && (i <
MAX_GAMEPADS); i++)
5064 EmscriptenGamepadEvent gamepadState;
5066 int result = emscripten_get_gamepad_status(i, &gamepadState);
5068 if (result == EMSCRIPTEN_RESULT_SUCCESS)
5099 if (gamepadState.digitalButton[j] == 1)
5121#if defined(PLATFORM_ANDROID)
5132 while ((pollResult = ALooper_pollAll(CORE.Android.appEnabled? 0 : -1,
NULL, &pollEvents, (
void**)&CORE.Android.source)) >= 0)
5135 if (CORE.Android.source !=
NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
5138 if (CORE.Android.app->destroyRequested != 0)
5146#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_SSH_KEYBOARD_RPI)
5157#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
5159static void ErrorCallback(
int error,
const char *description)
5166static void WindowSizeCallback(
GLFWwindow *window,
int width,
int height)
5169 SetupViewport(width, height);
5178#if defined(__APPLE__)
5200static void WindowIconifyCallback(
GLFWwindow *window,
int iconified)
5206#if !defined(PLATFORM_WEB)
5208static void WindowMaximizeCallback(
GLFWwindow *window,
int maximized)
5216static void WindowFocusCallback(
GLFWwindow *window,
int focused)
5218 if (focused) CORE.
Window.
flags &= ~FLAG_WINDOW_UNFOCUSED;
5223static void KeyCallback(
GLFWwindow *window,
int key,
int scancode,
int action,
int mods)
5241#if defined(SUPPORT_SCREEN_CAPTURE)
5244#if defined(SUPPORT_GIF_RECORDING)
5249 gifRecording =
false;
5256 #if defined(PLATFORM_WEB)
5259 emscripten_run_script(
TextFormat(
"saveFileFromMEMFSToDisk('%s','%s')",
TextFormat(
"screenrec%03i.gif", screenshotCounter - 1),
TextFormat(
"screenrec%03i.gif", screenshotCounter - 1)));
5266 gifRecording =
true;
5267 gifFrameCounter = 0;
5270 screenshotCounter++;
5279 screenshotCounter++;
5284#if defined(SUPPORT_EVENTS_AUTOMATION)
5287 eventsRecording = !eventsRecording;
5290 if (!eventsRecording) ExportAutomationEvents(
"eventsrec.rep");
5294 LoadAutomationEvents(
"eventsrec.rep");
5295 eventsPlaying =
true;
5303static void CharCallback(
GLFWwindow *window,
unsigned int key)
5322static void MouseButtonCallback(
GLFWwindow *window,
int button,
int action,
int mods)
5328#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
5357static void MouseCursorPosCallback(
GLFWwindow *window,
double x,
double y)
5363#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
5388static void MouseScrollCallback(
GLFWwindow *window,
double xoffset,
double yoffset)
5395static void CursorEnterCallback(
GLFWwindow *window,
int enter)
5404static void WindowDropCallback(
GLFWwindow *window,
int count,
const char **paths)
5410 for (
int i = 0; i < count; i++)
5420#if defined(PLATFORM_ANDROID)
5422static void AndroidCommandCallback(
struct android_app *app,
int32_t cmd)
5430 case APP_CMD_RESUME:
break;
5431 case APP_CMD_INIT_WINDOW:
5433 if (app->window !=
NULL)
5435 if (CORE.Android.contextRebindRequired)
5438 EGLint displayFormat = 0;
5446 CORE.Android.contextRebindRequired =
false;
5460 srand((
unsigned int)time(
NULL));
5462 #if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
5468 #if defined(SUPPORT_MODULE_RSHAPES)
5490 case APP_CMD_GAINED_FOCUS:
5492 CORE.Android.appEnabled =
true;
5495 case APP_CMD_PAUSE:
break;
5496 case APP_CMD_LOST_FOCUS:
5498 CORE.Android.appEnabled =
false;
5501 case APP_CMD_TERM_WINDOW:
5509 CORE.Android.contextRebindRequired =
true;
5511 case APP_CMD_SAVE_STATE:
break;
5512 case APP_CMD_STOP:
break;
5513 case APP_CMD_DESTROY:
5518 case APP_CMD_CONFIG_CHANGED:
5530static int32_t AndroidInputCallback(
struct android_app *app, AInputEvent *event)
5536 int type = AInputEvent_getType(event);
5537 int source = AInputEvent_getSource(event);
5539 if (type == AINPUT_EVENT_TYPE_MOTION)
5541 if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
5542 ((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
5552 int32_t keycode = AKeyEvent_getKeyCode(event);
5553 if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
5566 else if (type == AINPUT_EVENT_TYPE_KEY)
5568 int32_t keycode = AKeyEvent_getKeyCode(event);
5573 if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
5582 if (keycode == AKEYCODE_POWER)
5591 else if ((keycode == AKEYCODE_BACK) || (keycode == AKEYCODE_MENU))
5596 else if ((keycode == AKEYCODE_VOLUME_UP) || (keycode == AKEYCODE_VOLUME_DOWN))
5621 int32_t action = AMotionEvent_getAction(event);
5622 unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
5627#if defined(SUPPORT_GESTURES_SYSTEM)
5652#if defined(PLATFORM_WEB)
5654static EM_BOOL EmscriptenFullscreenChangeCallback(
int eventType,
const EmscriptenFullscreenChangeEvent *event,
void *userData)
5662static EM_BOOL EmscriptenWindowResizedCallback(
int eventType,
const EmscriptenUiEvent *event,
void *userData)
5669EM_JS(
int, GetCanvasWidth, (), {
return canvas.clientWidth; });
5670EM_JS(
int, GetCanvasHeight, (), {
return canvas.clientHeight; });
5673static EM_BOOL EmscriptenResizeCallback(
int eventType,
const EmscriptenUiEvent *event,
void *userData)
5680 int width = GetCanvasWidth();
5681 int height = GetCanvasHeight();
5682 emscripten_set_canvas_element_size(
"#canvas",width,height);
5684 SetupViewport(width, height);
5702static EM_BOOL EmscriptenMouseCallback(
int eventType,
const EmscriptenMouseEvent *mouseEvent,
void *userData)
5710static EM_BOOL EmscriptenGamepadCallback(
int eventType,
const EmscriptenGamepadEvent *gamepadEvent,
void *userData)
5721 if ((gamepadEvent->connected) && (gamepadEvent->index <
MAX_GAMEPADS))
5724 sprintf(CORE.
Input.
Gamepad.
name[gamepadEvent->index],
"%s",gamepadEvent->id);
5732static EM_BOOL EmscriptenTouchCallback(
int eventType,
const EmscriptenTouchEvent *touchEvent,
void *userData)
5737 double canvasWidth = 0.0;
5738 double canvasHeight = 0.0;
5742 emscripten_get_element_css_size(
"#canvas", &canvasWidth, &canvasHeight);
5760#if defined(SUPPORT_GESTURES_SYSTEM)
5785#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
5787static void InitKeyboard(
void)
5793 tcgetattr(STDIN_FILENO, &CORE.
Input.
Keyboard.defaultSettings);
5796 struct termios keyboardNewSettings = { 0 };
5801 keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG);
5803 keyboardNewSettings.c_cc[VMIN] = 1;
5804 keyboardNewSettings.c_cc[VTIME] = 0;
5807 tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);
5810 CORE.
Input.
Keyboard.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0);
5811 fcntl(STDIN_FILENO, F_SETFL, CORE.
Input.
Keyboard.defaultFileFlags | O_NONBLOCK);
5814 int result = ioctl(STDIN_FILENO, KDGKBMODE, &CORE.
Input.
Keyboard.defaultMode);
5817 if (result < 0)
TRACELOG(
LOG_WARNING,
"RPI: Failed to change keyboard mode, an SSH keyboard is probably used");
5825 ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
5829 atexit(RestoreKeyboard);
5833static void RestoreKeyboard(
void)
5836 tcsetattr(STDIN_FILENO, TCSANOW, &CORE.
Input.
Keyboard.defaultSettings);
5839 fcntl(STDIN_FILENO, F_SETFL, CORE.
Input.
Keyboard.defaultFileFlags);
5840 ioctl(STDIN_FILENO, KDSKBMODE, CORE.
Input.
Keyboard.defaultMode);
5843#if defined(SUPPORT_SSH_KEYBOARD_RPI)
5845static void ProcessKeyboard(
void)
5847 #define MAX_KEYBUFFER_SIZE 32
5850 int bufferByteCount = 0;
5851 char keysBuffer[MAX_KEYBUFFER_SIZE] = { 0 };
5854 bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE);
5860 for (
int i = 0; i < bufferByteCount; i++)
5864 if (keysBuffer[i] == 0x1b)
5870 if (keysBuffer[i + 1] == 0x5b)
5872 if ((keysBuffer[i + 2] == 0x5b) || (keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32))
5875 switch (keysBuffer[i + 3])
5892 if (keysBuffer[i + 2] == 0x5b) i += 4;
5893 else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5;
5897 switch (keysBuffer[i + 2])
5913 else if (keysBuffer[i] == 0x0a)
5920 else if (keysBuffer[i] == 0x7f)
5930 if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122))
5944#if defined(SUPPORT_SCREEN_CAPTURE)
5949 screenshotCounter++;
5956static void InitEvdevInput(
void)
5976 directory =
opendir(DEFAULT_EVDEV_PATH);
5982 if ((strncmp(
"event", entity->
d_name, strlen(
"event")) == 0) ||
5983 (strncmp(
"mouse", entity->
d_name, strlen(
"mouse")) == 0))
5985 sprintf(path,
"%s%s", DEFAULT_EVDEV_PATH, entity->
d_name);
5986 ConfigureEvdevDevice(path);
5992 else TRACELOG(
LOG_WARNING,
"RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
5996static void ConfigureEvdevDevice(
char *device)
5998 #define BITS_PER_LONG (8*sizeof(long))
5999 #define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
6000 #define OFF(x) ((x)%BITS_PER_LONG)
6001 #define BIT(x) (1UL<<OFF(x))
6002 #define LONG(x) ((x)/BITS_PER_LONG)
6003 #define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1)
6005 struct input_absinfo absinfo = { 0 };
6006 unsigned long evBits[NBITS(EV_MAX)] = { 0 };
6007 unsigned long absBits[NBITS(ABS_MAX)] = { 0 };
6008 unsigned long relBits[NBITS(REL_MAX)] = { 0 };
6009 unsigned long keyBits[NBITS(KEY_MAX)] = { 0 };
6010 bool hasAbs =
false;
6011 bool hasRel =
false;
6012 bool hasAbsMulti =
false;
6013 int freeWorkerId = -1;
6016 InputEventWorker *worker =
NULL;
6021 for (
int i = 0; i <
sizeof(CORE.
Input.eventWorker)/
sizeof(InputEventWorker); ++i)
6023 if (CORE.
Input.eventWorker[i].threadId == 0)
6031 if (freeWorkerId >= 0)
6033 worker = &(CORE.
Input.eventWorker[freeWorkerId]);
6034 memset(worker, 0,
sizeof(InputEventWorker));
6038 TRACELOG(
LOG_WARNING,
"RPI: Failed to create input device thread for %s, out of worker slots", device);
6043 fd = open(device, O_RDONLY | O_NONBLOCK);
6053 char *ptrDevName = strrchr(device,
't');
6054 worker->eventNum = -1;
6056 if (ptrDevName !=
NULL)
6058 if (sscanf(ptrDevName,
"t%d", &devNum) == 1) worker->eventNum = devNum;
6067 ioctl(fd, EVIOCGBIT(0,
sizeof(evBits)), evBits);
6070 if (TEST_BIT(evBits, EV_ABS))
6072 ioctl(fd, EVIOCGBIT(EV_ABS,
sizeof(absBits)), absBits);
6075 if (TEST_BIT(absBits, ABS_X) && TEST_BIT(absBits, ABS_Y))
6080 ioctl(fd, EVIOCGABS(ABS_X), &absinfo);
6081 worker->absRange.x = absinfo.minimum;
6082 worker->absRange.width = absinfo.maximum - absinfo.minimum;
6083 ioctl(fd, EVIOCGABS(ABS_Y), &absinfo);
6084 worker->absRange.y = absinfo.minimum;
6085 worker->absRange.height = absinfo.maximum - absinfo.minimum;
6089 if (TEST_BIT(absBits, ABS_MT_POSITION_X) && TEST_BIT(absBits, ABS_MT_POSITION_Y))
6094 ioctl(fd, EVIOCGABS(ABS_X), &absinfo);
6095 worker->absRange.x = absinfo.minimum;
6096 worker->absRange.width = absinfo.maximum - absinfo.minimum;
6097 ioctl(fd, EVIOCGABS(ABS_Y), &absinfo);
6098 worker->absRange.y = absinfo.minimum;
6099 worker->absRange.height = absinfo.maximum - absinfo.minimum;
6104 if (TEST_BIT(evBits, EV_REL))
6106 ioctl(fd, EVIOCGBIT(EV_REL,
sizeof(relBits)), relBits);
6108 if (TEST_BIT(relBits, REL_X) && TEST_BIT(relBits, REL_Y)) hasRel =
true;
6112 if (TEST_BIT(evBits, EV_KEY))
6114 ioctl(fd, EVIOCGBIT(EV_KEY,
sizeof(keyBits)), keyBits);
6116 if (hasAbs || hasAbsMulti)
6118 if (TEST_BIT(keyBits, BTN_TOUCH)) worker->isTouch =
true;
6119 if (TEST_BIT(keyBits, BTN_TOOL_FINGER)) worker->isTouch =
true;
6120 if (TEST_BIT(keyBits, BTN_TOOL_PEN)) worker->isTouch =
true;
6121 if (TEST_BIT(keyBits, BTN_STYLUS)) worker->isTouch =
true;
6122 if (worker->isTouch || hasAbsMulti) worker->isMultitouch =
true;
6127 if (TEST_BIT(keyBits, BTN_LEFT)) worker->isMouse =
true;
6128 if (TEST_BIT(keyBits, BTN_RIGHT)) worker->isMouse =
true;
6131 if (TEST_BIT(keyBits, BTN_A)) worker->isGamepad =
true;
6132 if (TEST_BIT(keyBits, BTN_TRIGGER)) worker->isGamepad =
true;
6133 if (TEST_BIT(keyBits, BTN_START)) worker->isGamepad =
true;
6134 if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad =
true;
6135 if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad =
true;
6137 if (TEST_BIT(keyBits,
KEY_SPACE)) worker->isKeyboard =
true;
6151 else if (worker->isTouch || worker->isMouse)
6155 worker->isMouse?
"mouse " :
"",
6156 worker->isMultitouch?
"multitouch " :
"",
6157 worker->isTouch?
"touchscreen " :
"",
6158 worker->isGamepad?
"gamepad " :
"");
6161 int error = pthread_create(&worker->threadId,
NULL, &EventThread, (
void *)worker);
6164 TRACELOG(
LOG_WARNING,
"RPI: Failed to create input device thread: %s (error: %d)", device, error);
6165 worker->threadId = 0;
6169#if defined(USE_LAST_TOUCH_DEVICE)
6171 int maxTouchNumber = -1;
6173 for (
int i = 0; i <
sizeof(CORE.
Input.eventWorker)/
sizeof(InputEventWorker); ++i)
6175 if (CORE.
Input.eventWorker[i].isTouch && (CORE.
Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.
Input.eventWorker[i].eventNum;
6179 for (
int i = 0; i <
sizeof(CORE.
Input.eventWorker)/
sizeof(InputEventWorker); ++i)
6181 if (CORE.
Input.eventWorker[i].isTouch && (CORE.
Input.eventWorker[i].eventNum < maxTouchNumber))
6183 if (CORE.
Input.eventWorker[i].threadId != 0)
6185 TRACELOG(
LOG_WARNING,
"RPI: Found duplicate touchscreen, killing touchscreen on event: %d", i);
6186 pthread_cancel(CORE.
Input.eventWorker[i].threadId);
6187 close(CORE.
Input.eventWorker[i].fd);
6197static void PollKeyboardEvents(
void)
6202 static const int keymapUS[] = {
6203 0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84,
6204 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96,
6205 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291,
6206 292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325,
6207 326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95,
6208 335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261,
6209 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127,
6210 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
6211 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
6212 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
6213 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
6214 192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
6215 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
6216 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
6217 243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0
6221 if (fd == -1)
return;
6223 struct input_event event = { 0 };
6227 while (read(fd, &event,
sizeof(event)) == (
int)
sizeof(event))
6230 if (event.type == EV_KEY)
6232#if defined(SUPPORT_SSH_KEYBOARD_RPI)
6237 if ((event.code >= 1) && (event.code <= 255))
6239 keycode = keymapUS[
event.code & 0xFF];
6248 if (event.value >= 1)
6254 #if defined(SUPPORT_SCREEN_CAPTURE)
6259 screenshotCounter++;
6265 TRACELOGD(
"RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ?
"UP":
"DOWN", event.code, keycode);
6273static void *EventThread(
void *arg)
6275 struct input_event event = { 0 };
6276 InputEventWorker *worker = (InputEventWorker *)arg;
6278 int touchAction = -1;
6279 bool gestureUpdate =
false;
6284 while (read(worker->fd, &event,
sizeof(event)) == (int)
sizeof(event))
6287 if (event.type == EV_REL)
6289 if (event.code == REL_X)
6295 gestureUpdate =
true;
6298 if (event.code == REL_Y)
6304 gestureUpdate =
true;
6311 if (event.type == EV_ABS)
6314 if (event.code == ABS_X)
6320 gestureUpdate =
true;
6323 if (event.code == ABS_Y)
6329 gestureUpdate =
true;
6333 if (event.code == ABS_MT_SLOT) worker->touchSlot =
event.value;
6335 if (event.code == ABS_MT_POSITION_X)
6340 if (event.code == ABS_MT_POSITION_Y)
6345 if (event.code == ABS_MT_TRACKING_ID)
6356 if (event.code == ABS_PRESSURE)
6360 if (!event.value && previousMouseLeftButtonState)
6365 gestureUpdate =
true;
6368 if (event.value && !previousMouseLeftButtonState)
6373 gestureUpdate =
true;
6380 if (event.type == EV_KEY)
6383 if ((event.code == BTN_TOUCH) || (
event.code == BTN_LEFT))
6387 if (event.value > 0) touchAction = 1;
6388 else touchAction = 0;
6389 gestureUpdate =
true;
6410#if defined(SUPPORT_GESTURES_SYSTEM)
6447static void InitGamepad(
void)
6449 char gamepadDev[128] = { 0 };
6453 sprintf(gamepadDev,
"%s%i", DEFAULT_GAMEPAD_DEV, i);
6455 if ((CORE.
Input.
Gamepad.streamId[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
6458 if (i == 0)
TRACELOG(
LOG_WARNING,
"RPI: Failed to open Gamepad device, no gamepad available");
6469 if (error != 0)
TRACELOG(
LOG_WARNING,
"RPI: Failed to create gamepad input event thread");
6477static void *GamepadThread(
void *arg)
6479 #define JS_EVENT_BUTTON 0x01
6480 #define JS_EVENT_AXIS 0x02
6481 #define JS_EVENT_INIT 0x80
6487 unsigned char number;
6491 struct js_event gamepadEvent = { 0 };
6497 if (read(CORE.
Input.
Gamepad.streamId[i], &gamepadEvent,
sizeof(
struct js_event)) == (
int)
sizeof(
struct js_event))
6499 gamepadEvent.type &= ~JS_EVENT_INIT;
6502 if (gamepadEvent.type == JS_EVENT_BUTTON)
6515 else if (gamepadEvent.type == JS_EVENT_AXIS)
6534#if defined(PLATFORM_DRM)
6536static int FindMatchingConnectorMode(
const drmModeConnector *connector,
const drmModeModeInfo *mode)
6538 if (
NULL == connector)
return -1;
6539 if (
NULL == mode)
return -1;
6542 #define BINCMP(a, b) memcmp((a), (b), (sizeof(a) < sizeof(b)) ? sizeof(a) : sizeof(b))
6544 for (
size_t i = 0; i < connector->count_modes; i++)
6546 TRACELOG(
LOG_TRACE,
"DISPLAY: DRM mode: %d %ux%u@%u %s", i, connector->modes[i].hdisplay, connector->modes[i].vdisplay,
6547 connector->modes[i].vrefresh, (connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE) ?
"interlaced" :
"progressive");
6549 if (0 == BINCMP(&CORE.
Window.crtc->mode, &CORE.
Window.connector->modes[i]))
return i;
6558static int FindExactConnectorMode(
const drmModeConnector *connector, uint width, uint height, uint fps,
bool allowInterlaced)
6560 TRACELOG(
LOG_TRACE,
"DISPLAY: Searching exact connector mode for %ux%u@%u, selecting an interlaced mode is allowed: %s", width, height, fps, allowInterlaced ?
"yes" :
"no");
6562 if (
NULL == connector)
return -1;
6564 for (
int i = 0; i < CORE.
Window.connector->count_modes; i++)
6566 const drmModeModeInfo *
const mode = &CORE.
Window.connector->modes[i];
6568 TRACELOG(
LOG_TRACE,
"DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
"interlaced" :
"progressive");
6570 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced))
continue;
6572 if ((mode->hdisplay == width) && (mode->vdisplay == height) && (mode->vrefresh == fps))
return i;
6580static int FindNearestConnectorMode(
const drmModeConnector *connector, uint width, uint height, uint fps,
bool allowInterlaced)
6582 TRACELOG(
LOG_TRACE,
"DISPLAY: Searching nearest connector mode for %ux%u@%u, selecting an interlaced mode is allowed: %s", width, height, fps, allowInterlaced ?
"yes" :
"no");
6584 if (
NULL == connector)
return -1;
6586 int nearestIndex = -1;
6587 for (
int i = 0; i < CORE.
Window.connector->count_modes; i++)
6589 const drmModeModeInfo *
const mode = &CORE.
Window.connector->modes[i];
6591 TRACELOG(
LOG_TRACE,
"DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh,
6592 (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
"interlaced" :
"progressive");
6594 if ((mode->hdisplay < width) || (mode->vdisplay < height) || (mode->vrefresh < fps))
6600 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced))
6606 if ((mode->hdisplay >= width) && (mode->vdisplay >= height) && (mode->vrefresh >= fps))
6608 const int widthDiff = mode->hdisplay - width;
6609 const int heightDiff = mode->vdisplay - height;
6610 const int fpsDiff = mode->vrefresh - fps;
6612 if (nearestIndex < 0)
6618 const int nearestWidthDiff = CORE.
Window.connector->modes[nearestIndex].hdisplay - width;
6619 const int nearestHeightDiff = CORE.
Window.connector->modes[nearestIndex].vdisplay - height;
6620 const int nearestFpsDiff = CORE.
Window.connector->modes[nearestIndex].vrefresh - fps;
6622 if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
6626 return nearestIndex;
6630#if defined(SUPPORT_EVENTS_AUTOMATION)
6633static void LoadAutomationEvents(
const char *fileName)
6653 FILE *repFile = fopen(fileName,
"rt");
6655 if (repFile !=
NULL)
6657 unsigned int count = 0;
6658 char buffer[256] = { 0 };
6660 fgets(buffer, 256, repFile);
6662 while (!feof(repFile))
6664 if (buffer[0] ==
'c') sscanf(buffer,
"c %i", &eventCount);
6665 else if (buffer[0] ==
'e')
6667 sscanf(buffer,
"e %d %d %d %d %d", &events[count].frame, &events[count].type,
6668 &events[count].params[0], &events[count].params[1], &events[count].params[2]);
6673 fgets(buffer, 256, repFile);
6676 if (count != eventCount)
TRACELOG(
LOG_WARNING,
"Events count provided is different than count");
6685static void ExportAutomationEvents(
const char *fileName)
6687 unsigned char fileId[4] =
"rEP ";
6699 FILE *repFile = fopen(fileName,
"wt");
6701 if (repFile !=
NULL)
6703 fprintf(repFile,
"# Automation events list\n");
6704 fprintf(repFile,
"# c <events_count>\n");
6705 fprintf(repFile,
"# e <frame> <event_type> <param0> <param1> <param2> // <event_type_name>\n");
6707 fprintf(repFile,
"c %i\n", eventCount);
6708 for (
int i = 0; i < eventCount; i++)
6710 fprintf(repFile,
"e %i %i %i %i %i // %s\n", events[i].frame, events[i].type,
6711 events[i].params[0], events[i].params[1], events[i].params[2], autoEventTypeName[events[i].type]);
6720static void RecordAutomationEvent(
unsigned int frame)
6727 events[eventCount].frame = frame;
6728 events[eventCount].type = INPUT_KEY_UP;
6729 events[eventCount].params[0] = key;
6730 events[eventCount].params[1] = 0;
6731 events[eventCount].params[2] = 0;
6733 TRACELOG(
LOG_INFO,
"[%i] INPUT_KEY_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6740 events[eventCount].frame = frame;
6741 events[eventCount].type = INPUT_KEY_DOWN;
6742 events[eventCount].params[0] = key;
6743 events[eventCount].params[1] = 0;
6744 events[eventCount].params[2] = 0;
6746 TRACELOG(
LOG_INFO,
"[%i] INPUT_KEY_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6756 events[eventCount].frame = frame;
6757 events[eventCount].type = INPUT_MOUSE_BUTTON_UP;
6758 events[eventCount].params[0] = button;
6759 events[eventCount].params[1] = 0;
6760 events[eventCount].params[2] = 0;
6762 TRACELOG(
LOG_INFO,
"[%i] INPUT_MOUSE_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6769 events[eventCount].frame = frame;
6770 events[eventCount].type = INPUT_MOUSE_BUTTON_DOWN;
6771 events[eventCount].params[0] = button;
6772 events[eventCount].params[1] = 0;
6773 events[eventCount].params[2] = 0;
6775 TRACELOG(
LOG_INFO,
"[%i] INPUT_MOUSE_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6784 events[eventCount].frame = frame;
6785 events[eventCount].type = INPUT_MOUSE_POSITION;
6788 events[eventCount].params[2] = 0;
6790 TRACELOG(
LOG_INFO,
"[%i] INPUT_MOUSE_POSITION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6797 events[eventCount].frame = frame;
6798 events[eventCount].type = INPUT_MOUSE_WHEEL_MOTION;
6800 events[eventCount].params[1] = 0;
6801 events[eventCount].params[2] = 0;
6803 TRACELOG(
LOG_INFO,
"[%i] INPUT_MOUSE_WHEEL_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6812 events[eventCount].frame = frame;
6813 events[eventCount].type = INPUT_TOUCH_UP;
6814 events[eventCount].params[0] =
id;
6815 events[eventCount].params[1] = 0;
6816 events[eventCount].params[2] = 0;
6818 TRACELOG(
LOG_INFO,
"[%i] INPUT_TOUCH_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6825 events[eventCount].frame = frame;
6826 events[eventCount].type = INPUT_TOUCH_DOWN;
6827 events[eventCount].params[0] =
id;
6828 events[eventCount].params[1] = 0;
6829 events[eventCount].params[2] = 0;
6831 TRACELOG(
LOG_INFO,
"[%i] INPUT_TOUCH_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6853 for (
int gamepad = 0; gamepad <
MAX_GAMEPADS; gamepad++)
6878 events[eventCount].frame = frame;
6879 events[eventCount].type = INPUT_GAMEPAD_BUTTON_UP;
6880 events[eventCount].params[0] = gamepad;
6881 events[eventCount].params[1] = button;
6882 events[eventCount].params[2] = 0;
6884 TRACELOG(
LOG_INFO,
"[%i] INPUT_GAMEPAD_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6891 events[eventCount].frame = frame;
6892 events[eventCount].type = INPUT_GAMEPAD_BUTTON_DOWN;
6893 events[eventCount].params[0] = gamepad;
6894 events[eventCount].params[1] = button;
6895 events[eventCount].params[2] = 0;
6897 TRACELOG(
LOG_INFO,
"[%i] INPUT_GAMEPAD_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6907 events[eventCount].frame = frame;
6908 events[eventCount].type = INPUT_GAMEPAD_AXIS_MOTION;
6909 events[eventCount].params[0] = gamepad;
6910 events[eventCount].params[1] = axis;
6913 TRACELOG(
LOG_INFO,
"[%i] INPUT_GAMEPAD_AXIS_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6922 events[eventCount].frame = frame;
6923 events[eventCount].type = INPUT_GESTURE;
6924 events[eventCount].params[0] = GESTURES.current;
6925 events[eventCount].params[1] = 0;
6926 events[eventCount].params[2] = 0;
6928 TRACELOG(
LOG_INFO,
"[%i] INPUT_GESTURE: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
6934static void PlayAutomationEvent(
unsigned int frame)
6936 for (
unsigned int i = 0; i < eventCount; i++)
6938 if (events[i].frame == frame)
6940 switch (events[i].type)
6947 case INPUT_MOUSE_POSITION:
6955 case INPUT_TOUCH_POSITION:
6960 case INPUT_GAMEPAD_CONNECT: CORE.
Input.
Gamepad.
ready[events[i].params[0]] =
true;
break;
6961 case INPUT_GAMEPAD_DISCONNECT: CORE.
Input.
Gamepad.
ready[events[i].params[0]] =
false;
break;
6964 case INPUT_GAMEPAD_AXIS_MOTION:
6966 CORE.
Input.
Gamepad.
axisState[events[i].params[0]][events[i].params[1]] = ((float)events[i].params[2]/32768.0f);
6968 case INPUT_GESTURE: GESTURES.current = events[i].params[0];
break;
6974 case WINDOW_RESIZE:
SetWindowSize(events[i].params[0], events[i].params[1]);
break;
6977 case ACTION_TAKE_SCREENSHOT:
6980 screenshotCounter++;
6982 case ACTION_SETTARGETFPS:
SetTargetFPS(events[i].params[0]);
break;
6990#if !defined(SUPPORT_MODULE_RTEXT)
6995#ifndef MAX_TEXTFORMAT_BUFFERS
6996 #define MAX_TEXTFORMAT_BUFFERS 4
6998#ifndef MAX_TEXT_BUFFER_LENGTH
6999 #define MAX_TEXT_BUFFER_LENGTH 1024
7004 static int index = 0;
7006 char *currentBuffer = buffers[index];
7010 va_start(args, text);
7017 return currentBuffer;
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW
#define MAX_CHAR_PRESSED_QUEUE
#define MAX_KEYBOARD_KEYS
#define MAX_MOUSE_BUTTONS
#define RL_CULL_DISTANCE_NEAR
#define MAX_FILEPATH_LENGTH
#define STORAGE_DATA_FILE
#define MAX_GAMEPAD_BUTTONS
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1
#define MAX_KEY_PRESSED_QUEUE
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD
#define MAX_TEXT_BUFFER_LENGTH
#define RL_CULL_DISTANCE_FAR
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR
#define RL_MAX_SHADER_LOCATIONS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2
#define MAX_DECOMPRESSION_SIZE
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
DIR * opendir(const char *name)
struct dirent * readdir(DIR *dir)
#define EGL_NATIVE_VISUAL_ID
#define EGL_RENDERABLE_TYPE
#define EGL_DEFAULT_DISPLAY
void * EGLNativeDisplayType
#define EGL_OPENGL_ES2_BIT
#define EGL_CONTEXT_CLIENT_VERSION
void * EGLNativeWindowType
#define EGL_OPENGL_ES_API
#define eglGetProcAddress
#define eglDestroyContext
#define eglCreateWindowSurface
#define eglDestroySurface
#define eglGetConfigAttrib
#define GLFW_EGL_CONTEXT_API
#define GLFW_NATIVE_CONTEXT_API
#define GLFW_CURSOR_DISABLED
#define GLFW_OPENGL_ES_API
#define GLFW_CURSOR_HIDDEN
#define GLFW_CURSOR_NORMAL
#define GLFW_OPENGL_CORE_PROFILE
GLFWAPI GLFWglproc glfwGetProcAddress(const char *procname)
Returns the address of the specified function for the current context.
GLFWAPI void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
GLFWAPI void glfwMakeContextCurrent(GLFWwindow *window)
Makes the context of the specified window current for the calling thread.
#define GLFW_GAMEPAD_AXIS_LAST
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback)
Sets the error callback.
GLFWAPI int glfwInit(void)
GLFW API functions.
#define GLFW_COCOA_CHDIR_RESOURCES
macOS specific init hint.
GLFWAPI void glfwInitHint(int hint, int value)
Sets the specified init hint to the desired value.
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
#define GLFW_MOD_CONTROL
If this bit is set one or more Control keys were held down.
GLFWAPI const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
Returns the current mode of the specified monitor.
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor *monitor, float *xscale, float *yscale)
Retrieves the content scale for the specified monitor.
GLFWAPI GLFWmonitor * glfwGetPrimaryMonitor(void)
Returns the primary monitor.
GLFWAPI void glfwGetMonitorPos(GLFWmonitor *monitor, int *xpos, int *ypos)
Returns the position of the monitor's viewport on the virtual screen.
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor *monitor, int *xpos, int *ypos, int *width, int *height)
Retrieves the work area of the monitor.
GLFWAPI const char * glfwGetMonitorName(GLFWmonitor *monitor)
Returns the name of the specified monitor.
GLFWAPI const GLFWvidmode * glfwGetVideoModes(GLFWmonitor *monitor, int *count)
Returns the available video modes for the specified monitor.
GLFWAPI GLFWmonitor ** glfwGetMonitors(int *count)
Returns the currently connected monitors.
struct GLFWmonitor GLFWmonitor
Opaque monitor object.
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor *monitor, int *widthMM, int *heightMM)
Returns the physical size of the monitor.
GLFWAPI void glfwGetWindowPos(GLFWwindow *window, int *xpos, int *ypos)
Retrieves the position of the content area of the specified window.
GLFWAPI void glfwSetWindowPos(GLFWwindow *window, int xpos, int ypos)
Sets the position of the content area of the specified window.
GLFWAPI void glfwSetWindowMonitor(GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
Sets the mode, monitor, video mode and placement of a window.
#define GLFW_OPENGL_FORWARD_COMPAT
OpenGL forward-compatibility hint and attribute.
GLFWAPI void glfwSetWindowIcon(GLFWwindow *window, int count, const GLFWimage *images)
Sets the icon for the specified window.
GLFWAPI int glfwGetWindowAttrib(GLFWwindow *window, int attrib)
Returns an attribute of the specified window.
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
GLFWAPI void glfwRestoreWindow(GLFWwindow *window)
Restores the specified window.
#define GLFW_DECORATED
Window decoration window hint and attribute.
GLFWAPI void glfwIconifyWindow(GLFWwindow *window)
Iconifies the specified window.
#define GLFW_SAMPLES
Framebuffer MSAA samples hint.
#define GLFW_CONTEXT_VERSION_MINOR
Context client API minor version hint and attribute.
struct GLFWwindow GLFWwindow
Opaque window object.
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow *window, GLFWwindowiconifyfun callback)
Sets the iconify callback for the specified window.
#define GLFW_OPENGL_PROFILE
OpenGL profile hint and attribute.
GLFWAPI void glfwMaximizeWindow(GLFWwindow *window)
Maximizes the specified window.
#define GLFW_CONTEXT_CREATION_API
Context creation API hint and attribute.
#define GLFW_FOCUSED
Input focus window hint and attribute.
#define GLFW_TRANSPARENT_FRAMEBUFFER
Window framebuffer transparency hint and attribute.
#define GLFW_SCALE_TO_MONITOR
Window content area scaling window window hint.
GLFWAPI void glfwSetWindowOpacity(GLFWwindow *window, float opacity)
Sets the opacity of the whole window.
#define GLFW_CLIENT_API
Context client API hint and attribute.
GLFWAPI void glfwWindowHint(int hint, int value)
Sets the specified window hint to the desired value.
GLFWAPI void glfwWaitEvents(void)
Waits until events are queued and processes them.
GLFWAPI void glfwGetWindowContentScale(GLFWwindow *window, float *xscale, float *yscale)
Retrieves the content scale for the specified window.
GLFWAPI void glfwShowWindow(GLFWwindow *window)
Makes the specified window visible.
#define GLFW_FLOATING
Window decoration window hint and attribute.
GLFWAPI void glfwDefaultWindowHints(void)
Resets all window hints to their default values.
GLFWAPI void glfwDestroyWindow(GLFWwindow *window)
Destroys the specified window and its context.
GLFWAPI void glfwSetWindowTitle(GLFWwindow *window, const char *title)
Sets the title of the specified window.
GLFWAPI void glfwPollEvents(void)
Processes all pending events.
#define GLFW_OPENGL_DEBUG_CONTEXT
Legacy name for compatibility.
GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
Sets the size limits of the specified window.
#define GLFW_AUTO_ICONIFY
Window auto-iconification window hint and attribute.
GLFWAPI void glfwHideWindow(GLFWwindow *window)
Hides the specified window.
GLFWAPI int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.
GLFWAPI GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
Creates a window and its associated context.
GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow *window, GLFWwindowsizefun callback)
Sets the size callback for the specified window.
#define GLFW_COCOA_RETINA_FRAMEBUFFER
macOS specific window hint.
GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow *window, GLFWwindowfocusfun callback)
Sets the focus callback for the specified window.
GLFWAPI void glfwSetWindowAttrib(GLFWwindow *window, int attrib, int value)
Sets an attribute of the specified window.
GLFWAPI GLFWmonitor * glfwGetWindowMonitor(GLFWwindow *window)
Returns the monitor that the window uses for full screen mode.
#define GLFW_RESIZABLE
Window resize-ability window hint and attribute.
GLFWAPI void glfwSetWindowSize(GLFWwindow *window, int width, int height)
Sets the size of the content area of the specified window.
GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow *window, GLFWwindowmaximizefun callback)
Sets the maximize callback for the specified window.
GLFWAPI void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the framebuffer of the specified window.
#define GLFW_FOCUS_ON_SHOW
Input focus on calling show window hint and attribute.
#define GLFW_VISIBLE
Window visibility window hint and attribute.
GLFWAPI void glfwSwapBuffers(GLFWwindow *window)
Swaps the front and back buffers of the specified window.
#define GLFW_CONTEXT_VERSION_MAJOR
Context client API major version hint and attribute.
void msf_gif_free(MsfGifResult result)
int msf_gif_frame(MsfGifState *handle, uint8_t *pixelData, int centiSecondsPerFame, int maxBitDepth, int pitchInBytes)
MsfGifResult msf_gif_end(MsfGifState *handle)
int msf_gif_begin(MsfGifState *handle, int width, int height)
#define RL_MALLOC(sz)
raudio v1.0 - A simple and easy-to-use audio library based on miniaudio
#define TRACELOG(level,...)
@ SHADER_LOC_MATRIX_MODEL
@ SHADER_LOC_COLOR_DIFFUSE
@ SHADER_LOC_VERTEX_COLOR
@ SHADER_LOC_VERTEX_TANGENT
@ SHADER_LOC_MATRIX_PROJECTION
@ SHADER_LOC_VERTEX_TEXCOORD01
@ SHADER_LOC_VERTEX_POSITION
@ SHADER_LOC_VERTEX_TEXCOORD02
@ SHADER_LOC_MATRIX_NORMAL
@ SHADER_LOC_VERTEX_NORMAL
RLAPI const char * TextFormat(const char *text,...)
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
RLAPI void UnloadFileData(unsigned char *data)
@ GAMEPAD_AXIS_RIGHT_TRIGGER
@ GAMEPAD_AXIS_LEFT_TRIGGER
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source)
@ PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
RLAPI unsigned char * LoadFileData(const char *fileName, unsigned int *bytesRead)
#define RL_REALLOC(ptr, sz)
RLAPI const char * TextToLower(const char *text)
@ GAMEPAD_BUTTON_LEFT_FACE_DOWN
@ GAMEPAD_BUTTON_LEFT_FACE_UP
@ GAMEPAD_BUTTON_RIGHT_THUMB
@ GAMEPAD_BUTTON_LEFT_TRIGGER_1
@ GAMEPAD_BUTTON_LEFT_FACE_LEFT
@ GAMEPAD_BUTTON_MIDDLE_LEFT
@ GAMEPAD_BUTTON_LEFT_TRIGGER_2
@ GAMEPAD_BUTTON_RIGHT_FACE_DOWN
@ GAMEPAD_BUTTON_RIGHT_FACE_LEFT
@ GAMEPAD_BUTTON_LEFT_FACE_RIGHT
@ GAMEPAD_BUTTON_RIGHT_FACE_RIGHT
@ GAMEPAD_BUTTON_LEFT_THUMB
@ GAMEPAD_BUTTON_MIDDLE_RIGHT
@ GAMEPAD_BUTTON_RIGHT_FACE_UP
@ GAMEPAD_BUTTON_RIGHT_TRIGGER_2
@ GAMEPAD_BUTTON_RIGHT_TRIGGER_1
RLAPI void TraceLog(int logLevel, const char *text,...)
RLAPI Font GetFontDefault(void)
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
#define SHADER_LOC_MAP_SPECULAR
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color)
RLAPI bool ExportImage(Image image, const char *fileName)
#define RAYLIB_VERSION
raylib v4.1-dev - A simple and easy-to-use library to enjoy videogames programming (www....
@ FLAG_WINDOW_UNDECORATED
@ FLAG_WINDOW_TRANSPARENT
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color)
RLAPI void UnloadFileText(char *text)
RLAPI const char ** TextSplit(const char *text, char delimiter, int *count)
RLAPI char * LoadFileText(const char *fileName)
#define SHADER_LOC_MAP_DIFFUSE
RMAPI Vector3 Vector3Normalize(Vector3 v)
RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat)
#define MatrixToFloat(mat)
RMAPI Matrix MatrixRotate(Vector3 axis, float angle)
RMAPI Matrix MatrixScale(float x, float y, float z)
RMAPI Matrix MatrixIdentity(void)
RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
RMAPI Matrix MatrixTranslate(float x, float y, float z)
RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view)
RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat)
RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far)
RMAPI Matrix MatrixInvert(Matrix mat)
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far)
RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
RMAPI Matrix MatrixMultiply(Matrix left, Matrix right)
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
void BeginScissorMode(int x, int y, int width, int height)
bool IsGamepadButtonReleased(int gamepad, int button)
const char * GetFileName(const char *filePath)
void SetMousePosition(int x, int y)
void BeginVrStereoMode(VrStereoConfig config)
unsigned char * CompressData(const unsigned char *data, int dataSize, int *compDataSize)
bool IsGamepadButtonUp(int gamepad, int button)
const char * GetDirectoryPath(const char *filePath)
bool IsWindowFullscreen(void)
void MaximizeWindow(void)
void BeginTextureMode(RenderTexture2D target)
void UnloadFontDefault(void)
bool IsMouseButtonPressed(int button)
void SetConfigFlags(unsigned int flags)
Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height)
void ClearDirectoryFiles(void)
void InitWindow(int width, int height, const char *title)
void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
const char * GetWorkingDirectory(void)
void SetClipboardText(const char *text)
void SetWindowOpacity(float opacity)
char ** GetDroppedFiles(int *count)
const char * GetPrevDirectoryPath(const char *dirPath)
void SetWindowMinSize(int width, int height)
bool WindowShouldClose(void)
void BeginMode3D(Camera3D camera)
bool DirectoryExists(const char *dirPath)
bool IsKeyPressed(int key)
bool IsWindowResized(void)
void SetWindowPosition(int x, int y)
bool IsCursorHidden(void)
char ** GetDirectoryFiles(const char *dirPath, int *fileCount)
void BeginShaderMode(Shader shader)
int GetRenderHeight(void)
void SwapScreenBuffer(void)
Matrix GetCameraMatrix(Camera camera)
bool IsGamepadButtonPressed(int gamepad, int button)
void SetRandomSeed(unsigned int seed)
bool IsFileExtension(const char *fileName, const char *ext)
void UnloadVrStereoConfig(VrStereoConfig config)
const char * GetClipboardText(void)
int GetTouchPointId(int index)
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera)
bool SaveStorageValue(unsigned int position, int value)
void ToggleFullscreen(void)
Vector2 GetTouchPosition(int index)
#define FPS_CAPTURE_FRAMES_COUNT
bool IsMouseButtonUp(int button)
void * GetWindowHandle(void)
bool IsWindowMaximized(void)
void MinimizeWindow(void)
float GetGamepadAxisMovement(int gamepad, int axis)
int GetRandomValue(int min, int max)
void SetMouseCursor(int cursor)
const char * GetApplicationDirectory(void)
const char * GetFileNameWithoutExt(const char *filePath)
bool IsGamepadButtonDown(int gamepad, int button)
void EndVrStereoMode(void)
#define MAX_FILENAMEWITHOUTEXT_LENGTH
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
void SetTargetFPS(int fps)
int GetMonitorWidth(int monitor)
bool IsGamepadAvailable(int gamepad)
void EndScissorMode(void)
int GetGamepadButtonPressed(void)
void EndTextureMode(void)
int GetMonitorHeight(int monitor)
void SetMouseScale(float scaleX, float scaleY)
void ClearWindowState(unsigned int flags)
void LoadFontDefault(void)
Vector2 GetWindowScaleDPI(void)
bool ChangeDirectory(const char *dir)
bool IsCursorOnScreen(void)
const char * GetMonitorName(int monitor)
Vector2 GetMonitorPosition(int monitor)
void PollInputEvents(void)
bool FileExists(const char *fileName)
void SetMouseOffset(int offsetX, int offsetY)
const char * GetFileExtension(const char *fileName)
float GetMouseWheelMove(void)
int LoadStorageValue(unsigned int position)
int GetFileLength(const char *fileName)
Shader LoadShader(const char *vsFileName, const char *fsFileName)
void ClearBackground(Color color)
int GetMonitorPhysicalHeight(int monitor)
#define COMPRESSION_QUALITY_DEFLATE
void SetWindowMonitor(int monitor)
void BeginMode2D(Camera2D camera)
const char * GetGamepadName(int gamepad)
const char * raylibVersion
int GetCurrentMonitor(void)
void UnloadShader(Shader shader)
bool IsWindowFocused(void)
void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count)
bool IsMouseButtonDown(int button)
void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType)
void ClearDroppedFiles(void)
int GetMonitorPhysicalWidth(int monitor)
bool IsWindowState(unsigned int flag)
int GetMonitorCount(void)
VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
int GetScreenHeight(void)
void SetWindowSize(int width, int height)
unsigned char * DecodeDataBase64(const unsigned char *data, int *outputSize)
int SetGamepadMappings(const char *mappings)
bool IsWindowMinimized(void)
void SetWindowIcon(Image image)
int GetShaderLocationAttrib(Shader shader, const char *attribName)
bool IsMouseButtonReleased(int button)
bool IsWindowHidden(void)
Vector2 GetMousePosition(void)
#define GIF_RECORD_FRAMERATE
Matrix GetCameraMatrix2D(Camera2D camera)
long GetFileModTime(const char *fileName)
Ray GetMouseRay(Vector2 mouse, Camera camera)
void SetWindowTitle(const char *title)
void BeginBlendMode(int mode)
void OpenURL(const char *url)
char * EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize)
void TakeScreenshot(const char *fileName)
int GetMonitorRefreshRate(int monitor)
Vector2 GetMouseDelta(void)
void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat)
int GetGamepadAxisCount(int gamepad)
int GetTouchPointCount(void)
void SetWindowState(unsigned int flags)
bool IsKeyReleased(int key)
unsigned char * DecompressData(const unsigned char *compData, int compDataSize, int *dataSize)
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
int GetShaderLocation(Shader shader, const char *uniformName)
Vector2 GetWindowPosition(void)
void ProcessGestureEvent(GestureEvent event)
void UpdateGestures(void)
RLAPI int * rlGetShaderLocsDefault(void)
RLAPI void rlClearScreenBuffers(void)
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
RLAPI void rlSetBlendMode(int mode)
RLAPI void rlLoadIdentity(void)
RLAPI void rlglClose(void)
RLAPI void rlDisableScissorTest(void)
RLAPI void rlEnableStereoRender(void)
RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
RLAPI void rlLoadExtensions(void *loader)
RLAPI unsigned int rlGetShaderIdDefault(void)
RLAPI unsigned char * rlReadScreenPixels(int width, int height)
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat)
RLAPI void rlSetFramebufferHeight(int height)
RLAPI void rlDisableStereoRender(void)
RLAPI void rlPushMatrix(void)
RLAPI unsigned int rlGetTextureIdDefault(void)
RLAPI void rlViewport(int x, int y, int width, int height)
RLAPI void rlScissor(int x, int y, int width, int height)
RLAPI int rlGetVersion(void)
RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId)
RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left)
#define RL_TEXTURE_FILTER_LINEAR
#define RL_TEXTURE_MIN_FILTER
RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
RLAPI void rlEnableFramebuffer(unsigned int id)
RLAPI void rlEnableShader(unsigned int id)
RLAPI void rlMultMatrixf(float *matf)
RLAPI void rlDisableFramebuffer(void)
RLAPI void rlEnableScissorTest(void)
RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left)
RLAPI void rlDrawRenderBatchActive(void)
RLAPI void rlEnableDepthTest(void)
RLAPI void rlSetShader(unsigned int id, int *locs)
RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName)
#define RL_TEXTURE_MAG_FILTER
RLAPI void rlglInit(int width, int height)
RLAPI void rlTextureParameters(unsigned int id, int param, int value)
RLAPI void rlPopMatrix(void)
RLAPI void rlUnloadShaderProgram(unsigned int id)
RLAPI void rlMatrixMode(int mode)
RLAPI void rlDisableDepthTest(void)
RLAPI void rlSetFramebufferWidth(int width)
RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
#define MAX_TEXTFORMAT_BUFFERS
int sdefl_bound(int in_len)
int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl)
int sinflate(void *out, int cap, const void *in, int size)
char currentButtonState[MAX_MOUSE_BUTTONS]
struct CoreData::@140::@145 Gamepad
char previousTouchState[MAX_TOUCH_POINTS]
struct CoreData::@140::@142 Keyboard
int pointId[MAX_TOUCH_POINTS]
struct CoreData::@138 Window
char currentTouchState[MAX_TOUCH_POINTS]
float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]
int charPressedQueueCount
struct CoreData::@141 Time
struct CoreData::@140 Input
char name[MAX_GAMEPADS][64]
char currentKeyState[MAX_KEYBOARD_KEYS]
char previousKeyState[MAX_KEYBOARD_KEYS]
int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]
struct CoreData::@139 Storage
char previousButtonState[MAX_MOUSE_BUTTONS]
int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]
struct CoreData::@140::@143 Mouse
struct CoreData::@140::@144 Touch
unsigned int frameCounter
int pointId[MAX_TOUCH_POINTS]
Vector2 position[MAX_TOUCH_POINTS]
float lensDistortionValues[4]
float lensSeparationDistance
float interpupillaryDistance
float eyeToScreenDistance
float leftScreenCenter[2]
float rightScreenCenter[2]
GLFWAPI HWND glfwGetWin32Window(GLFWwindow *handle)