Merge branch 'IsKeyPressedRepeat' of https://github.com/n77y/raylib into IsKeyPressedRepeat

This commit is contained in:
Nickolas McDonald 2023-08-20 18:50:42 -04:00
commit caca605351
6 changed files with 89 additions and 36 deletions

View File

@ -187,12 +187,11 @@ int main(void)
// Add a new set of emojis when SPACE is pressed // Add a new set of emojis when SPACE is pressed
if (IsKeyPressed(KEY_SPACE)) RandomizeEmoji(); if (IsKeyPressed(KEY_SPACE)) RandomizeEmoji();
// Set the selected emoji and copy its text to clipboard // Set the selected emoji
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (hovered != -1) && (hovered != selected)) if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (hovered != -1) && (hovered != selected))
{ {
selected = hovered; selected = hovered;
selectedPos = hoveredPos; selectedPos = hoveredPos;
SetClipboardText(messages[emoji[selected].message].text);
} }
Vector2 mouse = GetMousePosition(); Vector2 mouse = GetMousePosition();
@ -342,7 +341,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
{ {
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
float textOffsetY = 0; // Offset between lines (on line break '\n') float textOffsetY = 0.0f; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw float textOffsetX = 0.0f; // Offset X to next character to draw
float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor

View File

@ -6,7 +6,6 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
"-std=gnu99", "-std=gnu99",
"-D_GNU_SOURCE", "-D_GNU_SOURCE",
"-DGL_SILENCE_DEPRECATION=199309L", "-DGL_SILENCE_DEPRECATION=199309L",
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891
}; };
const raylib = b.addStaticLibrary(.{ const raylib = b.addStaticLibrary(.{
@ -22,15 +21,38 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
} }
raylib.addCSourceFiles(&.{ raylib.addCSourceFiles(&.{
srcdir ++ "/raudio.c",
srcdir ++ "/rcore.c", srcdir ++ "/rcore.c",
srcdir ++ "/rmodels.c",
srcdir ++ "/rshapes.c",
srcdir ++ "/rtext.c",
srcdir ++ "/rtextures.c",
srcdir ++ "/utils.c", srcdir ++ "/utils.c",
}, raylib_flags); }, raylib_flags);
if (options.raudio) {
raylib.addCSourceFiles(&.{
srcdir ++ "/raudio.c",
}, raylib_flags);
}
if (options.rmodels) {
raylib.addCSourceFiles(&.{
srcdir ++ "/rmodels.c",
}, &[_][]const u8{
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891
} ++ raylib_flags);
}
if (options.rshapes) {
raylib.addCSourceFiles(&.{
srcdir ++ "/rshapes.c",
}, raylib_flags);
}
if (options.rtext) {
raylib.addCSourceFiles(&.{
srcdir ++ "/rtext.c",
}, raylib_flags);
}
if (options.rtextures) {
raylib.addCSourceFiles(&.{
srcdir ++ "/rtextures.c",
}, raylib_flags);
}
var gen_step = std.build.Step.WriteFile.create(b); var gen_step = std.build.Step.WriteFile.create(b);
raylib.step.dependOn(&gen_step.step); raylib.step.dependOn(&gen_step.step);
@ -137,6 +159,11 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
} }
pub const Options = struct { pub const Options = struct {
raudio: bool = true,
rmodels: bool = true,
rshapes: bool = true,
rtext: bool = true,
rtextures: bool = true,
raygui: bool = false, raygui: bool = false,
platform_drm: bool = false, platform_drm: bool = false,
}; };
@ -152,19 +179,24 @@ pub fn build(b: *std.Build) void {
// set a preferred release mode, allowing the user to decide how to optimize. // set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
const raygui = b.option(bool, "raygui", "Compile with raygui support"); const defaults = Options{};
const platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)"); const options = Options{
.platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)") orelse defaults.platform_drm,
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
.raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui,
};
const lib = addRaylib(b, target, optimize, .{ const lib = addRaylib(b, target, optimize, options);
.raygui = raygui orelse false,
.platform_drm = platform_drm orelse false,
});
lib.installHeader("src/raylib.h", "raylib.h"); lib.installHeader("src/raylib.h", "raylib.h");
lib.installHeader("src/raymath.h", "raymath.h"); lib.installHeader("src/raymath.h", "raymath.h");
lib.installHeader("src/rlgl.h", "rlgl.h"); lib.installHeader("src/rlgl.h", "rlgl.h");
if (raygui orelse false) { if (options.raygui) {
lib.installHeader("../raygui/src/raygui.h", "raygui.h"); lib.installHeader("../raygui/src/raygui.h", "raygui.h");
} }

View File

@ -1115,6 +1115,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize
// Input-related functions: keyboard // Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed

View File

@ -438,7 +438,9 @@ typedef struct CoreData {
int exitKey; // Default exit key int exitKey; // Default exit key
char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state
char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state
char repeatKeyState[MAX_KEYBOARD_KEYS]; // Registers repeat frame key state
// NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially
char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame.
int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue
int keyPressedQueueCount; // Input keys queue count int keyPressedQueueCount; // Input keys queue count
@ -3757,6 +3759,13 @@ bool IsKeyPressed(int key)
return pressed; return pressed;
} }
// Check if a key has been pressed again (only PLATFORM_DESKTOP)
bool IsKeyPressedRepeat(int key)
{
if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true;
else return false;
}
// Check if a key is being pressed (key held down) // Check if a key is being pressed (key held down)
bool IsKeyDown(int key) bool IsKeyDown(int key)
{ {
@ -4474,13 +4483,16 @@ static bool InitGraphicsDevice(int width, int height)
#endif #endif
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
// NOTE: V-Sync can be enabled by graphic driver configuration // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need
// to be activated on web platforms since VSync is enforced there.
#if !defined(PLATFORM_WEB)
if (CORE.Window.flags & FLAG_VSYNC_HINT) if (CORE.Window.flags & FLAG_VSYNC_HINT)
{ {
// WARNING: It seems to hit a critical render path in Intel HD Graphics // WARNING: It seems to hit a critical render path in Intel HD Graphics
glfwSwapInterval(1); glfwSwapInterval(1);
TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC"); TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC");
} }
#endif
int fbWidth = CORE.Window.screen.width; int fbWidth = CORE.Window.screen.width;
int fbHeight = CORE.Window.screen.height; int fbHeight = CORE.Window.screen.height;
@ -5183,6 +5195,8 @@ void PollInputEvents(void)
// Reset keys/chars pressed registered // Reset keys/chars pressed registered
CORE.Input.Keyboard.keyPressedQueueCount = 0; CORE.Input.Keyboard.keyPressedQueueCount = 0;
CORE.Input.Keyboard.charPressedQueueCount = 0; CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset key repeats
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
#if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) #if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM))
// Reset last gamepad button/axis registered state // Reset last gamepad button/axis registered state
@ -5195,7 +5209,8 @@ void PollInputEvents(void)
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)
{ {
CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
CORE.Input.Keyboard.repeatKeyState[i] = 0;
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
} }
PollKeyboardEvents(); PollKeyboardEvents();
@ -5611,7 +5626,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
// to work properly with our implementation (IsKeyDown/IsKeyUp checks) // to work properly with our implementation (IsKeyDown/IsKeyUp checks)
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
else CORE.Input.Keyboard.currentKeyState[key] = 1; else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
if (action == GLFW_REPEAT) CORE.Input.Keyboard.repeatKeyState[key] = 1; if (action == GLFW_REPEAT) CORE.Input.Keyboard.repeatKeyState[key] = 1;
@ -6386,7 +6402,11 @@ static void ProcessKeyboard(void)
bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call
// Reset pressed keys array (it will be filled below) // Reset pressed keys array (it will be filled below)
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)
{
CORE.Input.Keyboard.currentKeyState[i] = 0;
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
}
// Fill all read bytes (looking for keys) // Fill all read bytes (looking for keys)
for (int i = 0; i < bufferByteCount; i++) for (int i = 0; i < bufferByteCount; i++)

View File

@ -2945,7 +2945,6 @@ bool rlCheckRenderBatchLimit(int vCount)
unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount)
{ {
unsigned int id = 0; unsigned int id = 0;
if (data == NULL) return id;
glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding

View File

@ -498,6 +498,13 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
DrawCircleV((Vector2){ (float)centerX, (float)centerY }, radius, color); DrawCircleV((Vector2){ (float)centerX, (float)centerY }, radius, color);
} }
// Draw a color-filled circle (Vector version)
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawCircleV(Vector2 center, float radius, Color color)
{
DrawCircleSector(center, radius, 0, 360, 36, color);
}
// Draw a piece of a circle // Draw a piece of a circle
void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color) void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color)
{ {
@ -530,6 +537,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
// NOTE: Every QUAD actually represents two segments // NOTE: Every QUAD actually represents two segments
for (int i = 0; i < segments/2; i++) for (int i = 0; i < segments/2; i++)
{ {
@ -539,7 +547,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); 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); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2.0f))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2.0f))*radius);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); 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); rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
@ -547,11 +555,11 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
angle += (stepLength*2); angle += (stepLength*2.0f);
} }
// NOTE: In case number of segments is odd, we add one last piece to the cake // NOTE: In case number of segments is odd, we add one last piece to the cake
if (segments%2) if ((segments%2) == 1)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -567,6 +575,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
} }
rlEnd(); rlEnd();
rlSetTexture(0); rlSetTexture(0);
@ -659,13 +668,6 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
rlEnd(); rlEnd();
} }
// Draw a color-filled circle (Vector version)
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawCircleV(Vector2 center, float radius, Color color)
{
DrawCircleSector(center, radius, 0, 360, 36, color);
}
// Draw circle outline // Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color) void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{ {