mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 06:20:52 -07:00 
			
		
		
		
	Got through parsing raylib.h, started to do some major refactors.
This commit is contained in:
		| @@ -1,89 +1,89 @@ | ||||
| /********************************************************************************************** | ||||
| * | ||||
| *   raylib configuration flags | ||||
| * | ||||
| *   This file defines all the configuration flags for the different raylib modules | ||||
| * | ||||
| *   LICENSE: zlib/libpng | ||||
| * | ||||
| *   Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) | ||||
| * | ||||
| *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
| *   will the authors be held liable for any damages arising from the use of this software. | ||||
| * | ||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
| * | ||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
| *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
| *     in the product documentation would be appreciated but is not required. | ||||
| * | ||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
| *     as being the original software. | ||||
| * | ||||
| *     3. This notice may not be removed or altered from any source distribution. | ||||
| * | ||||
| **********************************************************************************************/ | ||||
|  * | ||||
|  *   raylib configuration flags | ||||
|  * | ||||
|  *   This file defines all the configuration flags for the different raylib modules | ||||
|  * | ||||
|  *   LICENSE: zlib/libpng | ||||
|  * | ||||
|  *   Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) | ||||
|  * | ||||
|  *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
|  *   will the authors be held liable for any damages arising from the use of this software. | ||||
|  * | ||||
|  *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
|  *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
|  * | ||||
|  *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
|  *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
|  *     in the product documentation would be appreciated but is not required. | ||||
|  * | ||||
|  *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
|  *     as being the original software. | ||||
|  * | ||||
|  *     3. This notice may not be removed or altered from any source distribution. | ||||
|  * | ||||
|  **********************************************************************************************/ | ||||
|  | ||||
| #ifndef CONFIG_H | ||||
| #define RL_CONFIG_H  | ||||
| #define RL_CONFIG_H | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module selection - Some modules could be avoided | ||||
| // Mandatory modules: rcore, rlgl, utils | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_SUPPORT_MODULE_RSHAPES  1 | ||||
| #define RL_SUPPORT_MODULE_RTEXTURES  1 | ||||
| #define RL_SUPPORT_MODULE_RTEXT  1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures | ||||
| #define RL_SUPPORT_MODULE_RMODELS  1 | ||||
| #define RL_SUPPORT_MODULE_RAUDIO  1 | ||||
| #define RL_SUPPORT_MODULE_RSHAPES   1 | ||||
| #define RL_SUPPORT_MODULE_RTEXTURES 1 | ||||
| #define RL_SUPPORT_MODULE_RTEXT     1    // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures | ||||
| #define RL_SUPPORT_MODULE_RMODELS   1 | ||||
| #define RL_SUPPORT_MODULE_RAUDIO    1 | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module: rcore - Configuration Flags | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital | ||||
| #define RL_SUPPORT_CAMERA_SYSTEM  1 | ||||
| #define RL_SUPPORT_CAMERA_SYSTEM 1 | ||||
| // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag | ||||
| #define RL_SUPPORT_GESTURES_SYSTEM  1 | ||||
| #define RL_SUPPORT_GESTURES_SYSTEM 1 | ||||
| // Mouse gestures are directly mapped like touches and processed by gestures system | ||||
| #define RL_SUPPORT_MOUSE_GESTURES  1 | ||||
| #define RL_SUPPORT_MOUSE_GESTURES 1 | ||||
| // Reconfigure standard input to receive key inputs, works with SSH connection. | ||||
| #define RL_SUPPORT_SSH_KEYBOARD_RPI  1 | ||||
| #define RL_SUPPORT_SSH_KEYBOARD_RPI 1 | ||||
| // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. | ||||
| // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. | ||||
| #define RL_SUPPORT_WINMM_HIGHRES_TIMER  1 | ||||
| #define RL_SUPPORT_WINMM_HIGHRES_TIMER 1 | ||||
| // Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used | ||||
| //#define SUPPORT_BUSY_WAIT_LOOP          1 | ||||
| // #define SUPPORT_BUSY_WAIT_LOOP          1 | ||||
| // Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy | ||||
| #define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP  1 | ||||
| #define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP 1 | ||||
| // Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() | ||||
| #define RL_SUPPORT_SCREEN_CAPTURE  1 | ||||
| #define RL_SUPPORT_SCREEN_CAPTURE 1 | ||||
| // Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() | ||||
| #define RL_SUPPORT_GIF_RECORDING  1 | ||||
| #define RL_SUPPORT_GIF_RECORDING 1 | ||||
| // Support CompressData() and DecompressData() functions | ||||
| #define RL_SUPPORT_COMPRESSION_API  1 | ||||
| #define RL_SUPPORT_COMPRESSION_API 1 | ||||
| // Support automatic generated events, loading and recording of those events when required | ||||
| //#define SUPPORT_EVENTS_AUTOMATION       1 | ||||
| // #define SUPPORT_EVENTS_AUTOMATION       1 | ||||
| // Support custom frame control, only for advance users | ||||
| // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() | ||||
| // Enabling this flag allows manual control of the frame processes, use at your own risk | ||||
| //#define SUPPORT_CUSTOM_FRAME_CONTROL    1 | ||||
| // #define SUPPORT_CUSTOM_FRAME_CONTROL    1 | ||||
|  | ||||
| // rcore: Configuration values | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_MAX_FILEPATH_CAPACITY  8192 // Maximum file paths capacity | ||||
| #define RL_MAX_FILEPATH_LENGTH  4096 // Maximum length for filepaths (Linux PATH_MAX default value) | ||||
| #define RL_MAX_FILEPATH_CAPACITY  8192    // Maximum file paths capacity | ||||
| #define RL_MAX_FILEPATH_LENGTH    4096    // Maximum length for filepaths (Linux PATH_MAX default value) | ||||
|  | ||||
| #define RL_MAX_KEYBOARD_KEYS  512 // Maximum number of keyboard keys supported | ||||
| #define RL_MAX_MOUSE_BUTTONS  8 // Maximum number of mouse buttons supported | ||||
| #define RL_MAX_GAMEPADS  4 // Maximum number of gamepads supported | ||||
| #define RL_MAX_GAMEPAD_AXIS  8 // Maximum number of axis supported (per gamepad) | ||||
| #define RL_MAX_GAMEPAD_BUTTONS  32 // Maximum number of buttons supported (per gamepad) | ||||
| #define RL_MAX_TOUCH_POINTS  8 // Maximum number of touch points supported | ||||
| #define RL_MAX_KEY_PRESSED_QUEUE  16 // Maximum number of keys in the key input queue | ||||
| #define RL_MAX_CHAR_PRESSED_QUEUE  16 // Maximum number of characters in the char input queue | ||||
| #define RL_MAX_KEYBOARD_KEYS      512    // Maximum number of keyboard keys supported | ||||
| #define RL_MAX_MOUSE_BUTTONS      8      // Maximum number of mouse buttons supported | ||||
| #define RL_MAX_GAMEPADS           4      // Maximum number of gamepads supported | ||||
| #define RL_MAX_GAMEPAD_AXIS       8      // Maximum number of axis supported (per gamepad) | ||||
| #define RL_MAX_GAMEPAD_BUTTONS    32     // Maximum number of buttons supported (per gamepad) | ||||
| #define RL_MAX_TOUCH_POINTS       8      // Maximum number of touch points supported | ||||
| #define RL_MAX_KEY_PRESSED_QUEUE  16     // Maximum number of keys in the key input queue | ||||
| #define RL_MAX_CHAR_PRESSED_QUEUE 16     // Maximum number of characters in the char input queue | ||||
|  | ||||
| #define RL_MAX_DECOMPRESSION_SIZE  64 // Max size allocated for decompression in MB | ||||
| #define RL_MAX_DECOMPRESSION_SIZE 64    // Max size allocated for decompression in MB | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| @@ -91,41 +91,19 @@ | ||||
| //------------------------------------------------------------------------------------ | ||||
|  | ||||
| // Enable OpenGL Debug Context (only available on OpenGL 4.3) | ||||
| //#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT       1 | ||||
| // #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT       1 | ||||
|  | ||||
| // Show OpenGL extensions and capabilities detailed logs on init | ||||
| //#define RLGL_SHOW_GL_DETAILS_INFO              1 | ||||
| // #define RLGL_SHOW_GL_DETAILS_INFO              1 | ||||
|  | ||||
| //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS    4096    // Default internal render batch elements limits | ||||
| #define RL_DEFAULT_BATCH_BUFFERS  1 // Default number of batch buffers (multi-buffering) | ||||
| #define RL_DEFAULT_BATCH_DRAWCALLS  256 // Default number of batch draw calls (by state changes: mode, texture) | ||||
| #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS  4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) | ||||
| // #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS    4096    // Default internal render batch elements limits | ||||
|  | ||||
| #define RL_MAX_MATRIX_STACK_SIZE  32 // Maximum size of internal Matrix stack | ||||
|  | ||||
| #define RL_MAX_SHADER_LOCATIONS  32 // Maximum number of shader locations supported | ||||
|  | ||||
| #define RL_CULL_DISTANCE_NEAR  0.01 // Default projection matrix near cull distance | ||||
| #define RL_CULL_DISTANCE_FAR  1000.0 // Default projection matrix far cull distance | ||||
|  | ||||
| // Default shader vertex attribute names to set location points | ||||
| // NOTE: When a new shader is loaded, the following locations are tried to be set for convenience | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION  "vertexPosition" // Bound by default to shader location: 0 | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD  "vertexTexCoord" // Bound by default to shader location: 1 | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL  "vertexNormal" // Bound by default to shader location: 2 | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR  "vertexColor" // Bound by default to shader location: 3 | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT  "vertexTangent" // Bound by default to shader location: 4 | ||||
| #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2  "vertexTexCoord2" // Bound by default to shader location: 5 | ||||
|  | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP  "mvp" // model-view-projection matrix | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW  "matView" // view matrix | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION  "matProjection" // projection matrix | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL  "matModel" // model matrix | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL  "matNormal" // normal matrix (transpose(inverse(matModelView)) | ||||
| #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR  "colDiffuse" // color diffuse (base tint color, multiplied by texture color) | ||||
| #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0  "texture0" // texture0 (texture slot active 0) | ||||
| #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1  "texture1" // texture1 (texture slot active 1) | ||||
| #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2  "texture2" // texture2 (texture slot active 2) | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| @@ -133,36 +111,36 @@ | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Use QUADS instead of TRIANGLES for drawing when possible | ||||
| // Some lines-based shapes could still use lines | ||||
| #define RL_SUPPORT_QUADS_DRAW_MODE  1 | ||||
| #define RL_SUPPORT_QUADS_DRAW_MODE 1 | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module: rtextures - Configuration Flags | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Selecte desired fileformats to be supported for image data loading | ||||
| #define RL_SUPPORT_FILEFORMAT_PNG  1 | ||||
| //#define SUPPORT_FILEFORMAT_BMP      1 | ||||
| //#define SUPPORT_FILEFORMAT_TGA      1 | ||||
| //#define SUPPORT_FILEFORMAT_JPG      1 | ||||
| #define RL_SUPPORT_FILEFORMAT_GIF  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_QOI  1 | ||||
| //#define SUPPORT_FILEFORMAT_PSD      1 | ||||
| #define RL_SUPPORT_FILEFORMAT_DDS  1 | ||||
| //#define SUPPORT_FILEFORMAT_HDR      1 | ||||
| //#define SUPPORT_FILEFORMAT_PIC          1 | ||||
| //#define SUPPORT_FILEFORMAT_KTX      1 | ||||
| //#define SUPPORT_FILEFORMAT_ASTC     1 | ||||
| //#define SUPPORT_FILEFORMAT_PKM      1 | ||||
| //#define SUPPORT_FILEFORMAT_PVR      1 | ||||
| //#define SUPPORT_FILEFORMAT_SVG      1 | ||||
| #define RL_SUPPORT_FILEFORMAT_PNG 1 | ||||
| // #define SUPPORT_FILEFORMAT_BMP      1 | ||||
| // #define SUPPORT_FILEFORMAT_TGA      1 | ||||
| // #define SUPPORT_FILEFORMAT_JPG      1 | ||||
| #define RL_SUPPORT_FILEFORMAT_GIF 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_QOI 1 | ||||
| // #define SUPPORT_FILEFORMAT_PSD      1 | ||||
| #define RL_SUPPORT_FILEFORMAT_DDS 1 | ||||
| // #define SUPPORT_FILEFORMAT_HDR      1 | ||||
| // #define SUPPORT_FILEFORMAT_PIC          1 | ||||
| // #define SUPPORT_FILEFORMAT_KTX      1 | ||||
| // #define SUPPORT_FILEFORMAT_ASTC     1 | ||||
| // #define SUPPORT_FILEFORMAT_PKM      1 | ||||
| // #define SUPPORT_FILEFORMAT_PVR      1 | ||||
| // #define SUPPORT_FILEFORMAT_SVG      1 | ||||
|  | ||||
| // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) | ||||
| #define RL_SUPPORT_IMAGE_EXPORT  1 | ||||
| #define RL_SUPPORT_IMAGE_EXPORT 1 | ||||
| // Support procedural image generation functionality (gradient, spot, perlin-noise, cellular) | ||||
| #define RL_SUPPORT_IMAGE_GENERATION  1 | ||||
| #define RL_SUPPORT_IMAGE_GENERATION 1 | ||||
| // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... | ||||
| // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() | ||||
| #define RL_SUPPORT_IMAGE_MANIPULATION  1 | ||||
| #define RL_SUPPORT_IMAGE_MANIPULATION 1 | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| @@ -170,25 +148,25 @@ | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Default font is loaded on window initialization to be available for the user to render simple text | ||||
| // NOTE: If enabled, uses external module functions to load default raylib font | ||||
| #define RL_SUPPORT_DEFAULT_FONT  1 | ||||
| #define RL_SUPPORT_DEFAULT_FONT 1 | ||||
| // Selected desired font fileformats to be supported for loading | ||||
| #define RL_SUPPORT_FILEFORMAT_FNT  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_TTF  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_FNT 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_TTF 1 | ||||
|  | ||||
| // Support text management functions | ||||
| // If not defined, still some functions are supported: TextLength(), TextFormat() | ||||
| #define RL_SUPPORT_TEXT_MANIPULATION  1 | ||||
| #define RL_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 RL_SUPPORT_FONT_ATLAS_WHITE_REC  1 | ||||
| #define RL_SUPPORT_FONT_ATLAS_WHITE_REC 1 | ||||
|  | ||||
| // rtext: Configuration values | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_MAX_TEXT_BUFFER_LENGTH  1024 // Size of internal static buffers used on some functions: | ||||
| #define RL_MAX_TEXT_BUFFER_LENGTH 1024    // Size of internal static buffers used on some functions: | ||||
| // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() | ||||
| #define RL_MAX_TEXTSPLIT_COUNT  128 // Maximum number of substrings to split: TextSplit() | ||||
| #define RL_MAX_TEXTSPLIT_COUNT 128    // Maximum number of substrings to split: TextSplit() | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| @@ -198,51 +176,51 @@ | ||||
| #define RL_SUPPORT_FILEFORMAT_OBJ  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_MTL  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_IQM  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_GLTF  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_GLTF 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_VOX  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_M3D  1 | ||||
| // Support procedural mesh generation functions, uses external par_shapes.h library | ||||
| // NOTE: Some generated meshes DO NOT include generated texture coordinates | ||||
| #define RL_SUPPORT_MESH_GENERATION  1 | ||||
| #define RL_SUPPORT_MESH_GENERATION 1 | ||||
|  | ||||
| // rmodels: Configuration values | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_MAX_MATERIAL_MAPS  12 // Maximum number of shader maps supported | ||||
| #define RL_MAX_MESH_VERTEX_BUFFERS  7 // Maximum vertex buffers (VBO) per mesh | ||||
| #define RL_MAX_MATERIAL_MAPS       12    // Maximum number of shader maps supported | ||||
| #define RL_MAX_MESH_VERTEX_BUFFERS 7     // Maximum vertex buffers (VBO) per mesh | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module: raudio - Configuration Flags | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Desired audio fileformats to be supported for loading | ||||
| #define RL_SUPPORT_FILEFORMAT_WAV  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_OGG  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_MP3  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_QOA  1 | ||||
| //#define SUPPORT_FILEFORMAT_FLAC         1 | ||||
| #define RL_SUPPORT_FILEFORMAT_WAV 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_OGG 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_MP3 1 | ||||
| #define RL_SUPPORT_FILEFORMAT_QOA 1 | ||||
| // #define SUPPORT_FILEFORMAT_FLAC         1 | ||||
| #define RL_SUPPORT_FILEFORMAT_XM  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_MOD  1 | ||||
| #define RL_SUPPORT_FILEFORMAT_MOD 1 | ||||
|  | ||||
| // raudio: Configuration values | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_AUDIO_DEVICE_FORMAT  ma_format_f32 // Device output format (miniaudio: float-32bit) | ||||
| #define RL_AUDIO_DEVICE_CHANNELS  2 // Device output channels: stereo | ||||
| #define RL_AUDIO_DEVICE_SAMPLE_RATE  0 // Device sample rate (device default) | ||||
| #define RL_AUDIO_DEVICE_FORMAT            ma_format_f32    // Device output format (miniaudio: float-32bit) | ||||
| #define RL_AUDIO_DEVICE_CHANNELS          2                // Device output channels: stereo | ||||
| #define RL_AUDIO_DEVICE_SAMPLE_RATE       0                // Device sample rate (device default) | ||||
|  | ||||
| #define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS  16 // Maximum number of audio pool channels | ||||
| #define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS 16    // Maximum number of audio pool channels | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module: utils - Configuration Flags | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Standard file io library (stdio.h) included | ||||
| #define RL_SUPPORT_STANDARD_FILEIO  1 | ||||
| #define RL_SUPPORT_STANDARD_FILEIO 1 | ||||
| // Show TRACELOG() output messages | ||||
| // NOTE: By default LOG_DEBUG traces not shown | ||||
| #define RL_SUPPORT_TRACELOG  1 | ||||
| //#define SUPPORT_TRACELOG_DEBUG          1 | ||||
| #define RL_SUPPORT_TRACELOG 1 | ||||
| // #define SUPPORT_TRACELOG_DEBUG          1 | ||||
|  | ||||
| // utils: Configuration values | ||||
| //------------------------------------------------------------------------------------ | ||||
| #define RL_MAX_TRACELOG_MSG_LENGTH  256 // Max length of one trace-log message | ||||
| #define RL_MAX_TRACELOG_MSG_LENGTH 256    // Max length of one trace-log message | ||||
|  | ||||
| #endif | ||||
| // CONFIG_H | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,43 +1,43 @@ | ||||
| /******************************************************************************************* | ||||
| * | ||||
| *   rcamera - Basic camera system with support for multiple camera modes | ||||
| * | ||||
| *   CONFIGURATION: | ||||
| *       #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 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. | ||||
| * | ||||
| *   CONTRIBUTORS: | ||||
| *       Ramon Santamaria:   Supervision, review, update and maintenance | ||||
| *       Christoph Wagner:   Complete redesign, using raymath (2022) | ||||
| *       Marc Palau:         Initial implementation (2014) | ||||
| * | ||||
| * | ||||
| *   LICENSE: zlib/libpng | ||||
| * | ||||
| *   Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) | ||||
| * | ||||
| *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
| *   will the authors be held liable for any damages arising from the use of this software. | ||||
| * | ||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
| * | ||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
| *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
| *     in the product documentation would be appreciated but is not required. | ||||
| * | ||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
| *     as being the original software. | ||||
| * | ||||
| *     3. This notice may not be removed or altered from any source distribution. | ||||
| * | ||||
| **********************************************************************************************/ | ||||
|  * | ||||
|  *   rcamera - Basic camera system with support for multiple camera modes | ||||
|  * | ||||
|  *   CONFIGURATION: | ||||
|  *       #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 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. | ||||
|  * | ||||
|  *   CONTRIBUTORS: | ||||
|  *       Ramon Santamaria:   Supervision, review, update and maintenance | ||||
|  *       Christoph Wagner:   Complete redesign, using raymath (2022) | ||||
|  *       Marc Palau:         Initial implementation (2014) | ||||
|  * | ||||
|  * | ||||
|  *   LICENSE: zlib/libpng | ||||
|  * | ||||
|  *   Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) | ||||
|  * | ||||
|  *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
|  *   will the authors be held liable for any damages arising from the use of this software. | ||||
|  * | ||||
|  *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
|  *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
|  * | ||||
|  *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
|  *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
|  *     in the product documentation would be appreciated but is not required. | ||||
|  * | ||||
|  *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
|  *     as being the original software. | ||||
|  * | ||||
|  *     3. This notice may not be removed or altered from any source distribution. | ||||
|  * | ||||
|  **********************************************************************************************/ | ||||
|  | ||||
| #ifndef RCAMERA_H | ||||
| #define RCAMERA_H | ||||
| @@ -49,80 +49,86 @@ | ||||
|  | ||||
| // Function specifiers in case library is build/used as a shared library (Windows) | ||||
| // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll | ||||
| #if defined(_WIN32) | ||||
| #if defined(BUILD_LIBTYPE_SHARED) | ||||
| #if defined(__TINYC__) | ||||
| #define __declspec(x) __attribute__((x)) | ||||
| #if defined( _WIN32 ) | ||||
| #if defined( BUILD_LIBTYPE_SHARED ) | ||||
| #if defined( __TINYC__ ) | ||||
| #define __declspec( x ) __attribute__( ( x ) ) | ||||
| #endif | ||||
| #define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll) | ||||
| #elif defined(USE_LIBTYPE_SHARED) | ||||
| #define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll) | ||||
| #define RLAPI __declspec( dllexport )    // We are building the library as a Win32 shared library (.dll) | ||||
| #elif defined( USE_LIBTYPE_SHARED ) | ||||
| #define RLAPI __declspec( dllimport )    // We are using the library as a Win32 shared library (.dll) | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifndef RLAPI | ||||
|     #define RLAPI       // Functions defined as 'extern' by default (implicit specifiers) | ||||
| #define RLAPI    // Functions defined as 'extern' by default (implicit specifiers) | ||||
| #endif | ||||
|  | ||||
| #if defined(RCAMERA_STANDALONE) | ||||
|     #define CAMERA_CULL_DISTANCE_NEAR      0.01 | ||||
|     #define CAMERA_CULL_DISTANCE_FAR    1000.0 | ||||
| #if defined( RCAMERA_STANDALONE ) | ||||
| #define CAMERA_CULL_DISTANCE_NEAR 0.01 | ||||
| #define CAMERA_CULL_DISTANCE_FAR  1000.0 | ||||
| #else | ||||
|     #define CAMERA_CULL_DISTANCE_NEAR   RL_CULL_DISTANCE_NEAR | ||||
|     #define CAMERA_CULL_DISTANCE_FAR    RL_CULL_DISTANCE_FAR | ||||
| #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR | ||||
| #define CAMERA_CULL_DISTANCE_FAR  RL_CULL_DISTANCE_FAR | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Types and Structures Definition | ||||
| // NOTE: Below types are required for standalone usage | ||||
| //---------------------------------------------------------------------------------- | ||||
| #if defined(RCAMERA_STANDALONE) | ||||
|     // Vector2, 2 components | ||||
|     typedef struct Vector2 { | ||||
|         float x;                // Vector x component | ||||
|         float y;                // Vector y component | ||||
|     } Vector2; | ||||
| #if defined( RCAMERA_STANDALONE ) | ||||
| // Vector2, 2 components | ||||
| typedef struct Vector2 | ||||
| { | ||||
| 	float x;    // Vector x component | ||||
| 	float y;    // Vector y component | ||||
| } Vector2; | ||||
|  | ||||
|     // Vector3, 3 components | ||||
|     typedef struct Vector3 { | ||||
|         float x;                // Vector x component | ||||
|         float y;                // Vector y component | ||||
|         float z;                // Vector z component | ||||
|     } Vector3; | ||||
| // Vector3, 3 components | ||||
| typedef struct Vector3 | ||||
| { | ||||
| 	float x;    // Vector x component | ||||
| 	float y;    // Vector y component | ||||
| 	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; | ||||
| // 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 | ||||
|         Vector3 target;         // Camera target it looks-at | ||||
|         Vector3 up;             // Camera up vector (rotation over its axis) | ||||
|         float fovy;             // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic | ||||
|         int projection;         // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC | ||||
|     } Camera3D; | ||||
| // Camera type, defines a camera position/orientation in 3d space | ||||
| typedef struct Camera3D | ||||
| { | ||||
| 	Vector3 position;      // Camera position | ||||
| 	Vector3 target;        // Camera target it looks-at | ||||
| 	Vector3 up;            // Camera up vector (rotation over its axis) | ||||
| 	float   fovy;          // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic | ||||
| 	int     projection;    // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC | ||||
| } Camera3D; | ||||
|  | ||||
|     typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D | ||||
| typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D | ||||
|  | ||||
|     // Camera projection | ||||
|     typedef enum { | ||||
|         CAMERA_PERSPECTIVE = 0, // Perspective projection | ||||
|         CAMERA_ORTHOGRAPHIC     // Orthographic projection | ||||
|     } CameraProjection; | ||||
| // Camera projection | ||||
| typedef enum | ||||
| { | ||||
| 	CAMERA_PERSPECTIVE = 0,    // Perspective projection | ||||
| 	CAMERA_ORTHOGRAPHIC        // Orthographic projection | ||||
| } CameraProjection; | ||||
|  | ||||
|     // Camera system modes | ||||
|     typedef enum { | ||||
|         CAMERA_CUSTOM = 0,      // Camera custom, controlled by user (UpdateCamera() does nothing) | ||||
|         CAMERA_FREE,            // Camera free mode | ||||
|         CAMERA_ORBITAL,         // Camera orbital, around target, zoom supported | ||||
|         CAMERA_FIRST_PERSON,    // Camera first person | ||||
|         CAMERA_THIRD_PERSON     // Camera third person | ||||
|     } CameraMode; | ||||
| // Camera system modes | ||||
| typedef enum | ||||
| { | ||||
| 	CAMERA_CUSTOM = 0,      // Camera custom, controlled by user (UpdateCamera() does nothing) | ||||
| 	CAMERA_FREE,            // Camera free mode | ||||
| 	CAMERA_ORBITAL,         // Camera orbital, around target, zoom supported | ||||
| 	CAMERA_FIRST_PERSON,    // Camera first person | ||||
| 	CAMERA_THIRD_PERSON     // Camera third person | ||||
| } CameraMode; | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| @@ -134,85 +140,86 @@ | ||||
| // Module Functions Declaration | ||||
| //---------------------------------------------------------------------------------- | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| extern "C" {            // Prevents name mangling of functions | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" | ||||
| {    // Prevents name mangling of functions | ||||
| #endif | ||||
|  | ||||
| RLAPI Vector3 GetCameraForward(Camera *camera); | ||||
| RLAPI Vector3 GetCameraUp(Camera *camera); | ||||
| RLAPI Vector3 GetCameraRight(Camera *camera); | ||||
| 	RLAPI Vector3 GetCameraForward( Camera* camera ); | ||||
| 	RLAPI Vector3 GetCameraUp( Camera* camera ); | ||||
| 	RLAPI Vector3 GetCameraRight( Camera* camera ); | ||||
|  | ||||
| // Camera movement | ||||
| RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane); | ||||
| RLAPI void CameraMoveUp(Camera *camera, float distance); | ||||
| RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane); | ||||
| RLAPI void CameraMoveToTarget(Camera *camera, float delta); | ||||
| 	// Camera movement | ||||
| 	RLAPI void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ); | ||||
| 	RLAPI void CameraMoveUp( Camera* camera, float distance ); | ||||
| 	RLAPI void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ); | ||||
| 	RLAPI void CameraMoveToTarget( Camera* camera, float delta ); | ||||
|  | ||||
| // Camera rotation | ||||
| RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget); | ||||
| RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp); | ||||
| RLAPI void CameraRoll(Camera *camera, float angle); | ||||
| 	// Camera rotation | ||||
| 	RLAPI void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ); | ||||
| 	RLAPI void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ); | ||||
| 	RLAPI void CameraRoll( Camera* camera, float angle ); | ||||
|  | ||||
| RLAPI Matrix GetCameraViewMatrix(Camera *camera); | ||||
| RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); | ||||
| 	RLAPI Matrix GetCameraViewMatrix( Camera* camera ); | ||||
| 	RLAPI Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ); | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| #if defined( __cplusplus ) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif // RCAMERA_H | ||||
| #endif    // RCAMERA_H | ||||
|  | ||||
|  | ||||
| /*********************************************************************************** | ||||
| * | ||||
| *   CAMERA IMPLEMENTATION | ||||
| * | ||||
| ************************************************************************************/ | ||||
|  * | ||||
|  *   CAMERA IMPLEMENTATION | ||||
|  * | ||||
|  ************************************************************************************/ | ||||
|  | ||||
| #if defined(RCAMERA_IMPLEMENTATION) | ||||
| #if defined( RCAMERA_IMPLEMENTATION ) | ||||
|  | ||||
| #include "raymath.h"        // Required for vector maths: | ||||
|                             // Vector3Add() | ||||
|                             // Vector3Subtract() | ||||
|                             // Vector3Scale() | ||||
|                             // Vector3Normalize() | ||||
|                             // Vector3Distance() | ||||
|                             // Vector3CrossProduct() | ||||
|                             // Vector3RotateByAxisAngle() | ||||
|                             // Vector3Angle() | ||||
|                             // Vector3Negate() | ||||
|                             // MatrixLookAt() | ||||
|                             // MatrixPerspective() | ||||
|                             // MatrixOrtho() | ||||
|                             // MatrixIdentity() | ||||
| #include "raymath.h"    // Required for vector maths: | ||||
|                         // Vector3Add() | ||||
|                         // Vector3Subtract() | ||||
|                         // Vector3Scale() | ||||
|                         // Vector3Normalize() | ||||
|                         // Vector3Distance() | ||||
|                         // Vector3CrossProduct() | ||||
|                         // Vector3RotateByAxisAngle() | ||||
|                         // Vector3Angle() | ||||
|                         // Vector3Negate() | ||||
|                         // MatrixLookAt() | ||||
|                         // MatrixPerspective() | ||||
|                         // MatrixOrtho() | ||||
|                         // MatrixIdentity() | ||||
|  | ||||
| // raylib required functionality: | ||||
|                             // GetMouseDelta() | ||||
|                             // GetMouseWheelMove() | ||||
|                             // IsKeyDown() | ||||
|                             // IsKeyPressed() | ||||
|                             // GetFrameTime() | ||||
| // GetMouseDelta() | ||||
| // GetMouseWheelMove() | ||||
| // IsKeyDown() | ||||
| // IsKeyPressed() | ||||
| // GetFrameTime() | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Defines and Macros | ||||
| //---------------------------------------------------------------------------------- | ||||
| #define CAMERA_MOVE_SPEED                               0.09f | ||||
| #define CAMERA_ROTATION_SPEED                           0.03f | ||||
| #define CAMERA_PAN_SPEED                                0.2f | ||||
| #define CAMERA_MOVE_SPEED     0.09f | ||||
| #define CAMERA_ROTATION_SPEED 0.03f | ||||
| #define CAMERA_PAN_SPEED      0.2f | ||||
|  | ||||
| // Camera mouse movement sensitivity | ||||
| #define CAMERA_MOUSE_MOVE_SENSITIVITY                   0.003f     // TODO: it should be independant of framerate | ||||
| #define CAMERA_MOUSE_SCROLL_SENSITIVITY                 1.5f | ||||
| #define CAMERA_MOUSE_MOVE_SENSITIVITY                  0.003f    // TODO: it should be independant of framerate | ||||
| #define CAMERA_MOUSE_SCROLL_SENSITIVITY                1.5f | ||||
|  | ||||
| #define CAMERA_ORBITAL_SPEED                            0.5f       // Radians per second | ||||
| #define CAMERA_ORBITAL_SPEED                           0.5f    // Radians per second | ||||
|  | ||||
|  | ||||
| #define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER  8.0f | ||||
| #define CAMERA_FIRST_PERSON_STEP_DIVIDER                30.0f | ||||
| #define CAMERA_FIRST_PERSON_WAVING_DIVIDER              200.0f | ||||
| #define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f | ||||
| #define CAMERA_FIRST_PERSON_STEP_DIVIDER               30.0f | ||||
| #define CAMERA_FIRST_PERSON_WAVING_DIVIDER             200.0f | ||||
|  | ||||
| // PLAYER (used by camera) | ||||
| #define PLAYER_MOVEMENT_SENSITIVITY                     20.0f | ||||
| #define PLAYER_MOVEMENT_SENSITIVITY 20.0f | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Types and Structures Definition | ||||
| @@ -233,121 +240,122 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); | ||||
| // Module Functions Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Returns the cameras forward vector (normalized) | ||||
| Vector3 GetCameraForward(Camera *camera) | ||||
| Vector3 GetCameraForward( Camera* camera ) | ||||
| { | ||||
|     return Vector3Normalize(Vector3Subtract(camera->target, camera->position)); | ||||
| 	return Vector3Normalize( Vector3Subtract( camera->target, camera->position ) ); | ||||
| } | ||||
|  | ||||
| // Returns the cameras up vector (normalized) | ||||
| // Note: The up vector might not be perpendicular to the forward vector | ||||
| Vector3 GetCameraUp(Camera *camera) | ||||
| Vector3 GetCameraUp( Camera* camera ) | ||||
| { | ||||
|     return Vector3Normalize(camera->up); | ||||
| 	return Vector3Normalize( camera->up ); | ||||
| } | ||||
|  | ||||
| // Returns the cameras right vector (normalized) | ||||
| Vector3 GetCameraRight(Camera *camera) | ||||
| Vector3 GetCameraRight( Camera* camera ) | ||||
| { | ||||
|     Vector3 forward = GetCameraForward(camera); | ||||
|     Vector3 up = GetCameraUp(camera); | ||||
| 	Vector3 forward = GetCameraForward( camera ); | ||||
| 	Vector3 up      = GetCameraUp( camera ); | ||||
|  | ||||
|     return Vector3CrossProduct(forward, up); | ||||
| 	return Vector3CrossProduct( forward, up ); | ||||
| } | ||||
|  | ||||
| // Moves the camera in its forward direction | ||||
| void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) | ||||
| void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ) | ||||
| { | ||||
|     Vector3 forward = GetCameraForward(camera); | ||||
| 	Vector3 forward = GetCameraForward( camera ); | ||||
|  | ||||
|     if (moveInWorldPlane) | ||||
|     { | ||||
|         // Project vector onto world plane | ||||
|         forward.y = 0; | ||||
|         forward = Vector3Normalize(forward); | ||||
|     } | ||||
| 	if ( moveInWorldPlane ) | ||||
| 	{ | ||||
| 		// Project vector onto world plane | ||||
| 		forward.y = 0; | ||||
| 		forward   = Vector3Normalize( forward ); | ||||
| 	} | ||||
|  | ||||
|     // Scale by distance | ||||
|     forward = Vector3Scale(forward, distance); | ||||
| 	// Scale by distance | ||||
| 	forward = Vector3Scale( forward, distance ); | ||||
|  | ||||
|     // Move position and target | ||||
|     camera->position = Vector3Add(camera->position, forward); | ||||
|     camera->target = Vector3Add(camera->target, forward); | ||||
| 	// Move position and target | ||||
| 	camera->position = Vector3Add( camera->position, forward ); | ||||
| 	camera->target   = Vector3Add( camera->target, forward ); | ||||
| } | ||||
|  | ||||
| // Moves the camera in its up direction | ||||
| void CameraMoveUp(Camera *camera, float distance) | ||||
| void CameraMoveUp( Camera* camera, float distance ) | ||||
| { | ||||
|     Vector3 up = GetCameraUp(camera); | ||||
| 	Vector3 up = GetCameraUp( camera ); | ||||
|  | ||||
|     // Scale by distance | ||||
|     up = Vector3Scale(up, distance); | ||||
| 	// Scale by distance | ||||
| 	up = Vector3Scale( up, distance ); | ||||
|  | ||||
|     // Move position and target | ||||
|     camera->position = Vector3Add(camera->position, up); | ||||
|     camera->target = Vector3Add(camera->target, up); | ||||
| 	// Move position and target | ||||
| 	camera->position = Vector3Add( camera->position, up ); | ||||
| 	camera->target   = Vector3Add( camera->target, up ); | ||||
| } | ||||
|  | ||||
| // Moves the camera target in its current right direction | ||||
| void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) | ||||
| void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ) | ||||
| { | ||||
|     Vector3 right = GetCameraRight(camera); | ||||
| 	Vector3 right = GetCameraRight( camera ); | ||||
|  | ||||
|     if (moveInWorldPlane) | ||||
|     { | ||||
|         // Project vector onto world plane | ||||
|         right.y = 0; | ||||
|         right = Vector3Normalize(right); | ||||
|     } | ||||
| 	if ( moveInWorldPlane ) | ||||
| 	{ | ||||
| 		// Project vector onto world plane | ||||
| 		right.y = 0; | ||||
| 		right   = Vector3Normalize( right ); | ||||
| 	} | ||||
|  | ||||
|     // Scale by distance | ||||
|     right = Vector3Scale(right, distance); | ||||
| 	// Scale by distance | ||||
| 	right = Vector3Scale( right, distance ); | ||||
|  | ||||
|     // Move position and target | ||||
|     camera->position = Vector3Add(camera->position, right); | ||||
|     camera->target = Vector3Add(camera->target, right); | ||||
| 	// Move position and target | ||||
| 	camera->position = Vector3Add( camera->position, right ); | ||||
| 	camera->target   = Vector3Add( camera->target, right ); | ||||
| } | ||||
|  | ||||
| // Moves the camera position closer/farther to/from the camera target | ||||
| void CameraMoveToTarget(Camera *camera, float delta) | ||||
| void CameraMoveToTarget( Camera* camera, float delta ) | ||||
| { | ||||
|     float distance = Vector3Distance(camera->position, camera->target); | ||||
| 	float distance = Vector3Distance( camera->position, camera->target ); | ||||
|  | ||||
|     // Apply delta | ||||
|     distance += delta; | ||||
| 	// Apply delta | ||||
| 	distance += delta; | ||||
|  | ||||
|     // Distance must be greater than 0 | ||||
|     if (distance <= 0) distance = 0.001f; | ||||
| 	// Distance must be greater than 0 | ||||
| 	if ( distance <= 0 ) | ||||
| 		distance = 0.001f; | ||||
|  | ||||
|     // Set new distance by moving the position along the forward vector | ||||
|     Vector3 forward = GetCameraForward(camera); | ||||
|     camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance)); | ||||
| 	// Set new distance by moving the position along the forward vector | ||||
| 	Vector3 forward  = GetCameraForward( camera ); | ||||
| 	camera->position = Vector3Add( camera->target, Vector3Scale( forward, -distance ) ); | ||||
| } | ||||
|  | ||||
| // Rotates the camera around its up vector | ||||
| // Yaw is "looking left and right" | ||||
| // If rotateAroundTarget is false, the camera rotates around its position | ||||
| // Note: angle must be provided in radians | ||||
| void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) | ||||
| void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ) | ||||
| { | ||||
|     // Rotation axis | ||||
|     Vector3 up = GetCameraUp(camera); | ||||
| 	// Rotation axis | ||||
| 	Vector3 up = GetCameraUp( camera ); | ||||
|  | ||||
|     // View vector | ||||
|     Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); | ||||
| 	// View vector | ||||
| 	Vector3 targetPosition = Vector3Subtract( camera->target, camera->position ); | ||||
|  | ||||
|     // Rotate view vector around up axis | ||||
|     targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle); | ||||
| 	// Rotate view vector around up axis | ||||
| 	targetPosition = Vector3RotateByAxisAngle( targetPosition, up, angle ); | ||||
|  | ||||
|     if (rotateAroundTarget) | ||||
|     { | ||||
|         // Move position relative to target | ||||
|         camera->position = Vector3Subtract(camera->target, targetPosition); | ||||
|     } | ||||
|     else // rotate around camera.position | ||||
|     { | ||||
|         // Move target relative to position | ||||
|         camera->target = Vector3Add(camera->position, targetPosition); | ||||
|     } | ||||
| 	if ( rotateAroundTarget ) | ||||
| 	{ | ||||
| 		// Move position relative to target | ||||
| 		camera->position = Vector3Subtract( camera->target, targetPosition ); | ||||
| 	} | ||||
| 	else    // rotate around camera.position | ||||
| 	{ | ||||
| 		// Move target relative to position | ||||
| 		camera->target = Vector3Add( camera->position, targetPosition ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Rotates the camera around its right vector, pitch is "looking up and down" | ||||
| @@ -355,204 +363,234 @@ void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) | ||||
| //  - rotateAroundTarget defines if rotation is around target or around its position | ||||
| //  - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) | ||||
| // NOTE: angle must be provided in radians | ||||
| void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) | ||||
| void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ) | ||||
| { | ||||
|     // Up direction | ||||
|     Vector3 up = GetCameraUp(camera); | ||||
| 	// Up direction | ||||
| 	Vector3 up = GetCameraUp( camera ); | ||||
|  | ||||
|     // View vector | ||||
|     Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); | ||||
| 	// View vector | ||||
| 	Vector3 targetPosition = Vector3Subtract( camera->target, camera->position ); | ||||
|  | ||||
|     if (lockView) | ||||
|     { | ||||
|         // In these camera modes we clamp the Pitch angle | ||||
|         // to allow only viewing straight up or down. | ||||
| 	if ( lockView ) | ||||
| 	{ | ||||
| 		// In these camera modes we clamp the Pitch angle | ||||
| 		// to allow only viewing straight up or down. | ||||
|  | ||||
|         // Clamp view up | ||||
|         float maxAngleUp = Vector3Angle(up, targetPosition); | ||||
|         maxAngleUp -= 0.001f; // avoid numerical errors | ||||
|         if (angle > maxAngleUp) angle = maxAngleUp; | ||||
| 		// Clamp view up | ||||
| 		float maxAngleUp  = Vector3Angle( up, targetPosition ); | ||||
| 		maxAngleUp       -= 0.001f;    // avoid numerical errors | ||||
| 		if ( angle > maxAngleUp ) | ||||
| 			angle = maxAngleUp; | ||||
|  | ||||
|         // Clamp view down | ||||
|         float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition); | ||||
|         maxAngleDown *= -1.0f; // downwards angle is negative | ||||
|         maxAngleDown += 0.001f; // avoid numerical errors | ||||
|         if (angle < maxAngleDown) angle = maxAngleDown; | ||||
|     } | ||||
| 		// Clamp view down | ||||
| 		float maxAngleDown  = Vector3Angle( Vector3Negate( up ), targetPosition ); | ||||
| 		maxAngleDown       *= -1.0f;     // downwards angle is negative | ||||
| 		maxAngleDown       += 0.001f;    // avoid numerical errors | ||||
| 		if ( angle < maxAngleDown ) | ||||
| 			angle = maxAngleDown; | ||||
| 	} | ||||
|  | ||||
|     // Rotation axis | ||||
|     Vector3 right = GetCameraRight(camera); | ||||
| 	// Rotation axis | ||||
| 	Vector3 right = GetCameraRight( camera ); | ||||
|  | ||||
|     // Rotate view vector around right axis | ||||
|     targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle); | ||||
| 	// Rotate view vector around right axis | ||||
| 	targetPosition = Vector3RotateByAxisAngle( targetPosition, right, angle ); | ||||
|  | ||||
|     if (rotateAroundTarget) | ||||
|     { | ||||
|         // Move position relative to target | ||||
|         camera->position = Vector3Subtract(camera->target, targetPosition); | ||||
|     } | ||||
|     else // rotate around camera.position | ||||
|     { | ||||
|         // Move target relative to position | ||||
|         camera->target = Vector3Add(camera->position, targetPosition); | ||||
|     } | ||||
| 	if ( rotateAroundTarget ) | ||||
| 	{ | ||||
| 		// Move position relative to target | ||||
| 		camera->position = Vector3Subtract( camera->target, targetPosition ); | ||||
| 	} | ||||
| 	else    // rotate around camera.position | ||||
| 	{ | ||||
| 		// Move target relative to position | ||||
| 		camera->target = Vector3Add( camera->position, targetPosition ); | ||||
| 	} | ||||
|  | ||||
|     if (rotateUp) | ||||
|     { | ||||
|         // Rotate up direction around right axis | ||||
|         camera->up = Vector3RotateByAxisAngle(camera->up, right, angle); | ||||
|     } | ||||
| 	if ( rotateUp ) | ||||
| 	{ | ||||
| 		// Rotate up direction around right axis | ||||
| 		camera->up = Vector3RotateByAxisAngle( camera->up, right, angle ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Rotates the camera around its forward vector | ||||
| // Roll is "turning your head sideways to the left or right" | ||||
| // Note: angle must be provided in radians | ||||
| void CameraRoll(Camera *camera, float angle) | ||||
| void CameraRoll( Camera* camera, float angle ) | ||||
| { | ||||
|     // Rotation axis | ||||
|     Vector3 forward = GetCameraForward(camera); | ||||
| 	// Rotation axis | ||||
| 	Vector3 forward = GetCameraForward( camera ); | ||||
|  | ||||
|     // Rotate up direction around forward axis | ||||
|     camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle); | ||||
| 	// Rotate up direction around forward axis | ||||
| 	camera->up = Vector3RotateByAxisAngle( camera->up, forward, angle ); | ||||
| } | ||||
|  | ||||
| // Returns the camera view matrix | ||||
| Matrix GetCameraViewMatrix(Camera *camera) | ||||
| Matrix GetCameraViewMatrix( Camera* camera ) | ||||
| { | ||||
|     return MatrixLookAt(camera->position, camera->target, camera->up); | ||||
| 	return MatrixLookAt( camera->position, camera->target, camera->up ); | ||||
| } | ||||
|  | ||||
| // Returns the camera projection matrix | ||||
| Matrix GetCameraProjectionMatrix(Camera *camera, float aspect) | ||||
| Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ) | ||||
| { | ||||
|     if (camera->projection == CAMERA_PERSPECTIVE) | ||||
|     { | ||||
|         return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); | ||||
|     } | ||||
|     else if (camera->projection == CAMERA_ORTHOGRAPHIC) | ||||
|     { | ||||
|         double top = camera->fovy/2.0; | ||||
|         double right = top*aspect; | ||||
| 	if ( camera->projection == CAMERA_PERSPECTIVE ) | ||||
| 	{ | ||||
| 		return MatrixPerspective( camera->fovy * DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR ); | ||||
| 	} | ||||
| 	else if ( camera->projection == CAMERA_ORTHOGRAPHIC ) | ||||
| 	{ | ||||
| 		double top   = camera->fovy / 2.0; | ||||
| 		double right = top * aspect; | ||||
|  | ||||
|         return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); | ||||
|     } | ||||
| 		return MatrixOrtho( -right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR ); | ||||
| 	} | ||||
|  | ||||
|     return MatrixIdentity(); | ||||
| 	return MatrixIdentity(); | ||||
| } | ||||
|  | ||||
| #if !defined(RCAMERA_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) | ||||
| void UpdateCamera( Camera* camera, int mode ) | ||||
| { | ||||
|     Vector2 mousePositionDelta = GetMouseDelta(); | ||||
| 	Vector2 mousePositionDelta = GetMouseDelta(); | ||||
|  | ||||
|     bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)); | ||||
|     bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); | ||||
|     bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); | ||||
|     bool rotateUp = false; | ||||
| 	bool moveInWorldPlane      = ( ( mode == CAMERA_FIRST_PERSON ) || ( mode == CAMERA_THIRD_PERSON ) ); | ||||
| 	bool rotateAroundTarget    = ( ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) ); | ||||
| 	bool lockView              = ( ( mode == CAMERA_FIRST_PERSON ) || ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) ); | ||||
| 	bool rotateUp              = false; | ||||
|  | ||||
|     if (mode == CAMERA_ORBITAL) | ||||
|     { | ||||
|         // Orbital can just orbit | ||||
|         Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime()); | ||||
|         Vector3 view = Vector3Subtract(camera->position, camera->target); | ||||
|         view = Vector3Transform(view, rotation); | ||||
|         camera->position = Vector3Add(camera->target, view); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Camera rotation | ||||
|         if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); | ||||
|         if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); | ||||
|         if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget); | ||||
|         if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget); | ||||
|         if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED); | ||||
|         if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED); | ||||
| 	if ( mode == CAMERA_ORBITAL ) | ||||
| 	{ | ||||
| 		// Orbital can just orbit | ||||
| 		Matrix  rotation = MatrixRotate( GetCameraUp( camera ), CAMERA_ORBITAL_SPEED * GetFrameTime() ); | ||||
| 		Vector3 view     = Vector3Subtract( camera->position, camera->target ); | ||||
| 		view             = Vector3Transform( view, rotation ); | ||||
| 		camera->position = Vector3Add( camera->target, view ); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// Camera rotation | ||||
| 		if ( IsKeyDown( KEY_DOWN ) ) | ||||
| 			CameraPitch( camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp ); | ||||
| 		if ( IsKeyDown( KEY_UP ) ) | ||||
| 			CameraPitch( camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp ); | ||||
| 		if ( IsKeyDown( KEY_RIGHT ) ) | ||||
| 			CameraYaw( camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget ); | ||||
| 		if ( IsKeyDown( KEY_LEFT ) ) | ||||
| 			CameraYaw( camera, CAMERA_ROTATION_SPEED, rotateAroundTarget ); | ||||
| 		if ( IsKeyDown( KEY_Q ) ) | ||||
| 			CameraRoll( camera, -CAMERA_ROTATION_SPEED ); | ||||
| 		if ( IsKeyDown( KEY_E ) ) | ||||
| 			CameraRoll( camera, CAMERA_ROTATION_SPEED ); | ||||
|  | ||||
|         // Camera movement | ||||
|         if (!IsGamepadAvailable(0)) | ||||
|         { | ||||
|             // Camera pan (for CAMERA_FREE) | ||||
|             if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) | ||||
|             { | ||||
|                 const Vector2 mouseDelta = GetMouseDelta(); | ||||
|                 if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); | ||||
|                 if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); | ||||
|                 if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); | ||||
|                 if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // Mouse support | ||||
|                 CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); | ||||
|                 CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); | ||||
|             } | ||||
| 		// Camera movement | ||||
| 		if ( ! IsGamepadAvailable( 0 ) ) | ||||
| 		{ | ||||
| 			// Camera pan (for CAMERA_FREE) | ||||
| 			if ( ( mode == CAMERA_FREE ) && ( IsMouseButtonDown( MOUSE_BUTTON_MIDDLE ) ) ) | ||||
| 			{ | ||||
| 				const Vector2 mouseDelta = GetMouseDelta(); | ||||
| 				if ( mouseDelta.x > 0.0f ) | ||||
| 					CameraMoveRight( camera, CAMERA_PAN_SPEED, moveInWorldPlane ); | ||||
| 				if ( mouseDelta.x < 0.0f ) | ||||
| 					CameraMoveRight( camera, -CAMERA_PAN_SPEED, moveInWorldPlane ); | ||||
| 				if ( mouseDelta.y > 0.0f ) | ||||
| 					CameraMoveUp( camera, -CAMERA_PAN_SPEED ); | ||||
| 				if ( mouseDelta.y < 0.0f ) | ||||
| 					CameraMoveUp( camera, CAMERA_PAN_SPEED ); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// Mouse support | ||||
| 				CameraYaw( camera, -mousePositionDelta.x * CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget ); | ||||
| 				CameraPitch( camera, -mousePositionDelta.y * CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp ); | ||||
| 			} | ||||
|  | ||||
|             // Keyboard support | ||||
|             if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Gamepad controller support | ||||
|             CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); | ||||
|             CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); | ||||
| 			// Keyboard support | ||||
| 			if ( IsKeyDown( KEY_W ) ) | ||||
| 				CameraMoveForward( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( IsKeyDown( KEY_A ) ) | ||||
| 				CameraMoveRight( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( IsKeyDown( KEY_S ) ) | ||||
| 				CameraMoveForward( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( IsKeyDown( KEY_D ) ) | ||||
| 				CameraMoveRight( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Gamepad controller support | ||||
| 			CameraYaw( camera, -( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_RIGHT_X ) * 2 ) * CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget ); | ||||
| 			CameraPitch( | ||||
| 			    camera, | ||||
| 			    -( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_RIGHT_Y ) * 2 ) * CAMERA_MOUSE_MOVE_SENSITIVITY, | ||||
| 			    lockView, | ||||
| 			    rotateAroundTarget, | ||||
| 			    rotateUp | ||||
| 			); | ||||
|  | ||||
|             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); | ||||
|         } | ||||
| 			if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_Y ) <= -0.25f ) | ||||
| 				CameraMoveForward( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_X ) <= -0.25f ) | ||||
| 				CameraMoveRight( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_Y ) >= 0.25f ) | ||||
| 				CameraMoveForward( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 			if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_X ) >= 0.25f ) | ||||
| 				CameraMoveRight( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); | ||||
| 		} | ||||
|  | ||||
|         if (mode == CAMERA_FREE) | ||||
|         { | ||||
|             if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED); | ||||
|             if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -CAMERA_MOVE_SPEED); | ||||
|         } | ||||
|     } | ||||
| 		if ( mode == CAMERA_FREE ) | ||||
| 		{ | ||||
| 			if ( IsKeyDown( KEY_SPACE ) ) | ||||
| 				CameraMoveUp( camera, CAMERA_MOVE_SPEED ); | ||||
| 			if ( IsKeyDown( KEY_LEFT_CONTROL ) ) | ||||
| 				CameraMoveUp( camera, -CAMERA_MOVE_SPEED ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|     if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE)) | ||||
|     { | ||||
|         // Zoom target distance | ||||
|         CameraMoveToTarget(camera, -GetMouseWheelMove()); | ||||
|         if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f); | ||||
|         if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f); | ||||
|     } | ||||
| 	if ( ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) || ( mode == CAMERA_FREE ) ) | ||||
| 	{ | ||||
| 		// Zoom target distance | ||||
| 		CameraMoveToTarget( camera, -GetMouseWheelMove() ); | ||||
| 		if ( IsKeyPressed( KEY_KP_SUBTRACT ) ) | ||||
| 			CameraMoveToTarget( camera, 2.0f ); | ||||
| 		if ( IsKeyPressed( KEY_KP_ADD ) ) | ||||
| 			CameraMoveToTarget( camera, -2.0f ); | ||||
| 	} | ||||
| } | ||||
| #endif // !RCAMERA_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) | ||||
| void UpdateCameraPro( Camera* camera, Vector3 movement, Vector3 rotation, float zoom ) | ||||
| { | ||||
|     // Required values | ||||
|     // movement.x - Move forward/backward | ||||
|     // movement.y - Move right/left | ||||
|     // movement.z - Move up/down | ||||
|     // rotation.x - yaw | ||||
|     // rotation.y - pitch | ||||
|     // rotation.z - roll | ||||
|     // zoom - Move towards target | ||||
| 	// Required values | ||||
| 	// movement.x - Move forward/backward | ||||
| 	// movement.y - Move right/left | ||||
| 	// movement.z - Move up/down | ||||
| 	// rotation.x - yaw | ||||
| 	// rotation.y - pitch | ||||
| 	// rotation.z - roll | ||||
| 	// zoom - Move towards target | ||||
|  | ||||
|     bool lockView = true; | ||||
|     bool rotateAroundTarget = false; | ||||
|     bool rotateUp = false; | ||||
|     bool moveInWorldPlane = true; | ||||
| 	bool lockView           = true; | ||||
| 	bool rotateAroundTarget = false; | ||||
| 	bool rotateUp           = false; | ||||
| 	bool moveInWorldPlane   = true; | ||||
|  | ||||
|     // Camera rotation | ||||
|     CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp); | ||||
|     CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget); | ||||
|     CameraRoll(camera, rotation.z*DEG2RAD); | ||||
| 	// Camera rotation | ||||
| 	CameraPitch( camera, -rotation.y * DEG2RAD, lockView, rotateAroundTarget, rotateUp ); | ||||
| 	CameraYaw( camera, -rotation.x * DEG2RAD, rotateAroundTarget ); | ||||
| 	CameraRoll( camera, rotation.z * DEG2RAD ); | ||||
|  | ||||
|     // Camera movement | ||||
|     CameraMoveForward(camera, movement.x, moveInWorldPlane); | ||||
|     CameraMoveRight(camera, movement.y, moveInWorldPlane); | ||||
|     CameraMoveUp(camera, movement.z); | ||||
| 	// Camera movement | ||||
| 	CameraMoveForward( camera, movement.x, moveInWorldPlane ); | ||||
| 	CameraMoveRight( camera, movement.y, moveInWorldPlane ); | ||||
| 	CameraMoveUp( camera, movement.z ); | ||||
|  | ||||
|     // Zoom target distance | ||||
|     CameraMoveToTarget(camera, zoom); | ||||
| 	// Zoom target distance | ||||
| 	CameraMoveToTarget( camera, zoom ); | ||||
| } | ||||
|  | ||||
| #endif // RCAMERA_IMPLEMENTATION | ||||
| #endif    // RCAMERA_IMPLEMENTATION | ||||
|   | ||||
| @@ -1,204 +1,228 @@ | ||||
| /********************************************************************************************** | ||||
| * | ||||
| *   rcore - Common types and globals (all platforms) | ||||
| * | ||||
| *   LIMITATIONS: | ||||
| *       - Limitation 01 | ||||
| *       - Limitation 02 | ||||
| * | ||||
| *   POSSIBLE IMPROVEMENTS: | ||||
| *       - Improvement 01 | ||||
| *       - Improvement 02 | ||||
| * | ||||
| * | ||||
| *   LICENSE: zlib/libpng | ||||
| * | ||||
| *   Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors | ||||
| * | ||||
| *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
| *   will the authors be held liable for any damages arising from the use of this software. | ||||
| * | ||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
| * | ||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
| *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
| *     in the product documentation would be appreciated but is not required. | ||||
| * | ||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
| *     as being the original software. | ||||
| * | ||||
| *     3. This notice may not be removed or altered from any source distribution. | ||||
| * | ||||
| **********************************************************************************************/ | ||||
|  * | ||||
|  *   rcore - Common types and globals (all platforms) | ||||
|  * | ||||
|  *   LIMITATIONS: | ||||
|  *       - Limitation 01 | ||||
|  *       - Limitation 02 | ||||
|  * | ||||
|  *   POSSIBLE IMPROVEMENTS: | ||||
|  *       - Improvement 01 | ||||
|  *       - Improvement 02 | ||||
|  * | ||||
|  * | ||||
|  *   LICENSE: zlib/libpng | ||||
|  * | ||||
|  *   Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors | ||||
|  * | ||||
|  *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
|  *   will the authors be held liable for any damages arising from the use of this software. | ||||
|  * | ||||
|  *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
|  *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
|  * | ||||
|  *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
|  *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
|  *     in the product documentation would be appreciated but is not required. | ||||
|  * | ||||
|  *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
|  *     as being the original software. | ||||
|  * | ||||
|  *     3. This notice may not be removed or altered from any source distribution. | ||||
|  * | ||||
|  **********************************************************************************************/ | ||||
|  | ||||
| #ifndef RCORE_H | ||||
| #define RCORE_H | ||||
|  | ||||
| #include "raylib.h" | ||||
|  | ||||
| #include "utils.h"                  // Required for: TRACELOG() macros | ||||
| #include "utils.h"    // Required for: TRACELOG() macros | ||||
|  | ||||
| #include "rlgl.h"                   // Required for: graphics layer functionality | ||||
| #include "rlgl.h"    // Required for: graphics layer functionality | ||||
|  | ||||
| #define RAYMATH_IMPLEMENTATION | ||||
| #include "raymath.h"                // Required for: Vector2/Vector3/Matrix functionality | ||||
| #include "raymath.h"    // Required for: Vector2/Vector3/Matrix functionality | ||||
|  | ||||
| #include <stdlib.h>                 // Required for: srand(), rand(), atexit() | ||||
| #include <stdio.h>                  // Required for: sprintf() [Used in OpenURL()] | ||||
| #include <string.h>                 // Required for: strrchr(), strcmp(), strlen(), memset() | ||||
| #include <time.h>                   // Required for: time() [Used in InitTimer()] | ||||
| #include <math.h>                   // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] | ||||
| #include <stdlib.h>    // Required for: srand(), rand(), atexit() | ||||
| #include <stdio.h>     // Required for: sprintf() [Used in OpenURL()] | ||||
| #include <string.h>    // Required for: strrchr(), strcmp(), strlen(), memset() | ||||
| #include <time.h>      // Required for: time() [Used in InitTimer()] | ||||
| #include <math.h>      // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Defines and Macros | ||||
| //---------------------------------------------------------------------------------- | ||||
| #ifndef MAX_FILEPATH_CAPACITY | ||||
|     #define MAX_FILEPATH_CAPACITY       8192        // Maximum capacity for filepath | ||||
| #define MAX_FILEPATH_CAPACITY 8192    // Maximum capacity for filepath | ||||
| #endif | ||||
| #ifndef MAX_FILEPATH_LENGTH | ||||
|     #define MAX_FILEPATH_LENGTH         4096        // Maximum length for filepaths (Linux PATH_MAX default value) | ||||
| #define MAX_FILEPATH_LENGTH 4096    // Maximum length for filepaths (Linux PATH_MAX default value) | ||||
| #endif | ||||
|  | ||||
| #ifndef MAX_KEYBOARD_KEYS | ||||
|     #define MAX_KEYBOARD_KEYS            512        // Maximum number of keyboard keys supported | ||||
| #define MAX_KEYBOARD_KEYS 512    // Maximum number of keyboard keys supported | ||||
| #endif | ||||
| #ifndef MAX_MOUSE_BUTTONS | ||||
|     #define MAX_MOUSE_BUTTONS              8        // Maximum number of mouse buttons supported | ||||
| #define MAX_MOUSE_BUTTONS 8    // Maximum number of mouse buttons supported | ||||
| #endif | ||||
| #ifndef MAX_GAMEPADS | ||||
|     #define MAX_GAMEPADS                   4        // Maximum number of gamepads supported | ||||
| #define MAX_GAMEPADS 4    // Maximum number of gamepads supported | ||||
| #endif | ||||
| #ifndef MAX_GAMEPAD_AXIS | ||||
|     #define MAX_GAMEPAD_AXIS               8        // Maximum number of axis supported (per gamepad) | ||||
| #define MAX_GAMEPAD_AXIS 8    // Maximum number of axis supported (per gamepad) | ||||
| #endif | ||||
| #ifndef MAX_GAMEPAD_BUTTONS | ||||
|     #define MAX_GAMEPAD_BUTTONS           32        // Maximum number of buttons supported (per gamepad) | ||||
| #define MAX_GAMEPAD_BUTTONS 32    // Maximum number of buttons supported (per gamepad) | ||||
| #endif | ||||
| #ifndef MAX_TOUCH_POINTS | ||||
|     #define MAX_TOUCH_POINTS               8        // Maximum number of touch points supported | ||||
| #define MAX_TOUCH_POINTS 8    // Maximum number of touch points supported | ||||
| #endif | ||||
| #ifndef MAX_KEY_PRESSED_QUEUE | ||||
|     #define MAX_KEY_PRESSED_QUEUE         16        // Maximum number of keys in the key input queue | ||||
| #define MAX_KEY_PRESSED_QUEUE 16    // Maximum number of keys in the key input queue | ||||
| #endif | ||||
| #ifndef MAX_CHAR_PRESSED_QUEUE | ||||
|     #define MAX_CHAR_PRESSED_QUEUE        16        // Maximum number of characters in the char input queue | ||||
| #define MAX_CHAR_PRESSED_QUEUE 16    // Maximum number of characters in the char input queue | ||||
| #endif | ||||
|  | ||||
| #ifndef MAX_DECOMPRESSION_SIZE | ||||
|     #define MAX_DECOMPRESSION_SIZE        64        // Maximum size allocated for decompression in MB | ||||
| #define MAX_DECOMPRESSION_SIZE 64    // Maximum size allocated for decompression in MB | ||||
| #endif | ||||
|  | ||||
| // Flags operation macros | ||||
| #define FLAG_SET(n, f) ((n) |= (f)) | ||||
| #define FLAG_CLEAR(n, f) ((n) &= ~(f)) | ||||
| #define FLAG_TOGGLE(n, f) ((n) ^= (f)) | ||||
| #define FLAG_CHECK(n, f) ((n) & (f)) | ||||
| #define FLAG_SET( n, f )    ( ( n ) |= ( f ) ) | ||||
| #define FLAG_CLEAR( n, f )  ( ( n ) &= ~( f ) ) | ||||
| #define FLAG_TOGGLE( n, f ) ( ( n ) ^= ( f ) ) | ||||
| #define FLAG_CHECK( n, f )  ( ( n ) & ( f ) ) | ||||
|  | ||||
| #if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) | ||||
|     #undef _POSIX_C_SOURCE | ||||
|     #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. | ||||
| #if ( defined( __linux__ ) || defined( PLATFORM_WEB ) ) && ( _POSIX_C_SOURCE < 199309L ) | ||||
| #undef _POSIX_C_SOURCE | ||||
| #define _POSIX_C_SOURCE 199309L    // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Types and Structures Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
| typedef struct { int x; int y; } Point; | ||||
| typedef struct { unsigned int width; unsigned int height; } Size; | ||||
| typedef struct | ||||
| { | ||||
| 	int x; | ||||
| 	int y; | ||||
| } Point; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	unsigned int width; | ||||
| 	unsigned int height; | ||||
| } Size; | ||||
|  | ||||
| // Core global state context data | ||||
| typedef struct CoreData { | ||||
|     struct { | ||||
|         const char *title;                  // Window text title const pointer | ||||
|         unsigned int flags;                 // Configuration flags (bit based), keeps window state | ||||
|         bool ready;                         // Check if window has been initialized successfully | ||||
|         bool fullscreen;                    // Check if fullscreen mode is enabled | ||||
|         bool shouldClose;                   // Check if window set for closing | ||||
|         bool resizedLastFrame;              // Check if window has been resized last frame | ||||
|         bool eventWaiting;                  // Wait for events before ending frame | ||||
| typedef struct CoreData | ||||
| { | ||||
| 	struct | ||||
| 	{ | ||||
| 		const char*  title;               // Window text title const pointer | ||||
| 		unsigned int flags;               // Configuration flags (bit based), keeps window state | ||||
| 		bool         ready;               // Check if window has been initialized successfully | ||||
| 		bool         fullscreen;          // Check if fullscreen mode is enabled | ||||
| 		bool         shouldClose;         // Check if window set for closing | ||||
| 		bool         resizedLastFrame;    // Check if window has been resized last frame | ||||
| 		bool         eventWaiting;        // Wait for events before ending frame | ||||
|  | ||||
|         Point position;                     // Window position (required on fullscreen toggle) | ||||
|         Point previousPosition;             // Window previous position (required on borderless windowed toggle) | ||||
|         Size display;                       // Display width and height (monitor, device-screen, LCD, ...) | ||||
|         Size screen;                        // Screen width and height (used render area) | ||||
|         Size previousScreen;                // Screen previous width and height (required on borderless windowed toggle) | ||||
|         Size currentFbo;                    // Current render width and height (depends on active fbo) | ||||
|         Size render;                        // Framebuffer width and height (render area, including black bars if required) | ||||
|         Point renderOffset;                 // Offset from render area (must be divided by 2) | ||||
|         Size screenMin;                     // Screen minimum width and height (for resizable window) | ||||
|         Size screenMax;                     // Screen maximum width and height (for resizable window) | ||||
|         Matrix screenScale;                 // Matrix to scale screen (framebuffer rendering) | ||||
| 		Point  position;            // Window position (required on fullscreen toggle) | ||||
| 		Point  previousPosition;    // Window previous position (required on borderless windowed toggle) | ||||
| 		Size   display;             // Display width and height (monitor, device-screen, LCD, ...) | ||||
| 		Size   screen;              // Screen width and height (used render area) | ||||
| 		Size   previousScreen;      // Screen previous width and height (required on borderless windowed toggle) | ||||
| 		Size   currentFbo;          // Current render width and height (depends on active fbo) | ||||
| 		Size   render;              // Framebuffer width and height (render area, including black bars if required) | ||||
| 		Point  renderOffset;        // Offset from render area (must be divided by 2) | ||||
| 		Size   screenMin;           // Screen minimum width and height (for resizable window) | ||||
| 		Size   screenMax;           // Screen maximum width and height (for resizable window) | ||||
| 		Matrix screenScale;         // Matrix to scale screen (framebuffer rendering) | ||||
|  | ||||
|         char **dropFilepaths;               // Store dropped files paths pointers (provided by GLFW) | ||||
|         unsigned int dropFileCount;         // Count dropped files strings | ||||
| 		char**       dropFilepaths;    // Store dropped files paths pointers (provided by GLFW) | ||||
| 		unsigned int dropFileCount;    // Count dropped files strings | ||||
|  | ||||
|     } Window; | ||||
|     struct { | ||||
|         const char *basePath;               // Base path for data storage | ||||
| 	} Window; | ||||
|  | ||||
|     } Storage; | ||||
|     struct { | ||||
|         struct { | ||||
|             int exitKey;                    // Default exit key | ||||
|             char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state | ||||
|             char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state | ||||
| 	struct | ||||
| 	{ | ||||
| 		const char* basePath;    // Base path for data storage | ||||
|  | ||||
|             // 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. | ||||
| 	} Storage; | ||||
|  | ||||
|             int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue | ||||
|             int keyPressedQueueCount;       // Input keys queue count | ||||
| 	struct | ||||
| 	{ | ||||
| 		struct | ||||
| 		{ | ||||
| 			int  exitKey;                                  // Default exit key | ||||
| 			char currentKeyState[ MAX_KEYBOARD_KEYS ];     // Registers current frame key state | ||||
| 			char previousKeyState[ MAX_KEYBOARD_KEYS ];    // Registers previous frame key state | ||||
|  | ||||
|             int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) | ||||
|             int charPressedQueueCount;      // Input characters queue count | ||||
| 			// 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. | ||||
|  | ||||
|         } Keyboard; | ||||
|         struct { | ||||
|             Vector2 offset;                 // Mouse offset | ||||
|             Vector2 scale;                  // Mouse scaling | ||||
|             Vector2 currentPosition;        // Mouse position on screen | ||||
|             Vector2 previousPosition;       // Previous mouse position | ||||
| 			int keyPressedQueue[ MAX_KEY_PRESSED_QUEUE ];    // Input keys queue | ||||
| 			int keyPressedQueueCount;                        // Input keys queue count | ||||
|  | ||||
|             int cursor;                     // Tracks current mouse cursor | ||||
|             bool cursorHidden;              // Track if cursor is hidden | ||||
|             bool cursorOnScreen;            // Tracks if cursor is inside client area | ||||
| 			int charPressedQueue[ MAX_CHAR_PRESSED_QUEUE ];    // Input characters queue (unicode) | ||||
| 			int charPressedQueueCount;                         // Input characters queue count | ||||
|  | ||||
|             char currentButtonState[MAX_MOUSE_BUTTONS];     // Registers current mouse button state | ||||
|             char previousButtonState[MAX_MOUSE_BUTTONS];    // Registers previous mouse button state | ||||
|             Vector2 currentWheelMove;       // Registers current mouse wheel variation | ||||
|             Vector2 previousWheelMove;      // Registers previous mouse wheel variation | ||||
| 		} Keyboard; | ||||
|  | ||||
|         } Mouse; | ||||
|         struct { | ||||
|             int pointCount;                             // Number of touch points active | ||||
|             int pointId[MAX_TOUCH_POINTS];              // Point identifiers | ||||
|             Vector2 position[MAX_TOUCH_POINTS];         // Touch position on screen | ||||
|             char currentTouchState[MAX_TOUCH_POINTS];   // Registers current touch state | ||||
|             char previousTouchState[MAX_TOUCH_POINTS];  // Registers previous touch state | ||||
| 		struct | ||||
| 		{ | ||||
| 			Vector2 offset;              // Mouse offset | ||||
| 			Vector2 scale;               // Mouse scaling | ||||
| 			Vector2 currentPosition;     // Mouse position on screen | ||||
| 			Vector2 previousPosition;    // Previous mouse position | ||||
|  | ||||
|         } Touch; | ||||
|         struct { | ||||
|             int lastButtonPressed;          // Register last gamepad button pressed | ||||
|             int axisCount[MAX_GAMEPADS];                  // Register number of available gamepad axis | ||||
|             bool ready[MAX_GAMEPADS];       // Flag to know if gamepad is ready | ||||
|             char name[MAX_GAMEPADS][64];    // Gamepad name holder | ||||
|             char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS];     // Current gamepad buttons state | ||||
|             char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS];    // Previous gamepad buttons state | ||||
|             float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS];                // Gamepad axis state | ||||
| 			int  cursor;            // Tracks current mouse cursor | ||||
| 			bool cursorHidden;      // Track if cursor is hidden | ||||
| 			bool cursorOnScreen;    // Tracks if cursor is inside client area | ||||
|  | ||||
|         } Gamepad; | ||||
|     } Input; | ||||
|     struct { | ||||
|         double current;                     // Current time measure | ||||
|         double previous;                    // Previous time measure | ||||
|         double update;                      // Time measure for frame update | ||||
|         double draw;                        // Time measure for frame draw | ||||
|         double frame;                       // Time measure for one frame | ||||
|         double target;                      // Desired time for one frame, if 0 not applied | ||||
|         unsigned long long int base;        // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) | ||||
|         unsigned int frameCounter;          // Frame counter | ||||
| 			char    currentButtonState[ MAX_MOUSE_BUTTONS ];     // Registers current mouse button state | ||||
| 			char    previousButtonState[ MAX_MOUSE_BUTTONS ];    // Registers previous mouse button state | ||||
| 			Vector2 currentWheelMove;                            // Registers current mouse wheel variation | ||||
| 			Vector2 previousWheelMove;                           // Registers previous mouse wheel variation | ||||
|  | ||||
|     } Time; | ||||
| 		} Mouse; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| 			int     pointCount;                                // Number of touch points active | ||||
| 			int     pointId[ MAX_TOUCH_POINTS ];               // Point identifiers | ||||
| 			Vector2 position[ MAX_TOUCH_POINTS ];              // Touch position on screen | ||||
| 			char    currentTouchState[ MAX_TOUCH_POINTS ];     // Registers current touch state | ||||
| 			char    previousTouchState[ MAX_TOUCH_POINTS ];    // Registers previous touch state | ||||
|  | ||||
| 		} Touch; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| 			int   lastButtonPressed;                                             // Register last gamepad button pressed | ||||
| 			int   axisCount[ MAX_GAMEPADS ];                                     // Register number of available gamepad axis | ||||
| 			bool  ready[ MAX_GAMEPADS ];                                         // Flag to know if gamepad is ready | ||||
| 			char  name[ MAX_GAMEPADS ][ 64 ];                                    // Gamepad name holder | ||||
| 			char  currentButtonState[ MAX_GAMEPADS ][ MAX_GAMEPAD_BUTTONS ];     // Current gamepad buttons state | ||||
| 			char  previousButtonState[ MAX_GAMEPADS ][ MAX_GAMEPAD_BUTTONS ];    // Previous gamepad buttons state | ||||
| 			float axisState[ MAX_GAMEPADS ][ MAX_GAMEPAD_AXIS ];                 // Gamepad axis state | ||||
|  | ||||
| 		} Gamepad; | ||||
| 	} Input; | ||||
|  | ||||
| 	struct | ||||
| 	{ | ||||
| 		double                 current;         // Current time measure | ||||
| 		double                 previous;        // Previous time measure | ||||
| 		double                 update;          // Time measure for frame update | ||||
| 		double                 draw;            // Time measure for frame draw | ||||
| 		double                 frame;           // Time measure for one frame | ||||
| 		double                 target;          // Desired time for one frame, if 0 not applied | ||||
| 		unsigned long long int base;            // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) | ||||
| 		unsigned int           frameCounter;    // Frame counter | ||||
|  | ||||
| 	} Time; | ||||
| } CoreData; | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
|   | ||||
| @@ -1,57 +1,57 @@ | ||||
| /********************************************************************************************** | ||||
| * | ||||
| *   rgestures - Gestures system, gestures processing based on input events (touch/mouse) | ||||
| * | ||||
| *   CONFIGURATION: | ||||
| *       #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 RGESTURES_STANDALONE | ||||
| *           If defined, the library can be used as standalone to process gesture events with | ||||
| *           no external dependencies. | ||||
| * | ||||
| *   CONTRIBUTORS: | ||||
| *       Marc Palau:         Initial implementation (2014) | ||||
| *       Albert Martos:      Complete redesign and testing (2015) | ||||
| *       Ian Eito:           Complete redesign and testing (2015) | ||||
| *       Ramon Santamaria:   Supervision, review, update and maintenance | ||||
| * | ||||
| * | ||||
| *   LICENSE: zlib/libpng | ||||
| * | ||||
| *   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) | ||||
| * | ||||
| *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
| *   will the authors be held liable for any damages arising from the use of this software. | ||||
| * | ||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
| * | ||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
| *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
| *     in the product documentation would be appreciated but is not required. | ||||
| * | ||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
| *     as being the original software. | ||||
| * | ||||
| *     3. This notice may not be removed or altered from any source distribution. | ||||
| * | ||||
| **********************************************************************************************/ | ||||
|  * | ||||
|  *   rgestures - Gestures system, gestures processing based on input events (touch/mouse) | ||||
|  * | ||||
|  *   CONFIGURATION: | ||||
|  *       #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 RGESTURES_STANDALONE | ||||
|  *           If defined, the library can be used as standalone to process gesture events with | ||||
|  *           no external dependencies. | ||||
|  * | ||||
|  *   CONTRIBUTORS: | ||||
|  *       Marc Palau:         Initial implementation (2014) | ||||
|  *       Albert Martos:      Complete redesign and testing (2015) | ||||
|  *       Ian Eito:           Complete redesign and testing (2015) | ||||
|  *       Ramon Santamaria:   Supervision, review, update and maintenance | ||||
|  * | ||||
|  * | ||||
|  *   LICENSE: zlib/libpng | ||||
|  * | ||||
|  *   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) | ||||
|  * | ||||
|  *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
|  *   will the authors be held liable for any damages arising from the use of this software. | ||||
|  * | ||||
|  *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
|  *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
|  * | ||||
|  *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
|  *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
|  *     in the product documentation would be appreciated but is not required. | ||||
|  * | ||||
|  *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
|  *     as being the original software. | ||||
|  * | ||||
|  *     3. This notice may not be removed or altered from any source distribution. | ||||
|  * | ||||
|  **********************************************************************************************/ | ||||
|  | ||||
| #ifndef RGESTURES_H | ||||
| #define RGESTURES_H | ||||
|  | ||||
| #ifndef PI | ||||
|     #define PI 3.14159265358979323846 | ||||
| #define PI 3.14159265358979323846 | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Defines and Macros | ||||
| //---------------------------------------------------------------------------------- | ||||
| #ifndef MAX_TOUCH_POINTS | ||||
|     #define MAX_TOUCH_POINTS        8        // Maximum number of touch points supported | ||||
| #define MAX_TOUCH_POINTS 8    // Maximum number of touch points supported | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| @@ -59,51 +59,59 @@ | ||||
| // NOTE: Below types are required for standalone usage | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Boolean type | ||||
| #if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) | ||||
|     #include <stdbool.h> | ||||
| #elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) | ||||
|     typedef enum bool { false = 0, true = !false } bool; | ||||
| #if ( defined( __STDC__ ) && __STDC_VERSION__ >= 199901L ) || ( defined( _MSC_VER ) && _MSC_VER >= 1800 ) | ||||
| #include <stdbool.h> | ||||
| #elif ! defined( __cplusplus ) && ! defined( bool ) && ! defined( RL_BOOL_TYPE ) | ||||
| typedef enum bool | ||||
| { | ||||
| 	false = 0, | ||||
| 	true  = ! false | ||||
| } bool; | ||||
| #endif | ||||
|  | ||||
| #if !defined(RL_VECTOR2_TYPE) | ||||
| #if ! defined( RL_VECTOR2_TYPE ) | ||||
| // Vector2 type | ||||
| typedef struct Vector2 { | ||||
|     float x; | ||||
|     float y; | ||||
| typedef struct Vector2 | ||||
| { | ||||
| 	float x; | ||||
| 	float y; | ||||
| } Vector2; | ||||
| #endif | ||||
|  | ||||
| #if defined(RGESTURES_STANDALONE) | ||||
| #if defined( RGESTURES_STANDALONE ) | ||||
| // Gestures type | ||||
| // NOTE: It could be used as flags to enable only some gestures | ||||
| typedef enum { | ||||
|     GESTURE_NONE        = 0, | ||||
|     GESTURE_TAP         = 1, | ||||
|     GESTURE_DOUBLETAP   = 2, | ||||
|     GESTURE_HOLD        = 4, | ||||
|     GESTURE_DRAG        = 8, | ||||
|     GESTURE_SWIPE_RIGHT = 16, | ||||
|     GESTURE_SWIPE_LEFT  = 32, | ||||
|     GESTURE_SWIPE_UP    = 64, | ||||
|     GESTURE_SWIPE_DOWN  = 128, | ||||
|     GESTURE_PINCH_IN    = 256, | ||||
|     GESTURE_PINCH_OUT   = 512 | ||||
| typedef enum | ||||
| { | ||||
| 	GESTURE_NONE        = 0, | ||||
| 	GESTURE_TAP         = 1, | ||||
| 	GESTURE_DOUBLETAP   = 2, | ||||
| 	GESTURE_HOLD        = 4, | ||||
| 	GESTURE_DRAG        = 8, | ||||
| 	GESTURE_SWIPE_RIGHT = 16, | ||||
| 	GESTURE_SWIPE_LEFT  = 32, | ||||
| 	GESTURE_SWIPE_UP    = 64, | ||||
| 	GESTURE_SWIPE_DOWN  = 128, | ||||
| 	GESTURE_PINCH_IN    = 256, | ||||
| 	GESTURE_PINCH_OUT   = 512 | ||||
| } Gesture; | ||||
| #endif | ||||
|  | ||||
| typedef enum { | ||||
|     TOUCH_ACTION_UP = 0, | ||||
|     TOUCH_ACTION_DOWN, | ||||
|     TOUCH_ACTION_MOVE, | ||||
|     TOUCH_ACTION_CANCEL | ||||
| typedef enum | ||||
| { | ||||
| 	TOUCH_ACTION_UP = 0, | ||||
| 	TOUCH_ACTION_DOWN, | ||||
| 	TOUCH_ACTION_MOVE, | ||||
| 	TOUCH_ACTION_CANCEL | ||||
| } TouchAction; | ||||
|  | ||||
| // Gesture event | ||||
| typedef struct { | ||||
|     int touchAction; | ||||
|     int pointCount; | ||||
|     int pointId[MAX_TOUCH_POINTS]; | ||||
|     Vector2 position[MAX_TOUCH_POINTS]; | ||||
| typedef struct | ||||
| { | ||||
| 	int     touchAction; | ||||
| 	int     pointCount; | ||||
| 	int     pointId[ MAX_TOUCH_POINTS ]; | ||||
| 	Vector2 position[ MAX_TOUCH_POINTS ]; | ||||
| } GestureEvent; | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| @@ -115,441 +123,472 @@ typedef struct { | ||||
| // Module Functions Declaration | ||||
| //---------------------------------------------------------------------------------- | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| extern "C" {            // Prevents name mangling of functions | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" | ||||
| {    // Prevents name mangling of functions | ||||
| #endif | ||||
|  | ||||
| void ProcessGestureEvent(GestureEvent event);           // Process gesture event and translate it into gestures | ||||
| void UpdateGestures(void);                              // Update gestures detected (must be called every frame) | ||||
| 	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(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 | ||||
| #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 seconds | ||||
| Vector2 GetGestureDragVector(void);                     // Get gesture drag vector | ||||
| float GetGestureDragAngle(void);                        // Get gesture drag angle | ||||
| Vector2 GetGesturePinchVector(void);                    // Get gesture pinch delta | ||||
| float GetGesturePinchAngle(void);                       // Get gesture pinch angle | ||||
| 	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 | ||||
| 	float   GetGesturePinchAngle( void );      // Get gesture pinch angle | ||||
| #endif | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| #if defined( __cplusplus ) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif // RGESTURES_H | ||||
| #endif    // RGESTURES_H | ||||
|  | ||||
| /*********************************************************************************** | ||||
| * | ||||
| *   RGESTURES IMPLEMENTATION | ||||
| * | ||||
| ************************************************************************************/ | ||||
|  * | ||||
|  *   RGESTURES IMPLEMENTATION | ||||
|  * | ||||
|  ************************************************************************************/ | ||||
|  | ||||
| #if defined(RGESTURES_IMPLEMENTATION) | ||||
| #if defined( RGESTURES_IMPLEMENTATION ) | ||||
|  | ||||
| #if defined(RGESTURES_STANDALONE) | ||||
| #if defined(_WIN32) | ||||
|     #if defined(__cplusplus) | ||||
|     extern "C" {        // Prevents name mangling of functions | ||||
|     #endif | ||||
|     // Functions required to query time on Windows | ||||
|     int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); | ||||
|     int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); | ||||
|     #if defined(__cplusplus) | ||||
|     } | ||||
|     #endif | ||||
| #elif defined(__linux__) | ||||
|     #if _POSIX_C_SOURCE < 199309L | ||||
|         #undef _POSIX_C_SOURCE | ||||
|         #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. | ||||
|     #endif | ||||
|     #include <sys/time.h>               // Required for: timespec | ||||
|     #include <time.h>                   // Required for: clock_gettime() | ||||
|  | ||||
|     #include <math.h>                   // Required for: sqrtf(), atan2f() | ||||
| #if defined( RGESTURES_STANDALONE ) | ||||
| #if defined( _WIN32 ) | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" | ||||
| {    // Prevents name mangling of functions | ||||
| #endif | ||||
| #if defined(__APPLE__)                  // macOS also defines __MACH__ | ||||
|     #include <mach/clock.h>             // Required for: clock_get_time() | ||||
|     #include <mach/mach.h>              // Required for: mach_timespec_t | ||||
| 	// Functions required to query time on Windows | ||||
| 	int __stdcall QueryPerformanceCounter( unsigned long long int* lpPerformanceCount ); | ||||
| 	int __stdcall QueryPerformanceFrequency( unsigned long long int* lpFrequency ); | ||||
| #if defined( __cplusplus ) | ||||
| } | ||||
| #endif | ||||
| #elif defined( __linux__ ) | ||||
| #if _POSIX_C_SOURCE < 199309L | ||||
| #undef _POSIX_C_SOURCE | ||||
| #define _POSIX_C_SOURCE 199309L    // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. | ||||
| #endif | ||||
| #include <sys/time.h>    // Required for: timespec | ||||
| #include <time.h>        // Required for: clock_gettime() | ||||
|  | ||||
| #include <math.h>    // Required for: sqrtf(), atan2f() | ||||
| #endif | ||||
| #if defined( __APPLE__ )    // macOS also defines __MACH__ | ||||
| #include <mach/clock.h>     // Required for: clock_get_time() | ||||
| #include <mach/mach.h>      // Required for: mach_timespec_t | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Defines and Macros | ||||
| //---------------------------------------------------------------------------------- | ||||
| #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.3f        // 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         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) | ||||
| #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.3f      // 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     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) | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Types and Structures Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
|  | ||||
| // Gestures module state context [136 bytes] | ||||
| typedef struct { | ||||
|     unsigned int current;               // Current detected gesture | ||||
|     unsigned int enabledFlags;          // Enabled gestures flags | ||||
|     struct { | ||||
|         int firstId;                    // Touch id for first touch point | ||||
|         int pointCount;                 // Touch points counter | ||||
|         double eventTime;               // Time stamp when an event happened | ||||
|         Vector2 upPosition;             // Touch up position | ||||
|         Vector2 downPositionA;          // First touch down position | ||||
|         Vector2 downPositionB;          // Second touch down position | ||||
|         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 seconds | ||||
|     } Hold; | ||||
|     struct { | ||||
|         Vector2 vector;                 // DRAG vector (between initial and current position) | ||||
|         float angle;                    // DRAG angle (relative to x-axis) | ||||
|         float distance;                 // DRAG distance (from initial touch point to final) (normalized [0..1]) | ||||
|         float intensity;                // DRAG intensity, how far why did the DRAG (pixels per frame) | ||||
|     } Drag; | ||||
|     struct { | ||||
|         double startTime;               // SWIPE start time to calculate drag intensity | ||||
|     } Swipe; | ||||
|     struct { | ||||
|         Vector2 vector;                 // PINCH vector (between first and second touch points) | ||||
|         float angle;                    // PINCH angle (relative to x-axis) | ||||
|         float distance;                 // PINCH displacement distance (normalized [0..1]) | ||||
|     } Pinch; | ||||
| typedef struct | ||||
| { | ||||
| 	unsigned int current;         // Current detected gesture | ||||
| 	unsigned int enabledFlags;    // Enabled gestures flags | ||||
|  | ||||
| 	struct | ||||
| 	{ | ||||
| 		int     firstId;              // Touch id for first touch point | ||||
| 		int     pointCount;           // Touch points counter | ||||
| 		double  eventTime;            // Time stamp when an event happened | ||||
| 		Vector2 upPosition;           // Touch up position | ||||
| 		Vector2 downPositionA;        // First touch down position | ||||
| 		Vector2 downPositionB;        // Second touch down position | ||||
| 		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 seconds | ||||
| 	} Hold; | ||||
|  | ||||
| 	struct | ||||
| 	{ | ||||
| 		Vector2 vector;       // DRAG vector (between initial and current position) | ||||
| 		float   angle;        // DRAG angle (relative to x-axis) | ||||
| 		float   distance;     // DRAG distance (from initial touch point to final) (normalized [0..1]) | ||||
| 		float   intensity;    // DRAG intensity, how far why did the DRAG (pixels per frame) | ||||
| 	} Drag; | ||||
|  | ||||
| 	struct | ||||
| 	{ | ||||
| 		double startTime;    // SWIPE start time to calculate drag intensity | ||||
| 	} Swipe; | ||||
|  | ||||
| 	struct | ||||
| 	{ | ||||
| 		Vector2 vector;      // PINCH vector (between first and second touch points) | ||||
| 		float   angle;       // PINCH angle (relative to x-axis) | ||||
| 		float   distance;    // PINCH displacement distance (normalized [0..1]) | ||||
| 	} Pinch; | ||||
| } GesturesData; | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Global Variables Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
| static GesturesData GESTURES = { | ||||
|     .Touch.firstId = -1, | ||||
|     .current = GESTURE_NONE,        // No current gesture detected | ||||
|     .enabledFlags = 0b0000001111111111  // All gestures supported by default | ||||
| 	.Touch.firstId = -1, | ||||
| 	.current       = GESTURE_NONE,         // No current gesture detected | ||||
| 	.enabledFlags  = 0b0000001111111111    // All gestures supported by default | ||||
| }; | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Module specific Functions Declaration | ||||
| //---------------------------------------------------------------------------------- | ||||
| static float rgVector2Angle(Vector2 initialPosition, Vector2 finalPosition); | ||||
| static float rgVector2Distance(Vector2 v1, Vector2 v2); | ||||
| static double rgGetCurrentTime(void); | ||||
| static float  rgVector2Angle( Vector2 initialPosition, Vector2 finalPosition ); | ||||
| static float  rgVector2Distance( Vector2 v1, Vector2 v2 ); | ||||
| static double rgGetCurrentTime( void ); | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Module Functions Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
|  | ||||
| // Enable only desired gestures to be detected | ||||
| void SetGesturesEnabled(unsigned int flags) | ||||
| void SetGesturesEnabled( unsigned int flags ) | ||||
| { | ||||
|     GESTURES.enabledFlags = flags; | ||||
| 	GESTURES.enabledFlags = flags; | ||||
| } | ||||
|  | ||||
| // Check if a gesture have been detected | ||||
| bool IsGestureDetected(unsigned int gesture) | ||||
| bool IsGestureDetected( unsigned int gesture ) | ||||
| { | ||||
|     if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true; | ||||
|     else return false; | ||||
| 	if ( ( GESTURES.enabledFlags & GESTURES.current ) == gesture ) | ||||
| 		return true; | ||||
| 	else | ||||
| 		return false; | ||||
| } | ||||
|  | ||||
| // Process gesture event and translate it into gestures | ||||
| void ProcessGestureEvent(GestureEvent event) | ||||
| void ProcessGestureEvent( GestureEvent event ) | ||||
| { | ||||
|     // Reset required variables | ||||
|     GESTURES.Touch.pointCount = event.pointCount;      // Required on UpdateGestures() | ||||
| 	// Reset required variables | ||||
| 	GESTURES.Touch.pointCount = event.pointCount;    // Required on UpdateGestures() | ||||
|  | ||||
|     if (GESTURES.Touch.pointCount == 1)     // One touch point | ||||
|     { | ||||
|         if (event.touchAction == TOUCH_ACTION_DOWN) | ||||
|         { | ||||
|             GESTURES.Touch.tapCounter++;    // Tap counter | ||||
| 	if ( GESTURES.Touch.pointCount == 1 )    // One touch point | ||||
| 	{ | ||||
| 		if ( event.touchAction == TOUCH_ACTION_DOWN ) | ||||
| 		{ | ||||
| 			GESTURES.Touch.tapCounter++;    // Tap counter | ||||
|  | ||||
|             // Detect GESTURE_DOUBLE_TAP | ||||
|             if ((GESTURES.current == GESTURE_NONE) && (GESTURES.Touch.tapCounter >= 2) && ((rgGetCurrentTime() - GESTURES.Touch.eventTime) < TAP_TIMEOUT) && (rgVector2Distance(GESTURES.Touch.downPositionA, event.position[0]) < DOUBLETAP_RANGE)) | ||||
|             { | ||||
|                 GESTURES.current = GESTURE_DOUBLETAP; | ||||
|                 GESTURES.Touch.tapCounter = 0; | ||||
|             } | ||||
|             else    // Detect GESTURE_TAP | ||||
|             { | ||||
|                 GESTURES.Touch.tapCounter = 1; | ||||
|                 GESTURES.current = GESTURE_TAP; | ||||
|             } | ||||
| 			// Detect GESTURE_DOUBLE_TAP | ||||
| 			if ( ( GESTURES.current == GESTURE_NONE ) && ( GESTURES.Touch.tapCounter >= 2 ) | ||||
| 			     && ( ( rgGetCurrentTime() - GESTURES.Touch.eventTime ) < TAP_TIMEOUT ) | ||||
| 			     && ( rgVector2Distance( GESTURES.Touch.downPositionA, event.position[ 0 ] ) < DOUBLETAP_RANGE ) ) | ||||
| 			{ | ||||
| 				GESTURES.current          = GESTURE_DOUBLETAP; | ||||
| 				GESTURES.Touch.tapCounter = 0; | ||||
| 			} | ||||
| 			else    // Detect GESTURE_TAP | ||||
| 			{ | ||||
| 				GESTURES.Touch.tapCounter = 1; | ||||
| 				GESTURES.current          = GESTURE_TAP; | ||||
| 			} | ||||
|  | ||||
|             GESTURES.Touch.downPositionA = event.position[0]; | ||||
|             GESTURES.Touch.downDragPosition = event.position[0]; | ||||
| 			GESTURES.Touch.downPositionA    = event.position[ 0 ]; | ||||
| 			GESTURES.Touch.downDragPosition = event.position[ 0 ]; | ||||
|  | ||||
|             GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA; | ||||
|             GESTURES.Touch.eventTime = rgGetCurrentTime(); | ||||
| 			GESTURES.Touch.upPosition       = GESTURES.Touch.downPositionA; | ||||
| 			GESTURES.Touch.eventTime        = rgGetCurrentTime(); | ||||
|  | ||||
|             GESTURES.Swipe.startTime = rgGetCurrentTime(); | ||||
| 			GESTURES.Swipe.startTime        = rgGetCurrentTime(); | ||||
|  | ||||
|             GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f }; | ||||
|         } | ||||
|         else if (event.touchAction == TOUCH_ACTION_UP) | ||||
|         { | ||||
|             // 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]; | ||||
| 			GESTURES.Drag.vector            = ( Vector2 ) { 0.0f, 0.0f }; | ||||
| 		} | ||||
| 		else if ( event.touchAction == TOUCH_ACTION_UP ) | ||||
| 		{ | ||||
| 			// 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); | ||||
|             GESTURES.Drag.intensity = GESTURES.Drag.distance/(float)((rgGetCurrentTime() - GESTURES.Swipe.startTime)); | ||||
| 			// NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen | ||||
| 			GESTURES.Drag.distance  = rgVector2Distance( GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition ); | ||||
| 			GESTURES.Drag.intensity = GESTURES.Drag.distance / ( float )( ( rgGetCurrentTime() - GESTURES.Swipe.startTime ) ); | ||||
|  | ||||
|             // Detect GESTURE_SWIPE | ||||
|             if ((GESTURES.Drag.intensity > FORCE_TO_SWIPE) && (GESTURES.current != GESTURE_DRAG)) | ||||
|             { | ||||
|                 // NOTE: Angle should be inverted in Y | ||||
|                 GESTURES.Drag.angle = 360.0f - rgVector2Angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition); | ||||
| 			// Detect GESTURE_SWIPE | ||||
| 			if ( ( GESTURES.Drag.intensity > FORCE_TO_SWIPE ) && ( GESTURES.current != GESTURE_DRAG ) ) | ||||
| 			{ | ||||
| 				// 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 <= 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 | ||||
|             { | ||||
|                 GESTURES.Drag.distance = 0.0f; | ||||
|                 GESTURES.Drag.intensity = 0.0f; | ||||
|                 GESTURES.Drag.angle = 0.0f; | ||||
| 				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 | ||||
| 			{ | ||||
| 				GESTURES.Drag.distance  = 0.0f; | ||||
| 				GESTURES.Drag.intensity = 0.0f; | ||||
| 				GESTURES.Drag.angle     = 0.0f; | ||||
|  | ||||
|                 GESTURES.current = GESTURE_NONE; | ||||
|             } | ||||
| 				GESTURES.current        = GESTURE_NONE; | ||||
| 			} | ||||
|  | ||||
|             GESTURES.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f }; | ||||
|             GESTURES.Touch.pointCount = 0; | ||||
|         } | ||||
|         else if (event.touchAction == TOUCH_ACTION_MOVE) | ||||
|         { | ||||
|             GESTURES.Touch.moveDownPositionA = event.position[0]; | ||||
| 			GESTURES.Touch.downDragPosition = ( Vector2 ) { 0.0f, 0.0f }; | ||||
| 			GESTURES.Touch.pointCount       = 0; | ||||
| 		} | ||||
| 		else if ( event.touchAction == TOUCH_ACTION_MOVE ) | ||||
| 		{ | ||||
| 			GESTURES.Touch.moveDownPositionA = event.position[ 0 ]; | ||||
|  | ||||
|             if (GESTURES.current == GESTURE_HOLD) | ||||
|             { | ||||
|                 if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0]; | ||||
| 			if ( GESTURES.current == GESTURE_HOLD ) | ||||
| 			{ | ||||
| 				if ( GESTURES.Hold.resetRequired ) | ||||
| 					GESTURES.Touch.downPositionA = event.position[ 0 ]; | ||||
|  | ||||
|                 GESTURES.Hold.resetRequired = false; | ||||
| 				GESTURES.Hold.resetRequired = false; | ||||
|  | ||||
|                 // Detect GESTURE_DRAG | ||||
|                 if ((rgGetCurrentTime() - GESTURES.Touch.eventTime) > DRAG_TIMEOUT) | ||||
|                 { | ||||
|                     GESTURES.Touch.eventTime = rgGetCurrentTime(); | ||||
|                     GESTURES.current = GESTURE_DRAG; | ||||
|                 } | ||||
|             } | ||||
| 				// Detect GESTURE_DRAG | ||||
| 				if ( ( rgGetCurrentTime() - GESTURES.Touch.eventTime ) > DRAG_TIMEOUT ) | ||||
| 				{ | ||||
| 					GESTURES.Touch.eventTime = rgGetCurrentTime(); | ||||
| 					GESTURES.current         = GESTURE_DRAG; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
|             GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x; | ||||
|             GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y; | ||||
|         } | ||||
|     } | ||||
|     else if (GESTURES.Touch.pointCount == 2)    // Two touch points | ||||
|     { | ||||
|         if (event.touchAction == TOUCH_ACTION_DOWN) | ||||
|         { | ||||
|             GESTURES.Touch.downPositionA = event.position[0]; | ||||
|             GESTURES.Touch.downPositionB = event.position[1]; | ||||
| 			GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x; | ||||
| 			GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y; | ||||
| 		} | ||||
| 	} | ||||
| 	else if ( GESTURES.Touch.pointCount == 2 )    // Two touch points | ||||
| 	{ | ||||
| 		if ( event.touchAction == TOUCH_ACTION_DOWN ) | ||||
| 		{ | ||||
| 			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.Touch.previousPositionA = GESTURES.Touch.downPositionA; | ||||
| 			GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB; | ||||
|  | ||||
|             //GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.downPositionA, 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; | ||||
|             GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y; | ||||
| 			GESTURES.Pinch.vector.x    = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x; | ||||
| 			GESTURES.Pinch.vector.y    = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y; | ||||
|  | ||||
|             GESTURES.current = GESTURE_HOLD; | ||||
|             GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
|         } | ||||
|         else if (event.touchAction == TOUCH_ACTION_MOVE) | ||||
|         { | ||||
|             GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); | ||||
| 			GESTURES.current           = GESTURE_HOLD; | ||||
| 			GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
| 		} | ||||
| 		else if ( event.touchAction == TOUCH_ACTION_MOVE ) | ||||
| 		{ | ||||
| 			GESTURES.Pinch.distance          = rgVector2Distance( GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB ); | ||||
|  | ||||
|             GESTURES.Touch.moveDownPositionA = event.position[0]; | ||||
|             GESTURES.Touch.moveDownPositionB = event.position[1]; | ||||
| 			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; | ||||
| 			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.previousPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH)) | ||||
|             { | ||||
|                 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 | ||||
|             { | ||||
|                 GESTURES.current = GESTURE_HOLD; | ||||
|                 GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
|             } | ||||
| 			if ( ( rgVector2Distance( GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA ) >= MINIMUM_PINCH ) | ||||
| 			     || ( rgVector2Distance( GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB ) >= MINIMUM_PINCH ) ) | ||||
| 			{ | ||||
| 				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 | ||||
| 			{ | ||||
| 				GESTURES.current           = GESTURE_HOLD; | ||||
| 				GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
| 			} | ||||
|  | ||||
|             // NOTE: Angle should be inverted in Y | ||||
|             GESTURES.Pinch.angle = 360.0f - rgVector2Angle(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); | ||||
|         } | ||||
|         else if (event.touchAction == TOUCH_ACTION_UP) | ||||
|         { | ||||
|             GESTURES.Pinch.distance = 0.0f; | ||||
|             GESTURES.Pinch.angle = 0.0f; | ||||
|             GESTURES.Pinch.vector = (Vector2){ 0.0f, 0.0f }; | ||||
|             GESTURES.Touch.pointCount = 0; | ||||
| 			// NOTE: Angle should be inverted in Y | ||||
| 			GESTURES.Pinch.angle = 360.0f - rgVector2Angle( GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB ); | ||||
| 		} | ||||
| 		else if ( event.touchAction == TOUCH_ACTION_UP ) | ||||
| 		{ | ||||
| 			GESTURES.Pinch.distance   = 0.0f; | ||||
| 			GESTURES.Pinch.angle      = 0.0f; | ||||
| 			GESTURES.Pinch.vector     = ( Vector2 ) { 0.0f, 0.0f }; | ||||
| 			GESTURES.Touch.pointCount = 0; | ||||
|  | ||||
|             GESTURES.current = GESTURE_NONE; | ||||
|         } | ||||
|     } | ||||
|     else if (GESTURES.Touch.pointCount > 2)     // More than two touch points | ||||
|     { | ||||
|         // TODO: Process gesture events for more than two points | ||||
|     } | ||||
| 			GESTURES.current          = GESTURE_NONE; | ||||
| 		} | ||||
| 	} | ||||
| 	else if ( GESTURES.Touch.pointCount > 2 )    // More than two touch points | ||||
| 	{ | ||||
| 		// TODO: Process gesture events for more than two points | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Update gestures detected (must be called every frame) | ||||
| void UpdateGestures(void) | ||||
| void UpdateGestures( void ) | ||||
| { | ||||
|     // NOTE: Gestures are processed through system callbacks on touch events | ||||
| 	// NOTE: Gestures are processed through system callbacks on touch events | ||||
|  | ||||
|     // Detect GESTURE_HOLD | ||||
|     if (((GESTURES.current == GESTURE_TAP) || (GESTURES.current == GESTURE_DOUBLETAP)) && (GESTURES.Touch.pointCount < 2)) | ||||
|     { | ||||
|         GESTURES.current = GESTURE_HOLD; | ||||
|         GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
|     } | ||||
| 	// Detect GESTURE_HOLD | ||||
| 	if ( ( ( GESTURES.current == GESTURE_TAP ) || ( GESTURES.current == GESTURE_DOUBLETAP ) ) && ( GESTURES.Touch.pointCount < 2 ) ) | ||||
| 	{ | ||||
| 		GESTURES.current           = GESTURE_HOLD; | ||||
| 		GESTURES.Hold.timeDuration = rgGetCurrentTime(); | ||||
| 	} | ||||
|  | ||||
|     // Detect GESTURE_NONE | ||||
|     if ((GESTURES.current == GESTURE_SWIPE_RIGHT) || (GESTURES.current == GESTURE_SWIPE_UP) || (GESTURES.current == GESTURE_SWIPE_LEFT) || (GESTURES.current == GESTURE_SWIPE_DOWN)) | ||||
|     { | ||||
|         GESTURES.current = GESTURE_NONE; | ||||
|     } | ||||
| 	// Detect GESTURE_NONE | ||||
| 	if ( ( GESTURES.current == GESTURE_SWIPE_RIGHT ) || ( GESTURES.current == GESTURE_SWIPE_UP ) || ( GESTURES.current == GESTURE_SWIPE_LEFT ) | ||||
| 	     || ( GESTURES.current == GESTURE_SWIPE_DOWN ) ) | ||||
| 	{ | ||||
| 		GESTURES.current = GESTURE_NONE; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Get latest detected gesture | ||||
| int GetGestureDetected(void) | ||||
| int GetGestureDetected( void ) | ||||
| { | ||||
|     // Get current gesture only if enabled | ||||
|     return (GESTURES.enabledFlags & GESTURES.current); | ||||
| 	// Get current gesture only if enabled | ||||
| 	return ( GESTURES.enabledFlags & GESTURES.current ); | ||||
| } | ||||
|  | ||||
| // Hold time measured in ms | ||||
| float GetGestureHoldDuration(void) | ||||
| float GetGestureHoldDuration( void ) | ||||
| { | ||||
|     // NOTE: time is calculated on current gesture HOLD | ||||
| 	// NOTE: time is calculated on current gesture HOLD | ||||
|  | ||||
|     double time = 0.0; | ||||
| 	double time = 0.0; | ||||
|  | ||||
|     if (GESTURES.current == GESTURE_HOLD) time = rgGetCurrentTime() - GESTURES.Hold.timeDuration; | ||||
| 	if ( GESTURES.current == GESTURE_HOLD ) | ||||
| 		time = rgGetCurrentTime() - GESTURES.Hold.timeDuration; | ||||
|  | ||||
|     return (float)time; | ||||
| 	return ( float )time; | ||||
| } | ||||
|  | ||||
| // Get drag vector (between initial touch point to current) | ||||
| Vector2 GetGestureDragVector(void) | ||||
| Vector2 GetGestureDragVector( void ) | ||||
| { | ||||
|     // NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE | ||||
| 	// NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE | ||||
|  | ||||
|     return GESTURES.Drag.vector; | ||||
| 	return GESTURES.Drag.vector; | ||||
| } | ||||
|  | ||||
| // Get drag angle | ||||
| // NOTE: Angle in degrees, horizontal-right is 0, counterclockwise | ||||
| float GetGestureDragAngle(void) | ||||
| float GetGestureDragAngle( void ) | ||||
| { | ||||
|     // NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP | ||||
| 	// NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP | ||||
|  | ||||
|     return GESTURES.Drag.angle; | ||||
| 	return GESTURES.Drag.angle; | ||||
| } | ||||
|  | ||||
| // Get distance between two pinch points | ||||
| Vector2 GetGesturePinchVector(void) | ||||
| Vector2 GetGesturePinchVector( void ) | ||||
| { | ||||
|     // NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE | ||||
| 	// NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE | ||||
|  | ||||
|     return GESTURES.Pinch.vector; | ||||
| 	return GESTURES.Pinch.vector; | ||||
| } | ||||
|  | ||||
| // Get angle between two pinch points | ||||
| // NOTE: Angle in degrees, horizontal-right is 0, counterclockwise | ||||
| float GetGesturePinchAngle(void) | ||||
| float GetGesturePinchAngle( void ) | ||||
| { | ||||
|     // NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE | ||||
| 	// NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE | ||||
|  | ||||
|     return GESTURES.Pinch.angle; | ||||
| 	return GESTURES.Pinch.angle; | ||||
| } | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Module specific Functions Definition | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Get angle from two-points vector with X-axis | ||||
| static float rgVector2Angle(Vector2 v1, Vector2 v2) | ||||
| static float rgVector2Angle( Vector2 v1, Vector2 v2 ) | ||||
| { | ||||
|     float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI); | ||||
| 	float angle = atan2f( v2.y - v1.y, v2.x - v1.x ) * ( 180.0f / PI ); | ||||
|  | ||||
|     if (angle < 0) angle += 360.0f; | ||||
| 	if ( angle < 0 ) | ||||
| 		angle += 360.0f; | ||||
|  | ||||
|     return angle; | ||||
| 	return angle; | ||||
| } | ||||
|  | ||||
| // Calculate distance between two Vector2 | ||||
| static float rgVector2Distance(Vector2 v1, Vector2 v2) | ||||
| static float rgVector2Distance( Vector2 v1, Vector2 v2 ) | ||||
| { | ||||
|     float result; | ||||
| 	float result; | ||||
|  | ||||
|     float dx = v2.x - v1.x; | ||||
|     float dy = v2.y - v1.y; | ||||
| 	float dx = v2.x - v1.x; | ||||
| 	float dy = v2.y - v1.y; | ||||
|  | ||||
|     result = (float)sqrt(dx*dx + dy*dy); | ||||
| 	result   = ( float )sqrt( dx * dx + dy * dy ); | ||||
|  | ||||
|     return result; | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| // Time measure returned are seconds | ||||
| static double rgGetCurrentTime(void) | ||||
| static double rgGetCurrentTime( void ) | ||||
| { | ||||
|     double time = 0; | ||||
| 	double time = 0; | ||||
|  | ||||
| #if !defined(RGESTURES_STANDALONE) | ||||
|     time = GetTime(); | ||||
| #if ! defined( RGESTURES_STANDALONE ) | ||||
| 	time = GetTime(); | ||||
| #else | ||||
| #if defined(_WIN32) | ||||
|     unsigned long long int clockFrequency, currentTime; | ||||
| #if defined( _WIN32 ) | ||||
| 	unsigned long long int clockFrequency, currentTime; | ||||
|  | ||||
|     QueryPerformanceFrequency(&clockFrequency);     // BE CAREFUL: Costly operation! | ||||
|     QueryPerformanceCounter(¤tTime); | ||||
| 	QueryPerformanceFrequency( &clockFrequency );    // BE CAREFUL: Costly operation! | ||||
| 	QueryPerformanceCounter( ¤tTime ); | ||||
|  | ||||
|     time = (double)currentTime/clockFrequency;  // Time in seconds | ||||
| 	time = ( double )currentTime / clockFrequency;    // Time in seconds | ||||
| #endif | ||||
|  | ||||
| #if defined(__linux__) | ||||
|     // NOTE: Only for Linux-based systems | ||||
|     struct timespec now; | ||||
|     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 | ||||
| #if defined( __linux__ ) | ||||
| 	// NOTE: Only for Linux-based systems | ||||
| 	struct timespec now; | ||||
| 	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*1e-9);     // Time in seconds | ||||
| 	time                           = ( ( double )nowTime * 1e-9 );    // Time in seconds | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|     //#define CLOCK_REALTIME  CALENDAR_CLOCK    // returns UTC time since 1970-01-01 | ||||
|     //#define CLOCK_MONOTONIC SYSTEM_CLOCK      // returns the time since boot time | ||||
| #if defined( __APPLE__ ) | ||||
| 	// #define CLOCK_REALTIME  CALENDAR_CLOCK    // returns UTC time since 1970-01-01 | ||||
| 	// #define CLOCK_MONOTONIC SYSTEM_CLOCK      // returns the time since boot time | ||||
|  | ||||
|     clock_serv_t cclock; | ||||
|     mach_timespec_t now; | ||||
|     host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); | ||||
| 	clock_serv_t    cclock; | ||||
| 	mach_timespec_t now; | ||||
| 	host_get_clock_service( mach_host_self(), SYSTEM_CLOCK, &cclock ); | ||||
|  | ||||
|     // NOTE: OS X does not have clock_gettime(), using clock_get_time() | ||||
|     clock_get_time(cclock, &now); | ||||
|     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 | ||||
| 	// NOTE: OS X does not have clock_gettime(), using clock_get_time() | ||||
| 	clock_get_time( cclock, &now ); | ||||
| 	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*1e-9);     // Time in seconds | ||||
| 	time                           = ( ( double )nowTime * 1e-9 );    // Time in seconds | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|     return time; | ||||
| 	return time; | ||||
| } | ||||
|  | ||||
| #endif // RGESTURES_IMPLEMENTATION | ||||
| #endif    // RGESTURES_IMPLEMENTATION | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,55 +1,55 @@ | ||||
| /********************************************************************************************** | ||||
| * | ||||
| *   raylib.utils - Some common utility functions | ||||
| * | ||||
| * | ||||
| *   LICENSE: zlib/libpng | ||||
| * | ||||
| *   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) | ||||
| * | ||||
| *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
| *   will the authors be held liable for any damages arising from the use of this software. | ||||
| * | ||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
| * | ||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
| *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
| *     in the product documentation would be appreciated but is not required. | ||||
| * | ||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
| *     as being the original software. | ||||
| * | ||||
| *     3. This notice may not be removed or altered from any source distribution. | ||||
| * | ||||
| **********************************************************************************************/ | ||||
|  * | ||||
|  *   raylib.utils - Some common utility functions | ||||
|  * | ||||
|  * | ||||
|  *   LICENSE: zlib/libpng | ||||
|  * | ||||
|  *   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) | ||||
|  * | ||||
|  *   This software is provided "as-is", without any express or implied warranty. In no event | ||||
|  *   will the authors be held liable for any damages arising from the use of this software. | ||||
|  * | ||||
|  *   Permission is granted to anyone to use this software for any purpose, including commercial | ||||
|  *   applications, and to alter it and redistribute it freely, subject to the following restrictions: | ||||
|  * | ||||
|  *     1. The origin of this software must not be misrepresented; you must not claim that you | ||||
|  *     wrote the original software. If you use this software in a product, an acknowledgment | ||||
|  *     in the product documentation would be appreciated but is not required. | ||||
|  * | ||||
|  *     2. Altered source versions must be plainly marked as such, and must not be misrepresented | ||||
|  *     as being the original software. | ||||
|  * | ||||
|  *     3. This notice may not be removed or altered from any source distribution. | ||||
|  * | ||||
|  **********************************************************************************************/ | ||||
|  | ||||
| #ifndef UTILS_H | ||||
| #define UTILS_H | ||||
|  | ||||
| #if defined(PLATFORM_ANDROID) | ||||
|     #include <stdio.h>                      // Required for: FILE | ||||
|     #include <android/asset_manager.h>      // Required for: AAssetManager | ||||
| #if defined( PLATFORM_ANDROID ) | ||||
| #include <stdio.h>                    // Required for: FILE | ||||
| #include <android/asset_manager.h>    // Required for: AAssetManager | ||||
| #endif | ||||
|  | ||||
| #if defined(SUPPORT_TRACELOG) | ||||
|     #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) | ||||
| #if defined( SUPPORT_TRACELOG ) | ||||
| #define TRACELOG( level, ... ) TraceLog( level, __VA_ARGS__ ) | ||||
|  | ||||
|     #if defined(SUPPORT_TRACELOG_DEBUG) | ||||
|         #define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__) | ||||
|     #else | ||||
|         #define TRACELOGD(...) (void)0 | ||||
|     #endif | ||||
| #if defined( SUPPORT_TRACELOG_DEBUG ) | ||||
| #define TRACELOGD( ... ) TraceLog( LOG_DEBUG, __VA_ARGS__ ) | ||||
| #else | ||||
|     #define TRACELOG(level, ...) (void)0 | ||||
|     #define TRACELOGD(...) (void)0 | ||||
| #define TRACELOGD( ... ) ( void )0 | ||||
| #endif | ||||
| #else | ||||
| #define TRACELOG( level, ... ) ( void )0 | ||||
| #define TRACELOGD( ... )       ( void )0 | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Some basic Defines | ||||
| //---------------------------------------------------------------------------------- | ||||
| #if defined(PLATFORM_ANDROID) | ||||
|     #define fopen(name, mode) android_fopen(name, mode) | ||||
| #if defined( PLATFORM_ANDROID ) | ||||
| #define fopen( name, mode ) android_fopen( name, mode ) | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| @@ -65,17 +65,18 @@ | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Module Functions Declaration | ||||
| //---------------------------------------------------------------------------------- | ||||
| #if defined(__cplusplus) | ||||
| extern "C" {            // Prevents name mangling of functions | ||||
| #if defined( __cplusplus ) | ||||
| extern "C" | ||||
| {    // Prevents name mangling of functions | ||||
| #endif | ||||
|  | ||||
| #if defined(PLATFORM_ANDROID) | ||||
| void InitAssetManager(AAssetManager *manager, const char *dataPath);   // Initialize asset manager from android app | ||||
| FILE *android_fopen(const char *fileName, const char *mode);           // Replacement for fopen() -> Read-only! | ||||
| #if defined( PLATFORM_ANDROID ) | ||||
| 	void  InitAssetManager( AAssetManager* manager, const char* dataPath );    // Initialize asset manager from android app | ||||
| 	FILE* android_fopen( const char* fileName, const char* mode );             // Replacement for fopen() -> Read-only! | ||||
| #endif | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| #if defined( __cplusplus ) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif // UTILS_H | ||||
| #endif    // UTILS_H | ||||
|   | ||||
| @@ -0,0 +1,9 @@ | ||||
|  __VERSION 1 | ||||
|  | ||||
|  | ||||
| word SUPPORT_MODULE_RSHAPES,   RL_SUPPORT_MODULE_RSHAPES | ||||
| word SUPPORT_MODULE_RTEXTURES, RL_SUPPORT_MODULE_RTEXTURES | ||||
| word SUPPORT_MODULE_RTEXT,     RL_SUPPORT_MODULE_RTEXT | ||||
| word SUPPORT_MODULE_RMODELS,   RL_SUPPORT_MODULE_RMODELS | ||||
| word SUPPORT_MODULE_RAUDIO,    RL_SUPPORT_MODULE_RAUDIO | ||||
|  | ||||
| @@ -17,41 +17,272 @@ constexpr char const* path_rtext     = "rtext.h"; | ||||
|  | ||||
| using namespace gen; | ||||
|  | ||||
|  | ||||
| void refactor_file( CodeBody code_file ) | ||||
| StringCached upper_snake_to_mixed_snake(StringCached str) | ||||
| { | ||||
|     local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1)); | ||||
|     scratch.clear(); | ||||
|  | ||||
|     bool capitalizeNext = true; | ||||
|  | ||||
|     for (s32 index = 0; index < str.length(); ++index) | ||||
|     { | ||||
|         char c = str[index]; | ||||
|  | ||||
|         if (c == '_') | ||||
|         { | ||||
|             scratch.append(c); | ||||
|             capitalizeNext = true; | ||||
|         } | ||||
|         else if (capitalizeNext) | ||||
|         { | ||||
|             if (c >= 'a' && c <= 'z') | ||||
|             { | ||||
|                 scratch.append(c - 32); // Convert to uppercase | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 scratch.append(c); | ||||
|             } | ||||
|             capitalizeNext = false; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (c >= 'A' && c <= 'Z') | ||||
|             { | ||||
|                 scratch.append(c + 32); // Convert to lowercase | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 scratch.append(c); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     StringCached result = get_cached_string(scratch); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| StringCached pascal_to_lower_snake(StringCached str) | ||||
| { | ||||
|     local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1)); | ||||
|     scratch.clear(); | ||||
|  | ||||
|     for (s32 index = 0; index < str.length(); ++index) | ||||
|     { | ||||
|         char c = str[index]; | ||||
|         char next = (index + 1 < str.length()) ? str[index + 1] : '\0'; // Ensure we don't go out of bounds | ||||
|  | ||||
|         // Whitelist check for "2D" and "3D" | ||||
|         if ((c == '2' || c == '3' | c == '4') && (next == 'D' || next == 'd')) | ||||
|         { | ||||
|             if (index > 0) // If it's not the start of the string, append an underscore | ||||
|             { | ||||
|                 char* prev = str.Data + index - 1; | ||||
|                 if (*prev != '_') // Avoid double underscores | ||||
|                 { | ||||
|                     scratch.append('_'); | ||||
|                 } | ||||
|             } | ||||
|             scratch.append(c); | ||||
|             scratch.append('d'); // Convert to lowercase | ||||
|             index++; // Skip the next character since we've already processed it | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         if (c >= 'A' && c <= 'Z') | ||||
|         { | ||||
|             char* prev = (index > 0) ? str.Data + index - 1 : nullptr; | ||||
|  | ||||
|             if ((index > 0 && prev && *prev >= 'a' && *prev <= 'z') ||  | ||||
|                 (prev && char_is_digit(*prev) && (next >= 'A' && next <= 'Z'))) | ||||
|             { | ||||
|                 scratch.append('_'); | ||||
|             } | ||||
|  | ||||
|             scratch.append(c + 32); | ||||
|         } | ||||
|         else if (char_is_digit(c) && (next >= 'A' && next <= 'Z')) // Check for a number followed by an uppercase letter | ||||
|         { | ||||
|             scratch.append(c); | ||||
|             scratch.append('_'); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             scratch.append(c); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     StringCached result = get_cached_string(scratch); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void refactor_enum( CodeEnum& code ) | ||||
| { | ||||
| 	for ( Code elem : code->Body ) | ||||
| 	{ | ||||
| 		if ( elem->Type == ECode::Untyped ) | ||||
| 		{ | ||||
| 			elem->Content = upper_snake_to_mixed_snake( elem->Content ); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void refactor_typename( CodeType& type ) | ||||
| { | ||||
| 	local_persist CodeType t_unsigned_char      = parse_type( code(unsigned char) ); | ||||
| 	local_persist CodeType t_unsigned_char_ptr  = parse_type( code(unsigned char*) ); | ||||
| 	local_persist CodeType t_unsigned_short_ptr	= parse_type( code(unsigned short*) ); | ||||
| 	local_persist CodeType t_int                = parse_type( code(int) ); | ||||
| 	local_persist CodeType t_int_ptr 		    = parse_type( code(int*) ); | ||||
| 	local_persist CodeType t_unsigned_int       = parse_type( code(unsigned int) ); | ||||
| 	local_persist CodeType t_float 	            = parse_type( code(float) ); | ||||
| 	local_persist CodeType t_float_ptr          = parse_type( code(float*) ); | ||||
|  | ||||
| 	local_persist CodeType t_f32_ptr = parse_type( code(f32*) ); | ||||
| 	local_persist CodeType t_u8_ptr  = parse_type( code(u8*) ); | ||||
| 	local_persist CodeType t_s32_ptr = parse_type( code(s32*) ); | ||||
|  | ||||
| 	String type_str = type.to_string(); | ||||
|  | ||||
| 	if ( str_compare( type_str, t_unsigned_char.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_u8.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_unsigned_char_ptr.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_u8_ptr.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_unsigned_short_ptr.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_u8_ptr.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_int.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_s32.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_int_ptr.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_s32_ptr.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_unsigned_int.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_u32.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_float.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_f32.ast; | ||||
| 	} | ||||
| 	if ( str_compare( type_str, t_float_ptr.to_string() ) == 0 ) | ||||
| 	{ | ||||
| 		type.ast = t_f32_ptr.ast; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void refactor_fn( CodeFn& fn ) | ||||
| { | ||||
| 	fn->Name = pascal_to_lower_snake( fn->Name ); | ||||
|  | ||||
| 	for ( CodeParam param : fn->Params ) | ||||
| 	{ | ||||
| 		refactor_typename( param->ValueType ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void refactor_struct( CodeStruct& code ) | ||||
| { | ||||
| 	for ( Code field : code->Body ) | ||||
| 	{ | ||||
| 		if ( field->Type == ECode::Variable ) | ||||
| 		{ | ||||
| 			CodeVar var = field.cast<CodeVar>(); | ||||
| 			refactor_typename( var->ValueType ); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void refactor_file( char const* path ) | ||||
| { | ||||
| 	FileContents contents = file_read_contents( GlobalAllocator, true, path ); | ||||
| 	CodeBody     code     = parse_global_body( { contents.size, rcast(char const*, contents.data) } ); | ||||
|  | ||||
| 	String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	for ( Code elem : code_file ) | ||||
|  | ||||
| 	// CodeBody includes | ||||
| 	// CodeBody nspace_body = def_body( ECode::Namespace ); | ||||
| 	CodeBody new_code = def_body( ECode::Global_Body ); | ||||
|  | ||||
| 	for ( Code elem : code ) | ||||
| 	{ | ||||
| 		if ( elem->Type == ECode::Preprocess_Define ) | ||||
| 		{ | ||||
| 			if ( str_compare( elem->Name, txt("RL_"), 2 ) == 0 ) | ||||
| 			if ( str_compare( elem->Name, txt("RL"), 2 ) == 0 || str_compare( elem->Name, txt("RAYLIB"), 6 ) == 0 ) | ||||
| 				continue; | ||||
|  | ||||
| 			name_scratch.append_fmt( "%RL_%S", elem->Name ); | ||||
| 			elem->Name = get_cached_string( name_scratch ); | ||||
| 			name_scratch.clear(); | ||||
| 		} | ||||
|  | ||||
| 		if ( elem->Type == ECode::Enum ) | ||||
| 		{ | ||||
| 			refactor_enum( elem.cast<CodeEnum>() ); | ||||
| 		} | ||||
|  | ||||
| 		if ( elem->Type == ECode::Typedef ) | ||||
| 		{ | ||||
| 			CodeTypedef td = elem.cast<CodeTypedef>(); | ||||
| 			if ( td->UnderlyingType->Type == ECode::Enum ) | ||||
| 			{ | ||||
| 				CodeEnum code = td->UnderlyingType.cast<CodeEnum>(); | ||||
| 				refactor_enum( code ); | ||||
| 			} | ||||
| 			if ( td->UnderlyingType->Type == ECode::Struct ) | ||||
| 			{ | ||||
| 				CodeStruct code = td->UnderlyingType.cast<CodeStruct>(); | ||||
| 				refactor_struct( code ); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ( elem->Type == ECode::Struct ) | ||||
| 		{ | ||||
| 			refactor_struct( elem.cast<CodeStruct>() ); | ||||
| 		} | ||||
|  | ||||
| 		if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd ) | ||||
| 		{ | ||||
| 			refactor_fn( elem.cast<CodeFn>() ); | ||||
| 		} | ||||
|  | ||||
| 		if ( elem->Type == ECode::Extern_Linkage ) | ||||
| 		{ | ||||
| 			CodeBody body = elem.cast<CodeExtern>()->Body; | ||||
| 			for ( Code elem : body ) | ||||
| 			{ | ||||
| 				if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd ) | ||||
| 				{ | ||||
| 					refactor_fn( elem.cast<CodeFn>() ); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			Code nspace = def_namespace( txt("raylib"), def_namespace_body( args(elem) ) ); | ||||
| 			elem = nspace; | ||||
| 		} | ||||
|  | ||||
| 		new_code.append( elem ); | ||||
| 	} | ||||
|  | ||||
| 	Builder builder = Builder::open( path ); | ||||
| 	builder.print( new_code ); | ||||
| 	builder.write(); | ||||
| } | ||||
|  | ||||
| int gen_main() | ||||
| { | ||||
| 	gen::init(); | ||||
|  | ||||
| 	FileContents config_file_content = file_read_contents( GlobalAllocator, true, path_config ); | ||||
| 	CodeBody     config_code         = parse_global_body( { config_file_content.size, rcast(char const*, config_file_content.data) } ); | ||||
| 	refactor_file( config_code ); | ||||
| 	Builder config_builder = Builder::open( path_config ); | ||||
| 	config_builder.print( config_code ); | ||||
| 	config_builder.write(); | ||||
|  | ||||
| 	FileContents raylib_file_content = file_read_contents( GlobalAllocator, true, path_raylib ); | ||||
| 	CodeBody     raylib_code         = parse_global_body( { raylib_file_content.size, rcast(char const*, raylib_file_content.data) } ); | ||||
| 	refactor_file( raylib_code ); | ||||
| 	Builder raylib_builder = Builder::open( path_raylib ); | ||||
| 	config_builder.print( raylib_code ); | ||||
| 	config_builder.write(); | ||||
| 	refactor_file( path_config ); | ||||
| 	refactor_file( path_raylib ); | ||||
| 	refactor_file( path_raymath ); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -85,8 +85,12 @@ function setup-raylib { | ||||
| 		New-Item $path_build -ItemType Directory | ||||
| 	} | ||||
|  | ||||
| 	$raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File | ||||
| 	$raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file | ||||
|  | ||||
| 	# Refactor raylib | ||||
| 	if ( $true ) { | ||||
| 	# if ( $false ) { | ||||
| 		$path_gencpp = join-path $path_root 'project/gen' | ||||
|  | ||||
| 		$includes = @( | ||||
| @@ -114,6 +118,18 @@ function setup-raylib { | ||||
| 					} | ||||
| 			} | ||||
| 		Pop-Location | ||||
|  | ||||
| 		push-location $path_scripts | ||||
| 		# Time to format | ||||
| 		$fmt_includes = @() | ||||
| 		foreach ( $header in $raylib_headers ) { | ||||
| 			$fmt_includes +=  split-path $header -leaf | ||||
| 		} | ||||
| 		foreach ( $module in $raylib_modules ) { | ||||
| 			$fmt_includes +=  split-path $module -leaf | ||||
| 		} | ||||
| 		format-cpp $path_raylib_src $fmt_includes $null | ||||
| 		pop-location | ||||
| 	} | ||||
|  | ||||
| 	# Build raylib | ||||
| @@ -151,12 +167,10 @@ function setup-raylib { | ||||
| 		$dll  = join-path $path_raylib_lib 'raylib.dll' | ||||
| 		# $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll | ||||
|  | ||||
| 		$raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file | ||||
| 		$build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll | ||||
| 	} | ||||
|  | ||||
| 	# Move headers to used include | ||||
| 	$raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File | ||||
| 	foreach ($header in $raylib_headers) { | ||||
| 		Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf)) | ||||
| 	} | ||||
|   | ||||
| @@ -475,7 +475,8 @@ struct CodeParam | ||||
| 	} | ||||
| 	CodeParam end() | ||||
| 	{ | ||||
| 		return { (AST_Param*) rcast( AST*, ast)->Last }; | ||||
| 		// return { (AST_Param*) rcast( AST*, ast)->Last }; | ||||
| 		return { nullptr } | ||||
| 	} | ||||
| 	CodeParam& operator++(); | ||||
| 	CodeParam operator*() | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| #pragma region Constants | ||||
|  | ||||
| #ifndef GEN_GLOBAL_BUCKET_SIZE | ||||
| #	define GEN_GLOBAL_BUCKET_SIZE megabytes(4) | ||||
| #	define GEN_GLOBAL_BUCKET_SIZE megabytes(8) | ||||
| #endif | ||||
| #ifndef GEN_CODEPOOL_NUM_BLOCKS | ||||
| #	define GEN_CODEPOOL_NUM_BLOCKS kilobytes(16) | ||||
| @@ -31,7 +31,7 @@ | ||||
| #	define GEN_LEX_ALLOCATOR_SIZE megabytes(4) | ||||
| #endif | ||||
| #ifndef GEN_BUILDER_STR_BUFFER_RESERVE | ||||
| #	define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(1) | ||||
| #	define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(2) | ||||
| #endif | ||||
|  | ||||
| // These constexprs are used for allocation behavior of data structures | ||||
|   | ||||
| @@ -1294,7 +1294,7 @@ internal Code               parse_compilcated_definition       (); | ||||
| internal CodeBody           parse_class_struct_body            ( Parser::TokType which, Parser::Token name = Parser::NullToken ); | ||||
| internal Code               parse_class_struct                 ( Parser::TokType which, bool inplace_def ); | ||||
| internal CodeDefine         parse_define                       (); | ||||
| internal Code               parse_foward_or_definition         ( Parser::TokType which, bool is_inplace ); | ||||
| internal Code               parse_forward_or_definition         ( Parser::TokType which, bool is_inplace ); | ||||
| internal CodeFn             parse_function_after_name          ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType ret_type, Parser::Token name ); | ||||
| internal Code               parse_function_body                (); | ||||
| internal Code               parse_global_nspace                (); | ||||
| @@ -1317,7 +1317,7 @@ internal CodeDestructor  parse_destructor      ( CodeSpecifiers specifiers = NoC | ||||
| internal CodeEnum        parse_enum            ( bool inplace_def = false ); | ||||
| internal CodeBody        parse_export_body     (); | ||||
| internal CodeBody        parse_extern_link_body(); | ||||
| internal CodeExtern      parse_exten_link      (); | ||||
| internal CodeExtern      parse_extern_link     (); | ||||
| internal CodeFriend      parse_friend          (); | ||||
| internal CodeFn          parse_function        (); | ||||
| internal CodeNS          parse_namespace       (); | ||||
| @@ -1784,7 +1784,7 @@ Code parse_complicated_definition( Parser::TokType which ) | ||||
| 	if ( (idx - 2 ) == tokens.Idx ) | ||||
| 	{ | ||||
| 		// Its a forward declaration only | ||||
| 		Code result = parse_foward_or_definition( which, is_inplace ); | ||||
| 		Code result = parse_forward_or_definition( which, is_inplace ); | ||||
| 		Context.pop(); | ||||
| 		return result; | ||||
| 	} | ||||
| @@ -1834,7 +1834,7 @@ Code parse_complicated_definition( Parser::TokType which ) | ||||
| 	{ | ||||
| 		// Its a definition | ||||
| 		// <which> { ... }; | ||||
| 		Code result = parse_foward_or_definition( which, is_inplace ); | ||||
| 		Code result = parse_forward_or_definition( which, is_inplace ); | ||||
| 		Context.pop(); | ||||
| 		return result; | ||||
| 	} | ||||
| @@ -2267,7 +2267,7 @@ CodeDefine parse_define() | ||||
| } | ||||
|  | ||||
| internal inline | ||||
| Code parse_foward_or_definition( Parser::TokType which, bool is_inplace ) | ||||
| Code parse_forward_or_definition( Parser::TokType which, bool is_inplace ) | ||||
| { | ||||
| 	using namespace Parser; | ||||
|  | ||||
| @@ -2499,7 +2499,7 @@ CodeBody parse_global_nspace( CodeT which ) | ||||
| 				if ( which == Extern_Linkage_Body ) | ||||
| 					log_failure( "Nested extern linkage\n%s", Context.to_string() ); | ||||
|  | ||||
| 				member = parse_extern_link_body(); | ||||
| 				member = parse_extern_link(); | ||||
| 			break; | ||||
|  | ||||
| 			case TokType::Decl_Namespace: | ||||
| @@ -3693,7 +3693,10 @@ CodeVar parse_variable_after_name( | ||||
| 		result->InlineCmt = inline_cmt; | ||||
|  | ||||
| 	if ( next_var ) | ||||
| 		result->NextVar = next_var; | ||||
| 	{ | ||||
| 		result->NextVar         = next_var; | ||||
| 		result->NextVar->Parent = result; | ||||
| 	} | ||||
|  | ||||
| 	Context.pop(); | ||||
| 	return result; | ||||
| @@ -3758,15 +3761,18 @@ internal CodeVar parse_variable_declaration_list() | ||||
| 		eat( TokType::Identifier ); | ||||
|  | ||||
| 		CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name ); | ||||
|  | ||||
| 		// TODO(Ed) : CodeVar is going to need a procedure to append comma-defined vars to itself. | ||||
| 		if ( ! result ) | ||||
| 		{ | ||||
| 			result   = var; | ||||
| 			last_var = var; | ||||
| 			result.ast   = var.ast; | ||||
| 			last_var.ast = var.ast; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			last_var->NextVar = var; | ||||
| 			last_var 		  = var; | ||||
| 			last_var->NextVar.ast         = var.ast; | ||||
| 			last_var->NextVar->Parent.ast = rcast(AST*, var.ast); | ||||
| 			last_var.ast                  = var.ast; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -5319,7 +5325,7 @@ CodeTypedef parse_typedef() | ||||
| 			if ( (idx - 2 ) == tokens.Idx ) | ||||
| 			{ | ||||
| 				// Its a forward declaration only | ||||
| 				type = parse_foward_or_definition( currtok.Type, from_typedef ); | ||||
| 				type = parse_forward_or_definition( currtok.Type, from_typedef ); | ||||
| 			} | ||||
|  | ||||
| 			Token tok = tokens[ idx - 1 ]; | ||||
| @@ -5360,13 +5366,13 @@ CodeTypedef parse_typedef() | ||||
|  | ||||
| 				// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type. | ||||
| 				// type = parse_type(); | ||||
| 				type = parse_foward_or_definition( currtok.Type, from_typedef ); | ||||
| 				type = parse_forward_or_definition( currtok.Type, from_typedef ); | ||||
| 			} | ||||
| 			else if ( tok.Type == TokType::BraceCurly_Close ) | ||||
| 			{ | ||||
| 				// Its a definition | ||||
| 				// <which> { ... }; | ||||
| 				type = parse_foward_or_definition( currtok.Type, from_typedef ); | ||||
| 				type = parse_forward_or_definition( currtok.Type, from_typedef ); | ||||
| 			} | ||||
| 			else if ( tok.Type == TokType::BraceSquare_Close) | ||||
| 			{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user