|
@@ -3,17 +3,17 @@
|
|
|
* rcore - Window/display management, Graphic device/context management and input management
|
|
|
*
|
|
|
* PLATFORMS SUPPORTED:
|
|
|
-* - PLATFORM_DESKTOP:
|
|
|
+* - PLATFORM_DESKTOP:
|
|
|
* > Windows (Win32, Win64)
|
|
|
* > Linux (X11/Wayland desktop mode)
|
|
|
* > macOS/OSX (x64, arm64)
|
|
|
* > FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop)
|
|
|
-* - PLATFORM_WEB:
|
|
|
+* - PLATFORM_WEB:
|
|
|
* > HTML5 (WebAssembly)
|
|
|
-* - PLATFORM_DRM:
|
|
|
+* - PLATFORM_DRM:
|
|
|
* > Raspberry Pi 0-5
|
|
|
* > Linux native mode (KMS driver)
|
|
|
-* - PLATFORM_ANDROID:
|
|
|
+* - PLATFORM_ANDROID:
|
|
|
* > Android (ARM, ARM64)
|
|
|
*
|
|
|
* CONFIGURATION:
|
|
@@ -48,8 +48,8 @@
|
|
|
* provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module
|
|
|
* for linkage
|
|
|
*
|
|
|
-* #define SUPPORT_EVENTS_AUTOMATION
|
|
|
-* Support automatic generated events, loading and recording of those events when required
|
|
|
+* #define SUPPORT_AUTOMATION_EVENTS
|
|
|
+* Support automatic events recording and playing, useful for automated testing systems or AI based game playing
|
|
|
*
|
|
|
* DEPENDENCIES:
|
|
|
* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
|
|
@@ -183,9 +183,8 @@ bool gifRecording = false; // GIF recording state
|
|
|
MsfGifState gifState = { 0 }; // MSGIF context state
|
|
|
#endif
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
-#define MAX_CODE_AUTOMATION_EVENTS 16384
|
|
|
-
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+// Automation events type
|
|
|
typedef enum AutomationEventType {
|
|
|
EVENT_NONE = 0,
|
|
|
// Input events
|
|
@@ -212,12 +211,12 @@ typedef enum AutomationEventType {
|
|
|
WINDOW_MINIMIZE, // no params
|
|
|
WINDOW_RESIZE, // param[0]: width, param[1]: height
|
|
|
// Custom events
|
|
|
- ACTION_TAKE_SCREENSHOT,
|
|
|
- ACTION_SETTARGETFPS
|
|
|
+ ACTION_TAKE_SCREENSHOT, // no params
|
|
|
+ ACTION_SETTARGETFPS // param[0]: fps
|
|
|
} AutomationEventType;
|
|
|
|
|
|
-// Event type
|
|
|
-// Used to enable events flags
|
|
|
+// Event type to config events flags
|
|
|
+// TODO: Not used at the moment
|
|
|
typedef enum {
|
|
|
EVENT_INPUT_KEYBOARD = 0,
|
|
|
EVENT_INPUT_MOUSE = 1,
|
|
@@ -228,6 +227,7 @@ typedef enum {
|
|
|
EVENT_CUSTOM = 32
|
|
|
} EventType;
|
|
|
|
|
|
+// Event type name strings, required for export
|
|
|
static const char *autoEventTypeName[] = {
|
|
|
"EVENT_NONE",
|
|
|
"INPUT_KEY_UP",
|
|
@@ -255,19 +255,19 @@ static const char *autoEventTypeName[] = {
|
|
|
"ACTION_SETTARGETFPS"
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
// Automation event (24 bytes)
|
|
|
-typedef struct AutomationEvent {
|
|
|
+// NOTE: Opaque struct, internal to raylib
|
|
|
+struct AutomationEvent {
|
|
|
unsigned int frame; // Event frame
|
|
|
unsigned int type; // Event type (AutomationEventType)
|
|
|
int params[4]; // Event parameters (if required)
|
|
|
-} AutomationEvent;
|
|
|
-
|
|
|
-static AutomationEvent *events = NULL; // Events array
|
|
|
-static unsigned int eventCount = 0; // Events count
|
|
|
-static bool eventsPlaying = false; // Play events
|
|
|
-static bool eventsRecording = false; // Record events
|
|
|
+};
|
|
|
+*/
|
|
|
|
|
|
-//static short eventsEnabled = 0b0000001111111111; // Events enabled for checking
|
|
|
+static AutomationEventList *currentEventList = NULL; // Current automation events list, set by user, keep internal pointer
|
|
|
+static bool automationEventRecording = false; // Recording automation events flag
|
|
|
+//static short automationEventEnabled = 0b0000001111111111; // TODO: Automation events enabled for recording/playing
|
|
|
#endif
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
@@ -291,11 +291,8 @@ static void SetupViewport(int width, int height); // Set viewport for
|
|
|
static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path
|
|
|
static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories recursively from a base path
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
-static void LoadAutomationEvents(const char *fileName); // Load automation events from file
|
|
|
-static void ExportAutomationEvents(const char *fileName); // Export recorded automation events into a file
|
|
|
-static void RecordAutomationEvent(unsigned int frame); // Record frame events (to internal events array)
|
|
|
-static void PlayAutomationEvent(unsigned int frame); // Play frame events (from internal events array)
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+static void RecordAutomationEvent(void); // Record frame events (to internal events array)
|
|
|
#endif
|
|
|
|
|
|
#if defined(_WIN32)
|
|
@@ -304,14 +301,14 @@ void __stdcall Sleep(unsigned long msTimeout); // Required for: Wai
|
|
|
#endif
|
|
|
|
|
|
#if !defined(SUPPORT_MODULE_RTEXT)
|
|
|
-const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
|
|
+const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
|
|
|
#endif // !SUPPORT_MODULE_RTEXT
|
|
|
|
|
|
// Include platform-specific submodules
|
|
|
#if defined(PLATFORM_DESKTOP)
|
|
|
#include "platforms/rcore_desktop.c"
|
|
|
#elif defined(PLATFORM_DESKTOP_SDL)
|
|
|
- #include "platforms/rcore_desktop_sdl.c"
|
|
|
+ #include "platforms/rcore_desktop_sdl.c"
|
|
|
#elif defined(PLATFORM_WEB)
|
|
|
#include "platforms/rcore_web.c"
|
|
|
#elif defined(PLATFORM_DRM)
|
|
@@ -434,12 +431,12 @@ void InitWindow(int width, int height, const char *title)
|
|
|
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
|
|
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
|
|
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
|
|
-
|
|
|
+
|
|
|
// Initialize platform
|
|
|
- //--------------------------------------------------------------
|
|
|
+ //--------------------------------------------------------------
|
|
|
InitPlatform();
|
|
|
//--------------------------------------------------------------
|
|
|
-
|
|
|
+
|
|
|
// Initialize rlgl default data (buffers and shaders)
|
|
|
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
|
|
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
|
@@ -485,9 +482,6 @@ void InitWindow(int width, int height, const char *title)
|
|
|
#endif
|
|
|
|
|
|
CORE.Time.frameCounter = 0;
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
- events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent));
|
|
|
-#endif
|
|
|
|
|
|
// Initialize random seed
|
|
|
SetRandomSeed((unsigned int)time(NULL));
|
|
@@ -512,14 +506,10 @@ void CloseWindow(void)
|
|
|
rlglClose(); // De-init rlgl
|
|
|
|
|
|
// De-initialize platform
|
|
|
- //--------------------------------------------------------------
|
|
|
+ //--------------------------------------------------------------
|
|
|
ClosePlatform();
|
|
|
//--------------------------------------------------------------
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
- RL_FREE(events);
|
|
|
-#endif
|
|
|
-
|
|
|
CORE.Window.ready = false;
|
|
|
TRACELOG(LOG_INFO, "Window closed successfully");
|
|
|
}
|
|
@@ -684,34 +674,6 @@ void EndDrawing(void)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
- // Draw record/play indicator
|
|
|
- if (eventsRecording)
|
|
|
- {
|
|
|
- gifFrameCounter++;
|
|
|
-
|
|
|
- if (((gifFrameCounter/15)%2) == 1)
|
|
|
- {
|
|
|
- DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON);
|
|
|
- DrawText("EVENTS RECORDING", 50, CORE.Window.screen.height - 25, 10, RED);
|
|
|
- }
|
|
|
-
|
|
|
- rlDrawRenderBatchActive(); // Update and draw internal render batch
|
|
|
- }
|
|
|
- else if (eventsPlaying)
|
|
|
- {
|
|
|
- gifFrameCounter++;
|
|
|
-
|
|
|
- if (((gifFrameCounter/15)%2) == 1)
|
|
|
- {
|
|
|
- DrawCircle(30, CORE.Window.screen.height - 20, 10, LIME);
|
|
|
- DrawText("EVENTS PLAYING", 50, CORE.Window.screen.height - 25, 10, GREEN);
|
|
|
- }
|
|
|
-
|
|
|
- rlDrawRenderBatchActive(); // Update and draw internal render batch
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
|
|
|
SwapScreenBuffer(); // Copy back buffer to front buffer (screen)
|
|
|
|
|
@@ -775,16 +737,9 @@ void EndDrawing(void)
|
|
|
}
|
|
|
#endif // SUPPORT_SCREEN_CAPTURE
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
- // Events recording and playing logic
|
|
|
- if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter);
|
|
|
- else if (eventsPlaying)
|
|
|
- {
|
|
|
- // TODO: When should we play? After/before/replace PollInputEvents()?
|
|
|
- if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false;
|
|
|
- PlayAutomationEvent(CORE.Time.frameCounter);
|
|
|
- }
|
|
|
-#endif // SUPPORT_EVENTS_AUTOMATION
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ if (automationEventRecording) RecordAutomationEvent(); // Event recording
|
|
|
+#endif
|
|
|
|
|
|
CORE.Time.frameCounter++;
|
|
|
}
|
|
@@ -1470,7 +1425,7 @@ float GetFrameTime(void)
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
|
|
// NOTE: Functions with a platform-specific implementation on rcore_<platform>.c
|
|
|
-//void SwapScreenBuffer(void);
|
|
|
+//void SwapScreenBuffer(void);
|
|
|
//void PollInputEvents(void);
|
|
|
|
|
|
// Wait for some time (stop program execution)
|
|
@@ -1481,7 +1436,7 @@ float GetFrameTime(void)
|
|
|
void WaitTime(double seconds)
|
|
|
{
|
|
|
if (seconds < 0) return;
|
|
|
-
|
|
|
+
|
|
|
#if defined(SUPPORT_BUSY_WAIT_LOOP) || defined(SUPPORT_PARTIALBUSY_WAIT_LOOP)
|
|
|
double destinationTime = GetTime() + seconds;
|
|
|
#endif
|
|
@@ -2180,6 +2135,237 @@ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize)
|
|
|
return decodedData;
|
|
|
}
|
|
|
|
|
|
+//----------------------------------------------------------------------------------
|
|
|
+// Module Functions Definition: Automation Events Recording and Playing
|
|
|
+//----------------------------------------------------------------------------------
|
|
|
+
|
|
|
+// Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
|
|
+AutomationEventList LoadAutomationEventList(const char *fileName)
|
|
|
+{
|
|
|
+ AutomationEventList list = { 0 };
|
|
|
+
|
|
|
+ // Allocate and empty automation event list, ready to record new events
|
|
|
+ list.events = (AutomationEvent *)RL_CALLOC(MAX_AUTOMATION_EVENTS, sizeof(AutomationEvent));
|
|
|
+ list.capacity = MAX_AUTOMATION_EVENTS;
|
|
|
+
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ if (fileName == NULL) TRACELOG(LOG_INFO, "AUTOMATION: New empty events list loaded successfully");
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Load automation events file (binary)
|
|
|
+ /*
|
|
|
+ //int dataSize = 0;
|
|
|
+ //unsigned char *data = LoadFileData(fileName, &dataSize);
|
|
|
+
|
|
|
+ FILE *raeFile = fopen(fileName, "rb");
|
|
|
+ unsigned char fileId[4] = { 0 };
|
|
|
+
|
|
|
+ fread(fileId, 1, 4, raeFile);
|
|
|
+
|
|
|
+ if ((fileId[0] == 'r') && (fileId[1] == 'A') && (fileId[2] == 'E') && (fileId[1] == ' '))
|
|
|
+ {
|
|
|
+ fread(&eventCount, sizeof(int), 1, raeFile);
|
|
|
+ TRACELOG(LOG_WARNING, "Events loaded: %i\n", eventCount);
|
|
|
+ fread(events, sizeof(AutomationEvent), eventCount, raeFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(raeFile);
|
|
|
+ */
|
|
|
+
|
|
|
+ // Load events file (text)
|
|
|
+ //unsigned char *buffer = LoadFileText(fileName);
|
|
|
+ FILE *raeFile = fopen(fileName, "rt");
|
|
|
+
|
|
|
+ if (raeFile != NULL)
|
|
|
+ {
|
|
|
+ unsigned int counter = 0;
|
|
|
+ char buffer[256] = { 0 };
|
|
|
+ char eventDesc[64] = { 0 };
|
|
|
+
|
|
|
+ fgets(buffer, 256, raeFile);
|
|
|
+
|
|
|
+ while (!feof(raeFile))
|
|
|
+ {
|
|
|
+ switch (buffer[0])
|
|
|
+ {
|
|
|
+ case 'c': sscanf(buffer, "c %i", &list.count); break;
|
|
|
+ case 'e':
|
|
|
+ {
|
|
|
+ sscanf(buffer, "e %d %d %d %d %d %d %[^\n]s", &list.events[counter].frame, &list.events[counter].type,
|
|
|
+ &list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
|
|
|
+
|
|
|
+ counter++;
|
|
|
+ } break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+
|
|
|
+ fgets(buffer, 256, raeFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (counter != list.count)
|
|
|
+ {
|
|
|
+ TRACELOG(LOG_WARNING, "AUTOMATION: Events read from file [%i] do not mach event count specified [%i]", counter, list.count);
|
|
|
+ list.count = counter;
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(raeFile);
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Events file loaded successfully");
|
|
|
+ }
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Events loaded from file: %i", list.count);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return list;
|
|
|
+}
|
|
|
+
|
|
|
+// Unload automation events list from file
|
|
|
+void UnloadAutomationEventList(AutomationEventList *list)
|
|
|
+{
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ RL_FREE(list->events);
|
|
|
+ list->events = NULL;
|
|
|
+ list->count = 0;
|
|
|
+ list->capacity = 0;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Export automation events list as text file
|
|
|
+bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
|
|
|
+{
|
|
|
+ bool success = false;
|
|
|
+
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ // Export events as binary file
|
|
|
+ // TODO: Save to memory buffer and SaveFileData()
|
|
|
+ /*
|
|
|
+ unsigned char fileId[4] = "rAE ";
|
|
|
+ FILE *raeFile = fopen(fileName, "wb");
|
|
|
+ fwrite(fileId, sizeof(unsigned char), 4, raeFile);
|
|
|
+ fwrite(&eventCount, sizeof(int), 1, raeFile);
|
|
|
+ fwrite(events, sizeof(AutomationEvent), eventCount, raeFile);
|
|
|
+ fclose(raeFile);
|
|
|
+ */
|
|
|
+
|
|
|
+ // Export events as text
|
|
|
+ // TODO: Save to memory buffer and SaveFileText()
|
|
|
+ char *txtData = (char *)RL_CALLOC(256*list.count + 2048, sizeof(char)); // 256 characters per line plus some header
|
|
|
+
|
|
|
+ int byteCount = 0;
|
|
|
+ byteCount += sprintf(txtData + byteCount, "#\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# Automation events exporter v1.0 - raylib automation events list\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "#\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# c <events_count>\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# e <frame> <event_type> <param0> <param1> <param2> <param3> // <event_type_name>\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "#\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# more info and bugs-report: github.com/raysan5/raylib\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# feedback and support: ray[at]raylib.com\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "#\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "# Copyright (c) 2023-2024 Ramon Santamaria (@raysan5)\n");
|
|
|
+ byteCount += sprintf(txtData + byteCount, "#\n\n");
|
|
|
+
|
|
|
+ // Add events data
|
|
|
+ byteCount += sprintf(txtData + byteCount, "c %i\n", list.count);
|
|
|
+ for (int i = 0; i < list.count; i++)
|
|
|
+ {
|
|
|
+ byteCount += sprintf(txtData + byteCount, "e %i %i %i %i %i %i // Event: %s\n", list.events[i].frame, list.events[i].type,
|
|
|
+ list.events[i].params[0], list.events[i].params[1], list.events[i].params[2], list.events[i].params[3], autoEventTypeName[list.events[i].type]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // NOTE: Text data size exported is determined by '\0' (NULL) character
|
|
|
+ success = SaveFileText(fileName, txtData);
|
|
|
+
|
|
|
+ RL_FREE(txtData);
|
|
|
+#endif
|
|
|
+
|
|
|
+ return success;
|
|
|
+}
|
|
|
+
|
|
|
+// Setup automation event list to record to
|
|
|
+void SetAutomationEventList(AutomationEventList *list)
|
|
|
+{
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ currentEventList = list;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Start recording automation events (AutomationEventList must be set)
|
|
|
+void StartAutomationEventRecording(void)
|
|
|
+{
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ automationEventRecording = true;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Stop recording automation events
|
|
|
+void StopAutomationEventRecording(void)
|
|
|
+{
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ automationEventRecording = false;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Play a recorded automation event
|
|
|
+void PlayAutomationEvent(AutomationEvent event)
|
|
|
+{
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+ // WARNING: When should event be played? After/before/replace PollInputEvents()? -> Up to the user!
|
|
|
+
|
|
|
+ if (!automationEventRecording) // TODO: Allow recording events while playing?
|
|
|
+ {
|
|
|
+ switch (event.type)
|
|
|
+ {
|
|
|
+ // Input event
|
|
|
+ case INPUT_KEY_UP: CORE.Input.Keyboard.currentKeyState[event.params[0]] = false; break; // param[0]: key
|
|
|
+ case INPUT_KEY_DOWN: CORE.Input.Keyboard.currentKeyState[event.params[0]] = true; break; // param[0]: key
|
|
|
+ case INPUT_MOUSE_BUTTON_UP: CORE.Input.Mouse.currentButtonState[event.params[0]] = false; break; // param[0]: key
|
|
|
+ case INPUT_MOUSE_BUTTON_DOWN: CORE.Input.Mouse.currentButtonState[event.params[0]] = true; break; // param[0]: key
|
|
|
+ case INPUT_MOUSE_POSITION: // param[0]: x, param[1]: y
|
|
|
+ {
|
|
|
+ CORE.Input.Mouse.currentPosition.x = (float)event.params[0];
|
|
|
+ CORE.Input.Mouse.currentPosition.y = (float)event.params[1];
|
|
|
+ } break;
|
|
|
+ case INPUT_MOUSE_WHEEL_MOTION: // param[0]: x delta, param[1]: y delta
|
|
|
+ {
|
|
|
+ CORE.Input.Mouse.currentWheelMove.x = (float)event.params[0]; break;
|
|
|
+ CORE.Input.Mouse.currentWheelMove.y = (float)event.params[1]; break;
|
|
|
+ } break;
|
|
|
+ case INPUT_TOUCH_UP: CORE.Input.Touch.currentTouchState[event.params[0]] = false; break; // param[0]: id
|
|
|
+ case INPUT_TOUCH_DOWN: CORE.Input.Touch.currentTouchState[event.params[0]] = true; break; // param[0]: id
|
|
|
+ case INPUT_TOUCH_POSITION: // param[0]: id, param[1]: x, param[2]: y
|
|
|
+ {
|
|
|
+ CORE.Input.Touch.position[event.params[0]].x = (float)event.params[1];
|
|
|
+ CORE.Input.Touch.position[event.params[0]].y = (float)event.params[2];
|
|
|
+ } break;
|
|
|
+ case INPUT_GAMEPAD_CONNECT: CORE.Input.Gamepad.ready[event.params[0]] = true; break; // param[0]: gamepad
|
|
|
+ case INPUT_GAMEPAD_DISCONNECT: CORE.Input.Gamepad.ready[event.params[0]] = false; break; // param[0]: gamepad
|
|
|
+ case INPUT_GAMEPAD_BUTTON_UP: CORE.Input.Gamepad.currentButtonState[event.params[0]][event.params[1]] = false; break; // param[0]: gamepad, param[1]: button
|
|
|
+ case INPUT_GAMEPAD_BUTTON_DOWN: CORE.Input.Gamepad.currentButtonState[event.params[0]][event.params[1]] = true; break; // param[0]: gamepad, param[1]: button
|
|
|
+ case INPUT_GAMEPAD_AXIS_MOTION: // param[0]: gamepad, param[1]: axis, param[2]: delta
|
|
|
+ {
|
|
|
+ CORE.Input.Gamepad.axisState[event.params[0]][event.params[1]] = ((float)event.params[2]/32768.0f);
|
|
|
+ } break;
|
|
|
+ case INPUT_GESTURE: GESTURES.current = event.params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current
|
|
|
+
|
|
|
+ // Window event
|
|
|
+ case WINDOW_CLOSE: CORE.Window.shouldClose = true; break;
|
|
|
+ case WINDOW_MAXIMIZE: MaximizeWindow(); break;
|
|
|
+ case WINDOW_MINIMIZE: MinimizeWindow(); break;
|
|
|
+ case WINDOW_RESIZE: SetWindowSize(event.params[0], event.params[1]); break;
|
|
|
+
|
|
|
+ // Custom event
|
|
|
+ case ACTION_TAKE_SCREENSHOT:
|
|
|
+ {
|
|
|
+ TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
|
|
+ screenshotCounter++;
|
|
|
+ } break;
|
|
|
+ case ACTION_SETTARGETFPS: SetTargetFPS(event.params[0]); break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Module Functions Definition: Input Handling: Keyboard
|
|
|
//----------------------------------------------------------------------------------
|
|
@@ -2793,233 +2979,180 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
|
|
|
else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath);
|
|
|
}
|
|
|
|
|
|
-#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
-// NOTE: Loading happens over AutomationEvent *events
|
|
|
-// TODO: This system should probably be redesigned
|
|
|
-static void LoadAutomationEvents(const char *fileName)
|
|
|
-{
|
|
|
- // Load events file (binary)
|
|
|
- /*
|
|
|
- FILE *repFile = fopen(fileName, "rb");
|
|
|
- unsigned char fileId[4] = { 0 };
|
|
|
-
|
|
|
- fread(fileId, 1, 4, repFile);
|
|
|
-
|
|
|
- if ((fileId[0] == 'r') && (fileId[1] == 'E') && (fileId[2] == 'P') && (fileId[1] == ' '))
|
|
|
- {
|
|
|
- fread(&eventCount, sizeof(int), 1, repFile);
|
|
|
- TRACELOG(LOG_WARNING, "Events loaded: %i\n", eventCount);
|
|
|
- fread(events, sizeof(AutomationEvent), eventCount, repFile);
|
|
|
- }
|
|
|
-
|
|
|
- fclose(repFile);
|
|
|
- */
|
|
|
-
|
|
|
- // Load events file (text)
|
|
|
- FILE *repFile = fopen(fileName, "rt");
|
|
|
-
|
|
|
- if (repFile != NULL)
|
|
|
- {
|
|
|
- unsigned int count = 0;
|
|
|
- char buffer[256] = { 0 };
|
|
|
-
|
|
|
- fgets(buffer, 256, repFile);
|
|
|
-
|
|
|
- while (!feof(repFile))
|
|
|
- {
|
|
|
- if (buffer[0] == 'c') sscanf(buffer, "c %i", &eventCount);
|
|
|
- else if (buffer[0] == 'e')
|
|
|
- {
|
|
|
- sscanf(buffer, "e %d %d %d %d %d", &events[count].frame, &events[count].type,
|
|
|
- &events[count].params[0], &events[count].params[1], &events[count].params[2]);
|
|
|
-
|
|
|
- count++;
|
|
|
- }
|
|
|
-
|
|
|
- fgets(buffer, 256, repFile);
|
|
|
- }
|
|
|
-
|
|
|
- if (count != eventCount) TRACELOG(LOG_WARNING, "Events count provided is different than count");
|
|
|
-
|
|
|
- fclose(repFile);
|
|
|
- }
|
|
|
-
|
|
|
- TRACELOG(LOG_WARNING, "Events loaded: %i", eventCount);
|
|
|
-}
|
|
|
-
|
|
|
-// Export recorded events into a file
|
|
|
-static void ExportAutomationEvents(const char *fileName)
|
|
|
+#if defined(SUPPORT_AUTOMATION_EVENTS)
|
|
|
+// Automation event recording
|
|
|
+// NOTE: Recording is by default done at EndDrawing(), after PollInputEvents()
|
|
|
+static void RecordAutomationEvent(void)
|
|
|
{
|
|
|
- unsigned char fileId[4] = "rEP ";
|
|
|
-
|
|
|
- // Save as binary
|
|
|
- /*
|
|
|
- FILE *repFile = fopen(fileName, "wb");
|
|
|
- fwrite(fileId, sizeof(unsigned char), 4, repFile);
|
|
|
- fwrite(&eventCount, sizeof(int), 1, repFile);
|
|
|
- fwrite(events, sizeof(AutomationEvent), eventCount, repFile);
|
|
|
- fclose(repFile);
|
|
|
- */
|
|
|
-
|
|
|
- // Export events as text
|
|
|
- FILE *repFile = fopen(fileName, "wt");
|
|
|
-
|
|
|
- if (repFile != NULL)
|
|
|
- {
|
|
|
- fprintf(repFile, "# Automation events list\n");
|
|
|
- fprintf(repFile, "# c <events_count>\n");
|
|
|
- fprintf(repFile, "# e <frame> <event_type> <param0> <param1> <param2> // <event_type_name>\n");
|
|
|
-
|
|
|
- fprintf(repFile, "c %i\n", eventCount);
|
|
|
- for (int i = 0; i < eventCount; i++)
|
|
|
- {
|
|
|
- fprintf(repFile, "e %i %i %i %i %i // %s\n", events[i].frame, events[i].type,
|
|
|
- events[i].params[0], events[i].params[1], events[i].params[2], autoEventTypeName[events[i].type]);
|
|
|
- }
|
|
|
-
|
|
|
- fclose(repFile);
|
|
|
- }
|
|
|
-}
|
|
|
+ // Checking events in current frame and save them into currentEventList
|
|
|
+ // TODO: How important is the current frame? Could it be modified?
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
-// EndDrawing() -> After PollInputEvents()
|
|
|
-// Check event in current frame and save into the events[i] array
|
|
|
-static void RecordAutomationEvent(unsigned int frame)
|
|
|
-{
|
|
|
+ // Keyboard input events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
for (int key = 0; key < MAX_KEYBOARD_KEYS; key++)
|
|
|
{
|
|
|
- // INPUT_KEY_UP (only saved once)
|
|
|
+ // Event type: INPUT_KEY_UP (only saved once)
|
|
|
if (CORE.Input.Keyboard.previousKeyState[key] && !CORE.Input.Keyboard.currentKeyState[key])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_KEY_UP;
|
|
|
- events[eventCount].params[0] = key;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_KEY_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_KEY_UP;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = key;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_KEY_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
- // INPUT_KEY_DOWN
|
|
|
+ // Event type: INPUT_KEY_DOWN
|
|
|
if (CORE.Input.Keyboard.currentKeyState[key])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_KEY_DOWN;
|
|
|
- events[eventCount].params[0] = key;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_KEY_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_KEY_DOWN;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = key;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_KEY_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
|
|
|
+ // Mouse input currentEventList->events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
for (int button = 0; button < MAX_MOUSE_BUTTONS; button++)
|
|
|
{
|
|
|
- // INPUT_MOUSE_BUTTON_UP
|
|
|
+ // Event type: INPUT_MOUSE_BUTTON_UP
|
|
|
if (CORE.Input.Mouse.previousButtonState[button] && !CORE.Input.Mouse.currentButtonState[button])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_MOUSE_BUTTON_UP;
|
|
|
- events[eventCount].params[0] = button;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_MOUSE_BUTTON_UP;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = button;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_BUTTON_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
- // INPUT_MOUSE_BUTTON_DOWN
|
|
|
+ // Event type: INPUT_MOUSE_BUTTON_DOWN
|
|
|
if (CORE.Input.Mouse.currentButtonState[button])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_MOUSE_BUTTON_DOWN;
|
|
|
- events[eventCount].params[0] = button;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_MOUSE_BUTTON_DOWN;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = button;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_BUTTON_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
|
|
|
- // INPUT_MOUSE_POSITION (only saved if changed)
|
|
|
+ // Event type: INPUT_MOUSE_POSITION (only saved if changed)
|
|
|
if (((int)CORE.Input.Mouse.currentPosition.x != (int)CORE.Input.Mouse.previousPosition.x) ||
|
|
|
((int)CORE.Input.Mouse.currentPosition.y != (int)CORE.Input.Mouse.previousPosition.y))
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_MOUSE_POSITION;
|
|
|
- events[eventCount].params[0] = (int)CORE.Input.Mouse.currentPosition.x;
|
|
|
- events[eventCount].params[1] = (int)CORE.Input.Mouse.currentPosition.y;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_MOUSE_POSITION;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentPosition.x;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentPosition.y;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_POSITION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
|
|
|
- // INPUT_MOUSE_WHEEL_MOTION
|
|
|
+ // Event type: INPUT_MOUSE_WHEEL_MOTION
|
|
|
if (((int)CORE.Input.Mouse.currentWheelMove.x != (int)CORE.Input.Mouse.previousWheelMove.x) ||
|
|
|
((int)CORE.Input.Mouse.currentWheelMove.y != (int)CORE.Input.Mouse.previousWheelMove.y))
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_MOUSE_WHEEL_MOTION;
|
|
|
- events[eventCount].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x;
|
|
|
- events[eventCount].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_MOUSE_WHEEL_MOTION;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_MOUSE_WHEEL_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_WHEEL_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
|
|
|
+ // Touch input currentEventList->events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
for (int id = 0; id < MAX_TOUCH_POINTS; id++)
|
|
|
{
|
|
|
- // INPUT_TOUCH_UP
|
|
|
+ // Event type: INPUT_TOUCH_UP
|
|
|
if (CORE.Input.Touch.previousTouchState[id] && !CORE.Input.Touch.currentTouchState[id])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_TOUCH_UP;
|
|
|
- events[eventCount].params[0] = id;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_TOUCH_UP;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = id;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
- // INPUT_TOUCH_DOWN
|
|
|
+ // Event type: INPUT_TOUCH_DOWN
|
|
|
if (CORE.Input.Touch.currentTouchState[id])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_TOUCH_DOWN;
|
|
|
- events[eventCount].params[0] = id;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_TOUCH_DOWN;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = id;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
- // INPUT_TOUCH_POSITION
|
|
|
+ // Event type: INPUT_TOUCH_POSITION
|
|
|
// TODO: It requires the id!
|
|
|
/*
|
|
|
if (((int)CORE.Input.Touch.currentPosition[id].x != (int)CORE.Input.Touch.previousPosition[id].x) ||
|
|
|
((int)CORE.Input.Touch.currentPosition[id].y != (int)CORE.Input.Touch.previousPosition[id].y))
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_TOUCH_POSITION;
|
|
|
- events[eventCount].params[0] = id;
|
|
|
- events[eventCount].params[1] = (int)CORE.Input.Touch.currentPosition[id].x;
|
|
|
- events[eventCount].params[2] = (int)CORE.Input.Touch.currentPosition[id].y;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_TOUCH_POSITION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_TOUCH_POSITION;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = id;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.currentPosition[id].x;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.currentPosition[id].y;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
*/
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
|
|
|
+ // Gamepad input currentEventList->events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
for (int gamepad = 0; gamepad < MAX_GAMEPADS; gamepad++)
|
|
|
{
|
|
|
- // INPUT_GAMEPAD_CONNECT
|
|
|
+ // Event type: INPUT_GAMEPAD_CONNECT
|
|
|
/*
|
|
|
if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) &&
|
|
|
(CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to ready
|
|
@@ -3028,7 +3161,7 @@ static void RecordAutomationEvent(unsigned int frame)
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
- // INPUT_GAMEPAD_DISCONNECT
|
|
|
+ // Event type: INPUT_GAMEPAD_DISCONNECT
|
|
|
/*
|
|
|
if ((CORE.Input.Gamepad.currentState[gamepad] != CORE.Input.Gamepad.previousState[gamepad]) &&
|
|
|
(!CORE.Input.Gamepad.currentState[gamepad])) // Check if changed to not-ready
|
|
@@ -3039,122 +3172,84 @@ static void RecordAutomationEvent(unsigned int frame)
|
|
|
|
|
|
for (int button = 0; button < MAX_GAMEPAD_BUTTONS; button++)
|
|
|
{
|
|
|
- // INPUT_GAMEPAD_BUTTON_UP
|
|
|
+ // Event type: INPUT_GAMEPAD_BUTTON_UP
|
|
|
if (CORE.Input.Gamepad.previousButtonState[gamepad][button] && !CORE.Input.Gamepad.currentButtonState[gamepad][button])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_GAMEPAD_BUTTON_UP;
|
|
|
- events[eventCount].params[0] = gamepad;
|
|
|
- events[eventCount].params[1] = button;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_BUTTON_UP: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_BUTTON_UP;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = gamepad;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = button;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_BUTTON_UP | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
|
|
|
- // INPUT_GAMEPAD_BUTTON_DOWN
|
|
|
+ // Event type: INPUT_GAMEPAD_BUTTON_DOWN
|
|
|
if (CORE.Input.Gamepad.currentButtonState[gamepad][button])
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_GAMEPAD_BUTTON_DOWN;
|
|
|
- events[eventCount].params[0] = gamepad;
|
|
|
- events[eventCount].params[1] = button;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_BUTTON_DOWN: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_BUTTON_DOWN;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = gamepad;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = button;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_BUTTON_DOWN | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
|
|
|
for (int axis = 0; axis < MAX_GAMEPAD_AXIS; axis++)
|
|
|
{
|
|
|
- // INPUT_GAMEPAD_AXIS_MOTION
|
|
|
+ // Event type: INPUT_GAMEPAD_AXIS_MOTION
|
|
|
if (CORE.Input.Gamepad.axisState[gamepad][axis] > 0.1f)
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_GAMEPAD_AXIS_MOTION;
|
|
|
- events[eventCount].params[0] = gamepad;
|
|
|
- events[eventCount].params[1] = axis;
|
|
|
- events[eventCount].params[2] = (int)(CORE.Input.Gamepad.axisState[gamepad][axis]*32768.0f);
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_GAMEPAD_AXIS_MOTION: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_AXIS_MOTION;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = gamepad;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = axis;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = (int)(CORE.Input.Gamepad.axisState[gamepad][axis]*32768.0f);
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GAMEPAD_AXIS_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
}
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
}
|
|
|
}
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
|
|
|
- // INPUT_GESTURE
|
|
|
+ // Gestures input currentEventList->events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
if (GESTURES.current != GESTURE_NONE)
|
|
|
{
|
|
|
- events[eventCount].frame = frame;
|
|
|
- events[eventCount].type = INPUT_GESTURE;
|
|
|
- events[eventCount].params[0] = GESTURES.current;
|
|
|
- events[eventCount].params[1] = 0;
|
|
|
- events[eventCount].params[2] = 0;
|
|
|
-
|
|
|
- TRACELOG(LOG_INFO, "[%i] INPUT_GESTURE: %i, %i, %i", events[eventCount].frame, events[eventCount].params[0], events[eventCount].params[1], events[eventCount].params[2]);
|
|
|
- eventCount++;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Play automation event
|
|
|
-static void PlayAutomationEvent(unsigned int frame)
|
|
|
-{
|
|
|
- for (unsigned int i = 0; i < eventCount; i++)
|
|
|
- {
|
|
|
- if (events[i].frame == frame)
|
|
|
- {
|
|
|
- switch (events[i].type)
|
|
|
- {
|
|
|
- // Input events
|
|
|
- case INPUT_KEY_UP: CORE.Input.Keyboard.currentKeyState[events[i].params[0]] = false; break; // param[0]: key
|
|
|
- case INPUT_KEY_DOWN: CORE.Input.Keyboard.currentKeyState[events[i].params[0]] = true; break; // param[0]: key
|
|
|
- case INPUT_MOUSE_BUTTON_UP: CORE.Input.Mouse.currentButtonState[events[i].params[0]] = false; break; // param[0]: key
|
|
|
- case INPUT_MOUSE_BUTTON_DOWN: CORE.Input.Mouse.currentButtonState[events[i].params[0]] = true; break; // param[0]: key
|
|
|
- case INPUT_MOUSE_POSITION: // param[0]: x, param[1]: y
|
|
|
- {
|
|
|
- CORE.Input.Mouse.currentPosition.x = (float)events[i].params[0];
|
|
|
- CORE.Input.Mouse.currentPosition.y = (float)events[i].params[1];
|
|
|
- } break;
|
|
|
- case INPUT_MOUSE_WHEEL_MOTION: // param[0]: x delta, param[1]: y delta
|
|
|
- {
|
|
|
- CORE.Input.Mouse.currentWheelMove.x = (float)events[i].params[0]; break;
|
|
|
- CORE.Input.Mouse.currentWheelMove.y = (float)events[i].params[1]; break;
|
|
|
- } break;
|
|
|
- case INPUT_TOUCH_UP: CORE.Input.Touch.currentTouchState[events[i].params[0]] = false; break; // param[0]: id
|
|
|
- case INPUT_TOUCH_DOWN: CORE.Input.Touch.currentTouchState[events[i].params[0]] = true; break; // param[0]: id
|
|
|
- case INPUT_TOUCH_POSITION: // param[0]: id, param[1]: x, param[2]: y
|
|
|
- {
|
|
|
- CORE.Input.Touch.position[events[i].params[0]].x = (float)events[i].params[1];
|
|
|
- CORE.Input.Touch.position[events[i].params[0]].y = (float)events[i].params[2];
|
|
|
- } break;
|
|
|
- case INPUT_GAMEPAD_CONNECT: CORE.Input.Gamepad.ready[events[i].params[0]] = true; break; // param[0]: gamepad
|
|
|
- case INPUT_GAMEPAD_DISCONNECT: CORE.Input.Gamepad.ready[events[i].params[0]] = false; break; // param[0]: gamepad
|
|
|
- case INPUT_GAMEPAD_BUTTON_UP: CORE.Input.Gamepad.currentButtonState[events[i].params[0]][events[i].params[1]] = false; break; // param[0]: gamepad, param[1]: button
|
|
|
- case INPUT_GAMEPAD_BUTTON_DOWN: CORE.Input.Gamepad.currentButtonState[events[i].params[0]][events[i].params[1]] = true; break; // param[0]: gamepad, param[1]: button
|
|
|
- case INPUT_GAMEPAD_AXIS_MOTION: // param[0]: gamepad, param[1]: axis, param[2]: delta
|
|
|
- {
|
|
|
- CORE.Input.Gamepad.axisState[events[i].params[0]][events[i].params[1]] = ((float)events[i].params[2]/32768.0f);
|
|
|
- } break;
|
|
|
- case INPUT_GESTURE: GESTURES.current = events[i].params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current
|
|
|
-
|
|
|
- // Window events
|
|
|
- case WINDOW_CLOSE: CORE.Window.shouldClose = true; break;
|
|
|
- case WINDOW_MAXIMIZE: MaximizeWindow(); break;
|
|
|
- case WINDOW_MINIMIZE: MinimizeWindow(); break;
|
|
|
- case WINDOW_RESIZE: SetWindowSize(events[i].params[0], events[i].params[1]); break;
|
|
|
-
|
|
|
- // Custom events
|
|
|
- case ACTION_TAKE_SCREENSHOT:
|
|
|
- {
|
|
|
- TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
|
|
- screenshotCounter++;
|
|
|
- } break;
|
|
|
- case ACTION_SETTARGETFPS: SetTargetFPS(events[i].params[0]); break;
|
|
|
- default: break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // Event type: INPUT_GESTURE
|
|
|
+ currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
|
|
|
+ currentEventList->events[currentEventList->count].type = INPUT_GESTURE;
|
|
|
+ currentEventList->events[currentEventList->count].params[0] = GESTURES.current;
|
|
|
+ currentEventList->events[currentEventList->count].params[1] = 0;
|
|
|
+ currentEventList->events[currentEventList->count].params[2] = 0;
|
|
|
+
|
|
|
+ TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_GESTURE | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
|
|
|
+ currentEventList->count++;
|
|
|
+
|
|
|
+ if (currentEventList->count == currentEventList->capacity) return; // Security check
|
|
|
+ }
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
+
|
|
|
+ // Window events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
+ // TODO.
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
+
|
|
|
+ // Custom actions events recording
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
+ // TODO.
|
|
|
+ //-------------------------------------------------------------------------------------
|
|
|
}
|
|
|
#endif
|
|
|
|