Merge branch 'master' into big-cmake-changes

This commit is contained in:
Hristo Stamenov 2021-01-07 09:48:31 +02:00
commit 7b199c3145
4 changed files with 95 additions and 71 deletions

View File

@ -38,6 +38,7 @@ option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pr
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF) option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF)
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF) option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF)
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF) option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF)
option(SUPPORT_DATA_STORAGE "Support for persistent data storage" ON)
# rlgl.h # rlgl.h
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON) option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)

View File

@ -21,6 +21,8 @@
#cmakedefine SUPPORT_HIGH_DPI 1 #cmakedefine SUPPORT_HIGH_DPI 1
// Support CompressData() and DecompressData() functions // Support CompressData() and DecompressData() functions
#cmakedefine SUPPORT_COMPRESSION_API 1 #cmakedefine SUPPORT_COMPRESSION_API 1
// Support for persistent data storage
#cmakedefine SUPPORT_DATA_STORAGE 1
// rlgl.h // rlgl.h
// Support VR simulation functionality (stereo rendering) // Support VR simulation functionality (stereo rendering)

View File

@ -333,12 +333,6 @@ typedef struct {
bool isKeyboard; // True if device has letter keycodes bool isKeyboard; // True if device has letter keycodes
bool isGamepad; // True if device has gamepad buttons bool isGamepad; // True if device has gamepad buttons
} InputEventWorker; } InputEventWorker;
typedef struct {
int contents[8]; // Key events FIFO contents (8 positions)
char head; // Key events FIFO head position
char tail; // Key events FIFO tail position
} KeyEventFifo;
#endif #endif
typedef struct { int x; int y; } Point; typedef struct { int x; int y; } Point;
@ -420,7 +414,7 @@ typedef struct CoreData {
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
int defaultMode; // Default keyboard mode int defaultMode; // Default keyboard mode
struct termios defaultSettings; // Default keyboard settings struct termios defaultSettings; // Default keyboard settings
KeyEventFifo lastKeyPressed; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers) int fd; // File descriptor for the evdev keyboard
#endif #endif
} Keyboard; } Keyboard;
struct { struct {
@ -559,7 +553,8 @@ static void RestoreTerminal(void); // Restore terminal
#endif #endif
static void InitEvdevInput(void); // Evdev inputs initialization static void InitEvdevInput(void); // Evdev inputs initialization
static void EventThreadSpawn(char *device); // Identifies a input device and spawns a thread to handle it if needed static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
static void PollKeyboardEvents(void); // Process evdev keyboard events.
static void *EventThread(void *arg); // Input device events reading thread static void *EventThread(void *arg); // Input device events reading thread
static void InitGamepad(void); // Init raw gamepad input static void InitGamepad(void); // Init raw gamepad input
@ -899,6 +894,13 @@ void CloseWindow(void)
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
// Close the evdev keyboard
if (CORE.Input.Keyboard.fd != -1)
{
close(CORE.Input.Keyboard.fd);
CORE.Input.Keyboard.fd = -1;
}
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i) for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{ {
if (CORE.Input.eventWorker[i].threadId) if (CORE.Input.eventWorker[i].threadId)
@ -907,6 +909,7 @@ void CloseWindow(void)
} }
} }
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL); if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
#endif #endif
@ -4275,14 +4278,7 @@ static void PollInputEvents(void)
// Register previous keys states // Register previous keys states
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// Grab a keypress from the evdev fifo if avalable PollKeyboardEvents();
if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer
CORE.Input.Keyboard.keyPressedQueueCount++;
CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
}
// Register previous mouse states // Register previous mouse states
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
@ -5353,6 +5349,9 @@ static void InitEvdevInput(void)
DIR *directory; DIR *directory;
struct dirent *entity; struct dirent *entity;
// Initialise keyboard file descriptor
CORE.Input.Keyboard.fd = -1;
// Reset variables // Reset variables
for (int i = 0; i < MAX_TOUCH_POINTS; ++i) for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
{ {
@ -5360,10 +5359,6 @@ static void InitEvdevInput(void)
CORE.Input.Touch.position[i].y = -1; CORE.Input.Touch.position[i].y = -1;
} }
// Reset keypress buffer
CORE.Input.Keyboard.lastKeyPressed.head = 0;
CORE.Input.Keyboard.lastKeyPressed.tail = 0;
// Reset keyboard key state // Reset keyboard key state
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
@ -5377,7 +5372,7 @@ static void InitEvdevInput(void)
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*" if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
{ {
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name); sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
EventThreadSpawn(path); // Identify the device and spawn a thread for it ConfigureEvdevDevice(path); // Configure the device if appropriate
} }
} }
@ -5386,8 +5381,8 @@ static void InitEvdevInput(void)
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH); else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
} }
// Identifies a input device and spawns a thread to handle it if needed // Identifies a input device and configures it for use if appropriate
static void EventThreadSpawn(char *device) static void ConfigureEvdevDevice(char *device)
{ {
#define BITS_PER_LONG (8*sizeof(long)) #define BITS_PER_LONG (8*sizeof(long))
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1) #define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
@ -5459,7 +5454,7 @@ static void EventThreadSpawn(char *device)
// Identify the device // Identify the device
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the avalable device properties ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties
// Check for absolute input devices // Check for absolute input devices
if (TEST_BIT(evBits, EV_ABS)) if (TEST_BIT(evBits, EV_ABS))
@ -5535,15 +5530,22 @@ static void EventThreadSpawn(char *device)
// Decide what to do with the device // Decide what to do with the device
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
if (worker->isTouch || worker->isMouse || worker->isKeyboard) if (worker->isKeyboard && CORE.Input.Keyboard.fd == -1)
{
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
// threads so that they don't drop events when the frame rate is slow.
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
CORE.Input.Keyboard.fd = worker->fd;
}
else if (worker->isTouch || worker->isMouse)
{ {
// Looks like an interesting device // Looks like an interesting device
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s%s)", device, TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device,
worker->isMouse? "mouse " : "", worker->isMouse? "mouse " : "",
worker->isMultitouch? "multitouch " : "", worker->isMultitouch? "multitouch " : "",
worker->isTouch? "touchscreen " : "", worker->isTouch? "touchscreen " : "",
worker->isGamepad? "gamepad " : "", worker->isGamepad? "gamepad " : "");
worker->isKeyboard? "keyboard " : "");
// Create a thread for this device // Create a thread for this device
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker); int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
@ -5563,7 +5565,7 @@ static void EventThreadSpawn(char *device)
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum; if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
} }
// Find toucnscreens with lower indexes // Find touchscreens with lower indexes
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i) for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{ {
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber)) if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
@ -5582,8 +5584,7 @@ static void EventThreadSpawn(char *device)
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
} }
// Input device events reading thread static void PollKeyboardEvents(void)
static void *EventThread(void *arg)
{ {
// Scancode to keycode mapping for US keyboards // Scancode to keycode mapping for US keyboards
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard: // TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
@ -5605,12 +5606,62 @@ static void *EventThread(void *arg)
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242, 227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
243,244,245,246,247,248,0,0,0,0,0,0,0, }; 243,244,245,246,247,248,0,0,0,0,0,0,0, };
int fd = CORE.Input.Keyboard.fd;
if (fd == -1) return;
struct input_event event;
int keycode;
// Try to read data from the keyboard and only continue if successful
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
{
// Button parsing
if (event.type == EV_KEY)
{
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
{
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
if (event.value >= 1)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
CORE.Input.Keyboard.keyPressedQueueCount++;
}
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
}
}
}
// Input device events reading thread
static void *EventThread(void *arg)
{
struct input_event event; struct input_event event;
InputEventWorker *worker = (InputEventWorker *)arg; InputEventWorker *worker = (InputEventWorker *)arg;
int touchAction = -1; int touchAction = -1;
bool gestureUpdate = false; bool gestureUpdate = false;
int keycode;
while (!CORE.Window.shouldClose) while (!CORE.Window.shouldClose)
{ {
@ -5710,39 +5761,6 @@ static void *EventThread(void *arg)
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value; if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value; if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
{
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
if (event.value >= 1)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
CORE.Input.Keyboard.keyPressedQueueCount++;
}
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
} }
// Screen confinement // Screen confinement

View File

@ -1100,9 +1100,12 @@ void rlFrustum(double left, double right, double bottom, double top, double znea
// Multiply the current matrix by an orthographic matrix generated by parameters // Multiply the current matrix by an orthographic matrix generated by parameters
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
{ {
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar); if (((right - left) > 0) && ((bottom - top) > 0))
{
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho); Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
}
else *RLGL.State.currentMatrix = MatrixIdentity();
} }
#endif #endif
@ -4788,8 +4791,8 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
// Count mipmap levels required // Count mipmap levels required
while ((width != 1) && (height != 1)) while ((width != 1) && (height != 1))
{ {
if (width != 1) width /= 2; width /= 2;
if (height != 1) height /= 2; height /= 2;
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height); TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);