Merge branch 'master' of https://github.com/raysan5/raylib
This commit is contained in:
commit
73d62aab54
1
.github/ISSUE_TEMPLATE/new-issue-template.md
vendored
1
.github/ISSUE_TEMPLATE/new-issue-template.md
vendored
|
|
@ -21,6 +21,7 @@ Please, before submitting a new issue verify and check:
|
|||
|
||||
- [ ] I tested it on latest raylib version from master branch
|
||||
- [ ] I checked there is no similar issue already reported
|
||||
- [ ] I checked the documentation on the [wiki](https://github.com/raysan5/raylib/wiki)
|
||||
- [ ] My code has no errors or misuse of raylib
|
||||
|
||||
### Issue description
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| chez-raylib | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme/) | GPLv3 | https://github.com/Yunoinsky/chez-raylib |
|
||||
| raylib-cr | **4.6-dev (5e1a81)** | [Crystal](https://crystal-lang.org/) | Apache-2.0 | https://github.com/sol-vin/raylib-cr |
|
||||
| ray-cyber | 4.5 | [Cyber](https://cyberscript.dev) | MIT | https://github.com/fubark/ray-cyber |
|
||||
| raylib-c3 | **4.5** | [C3](https://c3-lang.org/) | MIT | https://github.com/Its-Kenta/Raylib-C3 |
|
||||
| raylib-c3 | **4.5** | [C3](https://c3-lang.org/) | Zlib | https://github.com/Its-Kenta/Raylib-C3 |
|
||||
| dart-raylib | 4.0 | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
|
||||
| bindbc-raylib3 | 4.0 | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 |
|
||||
| bindbc-raylib3 | **4.5** | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 |
|
||||
| dray | 4.2 | [D](https://dlang.org/) | Apache-2.0 | https://github.com/redthing1/dray |
|
||||
| raylib-d | **4.5** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d |
|
||||
| dlang_raylib | 4.0 | [D](https://dlang.org) | MPL-2.0 |https://github.com/rc-05/dlang_raylib |
|
||||
|
|
@ -28,7 +28,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib-go | 4.5 | [Go](https://golang.org/) | Zlib | https://github.com/gen2brain/raylib-go |
|
||||
| raylib-guile | **auto** | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile |
|
||||
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib |
|
||||
| h-raylib | **4.5** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib |
|
||||
| h-raylib | **4.6-dev** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib |
|
||||
| raylib-hx | 4.2 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx |
|
||||
| hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib |
|
||||
| jaylib | 4.5 | [Janet](https://janet-lang.org/) | MIT | https://github.com/janet-lang/jaylib |
|
||||
|
|
@ -40,7 +40,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib-lua | **4.5** | [Lua](http://www.lua.org/) | ISC | https://github.com/TSnake41/raylib-lua |
|
||||
| raylua | 4.0 | [Lua](http://www.lua.org/) | MIT | https://github.com/Rabios/raylua |
|
||||
| nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib |
|
||||
| Raylib-Nelua | **4.5-dev** | [nelua](https://nelua.io/) | MIT | https://github.com/Its-Kenta/Raylib-Nelua |
|
||||
| Raylib.nelua | **4.5** | [nelua](https://nelua.io/) | Zlib | https://github.com/Its-Kenta/Raylib-Nelua |
|
||||
| NimraylibNow! | 4.2 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now |
|
||||
| raylib-Forever | auto | [Nim](https://nim-lang.org/) | ? | https://github.com/Guevara-chan/Raylib-Forever |
|
||||
| naylib | auto | [Nim](https://nim-lang.org/) | MIT | https://github.com/planetis-m/naylib |
|
||||
|
|
@ -59,6 +59,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib-php | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php |
|
||||
| raylib-phpcpp | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/oraoto/raylib-phpcpp |
|
||||
| raylibr | 4.0 | [R](https://www.r-project.org) | MIT | https://github.com/jeroenjanssens/raylibr |
|
||||
| raylib-ffi | 4.5 | [Rust](https://www.rust-lang.org/) | GPLv3 | https://github.com/ewpratten/raylib-ffi |
|
||||
| raylib-rs | 3.5 | [Rust](https://www.rust-lang.org/) | Zlib | https://github.com/deltaphc/raylib-rs |
|
||||
| Relib | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | ? | https://github.com/RedCubeDev-ByteSpace/Relib |
|
||||
| racket-raylib | 4.0 | [Racket](https://racket-lang.org/) | MIT/Apache-2.0 | https://github.com/eutro/racket-raylib |
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures"
|
|||
cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FONT_ATLAS_WHITE_REC "Support white rec on font atlas bottom-right corner" ON CUSTOMIZE_BUILD ON)
|
||||
|
||||
# rmodels.c
|
||||
cmake_dependent_option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON CUSTOMIZE_BUILD ON)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ elseif ("${PLATFORM}" MATCHES "DRM")
|
|||
|
||||
endif ()
|
||||
|
||||
if (NOT ${OPENGL_VERSION})
|
||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
||||
if (${OPENGL_VERSION} MATCHES "4.3")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_43")
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ CORE = \
|
|||
core/core_input_gamepad \
|
||||
core/core_input_multitouch \
|
||||
core/core_input_gestures \
|
||||
core/core_input_gestures_web \
|
||||
core/core_2d_camera \
|
||||
core/core_2d_camera_platformer \
|
||||
core/core_2d_camera_mouse_zoom \
|
||||
|
|
@ -536,12 +537,20 @@ AUDIO = \
|
|||
audio/audio_stream_effects \
|
||||
audio/audio_mixed_processor
|
||||
|
||||
OTHERS = \
|
||||
others/easings_testbed \
|
||||
others/embedded_files_loading \
|
||||
others/raylib_opengl_interop \
|
||||
others/raymath_vector_angle \
|
||||
others/rlgl_compute_shader \
|
||||
others/rlgl_standalone
|
||||
|
||||
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
# Define processes to execute
|
||||
#------------------------------------------------------------------------------------------------
|
||||
# Default target entry
|
||||
all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO)
|
||||
all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO) $(OTHERS)
|
||||
|
||||
core: $(CORE)
|
||||
shapes: $(SHAPES)
|
||||
|
|
@ -550,6 +559,7 @@ text: $(TEXT)
|
|||
models: $(MODELS)
|
||||
shaders: $(SHADERS)
|
||||
audio: $(AUDIO)
|
||||
others: $(OTHERS)
|
||||
|
||||
# Generic compilation pattern
|
||||
# NOTE: Examples must be ready for Android compilation!
|
||||
|
|
|
|||
|
|
@ -386,6 +386,7 @@ CORE = \
|
|||
core/core_input_gamepad \
|
||||
core/core_input_multitouch \
|
||||
core/core_input_gestures \
|
||||
core/core_input_gestures_web \
|
||||
core/core_2d_camera \
|
||||
core/core_2d_camera_platformer \
|
||||
core/core_2d_camera_mouse_zoom \
|
||||
|
|
@ -558,6 +559,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
|
|||
core/core_input_gestures: core/core_input_gestures.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_input_gestures_web: core/core_input_gestures_web.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_2d_camera: core/core_2d_camera.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
|
|
|
|||
338
examples/core/core_input_gestures_web.c
Normal file
338
examples/core/core_input_gestures_web.c
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Input Gestures for Web
|
||||
*
|
||||
* Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev
|
||||
*
|
||||
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 ubkp (@ubkp)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "math.h" // Required for the protractor angle graphic drawing
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h> // Required for the Web/HTML5
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global definitions and declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Common variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800; // Update depending on web canvas
|
||||
const int screenHeight = 450;
|
||||
Vector2 messagePosition = { 160, 7 };
|
||||
|
||||
// Last gesture variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
int lastGesture = 0;
|
||||
Vector2 lastGesturePosition = { 165, 130 };
|
||||
|
||||
// Gesture log variables definitions and functions declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define GESTURE_LOG_SIZE 20
|
||||
char gestureLog[GESTURE_LOG_SIZE][12] = { "" }; // The gesture log uses an array (as an inverted circular queue) to store the performed gestures
|
||||
int gestureLogIndex = GESTURE_LOG_SIZE; // The index for the inverted circular queue (moving from last to first direction, then looping around)
|
||||
int previousGesture = 0;
|
||||
|
||||
char const *GetGestureName(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return "None"; break;
|
||||
case 1: return "Tap"; break;
|
||||
case 2: return "Double Tap"; break;
|
||||
case 4: return "Hold"; break;
|
||||
case 8: return "Drag"; break;
|
||||
case 16: return "Swipe Right"; break;
|
||||
case 32: return "Swipe Left"; break;
|
||||
case 64: return "Swipe Up"; break;
|
||||
case 128: return "Swipe Down"; break;
|
||||
case 256: return "Pinch In"; break;
|
||||
case 512: return "Pinch Out"; break;
|
||||
default: return "Unknown"; break;
|
||||
}
|
||||
}
|
||||
|
||||
Color GetGestureColor(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return BLACK; break;
|
||||
case 1: return BLUE; break;
|
||||
case 2: return SKYBLUE; break;
|
||||
case 4: return BLACK; break;
|
||||
case 8: return LIME; break;
|
||||
case 16: return RED; break;
|
||||
case 32: return RED; break;
|
||||
case 64: return RED; break;
|
||||
case 128: return RED; break;
|
||||
case 256: return VIOLET; break;
|
||||
case 512: return ORANGE; break;
|
||||
default: return BLACK; break;
|
||||
}
|
||||
}
|
||||
|
||||
int logMode = 1; // Log mode values: 0 shows repeated events; 1 hides repeated events; 2 shows repeated events but hide hold events; 3 hides repeated events and hide hold events
|
||||
|
||||
Color gestureColor = { 0, 0, 0, 255 };
|
||||
Rectangle logButton1 = { 53, 7, 48, 26 };
|
||||
Rectangle logButton2 = { 108, 7, 36, 26 };
|
||||
Vector2 gestureLogPosition = { 10, 10 };
|
||||
|
||||
// Protractor variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
float angleLength = 90.0f;
|
||||
float currentAngleDegrees = 0.0f;
|
||||
Vector2 finalVector = { 0.0f, 0.0f };
|
||||
char currentAngleStr[7] = "";
|
||||
Vector2 protractorPosition = { 266.0f, 315.0f };
|
||||
|
||||
// Update
|
||||
//--------------------------------------------------------------------------------------
|
||||
void Update(void)
|
||||
{
|
||||
// Handle common
|
||||
//--------------------------------------------------------------------------------------
|
||||
int i, ii; // Iterators that will be reused by all for loops
|
||||
const int currentGesture = GetGestureDetected();
|
||||
const float currentDragDegrees = GetGestureDragAngle();
|
||||
const float currentPitchDegrees = GetGesturePinchAngle();
|
||||
const int touchCount = GetTouchPointCount();
|
||||
|
||||
// Handle last gesture
|
||||
//--------------------------------------------------------------------------------------
|
||||
if ((currentGesture != 0) && (currentGesture != 4) && (currentGesture != previousGesture)) lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
|
||||
|
||||
// Handle gesture log
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode=2; break;
|
||||
case 2: logMode=3; break;
|
||||
case 1: logMode=0; break;
|
||||
default: logMode=1; break;
|
||||
}
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode=1; break;
|
||||
case 2: logMode=0; break;
|
||||
case 1: logMode=3; break;
|
||||
default: logMode=2; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
|
||||
if (currentGesture !=0)
|
||||
{
|
||||
if (logMode == 3) // 3 hides repeated events and hide hold events
|
||||
{
|
||||
if (((currentGesture != 4) && (currentGesture != previousGesture)) || (currentGesture < 3)) fillLog = 1;
|
||||
}
|
||||
else if (logMode == 2) // 2 shows repeated events but hide hold events
|
||||
{
|
||||
if (currentGesture != 4) fillLog = 1;
|
||||
}
|
||||
else if (logMode == 1) // 1 hides repeated events
|
||||
{
|
||||
if (currentGesture != previousGesture) fillLog = 1;
|
||||
}
|
||||
else // 0 shows repeated events
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillLog) // If one of the conditions from logMode was met, fill the gesture log
|
||||
{
|
||||
previousGesture = currentGesture;
|
||||
gestureColor = GetGestureColor(currentGesture);
|
||||
if (gestureLogIndex <= 0) gestureLogIndex = GESTURE_LOG_SIZE;
|
||||
gestureLogIndex--;
|
||||
|
||||
// Copy the gesture respective name to the gesture log array
|
||||
TextCopy(gestureLog[gestureLogIndex], GetGestureName(currentGesture));
|
||||
}
|
||||
|
||||
// Handle protractor
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (currentGesture > 255) // aka Pinch In and Pinch Out
|
||||
{
|
||||
currentAngleDegrees = currentPitchDegrees;
|
||||
}
|
||||
else if (currentGesture > 15) // aka Swipe Right, Swipe Left, Swipe Up and Swipe Down
|
||||
{
|
||||
currentAngleDegrees = currentDragDegrees;
|
||||
}
|
||||
else if (currentGesture > 0) // aka Tap, Doubletap, Hold and Grab
|
||||
{
|
||||
currentAngleDegrees = 0.0f;
|
||||
}
|
||||
|
||||
float currentAngleRadians = ((currentAngleDegrees +90.0f)*PI/180); // Convert the current angle to Radians
|
||||
finalVector = (Vector2){ (angleLength*sinf(currentAngleRadians)) + protractorPosition.x, (angleLength*cosf(currentAngleRadians)) + protractorPosition.y }; // Calculate the final vector for display
|
||||
|
||||
// Handle touch and mouse pointer points
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define MAX_TOUCH_COUNT 32
|
||||
|
||||
Vector2 touchPosition[MAX_TOUCH_COUNT] = { 0 };
|
||||
Vector2 mousePosition = {0, 0};
|
||||
if (currentGesture != GESTURE_NONE)
|
||||
{
|
||||
if (touchCount != 0)
|
||||
{
|
||||
for (i = 0; i < touchCount; i++) touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
|
||||
}
|
||||
else mousePosition = GetMousePosition();
|
||||
}
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw common
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
|
||||
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
|
||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
|
||||
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
|
||||
|
||||
// Draw last gesture
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
|
||||
DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
|
||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
|
||||
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||
for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
|
||||
|
||||
// Draw gesture log
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Log", gestureLogPosition.x, gestureLogPosition.y, 20, BLACK);
|
||||
|
||||
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
||||
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
||||
Color logButton1Color, logButton2Color;
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logButton1Color=MAROON; logButton2Color=MAROON; break;
|
||||
case 2: logButton1Color=GRAY; logButton2Color=MAROON; break;
|
||||
case 1: logButton1Color=MAROON; logButton2Color=GRAY; break;
|
||||
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
|
||||
}
|
||||
DrawRectangleRec(logButton1, logButton1Color);
|
||||
DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
|
||||
DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
|
||||
DrawRectangleRec(logButton2, logButton2Color);
|
||||
DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
|
||||
DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
|
||||
|
||||
// Draw protractor
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
|
||||
const char *angleString = TextFormat("%f", currentAngleDegrees);
|
||||
const int angleStringDot = TextFindIndex(angleString, ".");
|
||||
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
|
||||
DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
|
||||
DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
|
||||
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
|
||||
DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
|
||||
DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
|
||||
DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
|
||||
DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
|
||||
DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
|
||||
DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
|
||||
DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
|
||||
DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
|
||||
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
|
||||
|
||||
// Draw touch and mouse pointer points
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (currentGesture != GESTURE_NONE)
|
||||
{
|
||||
if ( touchCount != 0 )
|
||||
{
|
||||
for (i = 0; i < touchCount; i++)
|
||||
{
|
||||
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
|
||||
}
|
||||
|
||||
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(mousePosition, 5.0f, gestureColor);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
#if defined( PLATFORM_WEB )
|
||||
// Using Emscripten EM_ASM_INT macro, get the page canvas width
|
||||
const int canvasWidth = EM_ASM_INT( return document.getElementById('canvas').getBoundingClientRect().width; );
|
||||
|
||||
if (canvasWidth > 400) screenWidth = canvasWidth;
|
||||
else screenWidth = 400; // Set a minimum width for the screen
|
||||
#endif
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures web");
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
//--------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(Update, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60);
|
||||
while (!WindowShouldClose()) Update(); // Detect window close button or ESC key
|
||||
#endif
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/core/core_input_gestures_web.png
Normal file
BIN
examples/core/core_input_gestures_web.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
|
|
@ -41,7 +41,7 @@
|
|||
*
|
||||
* raylib [core] example - Basic window
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||
*
|
||||
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
|
|
|||
106
examples/others/raymath_vector_angle.c
Normal file
106
examples/others/raymath_vector_angle.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Vector Angle
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [math] example - vector angle");
|
||||
|
||||
Vector2 v0 = { screenWidth/2, screenHeight/2 };
|
||||
Vector2 v1 = { 100.0f, 80.0f };
|
||||
Vector2 v2 = { 0 }; // Updated with mouse position
|
||||
|
||||
float angle = 0.0f; // Angle in degrees
|
||||
int angleMode = 0; // 0-Vector2Angle(), 1-Vector2LineAngle()
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) angleMode = !angleMode;
|
||||
|
||||
if (angleMode == 0)
|
||||
{
|
||||
// Calculate angle between two vectors, considering a common origin (v0)
|
||||
v1 = Vector2Add(v0, (Vector2){ 100.0f, 80.0f });
|
||||
v2 = GetMousePosition();
|
||||
angle = Vector2Angle(Vector2Normalize(Vector2Subtract(v1, v0)), Vector2Normalize(Vector2Subtract(v2, v0)))*RAD2DEG;
|
||||
}
|
||||
else if (angleMode == 1)
|
||||
{
|
||||
// Calculate angle defined by a two vectors line, in reference to horizontal line
|
||||
v1 = (Vector2){ screenWidth/2, screenHeight/2 };
|
||||
v2 = GetMousePosition();
|
||||
angle = Vector2LineAngle(v1, v2)*RAD2DEG;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (angleMode == 0) DrawText("v0", v0.x, v0.y, 10, DARKGRAY);
|
||||
DrawText("v1", v1.x, v1.y, 10, DARKGRAY);
|
||||
DrawText("v2", v2.x, v2.y, 10, DARKGRAY);
|
||||
|
||||
if (angleMode == 0)
|
||||
{
|
||||
DrawText("MODE: Angle between V1 and V2", 10, 10, 20, BLACK);
|
||||
|
||||
DrawLineEx(v0, v1, 2.0f, BLACK);
|
||||
DrawLineEx(v0, v2, 2.0f, RED);
|
||||
|
||||
float startangle = 90 - Vector2LineAngle(v0, v1)*RAD2DEG;
|
||||
DrawCircleSector(v0, 40.0f, startangle, startangle + angle - 360.0f*(angle > 180.0f), 32, Fade(GREEN, 0.6f));
|
||||
}
|
||||
else if (angleMode == 1)
|
||||
{
|
||||
DrawText("MODE: Angle formed by line V1 to V2", 10, 10, 20, BLACK);
|
||||
|
||||
DrawLine(0, screenHeight/2, screenWidth, screenHeight/2, LIGHTGRAY);
|
||||
DrawLineEx(v1, v2, 2.0f, RED);
|
||||
|
||||
DrawCircleSector(v1, 40.0f, 90.0f, 180 - angle - 90, 32, Fade(GREEN, 0.6f));
|
||||
}
|
||||
|
||||
DrawText("Press SPACE to change MODE", 460, 10, 20, DARKGRAY);
|
||||
DrawText(TextFormat("ANGLE: %2.2f", angle), 10, 40, 20, LIME);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/others/raymath_vector_angle.png
Normal file
BIN
examples/others/raymath_vector_angle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -181,6 +181,11 @@
|
|||
// If not defined, still some functions are supported: TextLength(), TextFormat()
|
||||
#define SUPPORT_TEXT_MANIPULATION 1
|
||||
|
||||
// On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle
|
||||
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
||||
// drawing text and shapes with a single draw call [SetShapesTexture()].
|
||||
#define SUPPORT_FONT_ATLAS_WHITE_REC 1
|
||||
|
||||
// rtext: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
||||
|
|
|
|||
195
src/external/sdefl.h
vendored
195
src/external/sdefl.h
vendored
|
|
@ -71,7 +71,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
|
|||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2020 Micha Mettke
|
||||
Copyright (c) 2020-2023 Micha Mettke
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
|
|
@ -125,7 +125,7 @@ extern "C" {
|
|||
|
||||
#define SDEFL_MIN_MATCH 4
|
||||
#define SDEFL_BLK_MAX (256*1024)
|
||||
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX + SDEFL_MIN_MATCH)/SDEFL_MIN_MATCH)
|
||||
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX+2)/3)
|
||||
|
||||
#define SDEFL_SYM_MAX (288)
|
||||
#define SDEFL_OFF_MAX (32)
|
||||
|
|
@ -185,6 +185,7 @@ extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
|
|||
#define SDEFL_MAX_CODE_LEN (15)
|
||||
#define SDEFL_SYM_BITS (10u)
|
||||
#define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
|
||||
#define SDEFL_RAW_BLK_SIZE (65535)
|
||||
#define SDEFL_LIT_LEN_CODES (14)
|
||||
#define SDEFL_OFF_CODES (15)
|
||||
#define SDEFL_PRE_CODES (7)
|
||||
|
|
@ -192,6 +193,7 @@ extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
|
|||
#define SDEFL_EOB (256)
|
||||
|
||||
#define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
|
||||
#define sdefl_div_round_up(n,d) (((n)+((d)-1))/(d))
|
||||
|
||||
static int
|
||||
sdefl_ilog2(int n) {
|
||||
|
|
@ -438,12 +440,12 @@ sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
|
|||
} while (run_start != total);
|
||||
cnt->items = (int)(at - items);
|
||||
}
|
||||
struct sdefl_match_codes {
|
||||
struct sdefl_match_codest {
|
||||
int ls, lc;
|
||||
int dc, dx;
|
||||
};
|
||||
static void
|
||||
sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
|
||||
sdefl_match_codes(struct sdefl_match_codest *cod, int dist, int len) {
|
||||
static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
|
||||
static const unsigned char lslot[258+1] = {
|
||||
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
|
||||
|
|
@ -471,6 +473,44 @@ sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
|
|||
cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
|
||||
cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
|
||||
}
|
||||
enum sdefl_blk_type {
|
||||
SDEFL_BLK_UCOMPR,
|
||||
SDEFL_BLK_DYN
|
||||
};
|
||||
static enum sdefl_blk_type
|
||||
sdefl_blk_type(const struct sdefl *s, int blk_len, int pre_item_len,
|
||||
const unsigned *pre_freq, const unsigned char *pre_len) {
|
||||
static const unsigned char x_pre_bits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
|
||||
static const unsigned char x_len_bits[] = {0,0,0,0,0,0,0,0, 1,1,1,1,2,2,2,2,
|
||||
3,3,3,3,4,4,4,4, 5,5,5,5,0};
|
||||
static const unsigned char x_off_bits[] = {0,0,0,0,1,1,2,2, 3,3,4,4,5,5,6,6,
|
||||
7,7,8,8,9,9,10,10, 11,11,12,12,13,13};
|
||||
|
||||
int dyn_cost = 0;
|
||||
int fix_cost = 0;
|
||||
int sym = 0;
|
||||
|
||||
dyn_cost += 5 + 5 + 4 + (3 * pre_item_len);
|
||||
for (sym = 0; sym < SDEFL_PRE_MAX; sym++)
|
||||
dyn_cost += pre_freq[sym] * (x_pre_bits[sym] + pre_len[sym]);
|
||||
for (sym = 0; sym < 256; sym++)
|
||||
dyn_cost += s->freq.lit[sym] * s->cod.len.lit[sym];
|
||||
dyn_cost += s->cod.len.lit[SDEFL_EOB];
|
||||
for (sym = 257; sym < 286; sym++)
|
||||
dyn_cost += s->freq.lit[sym] * (x_len_bits[sym - 257] + s->cod.len.lit[sym]);
|
||||
for (sym = 0; sym < 30; sym++)
|
||||
dyn_cost += s->freq.off[sym] * (x_off_bits[sym] + s->cod.len.off[sym]);
|
||||
|
||||
fix_cost += 8*(5 * sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE) + blk_len + 1 + 2);
|
||||
return (dyn_cost < fix_cost) ? SDEFL_BLK_DYN : SDEFL_BLK_UCOMPR;
|
||||
}
|
||||
static void
|
||||
sdefl_put16(unsigned char **dst, unsigned short x) {
|
||||
unsigned char *val = *dst;
|
||||
val[0] = (unsigned char)(x & 0xff);
|
||||
val[1] = (unsigned char)(x >> 8);
|
||||
*dst = val + 2;
|
||||
}
|
||||
static void
|
||||
sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
|
||||
static const char lxn[] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
|
||||
|
|
@ -479,7 +519,7 @@ sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
|
|||
static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
|
||||
385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
|
||||
|
||||
struct sdefl_match_codes cod;
|
||||
struct sdefl_match_codest cod;
|
||||
sdefl_match_codes(&cod, dist, len);
|
||||
sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
|
||||
sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
|
||||
|
|
@ -488,7 +528,8 @@ sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
|
|||
}
|
||||
static void
|
||||
sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
|
||||
const unsigned char *in) {
|
||||
const unsigned char *in, int blk_begin, int blk_end) {
|
||||
int blk_len = blk_end - blk_begin;
|
||||
int j, i = 0, item_cnt = 0;
|
||||
struct sdefl_symcnt symcnt = {0};
|
||||
unsigned codes[SDEFL_PRE_MAX];
|
||||
|
|
@ -498,7 +539,7 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
|
|||
static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
|
||||
4,12,3,13,2,14,1,15};
|
||||
|
||||
/* huffman codes */
|
||||
/* calculate huffman codes */
|
||||
s->freq.lit[SDEFL_EOB]++;
|
||||
sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
|
||||
sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
|
||||
|
|
@ -509,35 +550,58 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* block header */
|
||||
sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */
|
||||
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
|
||||
sdefl_put(dst, s, symcnt.lit - 257, 5);
|
||||
sdefl_put(dst, s, symcnt.off - 1, 5);
|
||||
sdefl_put(dst, s, item_cnt - 4, 4);
|
||||
for (i = 0; i < item_cnt; ++i) {
|
||||
sdefl_put(dst, s, lens[perm[i]], 3);
|
||||
}
|
||||
for (i = 0; i < symcnt.items; ++i) {
|
||||
unsigned sym = items[i] & 0x1F;
|
||||
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
|
||||
if (sym < 16) continue;
|
||||
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
|
||||
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
|
||||
else sdefl_put(dst, s, items[i] >> 5, 7);
|
||||
}
|
||||
/* block sequences */
|
||||
for (i = 0; i < s->seq_cnt; ++i) {
|
||||
if (s->seq[i].off >= 0) {
|
||||
for (j = 0; j < s->seq[i].len; ++j) {
|
||||
int c = in[s->seq[i].off + j];
|
||||
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
|
||||
/* write block */
|
||||
switch (sdefl_blk_type(s, blk_len, item_cnt, freqs, lens)) {
|
||||
case SDEFL_BLK_UCOMPR: {
|
||||
/* uncompressed blocks */
|
||||
int n = sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE);
|
||||
for (i = 0; i < n; ++i) {
|
||||
int fin = is_last && (i + 1 == n);
|
||||
int amount = blk_len < SDEFL_RAW_BLK_SIZE ? blk_len : SDEFL_RAW_BLK_SIZE;
|
||||
sdefl_put(dst, s, !!fin, 1); /* block */
|
||||
sdefl_put(dst, s, 0x00, 2); /* stored block */
|
||||
if (s->bitcnt) {
|
||||
sdefl_put(dst, s, 0x00, 8 - s->bitcnt);
|
||||
}
|
||||
} else {
|
||||
sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
|
||||
assert(s->bitcnt == 0);
|
||||
sdefl_put16(dst, (unsigned short)amount);
|
||||
sdefl_put16(dst, ~(unsigned short)amount);
|
||||
memcpy(*dst, in + blk_begin + i * SDEFL_RAW_BLK_SIZE, amount);
|
||||
*dst = *dst + amount;
|
||||
blk_len -= amount;
|
||||
}
|
||||
}
|
||||
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
|
||||
} break;
|
||||
case SDEFL_BLK_DYN: {
|
||||
/* dynamic huffman block */
|
||||
sdefl_put(dst, s, !!is_last, 1); /* block */
|
||||
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
|
||||
sdefl_put(dst, s, symcnt.lit - 257, 5);
|
||||
sdefl_put(dst, s, symcnt.off - 1, 5);
|
||||
sdefl_put(dst, s, item_cnt - 4, 4);
|
||||
for (i = 0; i < item_cnt; ++i) {
|
||||
sdefl_put(dst, s, lens[perm[i]], 3);
|
||||
}
|
||||
for (i = 0; i < symcnt.items; ++i) {
|
||||
unsigned sym = items[i] & 0x1F;
|
||||
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
|
||||
if (sym < 16) continue;
|
||||
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
|
||||
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
|
||||
else sdefl_put(dst, s, items[i] >> 5, 7);
|
||||
}
|
||||
/* block sequences */
|
||||
for (i = 0; i < s->seq_cnt; ++i) {
|
||||
if (s->seq[i].off >= 0) {
|
||||
for (j = 0; j < s->seq[i].len; ++j) {
|
||||
int c = in[s->seq[i].off + j];
|
||||
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
|
||||
}
|
||||
} else {
|
||||
sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
|
||||
}
|
||||
}
|
||||
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
|
||||
} break;}
|
||||
memset(&s->freq, 0, sizeof(s->freq));
|
||||
s->seq_cnt = 0;
|
||||
}
|
||||
|
|
@ -550,8 +614,12 @@ sdefl_seq(struct sdefl *s, int off, int len) {
|
|||
}
|
||||
static void
|
||||
sdefl_reg_match(struct sdefl *s, int off, int len) {
|
||||
struct sdefl_match_codes cod;
|
||||
struct sdefl_match_codest cod;
|
||||
sdefl_match_codes(&cod, off, len);
|
||||
|
||||
assert(cod.lc < SDEFL_SYM_MAX);
|
||||
assert(cod.dc < SDEFL_OFF_MAX);
|
||||
|
||||
s->freq.lit[cod.lc]++;
|
||||
s->freq.off[cod.dc]++;
|
||||
}
|
||||
|
|
@ -560,22 +628,35 @@ struct sdefl_match {
|
|||
int len;
|
||||
};
|
||||
static void
|
||||
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s,
|
||||
int chain_len, int max_match, const unsigned char *in, int p) {
|
||||
int i = s->tbl[sdefl_hash32(&in[p])];
|
||||
int limit = ((p-SDEFL_WIN_SIZ)<SDEFL_NIL)?SDEFL_NIL:(p-SDEFL_WIN_SIZ);
|
||||
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s, int chain_len,
|
||||
int max_match, const unsigned char *in, int p, int e) {
|
||||
int i = s->tbl[sdefl_hash32(in + p)];
|
||||
int limit = ((p - SDEFL_WIN_SIZ) < SDEFL_NIL) ? SDEFL_NIL : (p-SDEFL_WIN_SIZ);
|
||||
|
||||
assert(p < e);
|
||||
assert(p + max_match <= e);
|
||||
while (i > limit) {
|
||||
if (in[i+m->len] == in[p+m->len] &&
|
||||
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))){
|
||||
assert(i + m->len < e);
|
||||
assert(p + m->len < e);
|
||||
assert(i + SDEFL_MIN_MATCH < e);
|
||||
assert(p + SDEFL_MIN_MATCH < e);
|
||||
|
||||
if (in[i + m->len] == in[p + m->len] &&
|
||||
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))) {
|
||||
int n = SDEFL_MIN_MATCH;
|
||||
while (n < max_match && in[i+n] == in[p+n]) n++;
|
||||
while (n < max_match && in[i + n] == in[p + n]) {
|
||||
assert(i + n < e);
|
||||
assert(p + n < e);
|
||||
n++;
|
||||
}
|
||||
if (n > m->len) {
|
||||
m->len = n, m->off = p - i;
|
||||
if (n == max_match) break;
|
||||
if (n == max_match)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(--chain_len)) break;
|
||||
i = s->prv[i&SDEFL_WIN_MSK];
|
||||
i = s->prv[i & SDEFL_WIN_MSK];
|
||||
}
|
||||
}
|
||||
static int
|
||||
|
|
@ -588,19 +669,20 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
|
|||
for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
|
||||
s->tbl[n] = SDEFL_NIL;
|
||||
}
|
||||
do {int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
|
||||
do {int blk_begin = i;
|
||||
int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
|
||||
while (i < blk_end) {
|
||||
struct sdefl_match m = {0};
|
||||
int left = blk_end - i;
|
||||
int max_match = (left >= SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
|
||||
int max_match = (left > SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
|
||||
int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
|
||||
int run = 1, inc = 1, run_inc = 0;
|
||||
if (max_match > SDEFL_MIN_MATCH) {
|
||||
sdefl_fnd(&m, s, max_chain, max_match, in, i);
|
||||
sdefl_fnd(&m, s, max_chain, max_match, in, i, in_len);
|
||||
}
|
||||
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len < nice_match){
|
||||
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len + 1 < nice_match){
|
||||
struct sdefl_match m2 = {0};
|
||||
sdefl_fnd(&m2, s, max_chain, m.len+1, in, i+1);
|
||||
sdefl_fnd(&m2, s, max_chain, m.len + 1, in, i + 1, in_len);
|
||||
m.len = (m2.len > m.len) ? 0 : m.len;
|
||||
}
|
||||
if (m.len >= SDEFL_MIN_MATCH) {
|
||||
|
|
@ -636,12 +718,12 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
|
|||
sdefl_seq(s, i - litlen, litlen);
|
||||
litlen = 0;
|
||||
}
|
||||
sdefl_flush(&q, s, blk_end == in_len, in);
|
||||
sdefl_flush(&q, s, blk_end == in_len, in, blk_begin, blk_end);
|
||||
} while (i < in_len);
|
||||
|
||||
if (s->bitcnt > 0)
|
||||
if (s->bitcnt) {
|
||||
sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
|
||||
|
||||
}
|
||||
assert(s->bitcnt == 0);
|
||||
return (int)(q - out);
|
||||
}
|
||||
extern int
|
||||
|
|
@ -701,9 +783,8 @@ zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
|
|||
}
|
||||
extern int
|
||||
sdefl_bound(int len) {
|
||||
int a = 128 + (len * 110) / 100;
|
||||
int b = 128 + len + ((len / (31 * 1024)) + 1) * 5;
|
||||
return (a > b) ? a : b;
|
||||
int max_blocks = 1 + sdefl_div_round_up(len, SDEFL_RAW_BLK_SIZE);
|
||||
int bound = 5 * max_blocks + len + 1 + 4 + 8;
|
||||
return bound;
|
||||
}
|
||||
#endif /* SDEFL_IMPLEMENTATION */
|
||||
|
||||
|
|
|
|||
28
src/external/sinfl.h
vendored
28
src/external/sinfl.h
vendored
|
|
@ -72,7 +72,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
|
|||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2020 Micha Mettke
|
||||
Copyright (c) 2020-2023 Micha Mettke
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
|
|
@ -400,17 +400,21 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
|
|||
} break;
|
||||
case stored: {
|
||||
/* uncompressed block */
|
||||
int len, nlen;
|
||||
sinfl_refill(&s);
|
||||
unsigned len, nlen;
|
||||
sinfl__get(&s,s.bitcnt & 7);
|
||||
len = sinfl__get(&s,16);
|
||||
nlen = sinfl__get(&s,16);
|
||||
in -= 2; s.bitcnt = 0;
|
||||
len = (unsigned short)sinfl__get(&s,16);
|
||||
nlen = (unsigned short)sinfl__get(&s,16);
|
||||
s.bitptr -= s.bitcnt / 8;
|
||||
s.bitbuf = s.bitcnt = 0;
|
||||
|
||||
if (len > (e-in) || !len)
|
||||
if ((unsigned short)len != (unsigned short)~nlen)
|
||||
return (int)(out-o);
|
||||
memcpy(out, in, (size_t)len);
|
||||
in += len, out += len;
|
||||
if (len > (e - s.bitptr) || !len)
|
||||
return (int)(out-o);
|
||||
|
||||
memcpy(out, s.bitptr, (size_t)len);
|
||||
s.bitptr += len, out += len;
|
||||
if (last) return (int)(out-o);
|
||||
state = hdr;
|
||||
} break;
|
||||
case fixed: {
|
||||
|
|
@ -443,8 +447,9 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
|
|||
|
||||
/* decode code lengths */
|
||||
for (n = 0; n < nlit + ndist;) {
|
||||
int sym = 0;
|
||||
sinfl_refill(&s);
|
||||
int sym = sinfl_decode(&s, hlens, 7);
|
||||
sym = sinfl_decode(&s, hlens, 7);
|
||||
switch (sym) {default: lens[n++] = (unsigned char)sym; break;
|
||||
case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
|
||||
case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break;
|
||||
|
|
@ -458,8 +463,9 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
|
|||
case blk: {
|
||||
/* decompress block */
|
||||
while (1) {
|
||||
int sym;
|
||||
sinfl_refill(&s);
|
||||
int sym = sinfl_decode(&s, s.lits, 10);
|
||||
sym = sinfl_decode(&s, s.lits, 10);
|
||||
if (sym < 256) {
|
||||
/* literal */
|
||||
if (sinfl_unlikely(out >= oe)) {
|
||||
|
|
|
|||
|
|
@ -958,6 +958,7 @@ RLAPI void SetWindowMonitor(int monitor); // Set monitor
|
|||
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
|
||||
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
|
||||
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP)
|
||||
RLAPI void *GetWindowHandle(void); // Get native window handle
|
||||
RLAPI int GetScreenWidth(void); // Get current screen width
|
||||
RLAPI int GetScreenHeight(void); // Get current screen height
|
||||
|
|
@ -1381,6 +1382,7 @@ RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float f
|
|||
RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint)
|
||||
|
||||
// Text font info functions
|
||||
RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks
|
||||
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
|
||||
RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
|
||||
RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
|
||||
|
|
@ -1589,7 +1591,7 @@ RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback);
|
|||
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream
|
||||
RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream
|
||||
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as <float>s
|
||||
RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
|||
|
|
@ -314,7 +314,11 @@ RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
|
|||
// NOTE: Angle is calculated from origin point (0, 0)
|
||||
RMAPI float Vector2Angle(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result = atan2f(v2.y - v1.y, v2.x - v1.x);
|
||||
float result = 0.0f;
|
||||
|
||||
float dot = v1.x*v2.x + v1.y*v2.y;
|
||||
float det = v1.x*v2.y - v1.y*v2.x;
|
||||
result = -atan2f(det, dot);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -326,17 +330,7 @@ RMAPI float Vector2LineAngle(Vector2 start, Vector2 end)
|
|||
{
|
||||
float result = 0.0f;
|
||||
|
||||
float dot = start.x*end.x + start.y*end.y; // Dot product
|
||||
|
||||
float dotClamp = (dot < -1.0f)? -1.0f : dot; // Clamp
|
||||
if (dotClamp > 1.0f) dotClamp = 1.0f;
|
||||
|
||||
result = acosf(dotClamp);
|
||||
|
||||
// Alternative implementation, more costly
|
||||
//float v1Length = sqrtf((start.x*start.x) + (start.y*start.y));
|
||||
//float v2Length = sqrtf((end.x*end.x) + (end.y*end.y));
|
||||
//float result = -acosf((start.x*end.x + start.y*end.y)/(v1Length*v2Length));
|
||||
result = atan2f(end.y - start.y, end.x - start.x);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1515,11 +1509,11 @@ RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top,
|
|||
|
||||
// Get perspective projection matrix
|
||||
// NOTE: Fovy angle must be provided in radians
|
||||
RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double far)
|
||||
RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, double farPlane)
|
||||
{
|
||||
Matrix result = { 0 };
|
||||
|
||||
double top = near*tan(fovy*0.5);
|
||||
double top = nearPlane*tan(fovY*0.5);
|
||||
double bottom = -top;
|
||||
double right = top*aspect;
|
||||
double left = -right;
|
||||
|
|
@ -1527,27 +1521,27 @@ RMAPI Matrix MatrixPerspective(double fovy, double aspect, double near, double f
|
|||
// MatrixFrustum(-right, right, -top, top, near, far);
|
||||
float rl = (float)(right - left);
|
||||
float tb = (float)(top - bottom);
|
||||
float fn = (float)(far - near);
|
||||
float fn = (float)(farPlane - nearPlane);
|
||||
|
||||
result.m0 = ((float)near*2.0f)/rl;
|
||||
result.m5 = ((float)near*2.0f)/tb;
|
||||
result.m0 = ((float)nearPlane*2.0f)/rl;
|
||||
result.m5 = ((float)nearPlane*2.0f)/tb;
|
||||
result.m8 = ((float)right + (float)left)/rl;
|
||||
result.m9 = ((float)top + (float)bottom)/tb;
|
||||
result.m10 = -((float)far + (float)near)/fn;
|
||||
result.m10 = -((float)farPlane + (float)nearPlane)/fn;
|
||||
result.m11 = -1.0f;
|
||||
result.m14 = -((float)far*(float)near*2.0f)/fn;
|
||||
result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get orthographic projection matrix
|
||||
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far)
|
||||
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double nearPlane, double farPlane)
|
||||
{
|
||||
Matrix result = { 0 };
|
||||
|
||||
float rl = (float)(right - left);
|
||||
float tb = (float)(top - bottom);
|
||||
float fn = (float)(far - near);
|
||||
float fn = (float)(farPlane - nearPlane);
|
||||
|
||||
result.m0 = 2.0f/rl;
|
||||
result.m1 = 0.0f;
|
||||
|
|
@ -1563,7 +1557,7 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d
|
|||
result.m11 = 0.0f;
|
||||
result.m12 = -((float)left + (float)right)/rl;
|
||||
result.m13 = -((float)top + (float)bottom)/tb;
|
||||
result.m14 = -((float)far + (float)near)/fn;
|
||||
result.m14 = -((float)farPlane + (float)nearPlane)/fn;
|
||||
result.m15 = 1.0f;
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
* rcamera - Basic camera system with support for multiple camera modes
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define CAMERA_IMPLEMENTATION
|
||||
* #define RCAMERA_IMPLEMENTATION
|
||||
* 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
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define CAMERA_STANDALONE
|
||||
* #define RCAMERA_STANDALONE
|
||||
* If defined, the library can be used as standalone as a camera system but some
|
||||
* functions must be redefined to manage inputs accordingly.
|
||||
*
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||
#endif
|
||||
|
||||
#if defined(CAMERA_STANDALONE)
|
||||
#if defined(RCAMERA_STANDALONE)
|
||||
#define CAMERA_CULL_DISTANCE_NEAR 0.01
|
||||
#define CAMERA_CULL_DISTANCE_FAR 1000.0
|
||||
#else
|
||||
|
|
@ -60,9 +60,9 @@
|
|||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for CAMERA_STANDALONE usage
|
||||
// NOTE: Below types are required for standalone usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(CAMERA_STANDALONE)
|
||||
#if defined(RCAMERA_STANDALONE)
|
||||
// Vector2, 2 components
|
||||
typedef struct Vector2 {
|
||||
float x; // Vector x component
|
||||
|
|
@ -76,6 +76,14 @@
|
|||
float z; // Vector z component
|
||||
} Vector3;
|
||||
|
||||
// Matrix, 4x4 components, column major, OpenGL style, right-handed
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12; // Matrix first row (4 components)
|
||||
float m1, m5, m9, m13; // Matrix second row (4 components)
|
||||
float m2, m6, m10, m14; // Matrix third row (4 components)
|
||||
float m3, m7, m11, m15; // Matrix fourth row (4 components)
|
||||
} Matrix;
|
||||
|
||||
// Camera type, defines a camera position/orientation in 3d space
|
||||
typedef struct Camera3D {
|
||||
Vector3 position; // Camera position
|
||||
|
|
@ -138,7 +146,7 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // CAMERA_H
|
||||
#endif // RCAMERA_H
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
|
|
@ -147,7 +155,7 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CAMERA_IMPLEMENTATION)
|
||||
#if defined(RCAMERA_IMPLEMENTATION)
|
||||
|
||||
#include "raymath.h" // Required for vector maths:
|
||||
// Vector3Add()
|
||||
|
|
@ -417,7 +425,7 @@ Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
|
|||
return MatrixIdentity();
|
||||
}
|
||||
|
||||
#ifndef CAMERA_STANDALONE
|
||||
#if !defined(RCAMERA_STANDALONE)
|
||||
// Update camera position for selected mode
|
||||
// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
|
||||
void UpdateCamera(Camera *camera, int mode)
|
||||
|
|
@ -483,7 +491,7 @@ void UpdateCamera(Camera *camera, int mode)
|
|||
if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
|
||||
}
|
||||
}
|
||||
#endif // !CAMERA_STANDALONE
|
||||
#endif // !RCAMERA_STANDALONE
|
||||
|
||||
// Update camera movement, movement/rotation values should be provided by user
|
||||
void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
|
||||
|
|
@ -516,4 +524,4 @@ void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float z
|
|||
CameraMoveToTarget(camera, zoom);
|
||||
}
|
||||
|
||||
#endif // CAMERA_IMPLEMENTATION
|
||||
#endif // RCAMERA_IMPLEMENTATION
|
||||
|
|
|
|||
27
src/rcore.c
27
src/rcore.c
|
|
@ -124,12 +124,12 @@
|
|||
#include "raymath.h" // Vector3, Quaternion and Matrix functionality
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#define GESTURES_IMPLEMENTATION
|
||||
#define RGESTURES_IMPLEMENTATION
|
||||
#include "rgestures.h" // Gestures detection functionality
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_CAMERA_SYSTEM)
|
||||
#define CAMERA_IMPLEMENTATION
|
||||
#define RCAMERA_IMPLEMENTATION
|
||||
#include "rcamera.h" // Camera system functionality
|
||||
#endif
|
||||
|
||||
|
|
@ -1705,6 +1705,14 @@ void SetWindowOpacity(float opacity)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Set window focused
|
||||
void SetWindowFocused(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
glfwFocusWindow(CORE.Window.handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get current screen width
|
||||
int GetScreenWidth(void)
|
||||
{
|
||||
|
|
@ -3219,7 +3227,7 @@ const char *GetApplicationDirectory(void)
|
|||
|
||||
#if defined(_WIN32)
|
||||
int len = 0;
|
||||
#if defined (UNICODE)
|
||||
#if defined(UNICODE)
|
||||
unsigned short widePath[MAX_PATH];
|
||||
len = GetModuleFileNameW(NULL, widePath, MAX_PATH);
|
||||
len = WideCharToMultiByte(0, 0, widePath, len, appDir, MAX_PATH, NULL, NULL);
|
||||
|
|
@ -5585,8 +5593,14 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
|||
gestureEvent.position[0].y /= (float)GetScreenHeight();
|
||||
|
||||
// Gesture data is sent to gestures-system for processing
|
||||
#if defined(PLATFORM_WEB)
|
||||
// Prevent calling ProcessGestureEvent() when Emscripten is present and there's a touch gesture, so EmscriptenTouchCallback() can handle it itself
|
||||
if (GetMouseX() != 0 || GetMouseY() != 0) ProcessGestureEvent(gestureEvent);
|
||||
#else
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// GLFW3 Cursor Position Callback, runs on mouse move
|
||||
|
|
@ -6123,10 +6137,17 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
|
|||
{
|
||||
gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i];
|
||||
gestureEvent.position[i] = CORE.Input.Touch.position[i];
|
||||
|
||||
// Normalize gestureEvent.position[i]
|
||||
gestureEvent.position[i].x /= (float)GetScreenWidth();
|
||||
gestureEvent.position[i].y /= (float)GetScreenHeight();
|
||||
}
|
||||
|
||||
// Gesture data is sent to gestures system for processing
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
|
||||
// Reset the pointCount for web, if it was the last Touch End event
|
||||
if (eventType == EMSCRIPTEN_EVENT_TOUCHEND && CORE.Input.Touch.pointCount == 1) CORE.Input.Touch.pointCount = 0;
|
||||
#endif
|
||||
|
||||
return 1; // The event was consumed by the callback handler
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
* rgestures - Gestures system, gestures processing based on input events (touch/mouse)
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define GESTURES_IMPLEMENTATION
|
||||
* #define RGESTURES_IMPLEMENTATION
|
||||
* 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
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define GESTURES_STANDALONE
|
||||
* #define RGESTURES_STANDALONE
|
||||
* If defined, the library can be used as standalone to process gesture events with
|
||||
* no external dependencies.
|
||||
*
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for GESTURES_STANDALONE usage
|
||||
// NOTE: Below types are required for standalone usage
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
|
|
@ -73,7 +73,7 @@ typedef struct Vector2 {
|
|||
} Vector2;
|
||||
#endif
|
||||
|
||||
#if defined(GESTURES_STANDALONE)
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
|
|
@ -122,12 +122,12 @@ extern "C" { // Prevents name mangling of functions
|
|||
void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
|
||||
void UpdateGestures(void); // Update gestures detected (must be called every frame)
|
||||
|
||||
#if defined(GESTURES_STANDALONE)
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
bool IsGestureDetected(int gesture); // Check if a gesture have been detected
|
||||
int GetGestureDetected(void); // Get latest detected gesture
|
||||
|
||||
float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
|
||||
float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
|
|
@ -138,17 +138,17 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // GESTURES_H
|
||||
#endif // RGESTURES_H
|
||||
|
||||
/***********************************************************************************
|
||||
*
|
||||
* GESTURES IMPLEMENTATION
|
||||
* RGESTURES IMPLEMENTATION
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(GESTURES_IMPLEMENTATION)
|
||||
#if defined(RGESTURES_IMPLEMENTATION)
|
||||
|
||||
#if defined(GESTURES_STANDALONE)
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
#if defined(_WIN32)
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
|
|
@ -178,11 +178,12 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
|
|||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define FORCE_TO_SWIPE 0.0005f // Swipe force, measured in normalized screen units/time
|
||||
#define FORCE_TO_SWIPE 0.2f // Swipe force, measured in normalized screen units/time
|
||||
#define MINIMUM_DRAG 0.015f // Drag minimum force, measured in normalized screen units (0.0f to 1.0f)
|
||||
#define DRAG_TIMEOUT 0.2f // Drag minimum time for web, measured in seconds
|
||||
#define MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f)
|
||||
#define TAP_TIMEOUT 300 // Tap minimum time, measured in milliseconds
|
||||
#define PINCH_TIMEOUT 300 // Pinch minimum time, measured in milliseconds
|
||||
#define TAP_TIMEOUT 0.3f // Tap minimum time, measured in seconds
|
||||
#define PINCH_TIMEOUT 0.3f // Pinch minimum time, measured in seconds
|
||||
#define DOUBLETAP_RANGE 0.03f // DoubleTap range, measured in normalized screen units (0.0f to 1.0f)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -203,11 +204,13 @@ typedef struct {
|
|||
Vector2 downDragPosition; // Touch drag position
|
||||
Vector2 moveDownPositionA; // First touch down position on move
|
||||
Vector2 moveDownPositionB; // Second touch down position on move
|
||||
Vector2 previousPositionA; // Previous position A to compare for pinch gestures
|
||||
Vector2 previousPositionB; // Previous position B to compare for pinch gestures
|
||||
int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions)
|
||||
} Touch;
|
||||
struct {
|
||||
bool resetRequired; // HOLD reset to get first touch point again
|
||||
double timeDuration; // HOLD duration in milliseconds
|
||||
double timeDuration; // HOLD duration in seconds
|
||||
} Hold;
|
||||
struct {
|
||||
Vector2 vector; // DRAG vector (between initial and current position)
|
||||
|
|
@ -295,7 +298,8 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
}
|
||||
else if (event.touchAction == TOUCH_ACTION_UP)
|
||||
{
|
||||
if (GESTURES.current == GESTURE_DRAG) GESTURES.Touch.upPosition = event.position[0];
|
||||
// A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases
|
||||
if (GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD) GESTURES.Touch.upPosition = event.position[0];
|
||||
|
||||
// NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen
|
||||
GESTURES.Drag.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
|
||||
|
|
@ -309,10 +313,10 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
// NOTE: Angle should be inverted in Y
|
||||
GESTURES.Drag.angle = 360.0f - rgVector2Angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
|
||||
|
||||
if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right
|
||||
else if ((GESTURES.Drag.angle > 30) && (GESTURES.Drag.angle < 120)) GESTURES.current = GESTURE_SWIPE_UP; // Up
|
||||
else if ((GESTURES.Drag.angle > 120) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left
|
||||
else if ((GESTURES.Drag.angle > 210) && (GESTURES.Drag.angle < 300)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down
|
||||
if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right
|
||||
else if ((GESTURES.Drag.angle >= 30) && (GESTURES.Drag.angle <= 150)) GESTURES.current = GESTURE_SWIPE_UP; // Up
|
||||
else if ((GESTURES.Drag.angle > 150) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left
|
||||
else if ((GESTURES.Drag.angle >= 210) && (GESTURES.Drag.angle <= 330)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down
|
||||
else GESTURES.current = GESTURE_NONE;
|
||||
}
|
||||
else
|
||||
|
|
@ -346,7 +350,12 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
GESTURES.Hold.resetRequired = false;
|
||||
|
||||
// Detect GESTURE_DRAG
|
||||
#if defined(PLATFORM_WEB)
|
||||
// An alternative check to detect gesture drag is necessary since moveDownPositionA on touch for web is always zero, causing the distance calculation to be inaccurate
|
||||
if ((rgGetCurrentTime() - GESTURES.Touch.eventTime) > DRAG_TIMEOUT)
|
||||
#else
|
||||
if (rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_DRAG)
|
||||
#endif
|
||||
{
|
||||
GESTURES.Touch.eventTime = rgGetCurrentTime();
|
||||
GESTURES.current = GESTURE_DRAG;
|
||||
|
|
@ -364,6 +373,9 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
GESTURES.Touch.downPositionA = event.position[0];
|
||||
GESTURES.Touch.downPositionB = event.position[1];
|
||||
|
||||
GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA;
|
||||
GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB;
|
||||
|
||||
//GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB);
|
||||
|
||||
GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x;
|
||||
|
|
@ -376,18 +388,15 @@ void ProcessGestureEvent(GestureEvent event)
|
|||
{
|
||||
GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB);
|
||||
|
||||
GESTURES.Touch.downPositionA = GESTURES.Touch.moveDownPositionA;
|
||||
GESTURES.Touch.downPositionB = GESTURES.Touch.moveDownPositionB;
|
||||
|
||||
GESTURES.Touch.moveDownPositionA = event.position[0];
|
||||
GESTURES.Touch.moveDownPositionB = event.position[1];
|
||||
|
||||
GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x;
|
||||
GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y;
|
||||
|
||||
if ((rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.downPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH))
|
||||
if ((rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH))
|
||||
{
|
||||
if ((rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) - GESTURES.Pinch.distance) < 0) GESTURES.current = GESTURE_PINCH_IN;
|
||||
if ( rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB) > rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) ) GESTURES.current = GESTURE_PINCH_IN;
|
||||
else GESTURES.current = GESTURE_PINCH_OUT;
|
||||
}
|
||||
else
|
||||
|
|
@ -520,12 +529,12 @@ static float rgVector2Distance(Vector2 v1, Vector2 v2)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Time measure returned are milliseconds
|
||||
// Time measure returned are seconds
|
||||
static double rgGetCurrentTime(void)
|
||||
{
|
||||
double time = 0;
|
||||
|
||||
#if !defined(GESTURES_STANDALONE)
|
||||
#if !defined(RGESTURES_STANDALONE)
|
||||
time = GetTime();
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
|
|
@ -534,7 +543,7 @@ static double rgGetCurrentTime(void)
|
|||
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
|
||||
time = (double)currentTime/clockFrequency; // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
|
|
@ -543,7 +552,7 @@ static double rgGetCurrentTime(void)
|
|||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
time = ((double)nowTime/1000000.0); // Time in miliseconds
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
|
@ -559,11 +568,11 @@ static double rgGetCurrentTime(void)
|
|||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
time = ((double)nowTime/1000000.0); // Time in miliseconds
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
#endif // GESTURES_IMPLEMENTATION
|
||||
#endif // RGESTURES_IMPLEMENTATION
|
||||
|
|
|
|||
233
src/rshapes.c
233
src/rshapes.c
|
|
@ -80,7 +80,7 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
Texture2D texShapes = { 1, 1, 1, 1, 7 }; // Texture used on shapes drawing (usually a white pixel)
|
||||
Texture2D texShapes = { 1, 1, 1, 1, 7 }; // Texture used on shapes drawing (white pixel loaded by rlgl)
|
||||
Rectangle texShapesRec = { 0.0f, 0.0f, 1.0f, 1.0f }; // Texture source rectangle used on shapes drawing
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -97,8 +97,19 @@ static float EaseCubicInOut(float t, float b, float c, float d); // Cubic eas
|
|||
// defining a font char white rectangle would allow drawing everything in a single draw call
|
||||
void SetShapesTexture(Texture2D texture, Rectangle source)
|
||||
{
|
||||
texShapes = texture;
|
||||
texShapesRec = source;
|
||||
// Reset texture to default pixel if required
|
||||
// WARNING: Shapes texture should be probably better validated,
|
||||
// it can break the rendering of all shapes if missused
|
||||
if ((texture.id == 0) || (source.width == 0) || (source.height == 0))
|
||||
{
|
||||
texShapes = (Texture2D){ 1, 1, 1, 1, 7 };
|
||||
texShapesRec = (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
}
|
||||
else
|
||||
{
|
||||
texShapes = texture;
|
||||
texShapesRec = source;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a pixel
|
||||
|
|
@ -382,14 +393,14 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
|
|||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
angle += (stepLength*2);
|
||||
}
|
||||
|
|
@ -402,11 +413,11 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
|
|||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
|
@ -421,8 +432,8 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
|
|||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -464,15 +475,15 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
}
|
||||
|
||||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -481,7 +492,7 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -496,9 +507,9 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
|
|||
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||
rlVertex2f((float)centerX, (float)centerY);
|
||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||
rlVertex2f((float)centerX + sinf(DEG2RAD*i)*radius, (float)centerY + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*(i + 10))*radius, (float)centerY + sinf(DEG2RAD*(i + 10))*radius);
|
||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||
rlVertex2f((float)centerX + sinf(DEG2RAD*(i + 10))*radius, (float)centerY + cosf(DEG2RAD*(i + 10))*radius);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*i)*radius, (float)centerY + sinf(DEG2RAD*i)*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -519,8 +530,8 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
|||
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlVertex2f(centerX + sinf(DEG2RAD*i)*radius, centerY + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(centerX + sinf(DEG2RAD*(i + 10))*radius, centerY + cosf(DEG2RAD*(i + 10))*radius);
|
||||
rlVertex2f(centerX + cosf(DEG2RAD*i)*radius, centerY + sinf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(centerX + cosf(DEG2RAD*(i + 10))*radius, centerY + sinf(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -533,8 +544,8 @@ void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color c
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f((float)centerX, (float)centerY);
|
||||
rlVertex2f((float)centerX + sinf(DEG2RAD*i)*radiusH, (float)centerY + cosf(DEG2RAD*i)*radiusV);
|
||||
rlVertex2f((float)centerX + sinf(DEG2RAD*(i + 10))*radiusH, (float)centerY + cosf(DEG2RAD*(i + 10))*radiusV);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*(i + 10))*radiusH, (float)centerY + sinf(DEG2RAD*(i + 10))*radiusV);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*i)*radiusH, (float)centerY + sinf(DEG2RAD*i)*radiusV);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -546,8 +557,8 @@ void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Co
|
|||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(centerX + sinf(DEG2RAD*i)*radiusH, centerY + cosf(DEG2RAD*i)*radiusV);
|
||||
rlVertex2f(centerX + sinf(DEG2RAD*(i + 10))*radiusH, centerY + cosf(DEG2RAD*(i + 10))*radiusV);
|
||||
rlVertex2f(centerX + cosf(DEG2RAD*(i + 10))*radiusH, centerY + sinf(DEG2RAD*(i + 10))*radiusV);
|
||||
rlVertex2f(centerX + cosf(DEG2RAD*i)*radiusH, centerY + sinf(DEG2RAD*i)*radiusV);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -605,17 +616,17 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -628,13 +639,13 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -691,19 +702,19 @@ void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float s
|
|||
if (showCapLines)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
}
|
||||
|
||||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -711,8 +722,8 @@ void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float s
|
|||
if (showCapLines)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -971,7 +982,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
|
|||
};
|
||||
|
||||
const Vector2 centers[4] = { point[8], point[9], point[10], point[11] };
|
||||
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
|
||||
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlSetTexture(texShapes.id);
|
||||
|
|
@ -989,12 +1000,16 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
|
|||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
angle += (stepLength*2);
|
||||
}
|
||||
|
||||
|
|
@ -1004,10 +1019,13 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
|
|||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
}
|
||||
|
|
@ -1082,8 +1100,8 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
angle += stepLength;
|
||||
}
|
||||
}
|
||||
|
|
@ -1197,7 +1215,7 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
|
|||
{(float)(rec.x + rec.width) - innerRadius, (float)(rec.y + rec.height) - innerRadius}, {(float)rec.x + innerRadius, (float)(rec.y + rec.height) - innerRadius} // P18, P19
|
||||
};
|
||||
|
||||
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
|
||||
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
|
||||
|
||||
if (lineThick > 1)
|
||||
{
|
||||
|
|
@ -1214,14 +1232,18 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
|
|||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -1286,13 +1308,13 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
|
|||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*innerRadius, center.y + sinf(DEG2RAD*angle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*innerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
|
||||
angle += stepLength;
|
||||
}
|
||||
|
|
@ -1350,8 +1372,8 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
|
|||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*outerRadius, center.y + sinf(DEG2RAD*angle)*outerRadius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + sinf(DEG2RAD*(angle + stepLength))*outerRadius);
|
||||
angle += stepLength;
|
||||
}
|
||||
}
|
||||
|
|
@ -1481,7 +1503,8 @@ void DrawTriangleStrip(Vector2 *points, int pointCount, Color color)
|
|||
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color)
|
||||
{
|
||||
if (sides < 3) sides = 3;
|
||||
float centralAngle = rotation;
|
||||
float centralAngle = rotation*DEG2RAD;
|
||||
float angleStep = 360.0f/(float)sides*DEG2RAD;
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlSetTexture(texShapes.id);
|
||||
|
|
@ -1490,19 +1513,21 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
|||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
float nextAngle = centralAngle + angleStep;
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
|
||||
centralAngle += 360.0f/(float)sides;
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
centralAngle = nextAngle;
|
||||
}
|
||||
rlEnd();
|
||||
rlSetTexture(0);
|
||||
|
|
@ -1513,10 +1538,10 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
|||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle + angleStep)*radius, center.y + sinf(centralAngle + angleStep)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
|
||||
centralAngle += 360.0f/(float)sides;
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
centralAngle += angleStep;
|
||||
}
|
||||
rlEnd();
|
||||
#endif
|
||||
|
|
@ -1526,16 +1551,18 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
|||
void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color)
|
||||
{
|
||||
if (sides < 3) sides = 3;
|
||||
float centralAngle = rotation;
|
||||
float centralAngle = rotation*DEG2RAD;
|
||||
float angleStep = 360.0f/(float)sides*DEG2RAD;
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
centralAngle += 360.0f/(float)sides;
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle + angleStep)*radius, center.y + sinf(centralAngle + angleStep)*radius);
|
||||
|
||||
centralAngle += angleStep;
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
|
@ -1543,8 +1570,8 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo
|
|||
void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color)
|
||||
{
|
||||
if (sides < 3) sides = 3;
|
||||
float centralAngle = rotation;
|
||||
float exteriorAngle = 360.0f/(float)sides;
|
||||
float centralAngle = rotation*DEG2RAD;
|
||||
float exteriorAngle = 360.0f/(float)sides*DEG2RAD;
|
||||
float innerRadius = radius - (lineThick*cosf(DEG2RAD*exteriorAngle/2.0f));
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
|
|
@ -1554,19 +1581,21 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
|
|||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
|
||||
float nextAngle = centralAngle + exteriorAngle;
|
||||
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
|
||||
centralAngle += exteriorAngle;
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius);
|
||||
|
||||
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius);
|
||||
|
||||
centralAngle = nextAngle;
|
||||
}
|
||||
rlEnd();
|
||||
rlSetTexture(0);
|
||||
|
|
@ -1577,13 +1606,13 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
|
|||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
float nextAngle = centralAngle + exteriorAngle;
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*radius, center.y + cosf(DEG2RAD*nextAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
|
||||
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*radius, center.y + cosf(DEG2RAD*nextAngle)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*innerRadius, center.y + cosf(DEG2RAD*nextAngle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius);
|
||||
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius);
|
||||
|
||||
centralAngle = nextAngle;
|
||||
}
|
||||
|
|
|
|||
120
src/rtext.c
120
src/rtext.c
|
|
@ -6,14 +6,19 @@
|
|||
* #define SUPPORT_MODULE_RTEXT
|
||||
* rtext module is included in the build
|
||||
*
|
||||
* #define SUPPORT_DEFAULT_FONT
|
||||
* Load default raylib font on initialization to be used by DrawText() and MeasureText().
|
||||
* If no default font loaded, DrawTextEx() and MeasureTextEx() are required.
|
||||
*
|
||||
* #define SUPPORT_FILEFORMAT_FNT
|
||||
* #define SUPPORT_FILEFORMAT_TTF
|
||||
* Selected desired fileformats to be supported for loading. Some of those formats are
|
||||
* supported by default, to remove support, just comment unrequired #define in this module
|
||||
*
|
||||
* #define SUPPORT_DEFAULT_FONT
|
||||
* Load default raylib font on initialization to be used by DrawText() and MeasureText().
|
||||
* If no default font loaded, DrawTextEx() and MeasureTextEx() are required.
|
||||
* #define SUPPORT_FONT_ATLAS_WHITE_REC
|
||||
* On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle
|
||||
* at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
||||
* drawing text and shapes with a single draw call [SetShapesTexture()].
|
||||
*
|
||||
* #define TEXTSPLIT_MAX_TEXT_BUFFER_LENGTH
|
||||
* TextSplit() function static buffer max size
|
||||
|
|
@ -111,8 +116,9 @@ static Font defaultFont = { 0 };
|
|||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||
#endif
|
||||
static int textLineSpacing = 15; // Text vertical line spacing in pixels
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
extern void LoadFontDefault(void);
|
||||
|
|
@ -123,7 +129,6 @@ extern void UnloadFontDefault(void);
|
|||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
|
||||
// Load raylib default font
|
||||
extern void LoadFontDefault(void)
|
||||
{
|
||||
|
|
@ -699,9 +704,11 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC
|
|||
for (int i = 0; i < glyphCount; i++)
|
||||
{
|
||||
if (chars[i].image.width > maxGlyphWidth) maxGlyphWidth = chars[i].image.width;
|
||||
totalWidth += chars[i].image.width + 2*padding;
|
||||
totalWidth += chars[i].image.width + 4*padding;
|
||||
}
|
||||
|
||||
//#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE
|
||||
#if defined(SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE)
|
||||
int rowCount = 0;
|
||||
int imageSize = 64; // Define minimum starting value to avoid unnecessary calculation steps for very small images
|
||||
|
||||
|
|
@ -714,6 +721,24 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC
|
|||
|
||||
atlas.width = imageSize; // Atlas bitmap width
|
||||
atlas.height = imageSize; // Atlas bitmap height
|
||||
#else
|
||||
// No need for a so-conservative atlas generation
|
||||
float totalArea = totalWidth*fontSize*1.2f;
|
||||
float imageMinSize = sqrtf(totalArea);
|
||||
int imageSize = (int)powf(2, ceilf(logf(imageMinSize)/logf(2)));
|
||||
|
||||
if (totalArea < ((imageSize*imageSize)/2))
|
||||
{
|
||||
atlas.width = imageSize; // Atlas bitmap width
|
||||
atlas.height = imageSize/2; // Atlas bitmap height
|
||||
}
|
||||
else
|
||||
{
|
||||
atlas.width = imageSize; // Atlas bitmap width
|
||||
atlas.height = imageSize; // Atlas bitmap height
|
||||
}
|
||||
#endif
|
||||
|
||||
atlas.data = (unsigned char *)RL_CALLOC(1, atlas.width*atlas.height); // Create a bitmap to store characters (8 bpp)
|
||||
atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
|
||||
atlas.mipmaps = 1;
|
||||
|
|
@ -819,6 +844,19 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC
|
|||
RL_FREE(context);
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_FONT_ATLAS_WHITE_REC)
|
||||
// Add a 3x3 white rectangle at the bottom-right corner of the generated atlas,
|
||||
// useful to use as the white texture to draw shapes with raylib, using this rectangle
|
||||
// shapes and text can be backed into a single draw call: SetShapesTexture()
|
||||
for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++)
|
||||
{
|
||||
((unsigned char *)atlas.data)[k - 0] = 255;
|
||||
((unsigned char *)atlas.data)[k - 1] = 255;
|
||||
((unsigned char *)atlas.data)[k - 2] = 255;
|
||||
k -= atlas.width;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convert image data from GRAYSCALE to GRAY_ALPHA
|
||||
unsigned char *dataGrayAlpha = (unsigned char *)RL_MALLOC(atlas.width*atlas.height*sizeof(unsigned char)*2); // Two channels
|
||||
|
||||
|
|
@ -1071,9 +1109,8 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
|
|||
|
||||
if (codepoint == '\n')
|
||||
{
|
||||
// NOTE: Fixed line spacing of 1.5 line-height
|
||||
// TODO: Support custom line spacing defined by user
|
||||
textOffsetY += (int)((font.baseSize + font.baseSize/2.0f)*scaleFactor);
|
||||
// NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup
|
||||
textOffsetY += textLineSpacing;
|
||||
textOffsetX = 0.0f;
|
||||
}
|
||||
else
|
||||
|
|
@ -1143,9 +1180,8 @@ void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 pos
|
|||
|
||||
if (codepoints[i] == '\n')
|
||||
{
|
||||
// NOTE: Fixed line spacing of 1.5 line-height
|
||||
// TODO: Support custom line spacing defined by user
|
||||
textOffsetY += (int)((font.baseSize + font.baseSize/2.0f)*scaleFactor);
|
||||
// NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup
|
||||
textOffsetY += textLineSpacing;
|
||||
textOffsetX = 0.0f;
|
||||
}
|
||||
else
|
||||
|
|
@ -1161,6 +1197,12 @@ void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 pos
|
|||
}
|
||||
}
|
||||
|
||||
// Set vertical line spacing when drawing with line-breaks
|
||||
void SetTextLineSpacing(int spacing)
|
||||
{
|
||||
textLineSpacing = spacing;
|
||||
}
|
||||
|
||||
// Measure string width for default font
|
||||
int MeasureText(const char *text, int fontSize)
|
||||
{
|
||||
|
|
@ -1219,7 +1261,9 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
|||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
byteCounter = 0;
|
||||
textWidth = 0;
|
||||
textHeight += ((float)font.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines
|
||||
|
||||
// NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup
|
||||
textHeight += (float)textLineSpacing;
|
||||
}
|
||||
|
||||
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
|
||||
|
|
@ -1227,7 +1271,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
|||
|
||||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
|
||||
textSize.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing); // Adds chars spacing to measure
|
||||
textSize.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing);
|
||||
textSize.y = textHeight*scaleFactor;
|
||||
|
||||
return textSize;
|
||||
|
|
@ -1574,7 +1618,8 @@ int TextFindIndex(const char *text, const char *find)
|
|||
}
|
||||
|
||||
// Get upper case version of provided string
|
||||
// REQUIRES: toupper()
|
||||
// WARNING: Limited functionality, only basic characters set
|
||||
// TODO: Support UTF-8 diacritics to upper-case, check codepoints
|
||||
const char *TextToUpper(const char *text)
|
||||
{
|
||||
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
|
||||
|
|
@ -1582,17 +1627,10 @@ const char *TextToUpper(const char *text)
|
|||
|
||||
if (text != NULL)
|
||||
{
|
||||
for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++)
|
||||
for (int i = 0; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[i] != '\0'); i++)
|
||||
{
|
||||
if (text[i] != '\0')
|
||||
{
|
||||
buffer[i] = (char)toupper(text[i]);
|
||||
//if ((text[i] >= 'a') && (text[i] <= 'z')) buffer[i] = text[i] - 32;
|
||||
|
||||
// TODO: Support UTF-8 diacritics to upper-case
|
||||
//if ((text[i] >= 'à') && (text[i] <= 'ý')) buffer[i] = text[i] - 32;
|
||||
}
|
||||
else { buffer[i] = '\0'; break; }
|
||||
if ((text[i] >= 'a') && (text[i] <= 'z')) buffer[i] = text[i] - 32;
|
||||
else buffer[i] = text[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1600,7 +1638,7 @@ const char *TextToUpper(const char *text)
|
|||
}
|
||||
|
||||
// Get lower case version of provided string
|
||||
// REQUIRES: tolower()
|
||||
// WARNING: Limited functionality, only basic characters set
|
||||
const char *TextToLower(const char *text)
|
||||
{
|
||||
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
|
||||
|
|
@ -1608,14 +1646,10 @@ const char *TextToLower(const char *text)
|
|||
|
||||
if (text != NULL)
|
||||
{
|
||||
for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++)
|
||||
for (int i = 0; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[i] != '\0'); i++)
|
||||
{
|
||||
if (text[i] != '\0')
|
||||
{
|
||||
buffer[i] = (char)tolower(text[i]);
|
||||
//if ((text[i] >= 'A') && (text[i] <= 'Z')) buffer[i] = text[i] + 32;
|
||||
}
|
||||
else { buffer[i] = '\0'; break; }
|
||||
if ((text[i] >= 'A') && (text[i] <= 'Z')) buffer[i] = text[i] + 32;
|
||||
else buffer[i] = text[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1623,7 +1657,7 @@ const char *TextToLower(const char *text)
|
|||
}
|
||||
|
||||
// Get Pascal case notation version of provided string
|
||||
// REQUIRES: toupper()
|
||||
// WARNING: Limited functionality, only basic characters set
|
||||
const char *TextToPascal(const char *text)
|
||||
{
|
||||
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
|
||||
|
|
@ -1631,20 +1665,18 @@ const char *TextToPascal(const char *text)
|
|||
|
||||
if (text != NULL)
|
||||
{
|
||||
buffer[0] = (char)toupper(text[0]);
|
||||
// Upper case first character
|
||||
if ((text[0] >= 'a') && (text[0] <= 'z')) buffer[0] = text[0] - 32;
|
||||
|
||||
for (int i = 1, j = 1; i < MAX_TEXT_BUFFER_LENGTH; i++, j++)
|
||||
// Check for next separator to upper case another character
|
||||
for (int i = 1, j = 1; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++, j++)
|
||||
{
|
||||
if (text[j] != '\0')
|
||||
if (text[j] != '_') buffer[i] = text[j];
|
||||
else
|
||||
{
|
||||
if (text[j] != '_') buffer[i] = text[j];
|
||||
else
|
||||
{
|
||||
j++;
|
||||
buffer[i] = (char)toupper(text[j]);
|
||||
}
|
||||
j++;
|
||||
if ((text[j] >= 'a') && (text[j] <= 'z')) buffer[i] = text[j] - 32;
|
||||
}
|
||||
else { buffer[i] = '\0'; break; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3290,8 +3290,7 @@ void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSiz
|
|||
if (GetFontDefault().texture.id == 0) LoadFontDefault();
|
||||
|
||||
Vector2 position = { (float)posX, (float)posY };
|
||||
// NOTE: For default font, spacing is set to desired font size / default font size (10)
|
||||
ImageDrawTextEx(dst, GetFontDefault(), text, position, (float)fontSize, (float)fontSize/10, color); // WARNING: Module required: rtext
|
||||
ImageDrawTextEx(dst, GetFontDefault(), text, position, (float)fontSize, 1.0f, color); // WARNING: Module required: rtext
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "IMAGE: ImageDrawText() requires module: rtext");
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user