mirror of
https://github.com/raysan5/raylib.git
synced 2025-12-15 19:05:34 +00:00
Some TODOs and format reviews
This commit is contained in:
@@ -49,10 +49,10 @@
|
|||||||
#define SUPPORT_RPRAND_GENERATOR 1
|
#define SUPPORT_RPRAND_GENERATOR 1
|
||||||
// Mouse gestures are directly mapped like touches and processed by gestures system
|
// Mouse gestures are directly mapped like touches and processed by gestures system
|
||||||
#define SUPPORT_MOUSE_GESTURES 1
|
#define SUPPORT_MOUSE_GESTURES 1
|
||||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
// Reconfigure standard input to receive key inputs, works with SSH connection
|
||||||
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
||||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions
|
||||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often
|
||||||
#define SUPPORT_WINMM_HIGHRES_TIMER 1
|
#define SUPPORT_WINMM_HIGHRES_TIMER 1
|
||||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used
|
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used
|
||||||
//#define SUPPORT_BUSY_WAIT_LOOP 1
|
//#define SUPPORT_BUSY_WAIT_LOOP 1
|
||||||
@@ -225,7 +225,7 @@
|
|||||||
|
|
||||||
// On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle
|
// On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle
|
||||||
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
||||||
// drawing text and shapes with a single draw call [SetShapesTexture()].
|
// drawing text and shapes with a single draw call [SetShapesTexture()]
|
||||||
#define SUPPORT_FONT_ATLAS_WHITE_REC 1
|
#define SUPPORT_FONT_ATLAS_WHITE_REC 1
|
||||||
|
|
||||||
// Support conservative font atlas size estimation
|
// Support conservative font atlas size estimation
|
||||||
|
|||||||
54
src/external/rlsw.h
vendored
54
src/external/rlsw.h
vendored
@@ -145,7 +145,7 @@
|
|||||||
#define SW_MAX_TEXTURES 128
|
#define SW_MAX_TEXTURES 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Under normal circumstances, clipping a polygon can add at most one vertex per clipping plane.
|
// Under normal circumstances, clipping a polygon can add at most one vertex per clipping plane
|
||||||
// Considering the largest polygon involved is a quadrilateral (4 vertices),
|
// Considering the largest polygon involved is a quadrilateral (4 vertices),
|
||||||
// and that clipping occurs against both the frustum (6 planes) and the scissors (4 planes),
|
// and that clipping occurs against both the frustum (6 planes) and the scissors (4 planes),
|
||||||
// the maximum number of vertices after clipping is:
|
// the maximum number of vertices after clipping is:
|
||||||
@@ -1530,7 +1530,7 @@ DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G5B5A1, uint16_t)
|
|||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
uint8_t r5 = (color[0]*31 + 127)/255;
|
||||||
uint8_t g5 = (color[1]*31 + 127)/255;
|
uint8_t g5 = (color[1]*31 + 127)/255;
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
uint8_t b5 = (color[2]*31 + 127)/255;
|
||||||
uint8_t a1 = color[3] >= 128 ? 1 : 0;
|
uint8_t a1 = (color[3] >= 128)? 1 : 0;
|
||||||
|
|
||||||
#if SW_GL_FRAMEBUFFER_COPY_BGRA
|
#if SW_GL_FRAMEBUFFER_COPY_BGRA
|
||||||
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
||||||
@@ -1661,7 +1661,7 @@ DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G5B5A1, uint16_t)
|
|||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
uint8_t r5 = (color[0]*31 + 127)/255;
|
||||||
uint8_t g5 = (color[1]*31 + 127)/255;
|
uint8_t g5 = (color[1]*31 + 127)/255;
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
uint8_t b5 = (color[2]*31 + 127)/255;
|
||||||
uint8_t a1 = color[3] >= 128 ? 1 : 0;
|
uint8_t a1 = (color[3] >= 128)? 1 : 0;
|
||||||
|
|
||||||
#if SW_GL_FRAMEBUFFER_COPY_BGRA
|
#if SW_GL_FRAMEBUFFER_COPY_BGRA
|
||||||
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
||||||
@@ -1919,7 +1919,7 @@ static inline void sw_texture_sample_nearest(float *color, const sw_texture_t *t
|
|||||||
static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v)
|
static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v)
|
||||||
{
|
{
|
||||||
// TODO: With a bit more cleverness we could clearly reduce the
|
// TODO: With a bit more cleverness we could clearly reduce the
|
||||||
// number of operations here, but for now it works fine.
|
// number of operations here, but for now it works fine
|
||||||
|
|
||||||
float xf = (u*tex->width) - 0.5f;
|
float xf = (u*tex->width) - 0.5f;
|
||||||
float yf = (v*tex->height) - 0.5f;
|
float yf = (v*tex->height) - 0.5f;
|
||||||
@@ -2203,13 +2203,13 @@ static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VE
|
|||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
static inline bool sw_triangle_face_culling(void)
|
static inline bool sw_triangle_face_culling(void)
|
||||||
{
|
{
|
||||||
// NOTE: Face culling is done before clipping to avoid unnecessary computations.
|
// NOTE: Face culling is done before clipping to avoid unnecessary computations
|
||||||
// To handle triangles crossing the w=0 plane correctly,
|
// To handle triangles crossing the w=0 plane correctly,
|
||||||
// we perform the winding order test in homogeneous coordinates directly,
|
// we perform the winding order test in homogeneous coordinates directly,
|
||||||
// before the perspective division (division by w).
|
// before the perspective division (division by w)
|
||||||
// This test determines the orientation of the triangle in the (x,y,w) plane,
|
// This test determines the orientation of the triangle in the (x,y,w) plane,
|
||||||
// which corresponds to the projected 2D winding order sign,
|
// which corresponds to the projected 2D winding order sign,
|
||||||
// even with negative w values.
|
// even with negative w values
|
||||||
|
|
||||||
// Preload homogeneous coordinates into local variables
|
// Preload homogeneous coordinates into local variables
|
||||||
const float *h0 = RLSW.vertexBuffer[0].homogeneous;
|
const float *h0 = RLSW.vertexBuffer[0].homogeneous;
|
||||||
@@ -2221,7 +2221,7 @@ static inline bool sw_triangle_face_culling(void)
|
|||||||
// This is the determinant of the matrix formed by the (x, y, w) components
|
// This is the determinant of the matrix formed by the (x, y, w) components
|
||||||
// of the vertices, which correctly captures the winding order in homogeneous
|
// of the vertices, which correctly captures the winding order in homogeneous
|
||||||
// space and its relationship to the projected 2D winding order, even with
|
// space and its relationship to the projected 2D winding order, even with
|
||||||
// negative w values.
|
// negative w values
|
||||||
// The determinant formula used here is:
|
// The determinant formula used here is:
|
||||||
// h0.x*(h1.y*h2.w - h2.y*h1.w) +
|
// h0.x*(h1.y*h2.w - h2.y*h1.w) +
|
||||||
// h1.x*(h2.y*h0.w - h0.y*h2.w) +
|
// h1.x*(h2.y*h0.w - h0.y*h2.w) +
|
||||||
@@ -2233,20 +2233,18 @@ static inline bool sw_triangle_face_culling(void)
|
|||||||
h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]);
|
h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]);
|
||||||
|
|
||||||
// Discard the triangle if its winding order (determined by the sign
|
// Discard the triangle if its winding order (determined by the sign
|
||||||
// of the homogeneous area/determinant) matches the culled direction.
|
// of the homogeneous area/determinant) matches the culled direction
|
||||||
// A positive hSgnArea typically corresponds to a counter-clockwise
|
// A positive hSgnArea typically corresponds to a counter-clockwise
|
||||||
// winding in the projected space when all w > 0.
|
// winding in the projected space when all w > 0.
|
||||||
// This test is robust for points with w > 0 or w < 0, correctly
|
// This test is robust for points with w > 0 or w < 0, correctly
|
||||||
// capturing the change in orientation when crossing the w=0 plane.
|
// capturing the change in orientation when crossing the w=0 plane
|
||||||
|
|
||||||
// The culling logic remains the same based on the signed area/determinant.
|
// The culling logic remains the same based on the signed area/determinant
|
||||||
// A value of 0 for hSgnArea means the points are collinear in (x, y, w)
|
// A value of 0 for hSgnArea means the points are collinear in (x, y, w)
|
||||||
// space, which corresponds to a degenerate triangle projection.
|
// space, which corresponds to a degenerate triangle projection.
|
||||||
// Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false)
|
// Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false)
|
||||||
// and should be handled by the clipper if necessary.
|
// and should be handled by the clipper if necessary
|
||||||
return (RLSW.cullFace == SW_FRONT)
|
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise"
|
||||||
? (hSgnArea < 0) // Cull if winding is "clockwise" in the projected sense
|
|
||||||
: (hSgnArea > 0); // Cull if winding is "counter-clockwise" in the projected sense
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_triangle_clip_and_project(void)
|
static inline void sw_triangle_clip_and_project(void)
|
||||||
@@ -2559,14 +2557,14 @@ static inline void sw_triangle_render(void)
|
|||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
static inline bool sw_quad_face_culling(void)
|
static inline bool sw_quad_face_culling(void)
|
||||||
{
|
{
|
||||||
// NOTE: Face culling is done before clipping to avoid unnecessary computations.
|
// NOTE: Face culling is done before clipping to avoid unnecessary computations
|
||||||
// To handle quads crossing the w=0 plane correctly,
|
// To handle quads crossing the w=0 plane correctly,
|
||||||
// we perform the winding order test in homogeneous coordinates directly,
|
// we perform the winding order test in homogeneous coordinates directly,
|
||||||
// before the perspective division (division by w).
|
// before the perspective division (division by w)
|
||||||
// For a convex quad with vertices P0, P1, P2, P3 in sequential order,
|
// For a convex quad with vertices P0, P1, P2, P3 in sequential order,
|
||||||
// the winding order of the quad is the same as the winding order
|
// the winding order of the quad is the same as the winding order
|
||||||
// of the triangle P0 P1 P2. We use the homogeneous triangle
|
// of the triangle P0 P1 P2. We use the homogeneous triangle
|
||||||
// winding test on this first triangle.
|
// winding test on this first triangle
|
||||||
|
|
||||||
// Preload homogeneous coordinates into local variables
|
// Preload homogeneous coordinates into local variables
|
||||||
const float *h0 = RLSW.vertexBuffer[0].homogeneous;
|
const float *h0 = RLSW.vertexBuffer[0].homogeneous;
|
||||||
@@ -2578,11 +2576,11 @@ static inline bool sw_quad_face_culling(void)
|
|||||||
|
|
||||||
// Compute a value proportional to the signed area of the triangle P0 P1 P2
|
// Compute a value proportional to the signed area of the triangle P0 P1 P2
|
||||||
// in the projected 2D plane, calculated directly using homogeneous coordinates
|
// in the projected 2D plane, calculated directly using homogeneous coordinates
|
||||||
// BEFORE division by w.
|
// BEFORE division by w
|
||||||
// This is the determinant of the matrix formed by the (x, y, w) components
|
// This is the determinant of the matrix formed by the (x, y, w) components
|
||||||
// of the vertices P0, P1, and P2. Its sign correctly indicates the winding order
|
// of the vertices P0, P1, and P2. Its sign correctly indicates the winding order
|
||||||
// in homogeneous space and its relationship to the projected 2D winding order,
|
// in homogeneous space and its relationship to the projected 2D winding order,
|
||||||
// even with negative w values.
|
// even with negative w values
|
||||||
// The determinant formula used here is:
|
// The determinant formula used here is:
|
||||||
// h0.x*(h1.y*h2.w - h2.y*h1.w) +
|
// h0.x*(h1.y*h2.w - h2.y*h1.w) +
|
||||||
// h1.x*(h2.y*h0.w - h0.y*h2.w) +
|
// h1.x*(h2.y*h0.w - h0.y*h2.w) +
|
||||||
@@ -2594,21 +2592,19 @@ static inline bool sw_quad_face_culling(void)
|
|||||||
h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]);
|
h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]);
|
||||||
|
|
||||||
// Perform face culling based on the winding order determined by the sign
|
// Perform face culling based on the winding order determined by the sign
|
||||||
// of the homogeneous area/determinant of triangle P0 P1 P2.
|
// of the homogeneous area/determinant of triangle P0 P1 P2
|
||||||
// This test is robust for points with w > 0 or w < 0 within the triangle,
|
// This test is robust for points with w > 0 or w < 0 within the triangle,
|
||||||
// correctly capturing the change in orientation when crossing the w=0 plane.
|
// correctly capturing the change in orientation when crossing the w=0 plane
|
||||||
|
|
||||||
// A positive hSgnArea typically corresponds to a counter-clockwise
|
// A positive hSgnArea typically corresponds to a counter-clockwise
|
||||||
// winding in the projected space when all w > 0.
|
// winding in the projected space when all w > 0
|
||||||
// A value of 0 for hSgnArea means P0, P1, P2 are collinear in (x, y, w)
|
// A value of 0 for hSgnArea means P0, P1, P2 are collinear in (x, y, w)
|
||||||
// space, which corresponds to a degenerate triangle projection.
|
// space, which corresponds to a degenerate triangle projection
|
||||||
// Such quads might also be degenerate or non-planar. They are typically
|
// Such quads might also be degenerate or non-planar. They are typically
|
||||||
// not culled by this test (0 < 0 is false, 0 > 0 is false)
|
// not culled by this test (0 < 0 is false, 0 > 0 is false)
|
||||||
// and should be handled by the clipper if necessary.
|
// and should be handled by the clipper if necessary.
|
||||||
|
|
||||||
return (RLSW.cullFace == SW_FRONT)
|
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise"
|
||||||
? (hSgnArea < 0.0f) // Cull if winding is "clockwise" in the projected sense
|
|
||||||
: (hSgnArea > 0.0f); // Cull if winding is "counter-clockwise" in the projected sense
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_quad_clip_and_project(void)
|
static inline void sw_quad_clip_and_project(void)
|
||||||
@@ -4596,8 +4592,8 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices)
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
int index = indicesUb ? indicesUb[i] :
|
int index = indicesUb? indicesUb[i] :
|
||||||
(indicesUs ? indicesUs[i] : indicesUi[i]);
|
(indicesUs? indicesUs[i] : indicesUi[i]);
|
||||||
|
|
||||||
float u, v;
|
float u, v;
|
||||||
if (texcoords)
|
if (texcoords)
|
||||||
|
|||||||
@@ -623,10 +623,9 @@ double GetTime(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open URL with default system browser (if available)
|
// Open URL with default system browser (if available)
|
||||||
// NOTE: This function is only safe to use if you control the URL given.
|
// NOTE: This function is only safe to use if you control the URL given
|
||||||
// A user could craft a malicious string performing another action.
|
// A user could craft a malicious string performing another action
|
||||||
// Only call this function yourself not with user input or make sure to check the string yourself.
|
// Only call this function yourself not with user input or make sure to check the string yourself
|
||||||
// Ref: https://github.com/raysan5/raylib/issues/686
|
|
||||||
void OpenURL(const char *url)
|
void OpenURL(const char *url)
|
||||||
{
|
{
|
||||||
// Security check to (partially) avoid malicious code
|
// Security check to (partially) avoid malicious code
|
||||||
@@ -687,7 +686,7 @@ 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.
|
// Get physical key name
|
||||||
const char *GetKeyName(int key)
|
const char *GetKeyName(int key)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
|
||||||
@@ -748,9 +747,9 @@ void PollInputEvents(void)
|
|||||||
// 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: Allow closing the window in case a configuration change happened.
|
// 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
|
// The android_main function should be allowed to return to its caller in order for the
|
||||||
// Android OS to relaunch the activity.
|
// Android OS to relaunch the activity
|
||||||
if (platform.app->destroyRequested != 0)
|
if (platform.app->destroyRequested != 0)
|
||||||
{
|
{
|
||||||
CORE.Window.shouldClose = true;
|
CORE.Window.shouldClose = true;
|
||||||
@@ -829,13 +828,13 @@ int InitPlatform(void)
|
|||||||
// 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 until we reach TIMEOUT, which indicates no more events queued.
|
// Process events until we reach TIMEOUT, which indicates no more events queued
|
||||||
while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
|
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: It's highly likely destroyRequested will never be non-zero at the start of the activity lifecycle.
|
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -869,8 +868,9 @@ void ClosePlatform(void)
|
|||||||
platform.device = EGL_NO_DISPLAY;
|
platform.device = EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Reset global state in case the activity is being relaunched.
|
// NOTE: Reset global state in case the activity is being relaunched
|
||||||
if (platform.app->destroyRequested != 0) {
|
if (platform.app->destroyRequested != 0)
|
||||||
|
{
|
||||||
CORE = (CoreData){0};
|
CORE = (CoreData){0};
|
||||||
platform = (PlatformData){0};
|
platform = (PlatformData){0};
|
||||||
}
|
}
|
||||||
@@ -925,7 +925,7 @@ static int InitGraphicsDevice(void)
|
|||||||
// Initialize the EGL device connection
|
// Initialize the EGL device connection
|
||||||
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
|
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
|
||||||
{
|
{
|
||||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1081,21 +1081,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||||||
|
|
||||||
// Initialize random seed
|
// Initialize random seed
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
|
||||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
|
||||||
/*
|
|
||||||
if (assetsReloadRequired)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < assetCount; i++)
|
|
||||||
{
|
|
||||||
// TODO: Unload old asset if required
|
|
||||||
|
|
||||||
// Load texture again to pointed texture
|
|
||||||
(*textureAsset + i) = LoadTexture(assetPath[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -1115,7 +1100,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||||||
case APP_CMD_TERM_WINDOW:
|
case APP_CMD_TERM_WINDOW:
|
||||||
{
|
{
|
||||||
// Detach OpenGL context and destroy display surface
|
// Detach OpenGL context and destroy display surface
|
||||||
// NOTE 1: This case is used when the user exits the app without closing it. We detach the context to ensure everything is recoverable upon resuming.
|
// NOTE 1: This case is used when the user exits the app without closing it, context is detached to ensure everything is recoverable upon resuming
|
||||||
// NOTE 2: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...)
|
// NOTE 2: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...)
|
||||||
// NOTE 3: In some cases (too many context loaded), OS could unload context automatically... :(
|
// NOTE 3: In some cases (too many context loaded), OS could unload context automatically... :(
|
||||||
if (platform.device != EGL_NO_DISPLAY)
|
if (platform.device != EGL_NO_DISPLAY)
|
||||||
@@ -1179,8 +1164,8 @@ static GamepadButton AndroidTranslateGamepadButton(int button)
|
|||||||
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||||
{
|
{
|
||||||
// If additional inputs are required check:
|
// If additional inputs are required check:
|
||||||
// https://developer.android.com/ndk/reference/group/input
|
// Ref: https://developer.android.com/ndk/reference/group/input
|
||||||
// https://developer.android.com/training/game-controllers/controller-input
|
// Ref: https://developer.android.com/training/game-controllers/controller-input
|
||||||
|
|
||||||
int type = AInputEvent_getType(event);
|
int type = AInputEvent_getType(event);
|
||||||
int source = AInputEvent_getSource(event);
|
int source = AInputEvent_getSource(event);
|
||||||
@@ -1290,7 +1275,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||||||
{
|
{
|
||||||
// Let the OS handle input to avoid app stuck. Behaviour: CMD_PAUSE -> CMD_SAVE_STATE -> CMD_STOP -> CMD_CONFIG_CHANGED -> CMD_LOST_FOCUS
|
// Let the OS handle input to avoid app stuck. Behaviour: CMD_PAUSE -> CMD_SAVE_STATE -> CMD_STOP -> CMD_CONFIG_CHANGED -> CMD_LOST_FOCUS
|
||||||
// Resuming Behaviour: CMD_START -> CMD_RESUME -> CMD_CONFIG_CHANGED -> CMD_CONFIG_CHANGED -> CMD_GAINED_FOCUS
|
// Resuming Behaviour: CMD_START -> CMD_RESUME -> CMD_CONFIG_CHANGED -> CMD_CONFIG_CHANGED -> CMD_GAINED_FOCUS
|
||||||
// It seems like locking mobile, screen size (CMD_CONFIG_CHANGED) is affected.
|
// It seems like locking mobile, screen size (CMD_CONFIG_CHANGED) is affected
|
||||||
// NOTE: AndroidManifest.xml must have <activity android:configChanges="orientation|keyboardHidden|screenSize" >
|
// NOTE: AndroidManifest.xml must have <activity android:configChanges="orientation|keyboardHidden|screenSize" >
|
||||||
// Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour
|
// Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1419,15 +1404,9 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||||||
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
|
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
|
||||||
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
|
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
|
||||||
|
|
||||||
// Stores the previous position of touch[0] only while it's active to calculate the delta.
|
// Stores the previous position of touch[0] only while it's active to calculate the delta
|
||||||
if (flags == AMOTION_EVENT_ACTION_MOVE)
|
if (flags == AMOTION_EVENT_ACTION_MOVE) CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
{
|
else CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0];
|
||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map touch[0] as mouse input for convenience
|
// Map touch[0] as mouse input for convenience
|
||||||
CORE.Input.Mouse.currentPosition = CORE.Input.Touch.position[0];
|
CORE.Input.Mouse.currentPosition = CORE.Input.Touch.position[0];
|
||||||
|
|||||||
@@ -1220,9 +1220,9 @@ void PollInputEvents(void)
|
|||||||
|
|
||||||
// Map touch position to mouse position for convenience
|
// Map touch position to mouse position for convenience
|
||||||
// WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed!
|
// WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed!
|
||||||
// TODO: GLFW does not support multi-touch input just yet
|
// TODO: GLFW does not support multi-touch input yet
|
||||||
// https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch
|
// Ref: https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
|
// Ref: https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
|
||||||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||||
|
|
||||||
// Check if gamepads are ready
|
// Check if gamepads are ready
|
||||||
@@ -1334,7 +1334,7 @@ void PollInputEvents(void)
|
|||||||
// Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform()
|
// Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform()
|
||||||
// We need to provide these because GLFWallocator expects function pointers with specific signatures
|
// We need to provide these because GLFWallocator expects function pointers with specific signatures
|
||||||
// Similar wrappers exist in utils.c but we cannot reuse them here due to declaration mismatch
|
// Similar wrappers exist in utils.c but we cannot reuse them here due to declaration mismatch
|
||||||
// https://www.glfw.org/docs/latest/intro_guide.html#init_allocator
|
// Ref: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator
|
||||||
static void *AllocateWrapper(size_t size, void *user)
|
static void *AllocateWrapper(size_t size, void *user)
|
||||||
{
|
{
|
||||||
(void)user;
|
(void)user;
|
||||||
@@ -1592,8 +1592,8 @@ int InitPlatform(void)
|
|||||||
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
|
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 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;
|
||||||
int creationHeight = CORE.Window.screen.height != 0 ? CORE.Window.screen.height : 1;
|
int creationHeight = (CORE.Window.screen.height != 0)? CORE.Window.screen.height : 1;
|
||||||
|
|
||||||
platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||||
if (!platform.handle)
|
if (!platform.handle)
|
||||||
|
|||||||
@@ -870,17 +870,27 @@ double GetTime(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open URL with default system browser (if available)
|
// Open URL with default system browser (if available)
|
||||||
// NOTE: This function is only safe to use if you control the URL given.
|
// NOTE: This function is only safe to use if you control the URL given
|
||||||
// A user could craft a malicious string performing another action.
|
// A user could craft a malicious string performing another action
|
||||||
// Only call this function yourself not with user input or make sure to check the string yourself.
|
|
||||||
// Ref: https://github.com/raysan5/raylib/issues/686
|
|
||||||
void OpenURL(const char *url)
|
void OpenURL(const char *url)
|
||||||
{
|
{
|
||||||
// Security check to (partially) avoid malicious code on target platform
|
// Security check to (partially) avoid malicious code on target platform
|
||||||
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Open URL implementation
|
char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
|
||||||
|
#if defined(_WIN32)
|
||||||
|
sprintf(cmd, "explorer \"%s\"", url);
|
||||||
|
#endif
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
|
sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser
|
||||||
|
#endif
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
sprintf(cmd, "open '%s'", url);
|
||||||
|
#endif
|
||||||
|
int result = system(cmd);
|
||||||
|
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
|
||||||
|
RL_FREE(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,7 +925,7 @@ void SetMouseCursor(int cursor)
|
|||||||
RGFW_window_setMouseStandard(platform.window, cursor);
|
RGFW_window_setMouseStandard(platform.window, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get physical key name.
|
// Get physical key name
|
||||||
const char *GetKeyName(int key)
|
const char *GetKeyName(int key)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GetKeyName() unsupported on target platform");
|
TRACELOG(LOG_WARNING, "GetKeyName() unsupported on target platform");
|
||||||
@@ -1095,11 +1105,7 @@ void PollInputEvents(void)
|
|||||||
CORE.Input.Keyboard.currentKeyState[key] = 1;
|
CORE.Input.Keyboard.currentKeyState[key] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Put exitKey verification outside the switch?
|
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true;
|
||||||
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey])
|
|
||||||
{
|
|
||||||
CORE.Window.shouldClose = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int)
|
// NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int)
|
||||||
// Check if there is space available in the queue
|
// Check if there is space available in the queue
|
||||||
|
|||||||
@@ -1129,7 +1129,7 @@ Vector2 GetWindowScaleDPI(void)
|
|||||||
|
|
||||||
#ifndef USING_VERSION_SDL3
|
#ifndef USING_VERSION_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
|
// Ref: 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
|
#else
|
||||||
@@ -1425,8 +1425,10 @@ void PollInputEvents(void)
|
|||||||
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));
|
||||||
|
|
||||||
#if defined(USING_VERSION_SDL3)
|
#if defined(USING_VERSION_SDL3)
|
||||||
// const char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
|
// 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.
|
// 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);
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
|
||||||
#else
|
#else
|
||||||
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
|
||||||
@@ -1458,7 +1460,7 @@ void PollInputEvents(void)
|
|||||||
// SDL3 states:
|
// SDL3 states:
|
||||||
// The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed
|
// 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
|
// 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.
|
// 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)
|
||||||
@@ -1582,11 +1584,9 @@ void PollInputEvents(void)
|
|||||||
|
|
||||||
if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||||
|
|
||||||
// TODO: Put exitKey verification outside the switch?
|
// Check for registered exit key to request exit game loop on next iteration
|
||||||
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey])
|
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true;
|
||||||
{
|
|
||||||
CORE.Window.shouldClose = true;
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
@@ -2080,7 +2080,7 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
// Disable mouse events being interpreted as touch events
|
// Disable mouse events being interpreted as touch events
|
||||||
// NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data
|
// NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data
|
||||||
// Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES
|
// Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES
|
||||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||||
|
|
||||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||||
|
|||||||
@@ -939,7 +939,7 @@ void SetWindowIcon(Image image)
|
|||||||
// Set icon for window
|
// Set icon for window
|
||||||
void SetWindowIcons(Image *images, int count)
|
void SetWindowIcons(Image *images, int count)
|
||||||
{
|
{
|
||||||
// TODO.
|
// TODO: Implement SetWindowIcons()
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindowTitle(const char *title)
|
void SetWindowTitle(const char *title)
|
||||||
@@ -1246,7 +1246,11 @@ void OpenURL(const char *url)
|
|||||||
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "OpenURL not implemented");
|
char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
|
||||||
|
sprintf(cmd, "explorer \"%s\"", url);
|
||||||
|
int result = system(cmd);
|
||||||
|
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
|
||||||
|
RL_FREE(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {
|
|||||||
248, 0, 0, 0, 0, 0, 0, 0,
|
248, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
// Gamepads are mapped according to:
|
// Gamepads are mapped according to:
|
||||||
// https://www.kernel.org/doc/html/next/input/gamepad.html
|
// Ref: https://www.kernel.org/doc/html/next/input/gamepad.html
|
||||||
// Those mappings are standardized, but that doesn't mean people follow
|
// Those mappings are standardized, but that doesn't mean people follow
|
||||||
// the standards, so this is more of an approximation
|
// the standards, so this is more of an approximation
|
||||||
[BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP,
|
[BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP,
|
||||||
@@ -637,7 +637,7 @@ static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Renders a blank frame to allocate initial buffers
|
// Renders a blank frame to allocate initial buffers
|
||||||
// TODO: WARNING: Platform layers do not include OpenGL code!
|
// TODO: WARNING: Platform backend should not include OpenGL code
|
||||||
void RenderBlankFrame()
|
void RenderBlankFrame()
|
||||||
{
|
{
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
@@ -1213,9 +1213,9 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes);
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes);
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
|
||||||
(con->connection == DRM_MODE_CONNECTED) ? "CONNECTED" :
|
(con->connection == DRM_MODE_CONNECTED)? "CONNECTED" :
|
||||||
(con->connection == DRM_MODE_DISCONNECTED) ? "DISCONNECTED" :
|
(con->connection == DRM_MODE_DISCONNECTED)? "DISCONNECTED" :
|
||||||
(con->connection == DRM_MODE_UNKNOWNCONNECTION) ? "UNKNOWN" : "OTHER");
|
(con->connection == DRM_MODE_UNKNOWNCONNECTION)? "UNKNOWN" : "OTHER");
|
||||||
|
|
||||||
// In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected
|
// 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
|
// This might be a hardware or software limitation like on Raspberry Pi Zero with composite output
|
||||||
@@ -1298,7 +1298,7 @@ int InitPlatform(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool allowInterlaced = FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT);
|
const bool allowInterlaced = FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT);
|
||||||
const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60;
|
const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;
|
||||||
|
|
||||||
// Try to find an exact matching mode
|
// Try to find an exact matching mode
|
||||||
platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||||
@@ -1345,7 +1345,7 @@ int InitPlatform(void)
|
|||||||
platform.connector->modes[0].name,
|
platform.connector->modes[0].name,
|
||||||
platform.connector->modes[0].hdisplay,
|
platform.connector->modes[0].hdisplay,
|
||||||
platform.connector->modes[0].vdisplay,
|
platform.connector->modes[0].vdisplay,
|
||||||
(platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
|
(platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
||||||
platform.connector->modes[0].vrefresh);
|
platform.connector->modes[0].vrefresh);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1740,10 +1740,10 @@ static void InitKeyboard(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Reconfigure keyboard mode to get:
|
// Reconfigure keyboard mode to get:
|
||||||
// - scancodes (K_RAW)
|
// - scancodes (K_RAW)
|
||||||
// - keycodes (K_MEDIUMRAW)
|
// - keycodes (K_MEDIUMRAW)
|
||||||
// - ASCII chars (K_XLATE)
|
// - ASCII chars (K_XLATE)
|
||||||
// - UNICODE chars (K_UNICODE)
|
// - UNICODE chars (K_UNICODE)
|
||||||
ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); // ASCII chars
|
ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); // ASCII chars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ static const char *GetCanvasId(void);
|
|||||||
bool WindowShouldClose(void)
|
bool WindowShouldClose(void)
|
||||||
{
|
{
|
||||||
// Emscripten Asyncify is required to run synchronous code in asynchronous JS
|
// Emscripten Asyncify is required to run synchronous code in asynchronous JS
|
||||||
// REF: https://emscripten.org/docs/porting/asyncify.html
|
// Ref: https://emscripten.org/docs/porting/asyncify.html
|
||||||
|
|
||||||
// WindowShouldClose() is not called on a web-ready raylib application if using emscripten_set_main_loop()
|
// WindowShouldClose() is not called on a web-ready raylib application if using emscripten_set_main_loop()
|
||||||
// and encapsulating one frame execution on a UpdateDrawFrame() function,
|
// and encapsulating one frame execution on a UpdateDrawFrame() function,
|
||||||
@@ -309,8 +309,8 @@ void ToggleBorderlessWindowed(void)
|
|||||||
|
|
||||||
if (enterBorderless)
|
if (enterBorderless)
|
||||||
{
|
{
|
||||||
// NOTE: 1. The setTimeouts handle the browser mode change delay
|
// 1. The setTimeouts handle the browser mode change delay
|
||||||
// 2. The style unset handles the possibility of a width="value%" like on the default shell.html file
|
// 2. The style unset handles the possibility of a width="value%" like on the default shell.html file
|
||||||
EM_ASM
|
EM_ASM
|
||||||
(
|
(
|
||||||
setTimeout(function()
|
setTimeout(function()
|
||||||
@@ -866,7 +866,6 @@ void EnableCursor(void)
|
|||||||
// Disables cursor (lock cursor)
|
// Disables cursor (lock cursor)
|
||||||
void DisableCursor(void)
|
void DisableCursor(void)
|
||||||
{
|
{
|
||||||
// TODO: figure out how not to hard code the canvas ID here.
|
|
||||||
emscripten_request_pointerlock(GetCanvasId(), 1);
|
emscripten_request_pointerlock(GetCanvasId(), 1);
|
||||||
|
|
||||||
// Set cursor position in the middle
|
// Set cursor position in the middle
|
||||||
@@ -893,10 +892,9 @@ double GetTime(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open URL with default system browser (if available)
|
// Open URL with default system browser (if available)
|
||||||
// NOTE: This function is only safe to use if you control the URL given.
|
// NOTE: This function is only safe to use if you control the URL given
|
||||||
// A user could craft a malicious string performing another action.
|
// A user could craft a malicious string performing another action
|
||||||
// Only call this function yourself not with user input or make sure to check the string yourself.
|
// Only call this function yourself not with user input or make sure to check the string yourself
|
||||||
// Ref: https://github.com/raysan5/raylib/issues/686
|
|
||||||
void OpenURL(const char *url)
|
void OpenURL(const char *url)
|
||||||
{
|
{
|
||||||
// Security check to (partially) avoid malicious code on target platform
|
// Security check to (partially) avoid malicious code on target platform
|
||||||
@@ -1090,10 +1088,6 @@ void PollInputEvents(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CORE.Window.resizedLastFrame = false;
|
CORE.Window.resizedLastFrame = false;
|
||||||
|
|
||||||
// TODO: This code does not seem to do anything??
|
|
||||||
//if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
|
|
||||||
//else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) --> WARNING: Where is key input reset?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@@ -1161,8 +1155,8 @@ int InitPlatform(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version
|
// NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version
|
||||||
// with backward compatibility to older OpenGL versions.
|
// with backward compatibility to older OpenGL versions
|
||||||
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context.
|
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context
|
||||||
|
|
||||||
// Check selection OpenGL version
|
// Check selection OpenGL version
|
||||||
if (rlGetVersion() == RL_OPENGL_21)
|
if (rlGetVersion() == RL_OPENGL_21)
|
||||||
@@ -1172,10 +1166,12 @@ int InitPlatform(void)
|
|||||||
}
|
}
|
||||||
else if (rlGetVersion() == RL_OPENGL_33)
|
else if (rlGetVersion() == RL_OPENGL_33)
|
||||||
{
|
{
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
|
// Profiles Hint, only OpenGL 3.3 and above
|
||||||
// Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
|
// Possible values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above!
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above!
|
||||||
// glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
|
// glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1194,6 @@ int InitPlatform(void)
|
|||||||
}
|
}
|
||||||
else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
|
else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
|
||||||
{
|
{
|
||||||
// TODO: It seems WebGL 2.0 context is not set despite being requested
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
@@ -1217,8 +1212,8 @@ int InitPlatform(void)
|
|||||||
// remember center for switchinging from fullscreen to window
|
// remember center for switchinging from fullscreen to window
|
||||||
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
|
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
|
||||||
{
|
{
|
||||||
// If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed.
|
// If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed
|
||||||
// Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11.
|
// Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11
|
||||||
CORE.Window.position.x = CORE.Window.display.width/4;
|
CORE.Window.position.x = CORE.Window.display.width/4;
|
||||||
CORE.Window.position.y = CORE.Window.display.height/4;
|
CORE.Window.position.y = CORE.Window.display.height/4;
|
||||||
}
|
}
|
||||||
@@ -1714,7 +1709,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
|
|||||||
else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0;
|
else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update mouse position if we detect a single touch.
|
// Update mouse position if we detect a single touch
|
||||||
if (CORE.Input.Touch.pointCount == 1)
|
if (CORE.Input.Touch.pointCount == 1)
|
||||||
{
|
{
|
||||||
CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x;
|
CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x;
|
||||||
|
|||||||
@@ -2092,9 +2092,7 @@ float GetMusicTimePlayed(Music music)
|
|||||||
int framesInFirstBuffer = music.stream.buffer->isSubBufferProcessed[0]? 0 : subBufferSize;
|
int framesInFirstBuffer = music.stream.buffer->isSubBufferProcessed[0]? 0 : subBufferSize;
|
||||||
int framesInSecondBuffer = music.stream.buffer->isSubBufferProcessed[1]? 0 : subBufferSize;
|
int framesInSecondBuffer = music.stream.buffer->isSubBufferProcessed[1]? 0 : subBufferSize;
|
||||||
int framesInBuffers = framesInFirstBuffer + framesInSecondBuffer;
|
int framesInBuffers = framesInFirstBuffer + framesInSecondBuffer;
|
||||||
if ((unsigned int)framesInBuffers > music.frameCount) {
|
if (((unsigned int)framesInBuffers > music.frameCount) && !music.looping) framesInBuffers = music.frameCount;
|
||||||
if (!music.looping) framesInBuffers = music.frameCount;
|
|
||||||
}
|
|
||||||
int framesSentToMix = music.stream.buffer->frameCursorPos%subBufferSize;
|
int framesSentToMix = music.stream.buffer->frameCursorPos%subBufferSize;
|
||||||
int framesPlayed = (framesProcessed - framesInBuffers + framesSentToMix)%(int)music.frameCount;
|
int framesPlayed = (framesProcessed - framesInBuffers + framesSentToMix)%(int)music.frameCount;
|
||||||
if (framesPlayed < 0) framesPlayed += music.frameCount;
|
if (framesPlayed < 0) framesPlayed += music.frameCount;
|
||||||
@@ -2125,7 +2123,7 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
|||||||
if (deviceBitsPerSample > 4) deviceBitsPerSample = 4;
|
if (deviceBitsPerSample > 4) deviceBitsPerSample = 4;
|
||||||
deviceBitsPerSample *= AUDIO.System.device.playback.channels;
|
deviceBitsPerSample *= AUDIO.System.device.playback.channels;
|
||||||
|
|
||||||
unsigned int subBufferSize = (AUDIO.Buffer.defaultSize == 0) ? (AUDIO.System.device.sampleRate/30*deviceBitsPerSample) : AUDIO.Buffer.defaultSize;
|
unsigned int subBufferSize = (AUDIO.Buffer.defaultSize == 0)? (AUDIO.System.device.sampleRate/30*deviceBitsPerSample) : AUDIO.Buffer.defaultSize;
|
||||||
|
|
||||||
if (subBufferSize < periodSize) subBufferSize = periodSize;
|
if (subBufferSize < periodSize) subBufferSize = periodSize;
|
||||||
|
|
||||||
|
|||||||
45
src/rcore.c
45
src/rcore.c
@@ -30,7 +30,7 @@
|
|||||||
* - Windows (Win32, Win64)
|
* - Windows (Win32, Win64)
|
||||||
* CONFIGURATION:
|
* CONFIGURATION:
|
||||||
* #define SUPPORT_DEFAULT_FONT (default)
|
* #define SUPPORT_DEFAULT_FONT (default)
|
||||||
* Default font is loaded on window initialization to be available for the user to render simple text.
|
* Default font is loaded on window initialization to be available for the user to render simple text
|
||||||
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
|
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
|
||||||
*
|
*
|
||||||
* #define SUPPORT_CAMERA_SYSTEM
|
* #define SUPPORT_CAMERA_SYSTEM
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
* Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
|
* Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
|
||||||
*
|
*
|
||||||
* #define SUPPORT_MOUSE_GESTURES
|
* #define SUPPORT_MOUSE_GESTURES
|
||||||
* Mouse gestures are directly mapped like touches and processed by gestures system.
|
* Mouse gestures are directly mapped like touches and processed by gestures system
|
||||||
*
|
*
|
||||||
* #define SUPPORT_BUSY_WAIT_LOOP
|
* #define SUPPORT_BUSY_WAIT_LOOP
|
||||||
* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
||||||
@@ -423,7 +423,7 @@ typedef enum AutomationEventType {
|
|||||||
} AutomationEventType;
|
} AutomationEventType;
|
||||||
|
|
||||||
// Event type to config events flags
|
// Event type to config events flags
|
||||||
// TODO: Not used at the moment
|
// WARNING: Not used at the moment
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EVENT_INPUT_KEYBOARD = 0,
|
EVENT_INPUT_KEYBOARD = 0,
|
||||||
EVENT_INPUT_MOUSE = 1,
|
EVENT_INPUT_MOUSE = 1,
|
||||||
@@ -534,12 +534,10 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab
|
|||||||
// Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
// Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
||||||
// #if !defined(STBI_REQUIRED)
|
// #if !defined(STBI_REQUIRED)
|
||||||
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
|
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
|
||||||
// #endif
|
|
||||||
|
|
||||||
#endif // SUPPORT_CLIPBOARD_IMAGE
|
#endif // SUPPORT_CLIPBOARD_IMAGE
|
||||||
|
|
||||||
// Include platform-specific submodules
|
// Include platform-specific submodules
|
||||||
#if defined(PLATFORM_DESKTOP_GLFW)
|
#if defined(PLATFORM_MEM)
|
||||||
#include "platforms/rcore_desktop_glfw.c"
|
#include "platforms/rcore_desktop_glfw.c"
|
||||||
#elif defined(PLATFORM_DESKTOP_SDL)
|
#elif defined(PLATFORM_DESKTOP_SDL)
|
||||||
#include "platforms/rcore_desktop_sdl.c"
|
#include "platforms/rcore_desktop_sdl.c"
|
||||||
@@ -611,7 +609,9 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
{
|
{
|
||||||
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
|
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP_GLFW)
|
#if defined(PLATFORM_MEM)
|
||||||
|
TRACELOG(LOG_INFO, "Platform backend: NONE (Memory Buffer)");
|
||||||
|
#elif defined(PLATFORM_DESKTOP_GLFW)
|
||||||
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)");
|
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)");
|
||||||
#elif defined(PLATFORM_DESKTOP_SDL)
|
#elif defined(PLATFORM_DESKTOP_SDL)
|
||||||
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)");
|
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)");
|
||||||
@@ -1267,14 +1267,14 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
|||||||
{
|
{
|
||||||
// After custom shader loading, we TRY to set default location names
|
// After custom shader loading, we TRY to set default location names
|
||||||
// Default shader attribute locations have been binded before linking:
|
// Default shader attribute locations have been binded before linking:
|
||||||
// vertex position location = 0
|
// - vertex position location = 0
|
||||||
// vertex texcoord location = 1
|
// - vertex texcoord location = 1
|
||||||
// vertex normal location = 2
|
// - vertex normal location = 2
|
||||||
// vertex color location = 3
|
// - vertex color location = 3
|
||||||
// vertex tangent location = 4
|
// - vertex tangent location = 4
|
||||||
// vertex texcoord2 location = 5
|
// - vertex texcoord2 location = 5
|
||||||
// vertex boneIds location = 6
|
// - vertex boneIds location = 6
|
||||||
// vertex boneWeights location = 7
|
// - vertex boneWeights location = 7
|
||||||
|
|
||||||
// NOTE: If any location is not found, loc point becomes -1
|
// NOTE: If any location is not found, loc point becomes -1
|
||||||
|
|
||||||
@@ -1543,8 +1543,6 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh
|
|||||||
// Calculate view matrix from camera look at (and transpose it)
|
// Calculate view matrix from camera look at (and transpose it)
|
||||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||||
|
|
||||||
// TODO: Why not use Vector3Transform(Vector3 v, Matrix mat)?
|
|
||||||
|
|
||||||
// Convert world position vector to quaternion
|
// Convert world position vector to quaternion
|
||||||
Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
|
Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
|
||||||
|
|
||||||
@@ -2484,8 +2482,6 @@ bool IsFileNameValid(const char *fileName)
|
|||||||
// Check non-glyph characters
|
// Check non-glyph characters
|
||||||
if ((unsigned char)fileName[i] < 32) { valid = false; break; }
|
if ((unsigned char)fileName[i] < 32) { valid = false; break; }
|
||||||
|
|
||||||
// TODO: Check trailing periods/spaces?
|
|
||||||
|
|
||||||
// Check if filename is not all periods
|
// Check if filename is not all periods
|
||||||
if (fileName[i] != '.') allPeriods = false;
|
if (fileName[i] != '.') allPeriods = false;
|
||||||
}
|
}
|
||||||
@@ -3210,7 +3206,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Export events as text
|
// Export events as text
|
||||||
// TODO: Save to memory buffer and SaveFileText()
|
// NOTE: Save to memory buffer and SaveFileText()
|
||||||
char *txtData = (char *)RL_CALLOC(256*list.count + 2048, sizeof(char)); // 256 characters per line plus some header
|
char *txtData = (char *)RL_CALLOC(256*list.count + 2048, sizeof(char)); // 256 characters per line plus some header
|
||||||
|
|
||||||
int byteCount = 0;
|
int byteCount = 0;
|
||||||
@@ -3279,7 +3275,7 @@ void PlayAutomationEvent(AutomationEvent event)
|
|||||||
#if defined(SUPPORT_AUTOMATION_EVENTS)
|
#if defined(SUPPORT_AUTOMATION_EVENTS)
|
||||||
// WARNING: When should event be played? After/before/replace PollInputEvents()? -> Up to the user!
|
// WARNING: When should event be played? After/before/replace PollInputEvents()? -> Up to the user!
|
||||||
|
|
||||||
if (!automationEventRecording) // TODO: Allow recording events while playing?
|
if (!automationEventRecording)
|
||||||
{
|
{
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
@@ -3716,7 +3712,6 @@ int GetTouchY(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get touch position XY for a touch point index (relative to screen size)
|
// Get touch position XY for a touch point index (relative to screen size)
|
||||||
// TODO: Touch position should be scaled depending on display size and render size
|
|
||||||
Vector2 GetTouchPosition(int index)
|
Vector2 GetTouchPosition(int index)
|
||||||
{
|
{
|
||||||
Vector2 position = { -1.0f, -1.0f };
|
Vector2 position = { -1.0f, -1.0f };
|
||||||
@@ -4015,13 +4010,11 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
|
|||||||
|
|
||||||
#if defined(SUPPORT_AUTOMATION_EVENTS)
|
#if defined(SUPPORT_AUTOMATION_EVENTS)
|
||||||
// Automation event recording
|
// Automation event recording
|
||||||
|
// Checking events in current frame and save them into currentEventList
|
||||||
// NOTE: Recording is by default done at EndDrawing(), before PollInputEvents()
|
// NOTE: Recording is by default done at EndDrawing(), before PollInputEvents()
|
||||||
static void RecordAutomationEvent(void)
|
static void RecordAutomationEvent(void)
|
||||||
{
|
{
|
||||||
// Checking events in current frame and save them into currentEventList
|
if (currentEventList->count == currentEventList->capacity) return;
|
||||||
// TODO: How important is the current frame? Could it be modified?
|
|
||||||
|
|
||||||
if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
||||||
|
|
||||||
// Keyboard input events recording
|
// Keyboard input events recording
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|||||||
12
src/rlgl.h
12
src/rlgl.h
@@ -903,6 +903,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||||||
|
|
||||||
// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi
|
// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi
|
||||||
// provided headers (despite being defined in official Khronos GLES2 headers)
|
// provided headers (despite being defined in official Khronos GLES2 headers)
|
||||||
|
// TODO: Avoid raylib platform-dependant code on rlgl, it should be a completely portable library
|
||||||
#if defined(PLATFORM_DRM)
|
#if defined(PLATFORM_DRM)
|
||||||
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
|
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
|
||||||
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
||||||
@@ -2921,7 +2922,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
|
|||||||
|
|
||||||
batch.bufferCount = numBuffers; // Record buffer count
|
batch.bufferCount = numBuffers; // Record buffer count
|
||||||
batch.drawCounter = 1; // Reset draws counter
|
batch.drawCounter = 1; // Reset draws counter
|
||||||
batch.currentDepth = -1.0f; // Reset depth value
|
batch.currentDepth = -1.0f; // Reset depth value
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2982,7 +2983,8 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
|
|||||||
// Update batch vertex buffers
|
// Update batch vertex buffers
|
||||||
//------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------
|
||||||
// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
|
// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
|
||||||
// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?)
|
// TODO: If no data changed on the CPU arrays there is no need to re-upload data to GPU,
|
||||||
|
// a flag can be used to detect changes but it would imply keeping a copy buffer and memcmp() both, does it worth it?
|
||||||
if (RLGL.State.vertexCounter > 0)
|
if (RLGL.State.vertexCounter > 0)
|
||||||
{
|
{
|
||||||
// Activate elements VAO
|
// Activate elements VAO
|
||||||
@@ -3900,7 +3902,7 @@ void rlUnloadFramebuffer(unsigned int id)
|
|||||||
|
|
||||||
// TODO: Review warning retrieving object name in WebGL
|
// TODO: Review warning retrieving object name in WebGL
|
||||||
// WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name
|
// WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name
|
||||||
// https://registry.khronos.org/webgl/specs/latest/1.0/
|
// Ref: https://registry.khronos.org/webgl/specs/latest/1.0/
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId);
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId);
|
||||||
|
|
||||||
unsigned int depthIdU = (unsigned int)depthId;
|
unsigned int depthIdU = (unsigned int)depthId;
|
||||||
@@ -4427,8 +4429,6 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
|
|||||||
#endif
|
#endif
|
||||||
case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
|
case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
|
||||||
default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
|
default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
|
||||||
|
|
||||||
// TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv()
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -4469,7 +4469,7 @@ void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
|
|||||||
glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
|
glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
|
||||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
// WARNING: WebGL does not support Matrix transpose ("true" parameter)
|
// WARNING: WebGL does not support Matrix transpose ("true" parameter)
|
||||||
// REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix
|
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix
|
||||||
glUniformMatrix4fv(locIndex, count, false, (const float *)matrices);
|
glUniformMatrix4fv(locIndex, count, false, (const float *)matrices);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3845,7 +3845,6 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
|
|||||||
|
|
||||||
// Draw a model points
|
// Draw a model points
|
||||||
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||||
// TODO: gate these properly for non es 2.0 versions only
|
|
||||||
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
||||||
{
|
{
|
||||||
rlEnablePointMode();
|
rlEnablePointMode();
|
||||||
@@ -5021,7 +5020,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
|
|||||||
animations[a].framePoses = (Transform **)RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
|
animations[a].framePoses = (Transform **)RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
|
||||||
memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here
|
memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here
|
||||||
TRACELOG(LOG_INFO, "IQM Anim %s", animations[a].name);
|
TRACELOG(LOG_INFO, "IQM Anim %s", animations[a].name);
|
||||||
// animations[a].framerate = anim.framerate; // TODO: Use animation framerate data?
|
//animations[a].framerate = anim.framerate; // TODO: Use animation framerate data?
|
||||||
|
|
||||||
for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
|
for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
|
||||||
{
|
{
|
||||||
@@ -5029,7 +5028,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
|
|||||||
if (iqmHeader->num_joints > 0)
|
if (iqmHeader->num_joints > 0)
|
||||||
memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char));
|
memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char));
|
||||||
else
|
else
|
||||||
strcpy(animations[a].bones[j].name, "ANIMJOINTNAME"); // default bone name otherwise
|
strcpy(animations[a].bones[j].name, "ANIMJOINTNAME"); // Default bone name otherwise
|
||||||
animations[a].bones[j].parent = poses[j].parent;
|
animations[a].bones[j].parent = poses[j].parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5875,8 +5874,8 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Load animation data
|
// Load animation data
|
||||||
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins
|
// Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins
|
||||||
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
|
// Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
|
||||||
//
|
//
|
||||||
// LIMITATIONS:
|
// LIMITATIONS:
|
||||||
// - Only supports 1 armature per file, and skips loading it if there are multiple armatures
|
// - Only supports 1 armature per file, and skips loading it if there are multiple armatures
|
||||||
|
|||||||
@@ -1169,9 +1169,9 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw rectangle with rounded edges
|
// Draw rectangle with rounded edges
|
||||||
// TODO: This function should be refactored to use RL_LINES, for consistency with other Draw*Lines()
|
|
||||||
void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color)
|
void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color)
|
||||||
{
|
{
|
||||||
|
// NOTE: For line thicknes <=1.0f we use RL_LINES, otherwise wee use RL_QUADS/RL_TRIANGLES
|
||||||
DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color);
|
DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1395,7 +1395,6 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
|
|||||||
{
|
{
|
||||||
// Use LINES to draw the outline
|
// Use LINES to draw the outline
|
||||||
rlBegin(RL_LINES);
|
rlBegin(RL_LINES);
|
||||||
|
|
||||||
// Draw all the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
|
// Draw all the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
|
||||||
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
|
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
|
||||||
{
|
{
|
||||||
@@ -1418,7 +1417,6 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
|
|||||||
rlVertex2f(point[i].x, point[i].y);
|
rlVertex2f(point[i].x, point[i].y);
|
||||||
rlVertex2f(point[i + 1].x, point[i + 1].y);
|
rlVertex2f(point[i + 1].x, point[i + 1].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
rlEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1701,7 +1701,7 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
|
|||||||
|
|
||||||
// Replace text string
|
// Replace text string
|
||||||
// REQUIRES: strstr(), strncpy(), strcpy()
|
// REQUIRES: strstr(), strncpy(), strcpy()
|
||||||
// TODO: If (replacement == NULL) remove "search" text
|
// TODO: If (replacement == "") remove "search" text
|
||||||
// WARNING: Allocated memory must be manually freed
|
// WARNING: Allocated memory must be manually freed
|
||||||
char *TextReplace(const char *text, const char *search, const char *replacement)
|
char *TextReplace(const char *text, const char *search, const char *replacement)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
|||||||
image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);
|
image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);
|
||||||
image.width = desc.width;
|
image.width = desc.width;
|
||||||
image.height = desc.height;
|
image.height = desc.height;
|
||||||
image.format = desc.channels == 4 ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
image.format = (desc.channels == 4)? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
||||||
image.mipmaps = 1;
|
image.mipmaps = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4001,9 +4001,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
|
|||||||
// [x] Consider fast path: no alpha blending required cases (src has no alpha)
|
// [x] Consider fast path: no alpha blending required cases (src has no alpha)
|
||||||
// [x] Consider fast path: same src/dst format with no alpha -> direct line copy
|
// [x] Consider fast path: same src/dst format with no alpha -> direct line copy
|
||||||
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
|
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
|
||||||
// [ ] Support f32bit channels drawing
|
// [ ] TODO: Support 16bit and 32bit (float) channels drawing
|
||||||
|
|
||||||
// TODO: Support PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and PIXELFORMAT_UNCOMPRESSED_R1616B16A16
|
|
||||||
|
|
||||||
Color colSrc, colDst, blend;
|
Color colSrc, colDst, blend;
|
||||||
bool blendRequired = true;
|
bool blendRequired = true;
|
||||||
@@ -4201,7 +4199,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
|
|||||||
}
|
}
|
||||||
/*else if (layout == CUBEMAP_LAYOUT_PANORAMA)
|
/*else if (layout == CUBEMAP_LAYOUT_PANORAMA)
|
||||||
{
|
{
|
||||||
// TODO: implement panorama by converting image to square faces...
|
// TODO: Implement panorama by converting image to square faces...
|
||||||
// Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp
|
// Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp
|
||||||
} */
|
} */
|
||||||
else
|
else
|
||||||
@@ -4227,6 +4225,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert image data to 6 faces in a vertical column, that's the optimum layout for loading
|
// Convert image data to 6 faces in a vertical column, that's the optimum layout for loading
|
||||||
|
// NOTE: Image formatting does not work with compressed textures
|
||||||
faces = GenImageColor(size, size*6, MAGENTA);
|
faces = GenImageColor(size, size*6, MAGENTA);
|
||||||
ImageFormat(&faces, image.format);
|
ImageFormat(&faces, image.format);
|
||||||
|
|
||||||
@@ -4239,8 +4238,6 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE: Image formatting does not work with compressed textures
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) ImageDraw(&faces, mipmapped, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, WHITE);
|
for (int i = 0; i < 6; i++) ImageDraw(&faces, mipmapped, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, WHITE);
|
||||||
|
|
||||||
UnloadImage(mipmapped);
|
UnloadImage(mipmapped);
|
||||||
@@ -4309,13 +4306,11 @@ bool IsTextureValid(Texture2D texture)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
// TODO: Validate maximum texture size supported by GPU
|
|
||||||
|
|
||||||
if ((texture.id > 0) && // Validate OpenGL id (texture uplaoded to GPU)
|
if ((texture.id > 0) && // Validate OpenGL id (texture uplaoded to GPU)
|
||||||
(texture.width > 0) && // Validate texture width
|
(texture.width > 0) && // Validate texture width
|
||||||
(texture.height > 0) && // Validate texture height
|
(texture.height > 0) && // Validate texture height
|
||||||
(texture.format > 0) && // Validate texture pixel format
|
(texture.format > 0) && // Validate texture pixel format
|
||||||
(texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level)
|
(texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -5412,7 +5407,7 @@ int GetPixelDataSize(int width, int height, int format)
|
|||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Convert half-float (stored as unsigned short) to float
|
// Convert half-float (stored as unsigned short) to float
|
||||||
// REF: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308
|
// Ref: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308
|
||||||
static float HalfToFloat(unsigned short x)
|
static float HalfToFloat(unsigned short x)
|
||||||
{
|
{
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
|
|||||||
Reference in New Issue
Block a user