Some TODOs and format reviews

This commit is contained in:
Ray
2025-11-23 21:40:39 +01:00
parent cf5e84c3c4
commit e1b9857b14
16 changed files with 154 additions and 191 deletions

View File

@@ -49,10 +49,10 @@
#define SUPPORT_RPRAND_GENERATOR 1
// Mouse gestures are directly mapped like touches and processed by gestures system
#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
// 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.
// 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
#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
//#define SUPPORT_BUSY_WAIT_LOOP 1
@@ -225,7 +225,7 @@
// 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
// 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
// Support conservative font atlas size estimation

50
src/external/rlsw.h vendored
View File

@@ -145,7 +145,7 @@
#define SW_MAX_TEXTURES 128
#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),
// and that clipping occurs against both the frustum (6 planes) and the scissors (4 planes),
// 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 g5 = (color[1]*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
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 g5 = (color[1]*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
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)
{
// 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 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)
{
// 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,
// 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,
// 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
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
// of the vertices, which correctly captures the winding order in homogeneous
// space and its relationship to the projected 2D winding order, even with
// negative w values.
// negative w values
// The determinant formula used here is:
// h0.x*(h1.y*h2.w - h2.y*h1.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]);
// 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
// winding in the projected space when all w > 0.
// 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)
// 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)
// and should be handled by the clipper if necessary.
return (RLSW.cullFace == SW_FRONT)
? (hSgnArea < 0) // Cull if winding is "clockwise" in the projected sense
: (hSgnArea > 0); // Cull if winding is "counter-clockwise" in the projected sense
// and should be handled by the clipper if necessary
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise"
}
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)
{
// 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,
// 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,
// the winding order of the quad is the same as the winding order
// 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
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
// 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
// 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,
// even with negative w values.
// even with negative w values
// The determinant formula used here is:
// h0.x*(h1.y*h2.w - h2.y*h1.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]);
// 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,
// 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
// 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)
// 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
// not culled by this test (0 < 0 is false, 0 > 0 is false)
// and should be handled by the clipper if necessary.
return (RLSW.cullFace == SW_FRONT)
? (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
return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise"
}
static inline void sw_quad_clip_and_project(void)

View File

@@ -623,10 +623,9 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// 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
// NOTE: This function is only safe to use if you control the URL given
// 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
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code
@@ -687,7 +686,7 @@ void SetMouseCursor(int cursor)
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
}
// Get physical key name.
// Get physical key name
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
@@ -748,9 +747,9 @@ void PollInputEvents(void)
// Process this event
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
// Android OS to relaunch the activity.
// Android OS to relaunch the activity
if (platform.app->destroyRequested != 0)
{
CORE.Window.shouldClose = true;
@@ -829,13 +828,13 @@ int InitPlatform(void)
// Wait for window to be initialized (display and context)
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))
{
// Process this event
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;
}
}
@@ -869,8 +868,9 @@ void ClosePlatform(void)
platform.device = EGL_NO_DISPLAY;
}
// NOTE: Reset global state in case the activity is being relaunched.
if (platform.app->destroyRequested != 0) {
// NOTE: Reset global state in case the activity is being relaunched
if (platform.app->destroyRequested != 0)
{
CORE = (CoreData){0};
platform = (PlatformData){0};
}
@@ -925,7 +925,7 @@ static int InitGraphicsDevice(void)
// Initialize the EGL device connection
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");
return -1;
}
@@ -1081,21 +1081,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Initialize random seed
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;
@@ -1115,7 +1100,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
case APP_CMD_TERM_WINDOW:
{
// 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 3: In some cases (too many context loaded), OS could unload context automatically... :(
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)
{
// If additional inputs are required check:
// https://developer.android.com/ndk/reference/group/input
// https://developer.android.com/training/game-controllers/controller-input
// Ref: https://developer.android.com/ndk/reference/group/input
// Ref: https://developer.android.com/training/game-controllers/controller-input
int type = AInputEvent_getType(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
// 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" >
// Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour
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;
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.
if (flags == AMOTION_EVENT_ACTION_MOVE)
{
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
else
{
CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0];
}
// Stores the previous position of touch[0] only while it's active to calculate the delta
if (flags == AMOTION_EVENT_ACTION_MOVE) 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
CORE.Input.Mouse.currentPosition = CORE.Input.Touch.position[0];

View File

@@ -1220,9 +1220,9 @@ void PollInputEvents(void)
// Map touch position to mouse position for convenience
// WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed!
// TODO: GLFW does not support multi-touch input just yet
// 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
// TODO: GLFW does not support multi-touch input yet
// Ref: https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch
// 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;
// Check if gamepads are ready
@@ -1334,7 +1334,7 @@ void PollInputEvents(void)
// 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
// 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)
{
(void)user;
@@ -1592,8 +1592,8 @@ int InitPlatform(void)
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
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 creationWidth = (CORE.Window.screen.width != 0)? CORE.Window.screen.width : 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);
if (!platform.handle)

View File

@@ -870,17 +870,27 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// 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
// NOTE: This function is only safe to use if you control the URL given
// A user could craft a malicious string performing another action
void OpenURL(const char *url)
{
// 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");
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);
}
// Get physical key name.
// Get physical key name
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() unsupported on target platform");
@@ -1095,11 +1105,7 @@ void PollInputEvents(void)
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)
// Check if there is space available in the queue

View File

@@ -1129,7 +1129,7 @@ Vector2 GetWindowScaleDPI(void)
#ifndef USING_VERSION_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
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
#else
@@ -1425,8 +1425,10 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
#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 */
// 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.
// const char *data; // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events
// Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE,
// and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events,
// you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
#else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
@@ -1458,7 +1460,7 @@ void PollInputEvents(void)
// SDL3 states:
// The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed
// In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT
// and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event.
// 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:
{
switch (event.window.event)
@@ -1582,11 +1584,9 @@ void PollInputEvents(void)
if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
// TODO: Put exitKey verification outside the switch?
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey])
{
CORE.Window.shouldClose = true;
}
// Check for registered exit key to request exit game loop on next iteration
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true;
} break;
case SDL_KEYUP:

View File

@@ -939,7 +939,7 @@ void SetWindowIcon(Image image)
// Set icon for window
void SetWindowIcons(Image *images, int count)
{
// TODO.
// TODO: Implement SetWindowIcons()
}
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");
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);
}
}

View File

@@ -220,7 +220,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {
248, 0, 0, 0, 0, 0, 0, 0,
// 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
// the standards, so this is more of an approximation
[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
// TODO: WARNING: Platform layers do not include OpenGL code!
// TODO: WARNING: Platform backend should not include OpenGL code
void RenderBlankFrame()
{
glClearColor(0, 0, 0, 1);

View File

@@ -159,7 +159,7 @@ static const char *GetCanvasId(void);
bool WindowShouldClose(void)
{
// 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()
// and encapsulating one frame execution on a UpdateDrawFrame() function,
@@ -309,7 +309,7 @@ void ToggleBorderlessWindowed(void)
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
EM_ASM
(
@@ -866,7 +866,6 @@ void EnableCursor(void)
// Disables cursor (lock cursor)
void DisableCursor(void)
{
// TODO: figure out how not to hard code the canvas ID here.
emscripten_request_pointerlock(GetCanvasId(), 1);
// Set cursor position in the middle
@@ -893,10 +892,9 @@ double GetTime(void)
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// 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
// NOTE: This function is only safe to use if you control the URL given
// 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
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code on target platform
@@ -1090,10 +1088,6 @@ void PollInputEvents(void)
}
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
// with backward compatibility to older OpenGL versions.
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context.
// with backward compatibility to older OpenGL versions
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context
// Check selection OpenGL version
if (rlGetVersion() == RL_OPENGL_21)
@@ -1174,8 +1168,10 @@ int InitPlatform(void)
{
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_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
// Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
// Profiles Hint, only OpenGL 3.3 and above
// 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_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
{
// TODO: It seems WebGL 2.0 context is not set despite being requested
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
@@ -1217,8 +1212,8 @@ int InitPlatform(void)
// 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 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.
// 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
CORE.Window.position.x = CORE.Window.display.width/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;
}
// Update mouse position if we detect a single touch.
// Update mouse position if we detect a single touch
if (CORE.Input.Touch.pointCount == 1)
{
CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x;

View File

@@ -2092,9 +2092,7 @@ float GetMusicTimePlayed(Music music)
int framesInFirstBuffer = music.stream.buffer->isSubBufferProcessed[0]? 0 : subBufferSize;
int framesInSecondBuffer = music.stream.buffer->isSubBufferProcessed[1]? 0 : subBufferSize;
int framesInBuffers = framesInFirstBuffer + framesInSecondBuffer;
if ((unsigned int)framesInBuffers > music.frameCount) {
if (!music.looping) framesInBuffers = music.frameCount;
}
if (((unsigned int)framesInBuffers > music.frameCount) && !music.looping) framesInBuffers = music.frameCount;
int framesSentToMix = music.stream.buffer->frameCursorPos%subBufferSize;
int framesPlayed = (framesProcessed - framesInBuffers + framesSentToMix)%(int)music.frameCount;
if (framesPlayed < 0) framesPlayed += music.frameCount;

View File

@@ -30,7 +30,7 @@
* - Windows (Win32, Win64)
* CONFIGURATION:
* #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)
*
* #define SUPPORT_CAMERA_SYSTEM
@@ -41,7 +41,7 @@
* Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
*
* #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
* 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;
// Event type to config events flags
// TODO: Not used at the moment
// WARNING: Not used at the moment
typedef enum {
EVENT_INPUT_KEYBOARD = 0,
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
// #if !defined(STBI_REQUIRED)
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
// #endif
#endif // SUPPORT_CLIPBOARD_IMAGE
// Include platform-specific submodules
#if defined(PLATFORM_DESKTOP_GLFW)
#if defined(PLATFORM_MEM)
#include "platforms/rcore_desktop_glfw.c"
#elif defined(PLATFORM_DESKTOP_SDL)
#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);
#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)");
#elif defined(PLATFORM_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
// Default shader attribute locations have been binded before linking:
// vertex position location = 0
// vertex texcoord location = 1
// vertex normal location = 2
// vertex color location = 3
// vertex tangent location = 4
// vertex texcoord2 location = 5
// vertex boneIds location = 6
// vertex boneWeights location = 7
// - vertex position location = 0
// - vertex texcoord location = 1
// - vertex normal location = 2
// - vertex color location = 3
// - vertex tangent location = 4
// - vertex texcoord2 location = 5
// - vertex boneIds location = 6
// - vertex boneWeights location = 7
// 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)
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
// TODO: Why not use Vector3Transform(Vector3 v, Matrix mat)?
// Convert world position vector to quaternion
Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
@@ -2484,8 +2482,6 @@ bool IsFileNameValid(const char *fileName)
// Check non-glyph characters
if ((unsigned char)fileName[i] < 32) { valid = false; break; }
// TODO: Check trailing periods/spaces?
// Check if filename is not all periods
if (fileName[i] != '.') allPeriods = false;
}
@@ -3210,7 +3206,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
*/
// 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
int byteCount = 0;
@@ -3279,7 +3275,7 @@ void PlayAutomationEvent(AutomationEvent event)
#if defined(SUPPORT_AUTOMATION_EVENTS)
// 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)
{
@@ -3716,7 +3712,6 @@ int GetTouchY(void)
}
// 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 position = { -1.0f, -1.0f };
@@ -4015,13 +4010,11 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
#if defined(SUPPORT_AUTOMATION_EVENTS)
// Automation event recording
// Checking events in current frame and save them into currentEventList
// NOTE: Recording is by default done at EndDrawing(), before PollInputEvents()
static void RecordAutomationEvent(void)
{
// Checking events in current frame and save them into currentEventList
// TODO: How important is the current frame? Could it be modified?
if (currentEventList->count == currentEventList->capacity) return; // Security check
if (currentEventList->count == currentEventList->capacity) return;
// Keyboard input events recording
//-------------------------------------------------------------------------------------

View File

@@ -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
// 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)
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);
@@ -2982,7 +2983,8 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
// Update batch vertex buffers
//------------------------------------------------------------------------------------------------------------
// 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)
{
// Activate elements VAO
@@ -3900,7 +3902,7 @@ void rlUnloadFramebuffer(unsigned int id)
// TODO: Review warning retrieving object name in WebGL
// 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);
unsigned int depthIdU = (unsigned int)depthId;
@@ -4427,8 +4429,6 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
#endif
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");
// TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv()
}
#endif
}
@@ -4469,7 +4469,7 @@ void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
#elif defined(GRAPHICS_API_OPENGL_ES2)
// 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);
#endif
}

View File

@@ -3845,7 +3845,6 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
// Draw a model points
// 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)
{
rlEnablePointMode();
@@ -5029,7 +5028,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
if (iqmHeader->num_joints > 0)
memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char));
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;
}
@@ -5875,8 +5874,8 @@ static Model LoadGLTF(const char *fileName)
//----------------------------------------------------------------------------------------------------
// 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#skinned-mesh-attributes
// 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
//
// LIMITATIONS:
// - Only supports 1 armature per file, and skips loading it if there are multiple armatures

View File

@@ -1169,9 +1169,9 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
}
// 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)
{
// NOTE: For line thicknes <=1.0f we use RL_LINES, otherwise wee use RL_QUADS/RL_TRIANGLES
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
rlBegin(RL_LINES);
// 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
{
@@ -1418,7 +1417,6 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
rlVertex2f(point[i].x, point[i].y);
rlVertex2f(point[i + 1].x, point[i + 1].y);
}
rlEnd();
}
}

View File

@@ -1701,7 +1701,7 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
// Replace text string
// REQUIRES: strstr(), strncpy(), strcpy()
// TODO: If (replacement == NULL) remove "search" text
// TODO: If (replacement == "") remove "search" text
// WARNING: Allocated memory must be manually freed
char *TextReplace(const char *text, const char *search, const char *replacement)
{

View File

@@ -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.width = desc.width;
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;
}
}
@@ -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: same src/dst format with no alpha -> direct line copy
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
// [ ] Support f32bit channels drawing
// TODO: Support PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and PIXELFORMAT_UNCOMPRESSED_R1616B16A16
// [ ] TODO: Support 16bit and 32bit (float) channels drawing
Color colSrc, colDst, blend;
bool blendRequired = true;
@@ -4201,7 +4199,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
}
/*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
} */
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
// NOTE: Image formatting does not work with compressed textures
faces = GenImageColor(size, size*6, MAGENTA);
ImageFormat(&faces, image.format);
@@ -4239,8 +4238,6 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
}
#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);
UnloadImage(mipmapped);
@@ -4309,8 +4306,6 @@ bool IsTextureValid(Texture2D texture)
{
bool result = false;
// TODO: Validate maximum texture size supported by GPU
if ((texture.id > 0) && // Validate OpenGL id (texture uplaoded to GPU)
(texture.width > 0) && // Validate texture width
(texture.height > 0) && // Validate texture height
@@ -5412,7 +5407,7 @@ int GetPixelDataSize(int width, int height, int format)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
// 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)
{
float result = 0.0f;