Remove trailing spaces

This commit is contained in:
Ray 2019-10-17 17:18:03 +02:00
parent e40c26dea5
commit b75511248d
13 changed files with 304 additions and 304 deletions

View file

@ -8,7 +8,7 @@
* *
* #define CAMERA_IMPLEMENTATION * #define CAMERA_IMPLEMENTATION
* Generates the implementation of the library into the included file. * Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation. * or source files without problems. But only ONE file should hold the implementation.
* *
* #define CAMERA_STANDALONE * #define CAMERA_STANDALONE
@ -77,7 +77,7 @@
} Camera3D; } Camera3D;
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera system modes // Camera system modes
typedef enum { typedef enum {
CAMERA_CUSTOM = 0, CAMERA_CUSTOM = 0,
@ -113,8 +113,8 @@ void UpdateCamera(Camera *camera); // Update camera pos
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
void SetCameraSmoothZoomControl(int szoomKey); // Set camera smooth zoom key to combine with mouse (free camera) void SetCameraSmoothZoomControl(int szoomKey); // Set camera smooth zoom key to combine with mouse (free camera)
void SetCameraMoveControls(int frontKey, int backKey, void SetCameraMoveControls(int frontKey, int backKey,
int rightKey, int leftKey, int rightKey, int leftKey,
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
#endif #endif
@ -188,21 +188,21 @@ void SetCameraMoveControls(int frontKey, int backKey,
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Camera move modes (first person and third person cameras) // Camera move modes (first person and third person cameras)
typedef enum { typedef enum {
MOVE_FRONT = 0, MOVE_FRONT = 0,
MOVE_BACK, MOVE_BACK,
MOVE_RIGHT, MOVE_RIGHT,
MOVE_LEFT, MOVE_LEFT,
MOVE_UP, MOVE_UP,
MOVE_DOWN MOVE_DOWN
} CameraMove; } CameraMove;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static Vector2 cameraAngle = { 0.0f, 0.0f }; // Camera angle in plane XZ static Vector2 cameraAngle = { 0.0f, 0.0f }; // Camera angle in plane XZ
static float cameraTargetDistance = 0.0f; // Camera distance from position to target static float cameraTargetDistance = 0.0f; // Camera distance from position to target
static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters) static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' }; static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' };
static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
@ -236,21 +236,21 @@ void SetCameraMode(Camera camera, int mode)
{ {
Vector3 v1 = camera.position; Vector3 v1 = camera.position;
Vector3 v2 = camera.target; Vector3 v2 = camera.target;
float dx = v2.x - v1.x; float dx = v2.x - v1.x;
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz); cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
Vector2 distance = { 0.0f, 0.0f }; Vector2 distance = { 0.0f, 0.0f };
distance.x = sqrtf(dx*dx + dz*dz); distance.x = sqrtf(dx*dx + dz*dz);
distance.y = sqrtf(dx*dx + dy*dy); distance.y = sqrtf(dx*dx + dy*dy);
// Camera angle calculation // Camera angle calculation
cameraAngle.x = asinf( (float)fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) cameraAngle.x = asinf( (float)fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
cameraAngle.y = -asinf( (float)fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) cameraAngle.y = -asinf( (float)fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
playerEyesPosition = camera.position.y; playerEyesPosition = camera.position.y;
// Lock cursor for first person and third person cameras // Lock cursor for first person and third person cameras
@ -272,24 +272,24 @@ void UpdateCamera(Camera *camera)
static Vector2 previousMousePosition = { 0.0f, 0.0f }; static Vector2 previousMousePosition = { 0.0f, 0.0f };
// TODO: Compute cameraTargetDistance and cameraAngle here // TODO: Compute cameraTargetDistance and cameraAngle here
// Mouse movement detection // Mouse movement detection
Vector2 mousePositionDelta = { 0.0f, 0.0f }; Vector2 mousePositionDelta = { 0.0f, 0.0f };
Vector2 mousePosition = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
int mouseWheelMove = GetMouseWheelMove(); int mouseWheelMove = GetMouseWheelMove();
// Keys input detection // Keys input detection
bool panKey = IsMouseButtonDown(cameraPanControlKey); bool panKey = IsMouseButtonDown(cameraPanControlKey);
bool altKey = IsKeyDown(cameraAltControlKey); bool altKey = IsKeyDown(cameraAltControlKey);
bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey); bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey);
bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]), bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]),
IsKeyDown(cameraMoveControl[MOVE_BACK]), IsKeyDown(cameraMoveControl[MOVE_BACK]),
IsKeyDown(cameraMoveControl[MOVE_RIGHT]), IsKeyDown(cameraMoveControl[MOVE_RIGHT]),
IsKeyDown(cameraMoveControl[MOVE_LEFT]), IsKeyDown(cameraMoveControl[MOVE_LEFT]),
IsKeyDown(cameraMoveControl[MOVE_UP]), IsKeyDown(cameraMoveControl[MOVE_UP]),
IsKeyDown(cameraMoveControl[MOVE_DOWN]) }; IsKeyDown(cameraMoveControl[MOVE_DOWN]) };
// TODO: Consider touch inputs for camera // TODO: Consider touch inputs for camera
if (cameraMode != CAMERA_CUSTOM) if (cameraMode != CAMERA_CUSTOM)
@ -384,7 +384,7 @@ void UpdateCamera(Camera *camera)
camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
} }
} }
// Update camera position with changes // Update camera position with changes
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
@ -395,15 +395,15 @@ void UpdateCamera(Camera *camera)
{ {
cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
// Update camera position with changes // Update camera position with changes
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
} break; } break;
case CAMERA_FIRST_PERSON: case CAMERA_FIRST_PERSON:
{ {
@ -411,11 +411,11 @@ void UpdateCamera(Camera *camera)
sinf(cameraAngle.x)*direction[MOVE_FRONT] - sinf(cameraAngle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] + cosf(cameraAngle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] + sinf(cameraAngle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] + cosf(cameraAngle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] - sinf(cameraAngle.x)*direction[MOVE_LEFT] -
@ -424,11 +424,11 @@ void UpdateCamera(Camera *camera)
bool isMoving = false; // Required for swinging bool isMoving = false; // Required for swinging
for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; } for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY); cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD; if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD; else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
@ -437,7 +437,7 @@ void UpdateCamera(Camera *camera)
camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
if (isMoving) swingCounter++; if (isMoving) swingCounter++;
// Camera position update // Camera position update
@ -446,8 +446,8 @@ void UpdateCamera(Camera *camera)
camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
} break; } break;
case CAMERA_THIRD_PERSON: case CAMERA_THIRD_PERSON:
{ {
@ -455,11 +455,11 @@ void UpdateCamera(Camera *camera)
sinf(cameraAngle.x)*direction[MOVE_FRONT] - sinf(cameraAngle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] + cosf(cameraAngle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] + sinf(cameraAngle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] + cosf(cameraAngle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] - sinf(cameraAngle.x)*direction[MOVE_LEFT] -
@ -468,7 +468,7 @@ void UpdateCamera(Camera *camera)
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY); cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD; if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD; else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
@ -487,7 +487,7 @@ void UpdateCamera(Camera *camera)
} break; } break;
default: break; default: break;
} }
} }
// Set camera pan key to combine with mouse movement (free camera) // Set camera pan key to combine with mouse movement (free camera)

View file

@ -579,7 +579,7 @@ static void InitTerminal(void)
} }
else else
{ {
ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
} }
@ -590,7 +590,7 @@ static void InitTerminal(void)
static void RestoreTerminal(void) static void RestoreTerminal(void)
{ {
TraceLog(LOG_INFO, "Restore Terminal ..."); TraceLog(LOG_INFO, "Restore Terminal ...");
// Reset to default keyboard settings // Reset to default keyboard settings
tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings); tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings);
@ -774,7 +774,7 @@ void CloseWindow(void)
pthread_join(eventWorkers[i].threadId, NULL); pthread_join(eventWorkers[i].threadId, NULL);
} }
} }
if (gamepadThreadId) pthread_join(gamepadThreadId, NULL); if (gamepadThreadId) pthread_join(gamepadThreadId, NULL);
#endif #endif
@ -1207,7 +1207,7 @@ void EndDrawing(void)
// we draw a small rectangle for user reference // we draw a small rectangle for user reference
DrawRectangle(mousePosition.x, mousePosition.y, 3, 3, MAROON); DrawRectangle(mousePosition.x, mousePosition.y, 3, 3, MAROON);
#endif #endif
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
#if defined(SUPPORT_GIF_RECORDING) #if defined(SUPPORT_GIF_RECORDING)
@ -1270,10 +1270,10 @@ void BeginMode2D(Camera2D camera)
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlLoadIdentity(); // Reset current matrix (MODELVIEW)
// Apply screen scaling if required // Apply screen scaling if required
rlMultMatrixf(MatrixToFloat(screenScaling)); rlMultMatrixf(MatrixToFloat(screenScaling));
// Apply 2d camera transformation to modelview // Apply 2d camera transformation to modelview
rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera))); rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera)));
} }
@ -1465,7 +1465,7 @@ Matrix GetCameraMatrix(Camera camera)
} }
// Returns camera 2d transform matrix // Returns camera 2d transform matrix
Matrix GetCameraMatrix2D(Camera2D camera) Matrix GetCameraMatrix2D(Camera2D camera)
{ {
Matrix matTransform = { 0 }; Matrix matTransform = { 0 };
// The camera in world-space is set by // The camera in world-space is set by
@ -1486,9 +1486,9 @@ Matrix GetCameraMatrix2D(Camera2D camera)
Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD); Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD);
Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f); Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f);
Matrix matTranslation = MatrixTranslate(camera.offset.x, camera.offset.y, 0.0f); Matrix matTranslation = MatrixTranslate(camera.offset.x, camera.offset.y, 0.0f);
matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation); matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
return matTransform; return matTransform;
} }
@ -1535,20 +1535,20 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
} }
// Returns the screen space position for a 2d camera world space position // Returns the screen space position for a 2d camera world space position
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera) Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera)
{ {
Matrix matCamera = GetCameraMatrix2D(camera); Matrix matCamera = GetCameraMatrix2D(camera);
Vector3 transform = Vector3Transform((Vector3){ position.x, position.y, 0 }, matCamera); Vector3 transform = Vector3Transform((Vector3){ position.x, position.y, 0 }, matCamera);
return (Vector2){ transform.x, transform.y }; return (Vector2){ transform.x, transform.y };
} }
// Returns the world space position for a 2d camera screen space position // Returns the world space position for a 2d camera screen space position
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera) Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera)
{ {
Matrix invMatCamera = MatrixInvert(GetCameraMatrix2D(camera)); Matrix invMatCamera = MatrixInvert(GetCameraMatrix2D(camera));
Vector3 transform = Vector3Transform((Vector3){ position.x, position.y, 0 }, invMatCamera); Vector3 transform = Vector3Transform((Vector3){ position.x, position.y, 0 }, invMatCamera);
return (Vector2){ transform.x, transform.y }; return (Vector2){ transform.x, transform.y };
} }
@ -1797,10 +1797,10 @@ bool IsFileExtension(const char *fileName, const char *ext)
{ {
bool result = false; bool result = false;
const char *fileExt = GetExtension(fileName); const char *fileExt = GetExtension(fileName);
int extCount = 0; int extCount = 0;
const char **checkExts = TextSplit(ext, ';', &extCount); const char **checkExts = TextSplit(ext, ';', &extCount);
for (int i = 0; i < extCount; i++) for (int i = 0; i < extCount; i++)
{ {
if (strcmp(fileExt, checkExts[i] + 1) == 0) if (strcmp(fileExt, checkExts[i] + 1) == 0)
@ -1905,9 +1905,9 @@ const char *GetPrevDirectoryPath(const char *dirPath)
static char prevDirPath[MAX_FILEPATH_LENGTH]; static char prevDirPath[MAX_FILEPATH_LENGTH];
memset(prevDirPath, 0, MAX_FILEPATH_LENGTH); memset(prevDirPath, 0, MAX_FILEPATH_LENGTH);
int pathLen = strlen(dirPath); int pathLen = strlen(dirPath);
if (pathLen <= 3) strcpy(prevDirPath, dirPath); if (pathLen <= 3) strcpy(prevDirPath, dirPath);
for (int i = (pathLen - 1); (i > 0) && (pathLen > 3); i--) for (int i = (pathLen - 1); (i > 0) && (pathLen > 3); i--)
{ {
if ((dirPath[i] == '\\') || (dirPath[i] == '/')) if ((dirPath[i] == '\\') || (dirPath[i] == '/'))
@ -1917,7 +1917,7 @@ const char *GetPrevDirectoryPath(const char *dirPath)
break; break;
} }
} }
return prevDirPath; return prevDirPath;
} }
@ -2034,9 +2034,9 @@ long GetFileModTime(const char *fileName)
unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLength) unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLength)
{ {
#define COMPRESSION_QUALITY_DEFLATE 8 #define COMPRESSION_QUALITY_DEFLATE 8
unsigned char *compData = NULL; unsigned char *compData = NULL;
#if defined(SUPPORT_COMPRESSION_API) #if defined(SUPPORT_COMPRESSION_API)
compData = stbi_zlib_compress(data, dataLength, compDataLength, COMPRESSION_QUALITY_DEFLATE); compData = stbi_zlib_compress(data, dataLength, compDataLength, COMPRESSION_QUALITY_DEFLATE);
#endif #endif
@ -2048,7 +2048,7 @@ unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLe
unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *dataLength) unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *dataLength)
{ {
char *data = NULL; char *data = NULL;
#if defined(SUPPORT_COMPRESSION_API) #if defined(SUPPORT_COMPRESSION_API)
data = stbi_zlib_decode_malloc((char *)compData, compDataLength, dataLength); data = stbi_zlib_decode_malloc((char *)compData, compDataLength, dataLength);
#endif #endif
@ -2653,9 +2653,9 @@ static bool InitGraphicsDevice(int width, int height)
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);
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
#else #else
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
#endif #endif
} }
@ -4920,7 +4920,7 @@ static void *EventThread(void *arg)
// TODO: This fifo is not fully threadsafe with multiple writers, so multiple keyboards hitting a key at the exact same time could miss a key (double write to head before it was incremented) // TODO: This fifo is not fully threadsafe with multiple writers, so multiple keyboards hitting a key at the exact same time could miss a key (double write to head before it was incremented)
} }
*/ */
currentKeyState[keycode] = event.value; currentKeyState[keycode] = event.value;
if (event.value == 1) lastKeyPressed = keycode; // Register last key pressed if (event.value == 1) lastKeyPressed = keycode; // Register last key pressed
@ -4934,7 +4934,7 @@ static void *EventThread(void *arg)
#endif #endif
if (currentKeyState[exitKey] == 1) windowShouldClose = true; if (currentKeyState[exitKey] == 1) windowShouldClose = true;
TraceLog(LOG_DEBUG, "KEY%s ScanCode: %4i KeyCode: %4i",event.value == 0 ? "UP":"DOWN", event.code, keycode); TraceLog(LOG_DEBUG, "KEY%s ScanCode: %4i KeyCode: %4i",event.value == 0 ? "UP":"DOWN", event.code, keycode);
} }
} }

View file

@ -8,7 +8,7 @@
* *
* #define GESTURES_IMPLEMENTATION * #define GESTURES_IMPLEMENTATION
* Generates the implementation of the library into the included file. * Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation. * or source files without problems. But only ONE file should hold the implementation.
* *
* #define GESTURES_STANDALONE * #define GESTURES_STANDALONE
@ -216,8 +216,8 @@ static float pinchDistance = 0.0f; // PINCH displacement distance (
static int currentGesture = GESTURE_NONE; // Current detected gesture static int currentGesture = GESTURE_NONE; // Current detected gesture
// Enabled gestures flags, all gestures enabled by default // Enabled gestures flags, all gestures enabled by default
static unsigned int enabledGestures = 0b0000001111111111; static unsigned int enabledGestures = 0b0000001111111111;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
@ -251,13 +251,13 @@ void ProcessGestureEvent(GestureEvent event)
{ {
// Reset required variables // Reset required variables
pointCount = event.pointCount; // Required on UpdateGestures() pointCount = event.pointCount; // Required on UpdateGestures()
if (pointCount < 2) if (pointCount < 2)
{ {
if (event.touchAction == TOUCH_DOWN) if (event.touchAction == TOUCH_DOWN)
{ {
tapCounter++; // Tap counter tapCounter++; // Tap counter
// Detect GESTURE_DOUBLE_TAP // Detect GESTURE_DOUBLE_TAP
if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE))
{ {
@ -269,15 +269,15 @@ void ProcessGestureEvent(GestureEvent event)
tapCounter = 1; tapCounter = 1;
currentGesture = GESTURE_TAP; currentGesture = GESTURE_TAP;
} }
touchDownPosition = event.position[0]; touchDownPosition = event.position[0];
touchDownDragPosition = event.position[0]; touchDownDragPosition = event.position[0];
touchUpPosition = touchDownPosition; touchUpPosition = touchDownPosition;
eventTime = GetCurrentTime(); eventTime = GetCurrentTime();
firstTouchId = event.pointerId[0]; firstTouchId = event.pointerId[0];
dragVector = (Vector2){ 0.0f, 0.0f }; dragVector = (Vector2){ 0.0f, 0.0f };
} }
else if (event.touchAction == TOUCH_UP) else if (event.touchAction == TOUCH_UP)
@ -287,15 +287,15 @@ void ProcessGestureEvent(GestureEvent event)
// NOTE: dragIntensity dependend on the resolution of the screen // NOTE: dragIntensity dependend on the resolution of the screen
dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); dragDistance = Vector2Distance(touchDownPosition, touchUpPosition);
dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime));
startMoving = false; startMoving = false;
// Detect GESTURE_SWIPE // Detect GESTURE_SWIPE
if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0])) if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0]))
{ {
// NOTE: Angle should be inverted in Y // NOTE: Angle should be inverted in Y
dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition); dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);
if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right
else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up
else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left
@ -307,31 +307,31 @@ void ProcessGestureEvent(GestureEvent event)
dragDistance = 0.0f; dragDistance = 0.0f;
dragIntensity = 0.0f; dragIntensity = 0.0f;
dragAngle = 0.0f; dragAngle = 0.0f;
currentGesture = GESTURE_NONE; currentGesture = GESTURE_NONE;
} }
touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; touchDownDragPosition = (Vector2){ 0.0f, 0.0f };
pointCount = 0; pointCount = 0;
} }
else if (event.touchAction == TOUCH_MOVE) else if (event.touchAction == TOUCH_MOVE)
{ {
if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime();
if (!startMoving) if (!startMoving)
{ {
swipeTime = GetCurrentTime(); swipeTime = GetCurrentTime();
startMoving = true; startMoving = true;
} }
moveDownPosition = event.position[0]; moveDownPosition = event.position[0];
if (currentGesture == GESTURE_HOLD) if (currentGesture == GESTURE_HOLD)
{ {
if (resetHold) touchDownPosition = event.position[0]; if (resetHold) touchDownPosition = event.position[0];
resetHold = false; resetHold = false;
// Detect GESTURE_DRAG // Detect GESTURE_DRAG
if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG)
{ {
@ -339,7 +339,7 @@ void ProcessGestureEvent(GestureEvent event)
currentGesture = GESTURE_DRAG; currentGesture = GESTURE_DRAG;
} }
} }
dragVector.x = moveDownPosition.x - touchDownDragPosition.x; dragVector.x = moveDownPosition.x - touchDownDragPosition.x;
dragVector.y = moveDownPosition.y - touchDownDragPosition.y; dragVector.y = moveDownPosition.y - touchDownDragPosition.y;
} }
@ -350,28 +350,28 @@ void ProcessGestureEvent(GestureEvent event)
{ {
touchDownPosition = event.position[0]; touchDownPosition = event.position[0];
touchDownPosition2 = event.position[1]; touchDownPosition2 = event.position[1];
//pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2);
pinchVector.x = touchDownPosition2.x - touchDownPosition.x; pinchVector.x = touchDownPosition2.x - touchDownPosition.x;
pinchVector.y = touchDownPosition2.y - touchDownPosition.y; pinchVector.y = touchDownPosition2.y - touchDownPosition.y;
currentGesture = GESTURE_HOLD; currentGesture = GESTURE_HOLD;
timeHold = GetCurrentTime(); timeHold = GetCurrentTime();
} }
else if (event.touchAction == TOUCH_MOVE) else if (event.touchAction == TOUCH_MOVE)
{ {
pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2);
touchDownPosition = moveDownPosition; touchDownPosition = moveDownPosition;
touchDownPosition2 = moveDownPosition2; touchDownPosition2 = moveDownPosition2;
moveDownPosition = event.position[0]; moveDownPosition = event.position[0];
moveDownPosition2 = event.position[1]; moveDownPosition2 = event.position[1];
pinchVector.x = moveDownPosition2.x - moveDownPosition.x; pinchVector.x = moveDownPosition2.x - moveDownPosition.x;
pinchVector.y = moveDownPosition2.y - moveDownPosition.y; pinchVector.y = moveDownPosition2.y - moveDownPosition.y;
if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH)) if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH))
{ {
if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN; if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN;
@ -382,7 +382,7 @@ void ProcessGestureEvent(GestureEvent event)
currentGesture = GESTURE_HOLD; currentGesture = GESTURE_HOLD;
timeHold = GetCurrentTime(); timeHold = GetCurrentTime();
} }
// NOTE: Angle should be inverted in Y // NOTE: Angle should be inverted in Y
pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2); pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2);
} }
@ -392,7 +392,7 @@ void ProcessGestureEvent(GestureEvent event)
pinchAngle = 0.0f; pinchAngle = 0.0f;
pinchVector = (Vector2){ 0.0f, 0.0f }; pinchVector = (Vector2){ 0.0f, 0.0f };
pointCount = 0; pointCount = 0;
currentGesture = GESTURE_NONE; currentGesture = GESTURE_NONE;
} }
} }
@ -409,14 +409,14 @@ void UpdateGestures(void)
currentGesture = GESTURE_HOLD; currentGesture = GESTURE_HOLD;
timeHold = GetCurrentTime(); timeHold = GetCurrentTime();
} }
if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2))
{ {
currentGesture = GESTURE_HOLD; currentGesture = GESTURE_HOLD;
timeHold = GetCurrentTime(); timeHold = GetCurrentTime();
resetHold = true; resetHold = true;
} }
// Detect GESTURE_NONE // Detect GESTURE_NONE
if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN))
{ {
@ -428,7 +428,7 @@ void UpdateGestures(void)
int GetTouchPointsCount(void) int GetTouchPointsCount(void)
{ {
// NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called
return pointCount; return pointCount;
} }
@ -443,11 +443,11 @@ int GetGestureDetected(void)
float GetGestureHoldDuration(void) float GetGestureHoldDuration(void)
{ {
// NOTE: time is calculated on current gesture HOLD // NOTE: time is calculated on current gesture HOLD
double time = 0.0; double time = 0.0;
if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold; if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold;
return (float)time; return (float)time;
} }
@ -455,7 +455,7 @@ float GetGestureHoldDuration(void)
Vector2 GetGestureDragVector(void) Vector2 GetGestureDragVector(void)
{ {
// NOTE: drag vector is calculated on one touch points TOUCH_MOVE // NOTE: drag vector is calculated on one touch points TOUCH_MOVE
return dragVector; return dragVector;
} }
@ -464,7 +464,7 @@ Vector2 GetGestureDragVector(void)
float GetGestureDragAngle(void) float GetGestureDragAngle(void)
{ {
// NOTE: drag angle is calculated on one touch points TOUCH_UP // NOTE: drag angle is calculated on one touch points TOUCH_UP
return dragAngle; return dragAngle;
} }
@ -473,7 +473,7 @@ Vector2 GetGesturePinchVector(void)
{ {
// NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index) // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index)
// NOTE: pinch distance is calculated on two touch points TOUCH_MOVE // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE
return pinchVector; return pinchVector;
} }
@ -482,7 +482,7 @@ Vector2 GetGesturePinchVector(void)
float GetGesturePinchAngle(void) float GetGesturePinchAngle(void)
{ {
// NOTE: pinch angle is calculated on two touch points TOUCH_MOVE // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE
return pinchAngle; return pinchAngle;
} }
@ -494,7 +494,7 @@ float GetGesturePinchAngle(void)
static float Vector2Angle(Vector2 v1, Vector2 v2) static float Vector2Angle(Vector2 v1, Vector2 v2)
{ {
float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI); float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
if (angle < 0) angle += 360.0f; if (angle < 0) angle += 360.0f;
return angle; return angle;
@ -518,13 +518,13 @@ static float Vector2Distance(Vector2 v1, Vector2 v2)
static double GetCurrentTime(void) static double GetCurrentTime(void)
{ {
double time = 0; double time = 0;
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int clockFrequency, currentTime; unsigned long long int clockFrequency, currentTime;
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation! QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
QueryPerformanceCounter(&currentTime); QueryPerformanceCounter(&currentTime);
time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
#endif #endif
@ -533,24 +533,24 @@ static double GetCurrentTime(void)
struct timespec now; struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
time = ((double)nowTime/1000000.0); // Time in miliseconds time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 //#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time //#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
clock_serv_t cclock; clock_serv_t cclock;
mach_timespec_t now; mach_timespec_t now;
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
// NOTE: OS X does not have clock_gettime(), using clock_get_time() // NOTE: OS X does not have clock_gettime(), using clock_get_time()
clock_get_time(cclock, &now); clock_get_time(cclock, &now);
mach_port_deallocate(mach_task_self(), cclock); mach_port_deallocate(mach_task_self(), cclock);
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
time = ((double)nowTime/1000000.0); // Time in miliseconds time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif #endif
return time; return time;

View file

@ -1896,7 +1896,7 @@ static Vector2 TriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3)
static void InitTimer(void) static void InitTimer(void)
{ {
srand(time(NULL)); // Initialize random seed srand(time(NULL)); // Initialize random seed
#if defined(_WIN32) #if defined(_WIN32)
QueryPerformanceFrequency((unsigned long long int *) &frequency); QueryPerformanceFrequency((unsigned long long int *) &frequency);
#endif #endif
@ -1911,7 +1911,7 @@ static void InitTimer(void)
mach_timebase_info(&timebase); mach_timebase_info(&timebase);
frequency = (timebase.denom*1e9)/timebase.numer; frequency = (timebase.denom*1e9)/timebase.numer;
#endif #endif
baseTime = GetTimeCount(); // Get MONOTONIC clock time offset baseTime = GetTimeCount(); // Get MONOTONIC clock time offset
startTime = GetCurrentTime(); // Get current time startTime = GetCurrentTime(); // Get current time
} }
@ -1920,7 +1920,7 @@ static void InitTimer(void)
static uint64_t GetTimeCount(void) static uint64_t GetTimeCount(void)
{ {
uint64_t value = 0; uint64_t value = 0;
#if defined(_WIN32) #if defined(_WIN32)
QueryPerformanceCounter((unsigned long long int *) &value); QueryPerformanceCounter((unsigned long long int *) &value);
#endif #endif

View file

@ -198,10 +198,10 @@ typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioB
// playback device depending on whether or not data is streamed // playback device depending on whether or not data is streamed
struct rAudioBuffer { struct rAudioBuffer {
ma_pcm_converter dsp; // PCM data converter ma_pcm_converter dsp; // PCM data converter
float volume; // Audio buffer volume float volume; // Audio buffer volume
float pitch; // Audio buffer pitch float pitch; // Audio buffer pitch
bool playing; // Audio buffer state: AUDIO_PLAYING bool playing; // Audio buffer state: AUDIO_PLAYING
bool paused; // Audio buffer state: AUDIO_PAUSED bool paused; // Audio buffer state: AUDIO_PAUSED
bool looping; // Audio buffer looping, always true for AudioStreams bool looping; // Audio buffer looping, always true for AudioStreams
@ -209,11 +209,11 @@ struct rAudioBuffer {
bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer) bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer)
unsigned int frameCursorPos; // Frame cursor position unsigned int frameCursorPos; // Frame cursor position
unsigned int bufferSizeInFrames; // Total buffer size in frames unsigned int bufferSizeInFrames; // Total buffer size in frames
unsigned int totalFramesProcessed; // Total frames processed in this buffer (required for play timming) unsigned int totalFramesProcessed; // Total frames processed in this buffer (required for play timming)
unsigned char *buffer; // Data buffer, on music stream keeps filling unsigned char *buffer; // Data buffer, on music stream keeps filling
rAudioBuffer *next; // Next audio buffer on the list rAudioBuffer *next; // Next audio buffer on the list
rAudioBuffer *prev; // Previous audio buffer on the list rAudioBuffer *prev; // Previous audio buffer on the list
}; };
@ -289,7 +289,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
if (!audioBuffer->playing || audioBuffer->paused) continue; if (!audioBuffer->playing || audioBuffer->paused) continue;
ma_uint32 framesRead = 0; ma_uint32 framesRead = 0;
while (1) while (1)
{ {
if (framesRead > frameCount) if (framesRead > frameCount)
@ -302,7 +302,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
// Just read as much data as we can from the stream // Just read as much data as we can from the stream
ma_uint32 framesToRead = (frameCount - framesRead); ma_uint32 framesToRead = (frameCount - framesRead);
while (framesToRead > 0) while (framesToRead > 0)
{ {
float tempBuffer[1024]; // 512 frames for stereo float tempBuffer[1024]; // 512 frames for stereo
@ -387,7 +387,7 @@ static ma_uint32 OnAudioBufferDSPRead(ma_pcm_converter *pDSP, void *pFramesOut,
{ {
if (framesRead >= frameCount) break; if (framesRead >= frameCount) break;
} }
else else
{ {
if (isSubBufferProcessed[currentSubBufferIndex]) break; if (isSubBufferProcessed[currentSubBufferIndex]) break;
} }
@ -465,7 +465,7 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr
static void InitAudioBufferPool() static void InitAudioBufferPool()
{ {
// Dummy buffers // Dummy buffers
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
{ {
audioBufferPool[i] = InitAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC); audioBufferPool[i] = InitAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC);
} }
@ -486,7 +486,7 @@ void InitAudioDevice(void)
// Init audio context // Init audio context
ma_context_config contextConfig = ma_context_config_init(); ma_context_config contextConfig = ma_context_config_init();
contextConfig.logCallback = OnLog; contextConfig.logCallback = OnLog;
ma_result result = ma_context_init(NULL, 0, &contextConfig, &context); ma_result result = ma_context_init(NULL, 0, &contextConfig, &context);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
{ {
@ -589,7 +589,7 @@ AudioBuffer *InitAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
{ {
AudioBuffer *audioBuffer = (AudioBuffer *)RL_CALLOC(1, sizeof(AudioBuffer)); AudioBuffer *audioBuffer = (AudioBuffer *)RL_CALLOC(1, sizeof(AudioBuffer));
audioBuffer->buffer = RL_CALLOC(bufferSizeInFrames*channels*ma_get_bytes_per_sample(format), 1); audioBuffer->buffer = RL_CALLOC(bufferSizeInFrames*channels*ma_get_bytes_per_sample(format), 1);
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
TraceLog(LOG_ERROR, "InitAudioBuffer() : Failed to allocate memory for audio buffer"); TraceLog(LOG_ERROR, "InitAudioBuffer() : Failed to allocate memory for audio buffer");
@ -608,7 +608,7 @@ AudioBuffer *InitAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
dspConfig.onRead = OnAudioBufferDSPRead; // Callback on data reading dspConfig.onRead = OnAudioBufferDSPRead; // Callback on data reading
dspConfig.pUserData = audioBuffer; // Audio data pointer dspConfig.pUserData = audioBuffer; // Audio data pointer
dspConfig.allowDynamicSampleRate = true; // Required for pitch shifting dspConfig.allowDynamicSampleRate = true; // Required for pitch shifting
ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp); ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
@ -655,7 +655,7 @@ void CloseAudioBuffer(AudioBuffer *buffer)
bool IsAudioBufferPlaying(AudioBuffer *buffer) bool IsAudioBufferPlaying(AudioBuffer *buffer)
{ {
bool result = false; bool result = false;
if (buffer != NULL) result = (buffer->playing && !buffer->paused); if (buffer != NULL) result = (buffer->playing && !buffer->paused);
else TraceLog(LOG_ERROR, "IsAudioBufferPlaying() : No audio buffer"); else TraceLog(LOG_ERROR, "IsAudioBufferPlaying() : No audio buffer");
@ -698,7 +698,7 @@ void StopAudioBuffer(AudioBuffer *buffer)
void PauseAudioBuffer(AudioBuffer *buffer) void PauseAudioBuffer(AudioBuffer *buffer)
{ {
if (buffer != NULL) buffer->paused = true; if (buffer != NULL) buffer->paused = true;
else TraceLog(LOG_ERROR, "PauseAudioBuffer() : No audio buffer"); else TraceLog(LOG_ERROR, "PauseAudioBuffer() : No audio buffer");
} }
// Resume an audio buffer // Resume an audio buffer
@ -722,8 +722,8 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
{ {
float pitchMul = pitch/buffer->pitch; float pitchMul = pitch/buffer->pitch;
// Pitching is just an adjustment of the sample rate. // Pitching is just an adjustment of the sample rate.
// Note that this changes the duration of the sound: // Note that this changes the duration of the sound:
// - higher pitches will make the sound faster // - higher pitches will make the sound faster
// - lower pitches make it slower // - lower pitches make it slower
ma_uint32 newOutputSampleRate = (ma_uint32)((float)buffer->dsp.src.config.sampleRateOut/pitchMul); ma_uint32 newOutputSampleRate = (ma_uint32)((float)buffer->dsp.src.config.sampleRateOut/pitchMul);
@ -816,7 +816,7 @@ Sound LoadSoundFromWave(Wave wave)
if (wave.data != NULL) if (wave.data != NULL)
{ {
// When using miniaudio we need to do our own mixing. // When using miniaudio we need to do our own mixing.
// To simplify this we need convert the format of each sound to be consistent with // To simplify this we need convert the format of each sound to be consistent with
// the format used to open the playback device. We can do this two ways: // the format used to open the playback device. We can do this two ways:
// //
@ -909,7 +909,7 @@ void ExportWaveAsCode(Wave wave, const char *fileName)
int dataSize = wave.sampleCount*wave.channels*wave.sampleSize/8; int dataSize = wave.sampleCount*wave.channels*wave.sampleSize/8;
FILE *txtFile = fopen(fileName, "wt"); FILE *txtFile = fopen(fileName, "wt");
if (txtFile != NULL) if (txtFile != NULL)
{ {
fprintf(txtFile, "\n//////////////////////////////////////////////////////////////////////////////////\n"); fprintf(txtFile, "\n//////////////////////////////////////////////////////////////////////////////////\n");
@ -967,7 +967,7 @@ void PlaySoundMulti(Sound sound)
oldAge = audioBufferPoolChannels[i]; oldAge = audioBufferPoolChannels[i];
oldIndex = i; oldIndex = i;
} }
if (!IsAudioBufferPlaying(audioBufferPool[i])) if (!IsAudioBufferPlaying(audioBufferPool[i]))
{ {
index = i; index = i;
@ -979,17 +979,17 @@ void PlaySoundMulti(Sound sound)
if (index == -1) if (index == -1)
{ {
TraceLog(LOG_WARNING,"pool age %i ended a sound early no room in buffer pool", audioBufferPoolCounter); TraceLog(LOG_WARNING,"pool age %i ended a sound early no room in buffer pool", audioBufferPoolCounter);
if (oldIndex == -1) if (oldIndex == -1)
{ {
// Shouldn't be able to get here... but just in case something odd happens! // Shouldn't be able to get here... but just in case something odd happens!
TraceLog(LOG_ERROR,"sound buffer pool couldn't determine oldest buffer not playing sound"); TraceLog(LOG_ERROR,"sound buffer pool couldn't determine oldest buffer not playing sound");
return; return;
} }
index = oldIndex; index = oldIndex;
// Just in case... // Just in case...
StopAudioBuffer(audioBufferPool[index]); StopAudioBuffer(audioBufferPool[index]);
} }
@ -1000,7 +1000,7 @@ void PlaySoundMulti(Sound sound)
audioBufferPoolChannels[index] = audioBufferPoolCounter; audioBufferPoolChannels[index] = audioBufferPoolCounter;
audioBufferPoolCounter++; audioBufferPoolCounter++;
audioBufferPool[index]->volume = sound.stream.buffer->volume; audioBufferPool[index]->volume = sound.stream.buffer->volume;
audioBufferPool[index]->pitch = sound.stream.buffer->pitch; audioBufferPool[index]->pitch = sound.stream.buffer->pitch;
audioBufferPool[index]->looping = sound.stream.buffer->looping; audioBufferPool[index]->looping = sound.stream.buffer->looping;
@ -1023,12 +1023,12 @@ void StopSoundMulti(void)
int GetSoundsPlaying(void) int GetSoundsPlaying(void)
{ {
int counter = 0; int counter = 0;
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
{ {
if (IsAudioBufferPlaying(audioBufferPool[i])) counter++; if (IsAudioBufferPlaying(audioBufferPool[i])) counter++;
} }
return counter; return counter;
} }
@ -1211,7 +1211,7 @@ Music LoadMusicStream(const char *fileName)
{ {
drmp3 *ctxMp3 = RL_MALLOC(sizeof(drmp3)); drmp3 *ctxMp3 = RL_MALLOC(sizeof(drmp3));
music.ctxData = ctxMp3; music.ctxData = ctxMp3;
int result = drmp3_init_file(ctxMp3, fileName, NULL); int result = drmp3_init_file(ctxMp3, fileName, NULL);
if (result > 0) if (result > 0)
@ -1242,7 +1242,7 @@ Music LoadMusicStream(const char *fileName)
music.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); music.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm);
music.loopCount = 0; // Infinite loop by default music.loopCount = 0; // Infinite loop by default
musicLoaded = true; musicLoaded = true;
music.ctxData = ctxXm; music.ctxData = ctxXm;
} }
} }
@ -1252,7 +1252,7 @@ Music LoadMusicStream(const char *fileName)
{ {
jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t)); jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t));
music.ctxData = ctxMod; music.ctxData = ctxMod;
jar_mod_init(ctxMod); jar_mod_init(ctxMod);
int result = jar_mod_load_file(ctxMod, fileName); int result = jar_mod_load_file(ctxMod, fileName);
@ -1335,7 +1335,7 @@ void PlayMusicStream(Music music)
{ {
// For music streams, we need to make sure we maintain the frame cursor position // For music streams, we need to make sure we maintain the frame cursor position
// This is a hack for this section of code in UpdateMusicStream() // This is a hack for this section of code in UpdateMusicStream()
// NOTE: In case window is minimized, music stream is stopped, just make sure to // NOTE: In case window is minimized, music stream is stopped, just make sure to
// play again on window restore: if (IsMusicPlaying(music)) PlayMusicStream(music); // play again on window restore: if (IsMusicPlaying(music)) PlayMusicStream(music);
ma_uint32 frameCursorPos = audioBuffer->frameCursorPos; ma_uint32 frameCursorPos = audioBuffer->frameCursorPos;
PlayAudioStream(music.stream); // WARNING: This resets the cursor position. PlayAudioStream(music.stream); // WARNING: This resets the cursor position.
@ -1395,7 +1395,7 @@ void UpdateMusicStream(Music music)
void *pcm = RL_CALLOC(subBufferSizeInFrames*music.stream.channels*music.stream.sampleSize/8, 1); void *pcm = RL_CALLOC(subBufferSizeInFrames*music.stream.channels*music.stream.sampleSize/8, 1);
int samplesCount = 0; // Total size of data streamed in L+R samples for xm floats, individual L or R for ogg shorts int samplesCount = 0; // Total size of data streamed in L+R samples for xm floats, individual L or R for ogg shorts
// TODO: Get the sampleLeft using totalFramesProcessed... but first, get total frames processed correctly... // TODO: Get the sampleLeft using totalFramesProcessed... but first, get total frames processed correctly...
//ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels; //ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels;
int sampleLeft = music.sampleCount - (music.stream.buffer->totalFramesProcessed*music.stream.channels); int sampleLeft = music.sampleCount - (music.stream.buffer->totalFramesProcessed*music.stream.channels);
@ -1449,7 +1449,7 @@ void UpdateMusicStream(Music music)
} }
UpdateAudioStream(music.stream, pcm, samplesCount); UpdateAudioStream(music.stream, pcm, samplesCount);
if ((music.ctxType == MUSIC_MODULE_XM) || (music.ctxType == MUSIC_MODULE_MOD)) if ((music.ctxType == MUSIC_MODULE_XM) || (music.ctxType == MUSIC_MODULE_MOD))
{ {
if (samplesCount > 1) sampleLeft -= samplesCount/2; if (samplesCount > 1) sampleLeft -= samplesCount/2;
@ -1549,11 +1549,11 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
// The size of a streaming buffer must be at least double the size of a period // The size of a streaming buffer must be at least double the size of a period
unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods; unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods;
unsigned int subBufferSize = AUDIO_BUFFER_SIZE; unsigned int subBufferSize = AUDIO_BUFFER_SIZE;
if (subBufferSize < periodSize) subBufferSize = periodSize; if (subBufferSize < periodSize) subBufferSize = periodSize;
stream.buffer = InitAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM); stream.buffer = InitAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM);
if (stream.buffer != NULL) if (stream.buffer != NULL)
{ {
stream.buffer->looping = true; // Always loop for streaming buffers stream.buffer->looping = true; // Always loop for streaming buffers
@ -1578,7 +1578,7 @@ void CloseAudioStream(AudioStream stream)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
{ {
AudioBuffer *audioBuffer = stream.buffer; AudioBuffer *audioBuffer = stream.buffer;
if (audioBuffer != NULL) if (audioBuffer != NULL)
{ {
if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1])
@ -1587,7 +1587,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1])
{ {
// Both buffers are available for updating. // Both buffers are available for updating.
// Update the first one and make sure the cursor is moved back to the front. // Update the first one and make sure the cursor is moved back to the front.
subBufferToUpdate = 0; subBufferToUpdate = 0;
audioBuffer->frameCursorPos = 0; audioBuffer->frameCursorPos = 0;
@ -1604,7 +1604,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
// TODO: Get total frames processed on this buffer... DOES NOT WORK. // TODO: Get total frames processed on this buffer... DOES NOT WORK.
audioBuffer->totalFramesProcessed += subBufferSizeInFrames; audioBuffer->totalFramesProcessed += subBufferSizeInFrames;
// Does this API expect a whole buffer to be updated in one go? // Does this API expect a whole buffer to be updated in one go?
// Assuming so, but if not will need to change this logic. // Assuming so, but if not will need to change this logic.
if (subBufferSizeInFrames >= (ma_uint32)samplesCount/stream.channels) if (subBufferSizeInFrames >= (ma_uint32)samplesCount/stream.channels)
{ {

View file

@ -110,7 +110,7 @@ typedef struct Sound {
typedef struct Music { typedef struct Music {
int ctxType; // Type of music context (audio filetype) int ctxType; // Type of music context (audio filetype)
void *ctxData; // Audio context data, depends on type void *ctxData; // Audio context data, depends on type
unsigned int sampleCount; // Total number of samples unsigned int sampleCount; // Total number of samples
unsigned int loopCount; // Loops count (times music will play), 0 means infinite loop unsigned int loopCount; // Loops count (times music will play), 0 means infinite loop

View file

@ -2,7 +2,7 @@
* *
* rglfw - raylib GLFW single file compilation * rglfw - raylib GLFW single file compilation
* *
* This file includes latest GLFW sources (https://github.com/glfw/glfw) to be compiled together * This file includes latest GLFW sources (https://github.com/glfw/glfw) to be compiled together
* with raylib for all supported platforms, this way, no external dependencies are required. * with raylib for all supported platforms, this way, no external dependencies are required.
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng

View file

@ -2967,7 +2967,7 @@ char *LoadText(const char *fileName)
Shader LoadShader(const char *vsFileName, const char *fsFileName) Shader LoadShader(const char *vsFileName, const char *fsFileName)
{ {
Shader shader = { 0 }; Shader shader = { 0 };
// NOTE: Shader.locs is allocated by LoadShaderCode() // NOTE: Shader.locs is allocated by LoadShaderCode()
char *vShaderStr = NULL; char *vShaderStr = NULL;

View file

@ -54,7 +54,7 @@
#else #else
#define RMEMAPI // We are building or using library as a static library (or Linux shared library) #define RMEMAPI // We are building or using library as a static library (or Linux shared library)
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -139,9 +139,9 @@ RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref);
#if defined(RMEM_IMPLEMENTATION) #if defined(RMEM_IMPLEMENTATION)
#include <stdio.h> // Required for: #include <stdio.h> // Required for:
#include <stdlib.h> // Required for: #include <stdlib.h> // Required for:
#include <string.h> // Required for: #include <string.h> // Required for:
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -163,8 +163,8 @@ RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static inline size_t __AlignSize(const size_t size, const size_t align) static inline size_t __AlignSize(const size_t size, const size_t align)
{ {
return (size + (align - 1)) & -align; return (size + (align - 1)) & -align;
} }
@ -175,9 +175,9 @@ static inline size_t __AlignSize(const size_t size, const size_t align)
MemPool CreateMemPool(const size_t size) MemPool CreateMemPool(const size_t size)
{ {
MemPool mempool = { 0 }; MemPool mempool = { 0 };
if (size == 0UL) return mempool; if (size == 0UL) return mempool;
else else
{ {
// Align the mempool size to at least the size of an alloc node. // Align the mempool size to at least the size of an alloc node.
mempool.stack.size = size; mempool.stack.size = size;
@ -188,7 +188,7 @@ MemPool CreateMemPool(const size_t size)
mempool.stack.size = 0UL; mempool.stack.size = 0UL;
return mempool; return mempool;
} }
else else
{ {
mempool.stack.base = mempool.stack.mem + mempool.stack.size; mempool.stack.base = mempool.stack.mem + mempool.stack.size;
return mempool; return mempool;
@ -199,9 +199,9 @@ MemPool CreateMemPool(const size_t size)
MemPool CreateMemPoolFromBuffer(void *buf, const size_t size) MemPool CreateMemPoolFromBuffer(void *buf, const size_t size)
{ {
MemPool mempool = { 0 }; MemPool mempool = { 0 };
if ((size == 0UL) || (buf == NULL) || (size <= sizeof(MemNode))) return mempool; if ((size == 0UL) || (buf == NULL) || (size <= sizeof(MemNode))) return mempool;
else else
{ {
mempool.stack.size = size; mempool.stack.size = size;
mempool.stack.mem = buf; mempool.stack.mem = buf;
@ -213,7 +213,7 @@ MemPool CreateMemPoolFromBuffer(void *buf, const size_t size)
void DestroyMemPool(MemPool *const mempool) void DestroyMemPool(MemPool *const mempool)
{ {
if ((mempool == NULL) || (mempool->stack.mem == NULL)) return; if ((mempool == NULL) || (mempool->stack.mem == NULL)) return;
else else
{ {
free(mempool->stack.mem); free(mempool->stack.mem);
*mempool = (MemPool){ 0 }; *mempool = (MemPool){ 0 };
@ -228,7 +228,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
MemNode *new_mem = NULL; MemNode *new_mem = NULL;
const size_t ALLOC_SIZE = __AlignSize(size + sizeof *new_mem, sizeof(intptr_t)); const size_t ALLOC_SIZE = __AlignSize(size + sizeof *new_mem, sizeof(intptr_t));
const size_t BUCKET_INDEX = (ALLOC_SIZE >> MEMPOOL_BUCKET_BITS) - 1; const size_t BUCKET_INDEX = (ALLOC_SIZE >> MEMPOOL_BUCKET_BITS) - 1;
// If the size is small enough, let's check if our buckets has a fitting memory block. // If the size is small enough, let's check if our buckets has a fitting memory block.
if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE && mempool->buckets[BUCKET_INDEX] != NULL && mempool->buckets[BUCKET_INDEX]->size >= ALLOC_SIZE) if (BUCKET_INDEX < MEMPOOL_BUCKET_SIZE && mempool->buckets[BUCKET_INDEX] != NULL && mempool->buckets[BUCKET_INDEX]->size >= ALLOC_SIZE)
{ {
@ -240,7 +240,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
else if (mempool->freeList.head != NULL) else if (mempool->freeList.head != NULL)
{ {
const size_t MEM_SPLIT_THRESHOLD = 16; const size_t MEM_SPLIT_THRESHOLD = 16;
// If the freelist is valid, let's allocate FROM the freelist then! // If the freelist is valid, let's allocate FROM the freelist then!
for (MemNode *inode = mempool->freeList.head; inode != NULL; inode = inode->next) for (MemNode *inode = mempool->freeList.head; inode != NULL; inode = inode->next)
{ {
@ -251,10 +251,10 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
new_mem = inode; new_mem = inode;
(inode->prev != NULL)? (inode->prev->next = inode->next) : (mempool->freeList.head = inode->next); (inode->prev != NULL)? (inode->prev->next = inode->next) : (mempool->freeList.head = inode->next);
(inode->next != NULL)? (inode->next->prev = inode->prev) : (mempool->freeList.tail = inode->prev); (inode->next != NULL)? (inode->next->prev = inode->prev) : (mempool->freeList.tail = inode->prev);
if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL; if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL;
else mempool->freeList.tail = NULL; else mempool->freeList.tail = NULL;
if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL; if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL;
mempool->freeList.len--; mempool->freeList.len--;
break; break;
@ -269,7 +269,7 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
} }
} }
} }
if (new_mem == NULL) if (new_mem == NULL)
{ {
// not enough memory to support the size! // not enough memory to support the size!
@ -279,13 +279,13 @@ void *MemPoolAlloc(MemPool *const mempool, const size_t size)
// Couldn't allocate from a freelist, allocate from available mempool. // Couldn't allocate from a freelist, allocate from available mempool.
// Subtract allocation size from the mempool. // Subtract allocation size from the mempool.
mempool->stack.base -= ALLOC_SIZE; mempool->stack.base -= ALLOC_SIZE;
// Use the available mempool space as the new node. // Use the available mempool space as the new node.
new_mem = (MemNode *)mempool->stack.base; new_mem = (MemNode *)mempool->stack.base;
new_mem->size = ALLOC_SIZE; new_mem->size = ALLOC_SIZE;
} }
} }
// Visual of the allocation block. // Visual of the allocation block.
// -------------- // --------------
// | mem size | lowest addr of block // | mem size | lowest addr of block
@ -314,7 +314,7 @@ void *MemPoolRealloc(MemPool *const restrict mempool, void *ptr, const size_t si
MemNode *const node = (MemNode *)((uint8_t *)ptr - sizeof *node); MemNode *const node = (MemNode *)((uint8_t *)ptr - sizeof *node);
const size_t NODE_SIZE = sizeof *node; const size_t NODE_SIZE = sizeof *node;
uint8_t *const resized_block = MemPoolAlloc(mempool, size); uint8_t *const resized_block = MemPoolAlloc(mempool, size);
if (resized_block == NULL) return NULL; if (resized_block == NULL) return NULL;
else else
{ {
@ -329,16 +329,16 @@ void *MemPoolRealloc(MemPool *const restrict mempool, void *ptr, const size_t si
void MemPoolFree(MemPool *const restrict mempool, void *ptr) void MemPoolFree(MemPool *const restrict mempool, void *ptr)
{ {
if ((mempool == NULL) || (ptr == NULL) || ((uintptr_t)ptr - sizeof(MemNode) < (uintptr_t)mempool->stack.mem)) return; if ((mempool == NULL) || (ptr == NULL) || ((uintptr_t)ptr - sizeof(MemNode) < (uintptr_t)mempool->stack.mem)) return;
else else
{ {
// Behind the actual pointer data is the allocation info. // Behind the actual pointer data is the allocation info.
MemNode *const mem_node = (MemNode *)((uint8_t *)ptr - sizeof *mem_node); MemNode *const mem_node = (MemNode *)((uint8_t *)ptr - sizeof *mem_node);
const size_t BUCKET_INDEX = (mem_node->size >> MEMPOOL_BUCKET_BITS) - 1; const size_t BUCKET_INDEX = (mem_node->size >> MEMPOOL_BUCKET_BITS) - 1;
// Make sure the pointer data is valid. // Make sure the pointer data is valid.
if (((uintptr_t)mem_node < (uintptr_t)mempool->stack.base) || if (((uintptr_t)mem_node < (uintptr_t)mempool->stack.base) ||
(((uintptr_t)mem_node - (uintptr_t)mempool->stack.mem) > mempool->stack.size) || (((uintptr_t)mem_node - (uintptr_t)mempool->stack.mem) > mempool->stack.size) ||
(mem_node->size == 0UL) || (mem_node->size == 0UL) ||
(mem_node->size > mempool->stack.size)) return; (mem_node->size > mempool->stack.size)) return;
// If the mem_node is right at the stack base ptr, then add it to the stack. // If the mem_node is right at the stack base ptr, then add it to the stack.
else if ((uintptr_t)mem_node == (uintptr_t)mempool->stack.base) else if ((uintptr_t)mem_node == (uintptr_t)mempool->stack.base)
@ -362,13 +362,13 @@ void MemPoolFree(MemPool *const restrict mempool, void *ptr)
else /*if ((mempool->freeList.len == 0UL) || ((uintptr_t)mempool->freeList.head >= (uintptr_t)mempool->stack.mem && (uintptr_t)mempool->freeList.head - (uintptr_t)mempool->stack.mem < mempool->stack.size))*/ else /*if ((mempool->freeList.len == 0UL) || ((uintptr_t)mempool->freeList.head >= (uintptr_t)mempool->stack.mem && (uintptr_t)mempool->freeList.head - (uintptr_t)mempool->stack.mem < mempool->stack.size))*/
{ {
for (MemNode *n = mempool->freeList.head; n != NULL; n = n->next) if (n == mem_node) return; for (MemNode *n = mempool->freeList.head; n != NULL; n = n->next) if (n == mem_node) return;
// This code insertion sorts where largest size is last. // This code insertion sorts where largest size is last.
if (mempool->freeList.head == NULL) if (mempool->freeList.head == NULL)
{ {
mempool->freeList.head = mempool->freeList.tail = mem_node; mempool->freeList.head = mempool->freeList.tail = mem_node;
mempool->freeList.len++; mempool->freeList.len++;
} }
else if (mempool->freeList.head->size >= mem_node->size) else if (mempool->freeList.head->size >= mem_node->size)
{ {
mem_node->next = mempool->freeList.head; mem_node->next = mempool->freeList.head;
@ -383,7 +383,7 @@ void MemPoolFree(MemPool *const restrict mempool, void *ptr)
mempool->freeList.tail = mem_node; mempool->freeList.tail = mem_node;
mempool->freeList.len++; mempool->freeList.len++;
} }
if (mempool->freeList.autoDefrag && (mempool->freeList.maxNodes != 0UL) && (mempool->freeList.len > mempool->freeList.maxNodes)) MemPoolDefrag(mempool); if (mempool->freeList.autoDefrag && (mempool->freeList.maxNodes != 0UL) && (mempool->freeList.len > mempool->freeList.maxNodes)) MemPoolDefrag(mempool);
} }
} }
@ -392,7 +392,7 @@ void MemPoolFree(MemPool *const restrict mempool, void *ptr)
void MemPoolCleanUp(MemPool *const restrict mempool, void **ptrref) void MemPoolCleanUp(MemPool *const restrict mempool, void **ptrref)
{ {
if ((mempool == NULL) || (ptrref == NULL) || (*ptrref == NULL)) return; if ((mempool == NULL) || (ptrref == NULL) || (*ptrref == NULL)) return;
else else
{ {
MemPoolFree(mempool, *ptrref); MemPoolFree(mempool, *ptrref);
*ptrref = NULL; *ptrref = NULL;
@ -402,11 +402,11 @@ void MemPoolCleanUp(MemPool *const restrict mempool, void **ptrref)
size_t GetMemPoolFreeMemory(const MemPool mempool) size_t GetMemPoolFreeMemory(const MemPool mempool)
{ {
size_t total_remaining = (uintptr_t)mempool.stack.base - (uintptr_t)mempool.stack.mem; size_t total_remaining = (uintptr_t)mempool.stack.base - (uintptr_t)mempool.stack.mem;
for (MemNode *n=mempool.freeList.head; n != NULL; n = n->next) total_remaining += n->size; for (MemNode *n=mempool.freeList.head; n != NULL; n = n->next) total_remaining += n->size;
for (size_t i=0; i<MEMPOOL_BUCKET_SIZE; i++) for (MemNode *n = mempool.buckets[i]; n != NULL; n = n->next) total_remaining += n->size; for (size_t i=0; i<MEMPOOL_BUCKET_SIZE; i++) for (MemNode *n = mempool.buckets[i]; n != NULL; n = n->next) total_remaining += n->size;
return total_remaining; return total_remaining;
} }
@ -423,12 +423,12 @@ bool MemPoolDefrag(MemPool *const mempool)
for (size_t i = 0; i < MEMPOOL_BUCKET_SIZE; i++) mempool->buckets[i] = NULL; for (size_t i = 0; i < MEMPOOL_BUCKET_SIZE; i++) mempool->buckets[i] = NULL;
mempool->stack.base = mempool->stack.mem + mempool->stack.size; mempool->stack.base = mempool->stack.mem + mempool->stack.size;
return true; return true;
} }
else else
{ {
for (size_t i=0; i<MEMPOOL_BUCKET_SIZE; i++) for (size_t i=0; i<MEMPOOL_BUCKET_SIZE; i++)
{ {
while (mempool->buckets[i] != NULL) while (mempool->buckets[i] != NULL)
{ {
if ((uintptr_t)mempool->buckets[i] == (uintptr_t)mempool->stack.base) if ((uintptr_t)mempool->buckets[i] == (uintptr_t)mempool->stack.base)
{ {
@ -440,42 +440,42 @@ bool MemPoolDefrag(MemPool *const mempool)
else break; else break;
} }
} }
const size_t PRE_DEFRAG_LEN = mempool->freeList.len; const size_t PRE_DEFRAG_LEN = mempool->freeList.len;
MemNode **node = &mempool->freeList.head; MemNode **node = &mempool->freeList.head;
while (*node != NULL) while (*node != NULL)
{ {
if ((uintptr_t)*node == (uintptr_t)mempool->stack.base) if ((uintptr_t)*node == (uintptr_t)mempool->stack.base)
{ {
// If node is right at the stack, merge it back into the stack. // If node is right at the stack, merge it back into the stack.
mempool->stack.base += (*node)->size; mempool->stack.base += (*node)->size;
(*node)->size = 0UL; (*node)->size = 0UL;
((*node)->prev != NULL)? ((*node)->prev->next = (*node)->next) : (mempool->freeList.head = (*node)->next); ((*node)->prev != NULL)? ((*node)->prev->next = (*node)->next) : (mempool->freeList.head = (*node)->next);
((*node)->next != NULL)? ((*node)->next->prev = (*node)->prev) : (mempool->freeList.tail = (*node)->prev); ((*node)->next != NULL)? ((*node)->next->prev = (*node)->prev) : (mempool->freeList.tail = (*node)->prev);
if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL; if (mempool->freeList.head != NULL) mempool->freeList.head->prev = NULL;
else mempool->freeList.tail = NULL; else mempool->freeList.tail = NULL;
if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL; if (mempool->freeList.tail != NULL) mempool->freeList.tail->next = NULL;
mempool->freeList.len--; mempool->freeList.len--;
node = &mempool->freeList.head; node = &mempool->freeList.head;
} }
else if (((uintptr_t)*node + (*node)->size) == (uintptr_t)(*node)->next) else if (((uintptr_t)*node + (*node)->size) == (uintptr_t)(*node)->next)
{ {
// Next node is at a higher address. // Next node is at a higher address.
(*node)->size += (*node)->next->size; (*node)->size += (*node)->next->size;
(*node)->next->size = 0UL; (*node)->next->size = 0UL;
// <-[P Curr N]-> <-[P Next N]-> <-[P NextNext N]-> // <-[P Curr N]-> <-[P Next N]-> <-[P NextNext N]->
// //
// |--------------------| // |--------------------|
// <-[P Curr N]-> <-[P Next N]-> [P NextNext N]-> // <-[P Curr N]-> <-[P Next N]-> [P NextNext N]->
if ((*node)->next->next != NULL) (*node)->next->next->prev = *node; if ((*node)->next->next != NULL) (*node)->next->next->prev = *node;
// <-[P Curr N]-> <-[P NextNext N]-> // <-[P Curr N]-> <-[P NextNext N]->
(*node)->next = (*node)->next->next; (*node)->next = (*node)->next->next;
mempool->freeList.len--; mempool->freeList.len--;
node = &mempool->freeList.head; node = &mempool->freeList.head;
} }
@ -484,16 +484,16 @@ bool MemPoolDefrag(MemPool *const mempool)
// Prev node is at a higher address. // Prev node is at a higher address.
(*node)->size += (*node)->prev->size; (*node)->size += (*node)->prev->size;
(*node)->prev->size = 0UL; (*node)->prev->size = 0UL;
// <-[P PrevPrev N]-> <-[P Prev N]-> <-[P Curr N]-> // <-[P PrevPrev N]-> <-[P Prev N]-> <-[P Curr N]->
// //
// |--------------------| // |--------------------|
// <-[P PrevPrev N] <-[P Prev N]-> <-[P Curr N]-> // <-[P PrevPrev N] <-[P Prev N]-> <-[P Curr N]->
(*node)->prev->prev->next = *node; (*node)->prev->prev->next = *node;
// <-[P PrevPrev N]-> <-[P Curr N]-> // <-[P PrevPrev N]-> <-[P Curr N]->
(*node)->prev = (*node)->prev->prev; (*node)->prev = (*node)->prev->prev;
mempool->freeList.len--; mempool->freeList.len--;
node = &mempool->freeList.head; node = &mempool->freeList.head;
} }
@ -501,12 +501,12 @@ bool MemPoolDefrag(MemPool *const mempool)
{ {
// Next node is at a lower address. // Next node is at a lower address.
(*node)->next->size += (*node)->size; (*node)->next->size += (*node)->size;
(*node)->size = 0UL; (*node)->size = 0UL;
(*node)->next->prev = (*node)->prev; (*node)->next->prev = (*node)->prev;
(*node)->prev->next = (*node)->next; (*node)->prev->next = (*node)->next;
*node = (*node)->next; *node = (*node)->next;
mempool->freeList.len--; mempool->freeList.len--;
node = &mempool->freeList.head; node = &mempool->freeList.head;
} }
@ -514,21 +514,21 @@ bool MemPoolDefrag(MemPool *const mempool)
{ {
// Prev node is at a lower address. // Prev node is at a lower address.
(*node)->prev->size += (*node)->size; (*node)->prev->size += (*node)->size;
(*node)->size = 0UL; (*node)->size = 0UL;
(*node)->next->prev = (*node)->prev; (*node)->next->prev = (*node)->prev;
(*node)->prev->next = (*node)->next; (*node)->prev->next = (*node)->next;
*node = (*node)->prev; *node = (*node)->prev;
mempool->freeList.len--; mempool->freeList.len--;
node = &mempool->freeList.head; node = &mempool->freeList.head;
} }
else else
{ {
node = &(*node)->next; node = &(*node)->next;
} }
} }
return PRE_DEFRAG_LEN > mempool->freeList.len; return PRE_DEFRAG_LEN > mempool->freeList.len;
} }
} }
@ -551,19 +551,19 @@ union ObjInfo {
ObjPool CreateObjPool(const size_t objsize, const size_t len) ObjPool CreateObjPool(const size_t objsize, const size_t len)
{ {
ObjPool objpool = { 0 }; ObjPool objpool = { 0 };
if ((len == 0UL) || (objsize == 0UL)) return objpool; if ((len == 0UL) || (objsize == 0UL)) return objpool;
else else
{ {
objpool.objSize = __AlignSize(objsize, sizeof(size_t)); objpool.objSize = __AlignSize(objsize, sizeof(size_t));
objpool.stack.size = objpool.freeBlocks = len; objpool.stack.size = objpool.freeBlocks = len;
objpool.stack.mem = calloc(objpool.stack.size, objpool.objSize); objpool.stack.mem = calloc(objpool.stack.size, objpool.objSize);
if (objpool.stack.mem == NULL) if (objpool.stack.mem == NULL)
{ {
objpool.stack.size = 0UL; objpool.stack.size = 0UL;
return objpool; return objpool;
} }
else else
{ {
for (size_t i=0; i<objpool.freeBlocks; i++) for (size_t i=0; i<objpool.freeBlocks; i++)
@ -571,7 +571,7 @@ ObjPool CreateObjPool(const size_t objsize, const size_t len)
union ObjInfo block = { .byte = &objpool.stack.mem[i*objpool.objSize] }; union ObjInfo block = { .byte = &objpool.stack.mem[i*objpool.objSize] };
*block.index = i + 1; *block.index = i + 1;
} }
objpool.stack.base = objpool.stack.mem; objpool.stack.base = objpool.stack.mem;
return objpool; return objpool;
} }
@ -581,7 +581,7 @@ ObjPool CreateObjPool(const size_t objsize, const size_t len)
ObjPool CreateObjPoolFromBuffer(void *const buf, const size_t objsize, const size_t len) ObjPool CreateObjPoolFromBuffer(void *const buf, const size_t objsize, const size_t len)
{ {
ObjPool objpool = { 0 }; ObjPool objpool = { 0 };
// If the object size isn't large enough to align to a size_t, then we can't use it. // If the object size isn't large enough to align to a size_t, then we can't use it.
if ((buf == NULL) || (len == 0UL) || (objsize < sizeof(size_t)) || (objsize*len != __AlignSize(objsize, sizeof(size_t))*len)) return objpool; if ((buf == NULL) || (len == 0UL) || (objsize < sizeof(size_t)) || (objsize*len != __AlignSize(objsize, sizeof(size_t))*len)) return objpool;
else else
@ -589,13 +589,13 @@ ObjPool CreateObjPoolFromBuffer(void *const buf, const size_t objsize, const siz
objpool.objSize = __AlignSize(objsize, sizeof(size_t)); objpool.objSize = __AlignSize(objsize, sizeof(size_t));
objpool.stack.size = objpool.freeBlocks = len; objpool.stack.size = objpool.freeBlocks = len;
objpool.stack.mem = buf; objpool.stack.mem = buf;
for (size_t i=0; i<objpool.freeBlocks; i++) for (size_t i=0; i<objpool.freeBlocks; i++)
{ {
union ObjInfo block = { .byte = &objpool.stack.mem[i*objpool.objSize] }; union ObjInfo block = { .byte = &objpool.stack.mem[i*objpool.objSize] };
*block.index = i + 1; *block.index = i + 1;
} }
objpool.stack.base = objpool.stack.mem; objpool.stack.base = objpool.stack.mem;
return objpool; return objpool;
} }
@ -623,7 +623,7 @@ void *ObjPoolAlloc(ObjPool *const objpool)
// ret = Head == ret = &pool[0]; // ret = Head == ret = &pool[0];
union ObjInfo ret = { .byte = objpool->stack.base }; union ObjInfo ret = { .byte = objpool->stack.base };
objpool->freeBlocks--; objpool->freeBlocks--;
// after allocating, we set head to the address of the index that *Head holds. // after allocating, we set head to the address of the index that *Head holds.
// Head = &pool[*Head * pool.objsize]; // Head = &pool[*Head * pool.objsize];
objpool->stack.base = (objpool->freeBlocks != 0UL)? objpool->stack.mem + (*ret.index*objpool->objSize) : NULL; objpool->stack.base = (objpool->freeBlocks != 0UL)? objpool->stack.mem + (*ret.index*objpool->objSize) : NULL;

View file

@ -95,10 +95,10 @@
// Platform type definitions // Platform type definitions
// From: https://github.com/DFHack/clsocket/blob/master/src/Host.h // From: https://github.com/DFHack/clsocket/blob/master/src/Host.h
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#ifdef WIN32 #ifdef WIN32
typedef int socklen_t; typedef int socklen_t;
#endif #endif
#ifndef RESULT_SUCCESS #ifndef RESULT_SUCCESS
# define RESULT_SUCCESS 0 # define RESULT_SUCCESS 0
@ -171,7 +171,7 @@ typedef int socklen_t;
#define SOCKET_MAX_QUEUE_SIZE (16) // Maximum socket queue size #define SOCKET_MAX_QUEUE_SIZE (16) // Maximum socket queue size
#define SOCKET_MAX_SOCK_OPTS (4) // Maximum socket options #define SOCKET_MAX_SOCK_OPTS (4) // Maximum socket options
#define SOCKET_MAX_UDPCHANNELS (32) // Maximum UDP channels #define SOCKET_MAX_UDPCHANNELS (32) // Maximum UDP channels
#define SOCKET_MAX_UDPADDRESSES (4) // Maximum bound UDP addresses #define SOCKET_MAX_UDPADDRESSES (4) // Maximum bound UDP addresses
// Network address related defines // Network address related defines
@ -386,7 +386,7 @@ int AddSocket(SocketSet *set, Socket *sock);
int RemoveSocket(SocketSet *set, Socket *sock); int RemoveSocket(SocketSet *set, Socket *sock);
int CheckSockets(SocketSet *set, unsigned int timeout); int CheckSockets(SocketSet *set, unsigned int timeout);
// Packet API // Packet API
void PacketSend(Packet *packet); void PacketSend(Packet *packet);
void PacketReceive(Packet *packet); void PacketReceive(Packet *packet);
void PacketWrite8(Packet *packet, uint16_t value); void PacketWrite8(Packet *packet, uint16_t value);

View file

@ -323,7 +323,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCou
{ {
Image atlas = GenImageFontAtlas(font.chars, &font.recs, font.charsCount, font.baseSize, 2, 0); Image atlas = GenImageFontAtlas(font.chars, &font.recs, font.charsCount, font.baseSize, 2, 0);
font.texture = LoadTextureFromImage(atlas); font.texture = LoadTextureFromImage(atlas);
// Update chars[i].image to use alpha, required to be used on ImageDrawText() // Update chars[i].image to use alpha, required to be used on ImageDrawText()
for (int i = 0; i < font.charsCount; i++) for (int i = 0; i < font.charsCount; i++)
{ {
@ -441,7 +441,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
for (int i = 0; i < spriteFont.charsCount; i++) for (int i = 0; i < spriteFont.charsCount; i++)
{ {
spriteFont.chars[i].value = tempCharValues[i]; spriteFont.chars[i].value = tempCharValues[i];
// Get character rectangle in the font atlas texture // Get character rectangle in the font atlas texture
spriteFont.recs[i] = tempCharRecs[i]; spriteFont.recs[i] = tempCharRecs[i];
@ -449,7 +449,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
spriteFont.chars[i].offsetX = 0; spriteFont.chars[i].offsetX = 0;
spriteFont.chars[i].offsetY = 0; spriteFont.chars[i].offsetY = 0;
spriteFont.chars[i].advanceX = 0; spriteFont.chars[i].advanceX = 0;
// Fill character image data from fontClear data // Fill character image data from fontClear data
spriteFont.chars[i].image = ImageFromImage(fontClear, tempCharRecs[i]); spriteFont.chars[i].image = ImageFromImage(fontClear, tempCharRecs[i]);
} }
@ -589,7 +589,7 @@ Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCo
// In case no chars count provided we suppose default of 95 // In case no chars count provided we suppose default of 95
charsCount = (charsCount > 0)? charsCount : 95; charsCount = (charsCount > 0)? charsCount : 95;
// NOTE: Rectangles memory is loaded here! // NOTE: Rectangles memory is loaded here!
Rectangle *recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle)); Rectangle *recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle));
@ -713,7 +713,7 @@ Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCo
RL_FREE(atlas.data); RL_FREE(atlas.data);
atlas.data = dataGrayAlpha; atlas.data = dataGrayAlpha;
atlas.format = UNCOMPRESSED_GRAY_ALPHA; atlas.format = UNCOMPRESSED_GRAY_ALPHA;
*charRecs = recs; *charRecs = recs;
return atlas; return atlas;
@ -761,12 +761,12 @@ void DrawFPS(int posX, int posY)
// Returns next codepoint in a UTF8 encoded text, scanning until '\0' is found // Returns next codepoint in a UTF8 encoded text, scanning until '\0' is found
// When a invalid UTF8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned // When a invalid UTF8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned
// Total number of bytes processed are returned as a parameter // Total number of bytes processed are returned as a parameter
// NOTE: the standard says U+FFFD should be returned in case of errors // NOTE: the standard says U+FFFD should be returned in case of errors
// but that character is not supported by the default font in raylib // but that character is not supported by the default font in raylib
// TODO: optimize this code for speed!! // TODO: optimize this code for speed!!
int GetNextCodepoint(const char *text, int *bytesProcessed) int GetNextCodepoint(const char *text, int *bytesProcessed)
{ {
/* /*
UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt
Char. number range | UTF-8 octet sequence Char. number range | UTF-8 octet sequence
@ -777,26 +777,26 @@ int GetNextCodepoint(const char *text, int *bytesProcessed)
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/ */
// NOTE: on decode errors we return as soon as possible // NOTE: on decode errors we return as soon as possible
int code = 0x3f; // Codepoint (defaults to '?') int code = 0x3f; // Codepoint (defaults to '?')
int octet = (unsigned char)(text[0]); // The first UTF8 octet int octet = (unsigned char)(text[0]); // The first UTF8 octet
*bytesProcessed = 1; *bytesProcessed = 1;
if (octet <= 0x7f) if (octet <= 0x7f)
{ {
// Only one octet (ASCII range x00-7F) // Only one octet (ASCII range x00-7F)
code = text[0]; code = text[0];
} }
else if ((octet & 0xe0) == 0xc0) else if ((octet & 0xe0) == 0xc0)
{ {
// Two octets // Two octets
// [0]xC2-DF [1]UTF8-tail(x80-BF) // [0]xC2-DF [1]UTF8-tail(x80-BF)
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
if ((octet >= 0xc2) && (octet <= 0xdf)) if ((octet >= 0xc2) && (octet <= 0xdf))
{ {
code = ((octet & 0x1f) << 6) | (octet1 & 0x3f); code = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
@ -808,66 +808,66 @@ int GetNextCodepoint(const char *text, int *bytesProcessed)
// Three octets // Three octets
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
unsigned char octet2 = '\0'; unsigned char octet2 = '\0';
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
octet2 = text[2]; octet2 = text[2];
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
/* /*
[0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF) [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF)
[0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF) [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF)
[0]xED [1]x80-9F [2]UTF8-tail(x80-BF) [0]xED [1]x80-9F [2]UTF8-tail(x80-BF)
[0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF) [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF)
*/ */
if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) || if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) ||
((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; } ((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; }
if ((octet >= 0xe0) && (0 <= 0xef)) if ((octet >= 0xe0) && (0 <= 0xef))
{ {
code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f); code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
*bytesProcessed = 3; *bytesProcessed = 3;
} }
} }
else if ((octet & 0xf8) == 0xf0) else if ((octet & 0xf8) == 0xf0)
{ {
// Four octets // Four octets
if (octet > 0xf4) return code; if (octet > 0xf4) return code;
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
unsigned char octet2 = '\0'; unsigned char octet2 = '\0';
unsigned char octet3 = '\0'; unsigned char octet3 = '\0';
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
octet2 = text[2]; octet2 = text[2];
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
octet3 = text[3]; octet3 = text[3];
if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence
/* /*
[0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail
[0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail
[0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail
*/ */
if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) || if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) ||
((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence ((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence
if (octet >= 0xf0) if (octet >= 0xf0)
{ {
code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f); code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
*bytesProcessed = 4; *bytesProcessed = 4;
} }
} }
if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid
return code; return code;
} }
@ -876,7 +876,7 @@ int *GetCodepoints(const char *text, int *count)
{ {
static int codepoints[MAX_TEXT_UNICODE_CHARS] = { 0 }; static int codepoints[MAX_TEXT_UNICODE_CHARS] = { 0 };
memset(codepoints, 0, MAX_TEXT_UNICODE_CHARS*sizeof(int)); memset(codepoints, 0, MAX_TEXT_UNICODE_CHARS*sizeof(int));
int bytesProcessed = 0; int bytesProcessed = 0;
int textLength = strlen(text); int textLength = strlen(text);
int codepointsCount = 0; int codepointsCount = 0;
@ -888,7 +888,7 @@ int *GetCodepoints(const char *text, int *count)
} }
*count = codepointsCount; *count = codepointsCount;
return codepoints; return codepoints;
} }
@ -931,12 +931,12 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
int next = 0; int next = 0;
letter = GetNextCodepoint(&text[i], &next); letter = GetNextCodepoint(&text[i], &next);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set 'next = 1' // but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set 'next = 1'
if (letter == 0x3f) next = 1; if (letter == 0x3f) next = 1;
i += (next - 1); i += (next - 1);
if (letter == '\n') if (letter == '\n')
{ {
// NOTE: Fixed line spacing of 1.5 lines // NOTE: Fixed line spacing of 1.5 lines
@ -984,17 +984,17 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
int startLine = -1; // Index where to begin drawing (where a line begins) int startLine = -1; // Index where to begin drawing (where a line begins)
int endLine = -1; // Index where to stop drawing (where a line ends) int endLine = -1; // Index where to stop drawing (where a line ends)
int lastk = -1; // Holds last value of the character position int lastk = -1; // Holds last value of the character position
for (int i = 0, k = 0; i < length; i++, k++) for (int i = 0, k = 0; i < length; i++, k++)
{ {
int glyphWidth = 0; int glyphWidth = 0;
int next = 0; int next = 0;
letter = GetNextCodepoint(&text[i], &next); letter = GetNextCodepoint(&text[i], &next);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1 // but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1
if (letter == 0x3f) next = 1; if (letter == 0x3f) next = 1;
i += next - 1; i += next - 1;
if (letter != '\n') if (letter != '\n')
@ -1012,7 +1012,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
if (state == MEASURE_STATE) if (state == MEASURE_STATE)
{ {
// TODO: there are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more // TODO: there are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
// See: http://jkorpela.fi/chars/spaces.html // See: http://jkorpela.fi/chars/spaces.html
if ((letter == ' ') || (letter == '\t') || (letter == '\n')) endLine = i; if ((letter == ' ') || (letter == '\t') || (letter == '\n')) endLine = i;
if ((textOffsetX + glyphWidth + 1) >= rec.width) if ((textOffsetX + glyphWidth + 1) >= rec.width)
@ -1037,7 +1037,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
textOffsetX = 0; textOffsetX = 0;
i = startLine; i = startLine;
glyphWidth = 0; glyphWidth = 0;
// Save character position when we switch states // Save character position when we switch states
int tmp = lastk; int tmp = lastk;
lastk = k - 1; lastk = k - 1;
@ -1138,16 +1138,16 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
lenCounter++; lenCounter++;
int next = 0; int next = 0;
letter = GetNextCodepoint(&text[i], &next); letter = GetNextCodepoint(&text[i], &next);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1 // but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1
if (letter == 0x3f) next = 1; if (letter == 0x3f) next = 1;
i += next - 1; i += next - 1;
if (letter != '\n') if (letter != '\n')
{ {
if (font.chars[index].advanceX != 0) textWidth += font.chars[index].advanceX; if (font.chars[index].advanceX != 0) textWidth += font.chars[index].advanceX;
@ -1220,22 +1220,22 @@ unsigned int TextLength(const char *text)
// Returns total number of characters(codepoints) in a UTF8 encoded text, until '\0' is found // Returns total number of characters(codepoints) in a UTF8 encoded text, until '\0' is found
// NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead // NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead
unsigned int TextCountCodepoints(const char *text) unsigned int TextCountCodepoints(const char *text)
{ {
unsigned int len = 0; unsigned int len = 0;
char *ptr = (char *)&text[0]; char *ptr = (char *)&text[0];
while (*ptr != '\0') while (*ptr != '\0')
{ {
int next = 0; int next = 0;
int letter = GetNextCodepoint(ptr, &next); int letter = GetNextCodepoint(ptr, &next);
if (letter == 0x3f) ptr += 1; if (letter == 0x3f) ptr += 1;
else ptr += next; else ptr += next;
len++; len++;
} }
return len; return len;
} }
@ -1362,14 +1362,14 @@ const char *TextJoin(const char **textList, int count, const char *delimiter)
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
int textListLength = strlen(textList[i]); int textListLength = strlen(textList[i]);
// Make sure joined text could fit inside MAX_TEXT_BUFFER_LENGTH // Make sure joined text could fit inside MAX_TEXT_BUFFER_LENGTH
if ((totalLength + textListLength) < MAX_TEXT_BUFFER_LENGTH) if ((totalLength + textListLength) < MAX_TEXT_BUFFER_LENGTH)
{ {
strcat(text, textList[i]); strcat(text, textList[i]);
totalLength += textListLength; totalLength += textListLength;
if ((delimiterLen > 0) && (i < (count - 1))) if ((delimiterLen > 0) && (i < (count - 1)))
{ {
strcat(text, delimiter); strcat(text, delimiter);
totalLength += delimiterLen; totalLength += delimiterLen;
@ -1397,11 +1397,11 @@ const char **TextSplit(const char *text, char delimiter, int *count)
result[0] = buffer; result[0] = buffer;
int counter = 0; int counter = 0;
if (text != NULL) if (text != NULL)
{ {
counter = 1; counter = 1;
// Count how many substrings we have on text and point to every one // Count how many substrings we have on text and point to every one
for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++) for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++)
{ {
@ -1603,7 +1603,7 @@ static Font LoadBMFont(const char *fileName)
ImageAlphaMask(&imFont, imFont); ImageAlphaMask(&imFont, imFont);
for (int p = 0; p < (imFont.width*imFont.height*2); p += 2) ((unsigned char *)(imFont.data))[p] = 0xff; for (int p = 0; p < (imFont.width*imFont.height*2); p += 2) ((unsigned char *)(imFont.data))[p] = 0xff;
} }
font.texture = LoadTextureFromImage(imFont); font.texture = LoadTextureFromImage(imFont);
RL_FREE(texPath); RL_FREE(texPath);
@ -1621,7 +1621,7 @@ static Font LoadBMFont(const char *fileName)
fgets(buffer, MAX_BUFFER_SIZE, fntFile); fgets(buffer, MAX_BUFFER_SIZE, fntFile);
sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i", sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX); &charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX);
// Get character rectangle in the font atlas texture // Get character rectangle in the font atlas texture
font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight }; font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight };
@ -1630,7 +1630,7 @@ static Font LoadBMFont(const char *fileName)
font.chars[i].offsetX = charOffsetX; font.chars[i].offsetX = charOffsetX;
font.chars[i].offsetY = charOffsetY; font.chars[i].offsetY = charOffsetY;
font.chars[i].advanceX = charAdvanceX; font.chars[i].advanceX = charAdvanceX;
// Fill character image data from imFont data // Fill character image data from imFont data
font.chars[i].image = ImageFromImage(imFont, font.recs[i]); font.chars[i].image = ImageFromImage(imFont, font.recs[i]);
} }

View file

@ -850,7 +850,7 @@ void ExportImageAsCode(Image image, const char *fileName)
#define BYTES_TEXT_PER_LINE 20 #define BYTES_TEXT_PER_LINE 20
FILE *txtFile = fopen(fileName, "wt"); FILE *txtFile = fopen(fileName, "wt");
if (txtFile != NULL) if (txtFile != NULL)
{ {
char varFileName[256] = { 0 }; char varFileName[256] = { 0 };
@ -926,11 +926,11 @@ Image ImageCopy(Image image)
Image ImageFromImage(Image image, Rectangle rec) Image ImageFromImage(Image image, Rectangle rec)
{ {
Image result = ImageCopy(image); Image result = ImageCopy(image);
#if defined(SUPPORT_IMAGE_MANIPULATION) #if defined(SUPPORT_IMAGE_MANIPULATION)
ImageCrop(&result, rec); ImageCrop(&result, rec);
#endif #endif
return result; return result;
} }
@ -1189,7 +1189,7 @@ void ImageAlphaMask(Image *image, Image alphaMask)
data[k] = ((unsigned char *)image->data)[i]; data[k] = ((unsigned char *)image->data)[i];
data[k + 1] = ((unsigned char *)mask.data)[i]; data[k + 1] = ((unsigned char *)mask.data)[i];
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = data; image->data = data;
image->format = UNCOMPRESSED_GRAY_ALPHA; image->format = UNCOMPRESSED_GRAY_ALPHA;
@ -1343,13 +1343,13 @@ void ImageCrop(Image *image, Rectangle crop)
{ {
// Security check to avoid program crash // Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
// Security checks to validate crop rectangle // Security checks to validate crop rectangle
if (crop.x < 0) { crop.width += crop.x; crop.x = 0; } if (crop.x < 0) { crop.width += crop.x; crop.x = 0; }
if (crop.y < 0) { crop.height += crop.y; crop.y = 0; } if (crop.y < 0) { crop.height += crop.y; crop.y = 0; }
if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x; if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x;
if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y; if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y;
if ((crop.x < image->width) && (crop.y < image->height)) if ((crop.x < image->width) && (crop.y < image->height))
{ {
// Start the cropping process // Start the cropping process
@ -1823,7 +1823,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
} }
Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
// Crop source image to desired source rectangle (if required) // Crop source image to desired source rectangle (if required)
if ((src.width != (int)srcRec.width) && (src.height != (int)srcRec.height)) ImageCrop(&srcCopy, srcRec); if ((src.width != (int)srcRec.width) && (src.height != (int)srcRec.height)) ImageCrop(&srcCopy, srcRec);
@ -1832,7 +1832,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
{ {
ImageResize(&srcCopy, (int)dstRec.width, (int)dstRec.height); ImageResize(&srcCopy, (int)dstRec.width, (int)dstRec.height);
} }
// Check that dstRec is inside dst image // Check that dstRec is inside dst image
// Allow negative position within destination with cropping // Allow negative position within destination with cropping
if (dstRec.x < 0) if (dstRec.x < 0)
@ -1841,7 +1841,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
dstRec.width = dstRec.width + dstRec.x; dstRec.width = dstRec.width + dstRec.x;
dstRec.x = 0; dstRec.x = 0;
} }
if ((dstRec.x + dstRec.width) > dst->width) if ((dstRec.x + dstRec.width) > dst->width)
{ {
ImageCrop(&srcCopy, (Rectangle) { 0, 0, dst->width - dstRec.x, dstRec.height }); ImageCrop(&srcCopy, (Rectangle) { 0, 0, dst->width - dstRec.x, dstRec.height });
@ -1854,7 +1854,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
dstRec.height = dstRec.height + dstRec.y; dstRec.height = dstRec.height + dstRec.y;
dstRec.y = 0; dstRec.y = 0;
} }
if ((dstRec.y + dstRec.height) > dst->height) if ((dstRec.y + dstRec.height) > dst->height)
{ {
ImageCrop(&srcCopy, (Rectangle) { 0, 0, dstRec.width, dst->height - dstRec.y }); ImageCrop(&srcCopy, (Rectangle) { 0, 0, dstRec.width, dst->height - dstRec.y });
@ -1880,7 +1880,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
fdst = ColorNormalize(dstPixels[j*(int)dst->width + i]); fdst = ColorNormalize(dstPixels[j*(int)dst->width + i]);
fsrc = ColorNormalize(srcPixels[(j - (int)dstRec.y)*(int)dstRec.width + (i - (int)dstRec.x)]); fsrc = ColorNormalize(srcPixels[(j - (int)dstRec.y)*(int)dstRec.width + (i - (int)dstRec.x)]);
// Apply color tint to source image // Apply color tint to source image
fsrc.x *= ftint.x; fsrc.y *= ftint.y; fsrc.z *= ftint.z; fsrc.w *= ftint.w; fsrc.x *= ftint.x; fsrc.y *= ftint.y; fsrc.z *= ftint.z; fsrc.w *= ftint.w;
@ -1943,16 +1943,16 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
// Create image to store text // Create image to store text
Image imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK); Image imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
int next = 0; int next = 0;
letter = GetNextCodepoint(&text[i], &next); letter = GetNextCodepoint(&text[i], &next);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
if (letter == 0x3f) next = 1; if (letter == 0x3f) next = 1;
i += (next - 1); i += (next - 1);
if (letter == '\n') if (letter == '\n')
{ {
// TODO: Support line break // TODO: Support line break
@ -1962,7 +1962,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
if (letter != ' ') if (letter != ' ')
{ {
ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height }, ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height },
(Rectangle){ (float)(positionX + font.chars[index].offsetX),(float)font.chars[index].offsetY, (Rectangle){ (float)(positionX + font.chars[index].offsetX),(float)font.chars[index].offsetY,
font.chars[index].image.width, font.chars[index].image.height }, tint); font.chars[index].image.width, font.chars[index].image.height }, tint);
} }
@ -2717,9 +2717,9 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
{ {
float width = (float)texture.width; float width = (float)texture.width;
float height = (float)texture.height; float height = (float)texture.height;
bool flipX = false; bool flipX = false;
if (sourceRec.width < 0) { flipX = true; sourceRec.width *= -1; } if (sourceRec.width < 0) { flipX = true; sourceRec.width *= -1; }
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height; if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
@ -2981,12 +2981,12 @@ static Image LoadAnimatedGIF(const char *fileName, int *frames, int **delays)
fseek(gifFile, 0L, SEEK_END); fseek(gifFile, 0L, SEEK_END);
int size = ftell(gifFile); int size = ftell(gifFile);
fseek(gifFile, 0L, SEEK_SET); fseek(gifFile, 0L, SEEK_SET);
unsigned char *buffer = (unsigned char *)RL_CALLOC(size, sizeof(char)); unsigned char *buffer = (unsigned char *)RL_CALLOC(size, sizeof(char));
fread(buffer, sizeof(char), size, gifFile); fread(buffer, sizeof(char), size, gifFile);
fclose(gifFile); // Close file pointer fclose(gifFile); // Close file pointer
int comp = 0; int comp = 0;
image.data = stbi_load_gif_from_memory(buffer, size, delays, &image.width, &image.height, frames, &comp, 4); image.data = stbi_load_gif_from_memory(buffer, size, delays, &image.width, &image.height, frames, &comp, 4);

View file

@ -36,7 +36,7 @@
// Some basic Defines // Some basic Defines
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
#define fopen(name, mode) android_fopen(name, mode) #define fopen(name, mode) android_fopen(name, mode)
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -86,8 +86,8 @@ typedef enum {
typedef struct UWPMessage { typedef struct UWPMessage {
UWPMessageType type; // Message type UWPMessageType type; // Message type
Vector2 paramVector0; // Vector parameters Vector2 paramVector0; // Vector parameters
int paramInt0; // Int parameter int paramInt0; // Int parameter
int paramInt1; // Int parameter int paramInt1; // Int parameter
char paramChar0; // Char parameters char paramChar0; // Char parameters