Remove uneeded include copies

This commit is contained in:
Tobias Berger 2021-11-22 09:36:33 +01:00
parent fc1806e1b2
commit 19608b3283
13 changed files with 2 additions and 17126 deletions

2
.vscode/tasks.json vendored
View file

@ -14,6 +14,7 @@
{ "value": "-v", "quoting": "strong" },
{ "value": "-b", "quoting": "strong" },
{ "value": "-Iinclude", "quoting": "strong" },
{ "value": "-Iraylib/src", "quoting": "strong" },
{ "value": "-Llib", "quoting": "strong" },
{ "value": "-stdc99", "quoting": "strong" },
{ "value": "-Wall", "quoting": "strong" },
@ -42,6 +43,7 @@
{ "value": "-bench", "quoting": "strong" },
{ "value": "-v", "quoting": "strong" },
{ "value": "-Iinclude", "quoting": "strong" },
{ "value": "-Iraylib/src", "quoting": "strong" },
{ "value": "-Llib", "quoting": "strong" },
{ "value": "-stdc99", "quoting": "strong" },
{ "value": "-Wall", "quoting": "strong" },

View file

@ -1,230 +0,0 @@
/**********************************************************************************************
*
* raylib configuration flags
*
* This file defines all the configuration flags for the different raylib modules
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2018-2021 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.
*
**********************************************************************************************/
//------------------------------------------------------------------------------------
// Module: core - Configuration Flags
//------------------------------------------------------------------------------------
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
#define SUPPORT_CAMERA_SYSTEM 1
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
#define SUPPORT_GESTURES_SYSTEM 1
// Mouse gestures are directly mapped like touches and processed by gestures system
#define SUPPORT_MOUSE_GESTURES 1
// Reconfigure standard input to receive key inputs, works with SSH connection.
#define SUPPORT_SSH_KEYBOARD_RPI 1
// Draw a mouse pointer on screen
//#define SUPPORT_MOUSE_CURSOR_POINT 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 SUPPORT_WINMM_HIGHRES_TIMER 1
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
//#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 SUPPORT_PARTIALBUSY_WAIT_LOOP
// Wait for events passively (sleeping while no events) instead of polling them actively every frame
//#define SUPPORT_EVENTS_WAITING 1
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
#define SUPPORT_SCREEN_CAPTURE 1
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
#define SUPPORT_GIF_RECORDING 1
// Support CompressData() and DecompressData() functions
#define SUPPORT_COMPRESSION_API 1
// Support saving binary data automatically to a generated storage.data file. This file is managed internally.
#define SUPPORT_DATA_STORAGE 1
// Support automatic generated events, loading and recording of those events when required
#define SUPPORT_EVENTS_AUTOMATION 1
// Support custom frame control, only for advance users
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents()
// Enabling this flag allows manual control of the frame processes, use at your own risk
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1
// core: Configuration values
//------------------------------------------------------------------------------------
#if defined(__linux__)
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
#else
#define MAX_FILEPATH_LENGTH 512 // Maximum length supported for filepaths
#endif
#define MAX_GAMEPADS 4 // Max number of gamepads supported
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
#define MAX_KEY_PRESSED_QUEUE 16 // Max number of characters in the key input queue
#define STORAGE_DATA_FILE "storage.data" // Automatic storage filename
#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB
//------------------------------------------------------------------------------------
// Module: rlgl - Configuration values
//------------------------------------------------------------------------------------
// Enable OpenGL Debug Context (only available on OpenGL 4.3)
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
// Show OpenGL extensions and capabilities detailed logs on init
//#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_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" // Binded by default to shader location: 0
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Binded by default to shader location: 1
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Binded by default to shader location: 2
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Binded by default to shader location: 3
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Binded by default to shader location: 4
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Binded 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)
//------------------------------------------------------------------------------------
// Module: shapes - Configuration Flags
//------------------------------------------------------------------------------------
// Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines
#define SUPPORT_QUADS_DRAW_MODE 1
//------------------------------------------------------------------------------------
// Module: textures - Configuration Flags
//------------------------------------------------------------------------------------
// Selecte desired fileformats to be supported for image data loading
#define SUPPORT_FILEFORMAT_PNG 1
//#define SUPPORT_FILEFORMAT_BMP 1
//#define SUPPORT_FILEFORMAT_TGA 1
#define SUPPORT_FILEFORMAT_JPG 1
#define SUPPORT_FILEFORMAT_GIF 1
//#define SUPPORT_FILEFORMAT_PSD 1
//#define SUPPORT_FILEFORMAT_DDS 1
//#define SUPPORT_FILEFORMAT_HDR 1
//#define SUPPORT_FILEFORMAT_KTX 1
//#define SUPPORT_FILEFORMAT_ASTC 1
//#define SUPPORT_FILEFORMAT_PKM 1
//#define SUPPORT_FILEFORMAT_PVR 1
// Support image export functionality (.png, .bmp, .tga, .jpg)
#define SUPPORT_IMAGE_EXPORT 1
// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)
#define 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 SUPPORT_IMAGE_MANIPULATION 1
//------------------------------------------------------------------------------------
// Module: text - Configuration Flags
//------------------------------------------------------------------------------------
// 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 SUPPORT_DEFAULT_FONT 1
// Selected desired font fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_FNT 1
#define SUPPORT_FILEFORMAT_TTF 1
// Support text management functions
// If not defined, still some functions are supported: TextLength(), TextFormat()
#define SUPPORT_TEXT_MANIPULATION 1
// text: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit()
//------------------------------------------------------------------------------------
// Module: models - Configuration Flags
//------------------------------------------------------------------------------------
// Selected desired model fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_OBJ 1
#define SUPPORT_FILEFORMAT_MTL 1
#define SUPPORT_FILEFORMAT_IQM 1
#define SUPPORT_FILEFORMAT_GLTF 1
#define SUPPORT_FILEFORMAT_VOX 1
// Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1
// models: Configuration values
//------------------------------------------------------------------------------------
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
//------------------------------------------------------------------------------------
// Module: audio - Configuration Flags
//------------------------------------------------------------------------------------
// Desired audio fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_WAV 1
#define SUPPORT_FILEFORMAT_OGG 1
#define SUPPORT_FILEFORMAT_XM 1
#define SUPPORT_FILEFORMAT_MOD 1
#define SUPPORT_FILEFORMAT_MP3 1
//#define SUPPORT_FILEFORMAT_FLAC 1
// audio: Configuration values
//------------------------------------------------------------------------------------
#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default)
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels
//------------------------------------------------------------------------------------
// Module: utils - Configuration Flags
//------------------------------------------------------------------------------------
// Standard file io library (stdio.h) included
#define SUPPORT_STANDARD_FILEIO
// Show TRACELOG() output messages
// NOTE: By default LOG_DEBUG traces not shown
#define SUPPORT_TRACELOG 1
//#define SUPPORT_TRACELOG_DEBUG 1
// utils: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message

View file

@ -1,263 +0,0 @@
/*******************************************************************************************
*
* raylib easings (header only file)
*
* Useful easing functions for values animation
*
* This header uses:
* #define EASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster.
* // This requires lots of memory on system.
* How to use:
* The four inputs t,b,c,d are defined as follows:
* t = current time (in any unit measure, but same unit as duration)
* b = starting value to interpolate
* c = the total change in value of b that needs to occur
* d = total time it should take to complete (duration)
*
* Example:
*
* int currentTime = 0;
* int duration = 100;
* float startPositionX = 0.0f;
* float finalPositionX = 30.0f;
* float currentPositionX = startPositionX;
*
* while (currentPositionX < finalPositionX)
* {
* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration);
* currentTime++;
* }
*
* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
*
* Robert Penner License
* ---------------------------------------------------------------------------------
* Open source under the BSD License.
*
* Copyright (c) 2001 Robert Penner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the author nor the names of contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ---------------------------------------------------------------------------------
*
* Copyright (c) 2015 Ramon Santamaria
*
* 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 EASINGS_H
#define EASINGS_H
#define EASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline
#if defined(EASINGS_STATIC_INLINE)
#define EASEDEF static inline
#else
#define EASEDEF extern
#endif
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), powf()
#ifndef PI
#define PI 3.14159265358979323846f //Required as PI is not always defined in math.h
#endif
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
// Linear Easing functions
EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearInOut(float t,float b, float c, float d) { return (c*t/d + b); }
// Sine Easing functions
EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cosf(t/d*(PI/2.0f)) + c + b); }
EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); }
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + b); }
// Circular Easing functions
EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrtf(1.0f - t*t) - 1.0f) + b); }
EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); }
EASEDEF float EaseCircInOut(float t, float b, float c, float d)
{
if ((t/=d/2.0f) < 1.0f) return (-c/2.0f*(sqrtf(1.0f - t*t) - 1.0f) + b);
t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b);
}
// Cubic Easing functions
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); }
EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*(t*t*t + 1.0f) + b); }
EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
{
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*t*t*t + b);
t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b);
}
// Quadratic Easing functions
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); }
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); }
EASEDEF float EaseQuadInOut(float t, float b, float c, float d)
{
if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b);
}
// Exponential Easing functions
EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0.0f) ? b : (c*powf(2.0f, 10.0f*(t/d - 1.0f)) + b); }
EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-powf(2.0f, -10.0f*t/d) + 1.0f) + b); }
EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
{
if (t == 0.0f) return b;
if (t == d) return (b + c);
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*powf(2.0f, 10.0f*(t - 1.0f)) + b);
return (c/2.0f*(-powf(2.0f, -10.0f*(t - 1.0f)) + 2.0f) + b);
}
// Back Easing functions
EASEDEF float EaseBackIn(float t, float b, float c, float d)
{
float s = 1.70158f;
float postFix = t/=d;
return (c*(postFix)*t*((s + 1.0f)*t - s) + b);
}
EASEDEF float EaseBackOut(float t, float b, float c, float d)
{
float s = 1.70158f;
t = t/d - 1.0f;
return (c*(t*t*((s + 1.0f)*t + s) + 1.0f) + b);
}
EASEDEF float EaseBackInOut(float t, float b, float c, float d)
{
float s = 1.70158f;
if ((t/=d/2.0f) < 1.0f)
{
s *= 1.525f;
return (c/2.0f*(t*t*((s + 1.0f)*t - s)) + b);
}
float postFix = t-=2.0f;
s *= 1.525f;
return (c/2.0f*((postFix)*t*((s + 1.0f)*t + s) + 2.0f) + b);
}
// Bounce Easing functions
EASEDEF float EaseBounceOut(float t, float b, float c, float d)
{
if ((t/=d) < (1.0f/2.75f))
{
return (c*(7.5625f*t*t) + b);
}
else if (t < (2.0f/2.75f))
{
float postFix = t-=(1.5f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.75f) + b);
}
else if (t < (2.5/2.75))
{
float postFix = t-=(2.25f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.9375f) + b);
}
else
{
float postFix = t-=(2.625f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.984375f) + b);
}
}
EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d - t, 0.0f, c, d) + b); }
EASEDEF float EaseBounceInOut(float t, float b, float c, float d)
{
if (t < d/2.0f) return (EaseBounceIn(t*2.0f, 0.0f, c, d)*0.5f + b);
else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b);
}
// Elastic Easing functions
EASEDEF float EaseElasticIn(float t, float b, float c, float d)
{
if (t == 0.0f) return b;
if ((t/=d) == 1.0f) return (b + c);
float p = d*0.3f;
float a = c;
float s = p/4.0f;
float postFix = a*powf(2.0f, 10.0f*(t-=1.0f));
return (-(postFix*sinf((t*d-s)*(2.0f*PI)/p )) + b);
}
EASEDEF float EaseElasticOut(float t, float b, float c, float d)
{
if (t == 0.0f) return b;
if ((t/=d) == 1.0f) return (b + c);
float p = d*0.3f;
float a = c;
float s = p/4.0f;
return (a*powf(2.0f,-10.0f*t)*sinf((t*d-s)*(2.0f*PI)/p) + c + b);
}
EASEDEF float EaseElasticInOut(float t, float b, float c, float d)
{
if (t == 0.0f) return b;
if ((t/=d/2.0f) == 2.0f) return (b + c);
float p = d*(0.3f*1.5f);
float a = c;
float s = p/4.0f;
if (t < 1.0f)
{
float postFix = a*powf(2.0f, 10.0f*(t-=1.0f));
return -0.5f*(postFix*sinf((t*d-s)*(2.0f*PI)/p)) + b;
}
float postFix = a*powf(2.0f, -10.0f*(t-=1.0f));
return (postFix*sinf((t*d-s)*(2.0f*PI)/p)*0.5f + c + b);
}
#ifdef __cplusplus
}
#endif
#endif // EASINGS_H

File diff suppressed because it is too large Load diff

View file

@ -1,198 +0,0 @@
/**********************************************************************************************
*
* raudio v1.0 - A simple and easy-to-use audio library based on miniaudio
*
* FEATURES:
* - Manage audio device (init/close)
* - Load and unload audio files
* - Format wave data (sample rate, size, channels)
* - Play/Stop/Pause/Resume loaded audio
* - Manage mixing channels
* - Manage raw audio context
*
* DEPENDENCIES:
* miniaudio.h - Audio device management lib (https://github.com/dr-soft/miniaudio)
* stb_vorbis.h - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
* dr_mp3.h - MP3 audio file loading (https://github.com/mackron/dr_libs)
* dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)
* jar_xm.h - XM module file loading
* jar_mod.h - MOD audio file loading
*
* CONTRIBUTORS:
* David Reid (github: @mackron) (Nov. 2017):
* - Complete port to miniaudio library
*
* Joshua Reisenauer (github: @kd7tck) (2015)
* - XM audio module support (jar_xm)
* - MOD audio module support (jar_mod)
* - Mixing channels support
* - Raw audio context support
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2021 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 RAUDIO_H
#define RAUDIO_H
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
// Allow custom memory allocators
#ifndef RL_MALLOC
#define RL_MALLOC(sz) malloc(sz)
#endif
#ifndef RL_CALLOC
#define RL_CALLOC(n,sz) calloc(n,sz)
#endif
#ifndef RL_FREE
#define RL_FREE(p) free(p)
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
#if !defined(_STDBOOL_H)
typedef enum { false, true } bool;
#define _STDBOOL_H
#endif
#endif
// Wave, audio wave data
typedef struct Wave {
unsigned int frameCount; // Total number of frames (considering channels)
unsigned int sampleRate; // Frequency (samples per second)
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo, ...)
void *data; // Buffer data pointer
} Wave;
typedef struct rAudioBuffer rAudioBuffer;
// AudioStream, custom audio stream
typedef struct AudioStream {
rAudioBuffer *buffer; // Pointer to internal data used by the audio system
unsigned int sampleRate; // Frequency (samples per second)
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo, ...)
} AudioStream;
// Sound
typedef struct Sound {
AudioStream stream; // Audio stream
unsigned int frameCount; // Total number of frames (considering channels)
} Sound;
// Music, audio stream, anything longer than ~10 seconds should be streamed
typedef struct Music {
AudioStream stream; // Audio stream
unsigned int frameCount; // Total number of frames (considering channels)
bool looping; // Music looping enable
int ctxType; // Type of music context (audio filetype)
void *ctxData; // Audio context data, depends on type
} Music;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
// Audio device management functions
void InitAudioDevice(void); // Initialize audio device and context
void CloseAudioDevice(void); // Close the audio device and context
bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
void SetMasterVolume(float volume); // Set master volume (listener)
// Wave/Sound loading/unloading functions
Wave LoadWave(const char *fileName); // Load wave data from file
Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. ".wav"
Sound LoadSound(const char *fileName); // Load sound from file
Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
void UnloadWave(Wave wave); // Unload wave data
void UnloadSound(Sound sound); // Unload sound
bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success
bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success
// Wave/Sound management functions
void PlaySound(Sound sound); // Play a sound
void StopSound(Sound sound); // Stop playing a sound
void PauseSound(Sound sound); // Pause a sound
void ResumeSound(Sound sound); // Resume a paused sound
void PlaySoundMulti(Sound sound); // Play a sound (using multichannel buffer pool)
void StopSoundMulti(void); // Stop any sound playing (using multichannel buffer pool)
int GetSoundsPlaying(void); // Get number of sounds playing in the multichannel
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format
Wave WaveCopy(Wave wave); // Copy a wave to a new wave
void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
float *LoadWaveSamples(Wave wave); // Load samples data from wave as a floats array
void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples()
// Music management functions
Music LoadMusicStream(const char *fileName); // Load music stream from file
Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int dataSize); // Load music stream from data
void UnloadMusicStream(Music music); // Unload music stream
void PlayMusicStream(Music music); // Start music playing
bool IsMusicStreamPlaying(Music music); // Check if music is playing
void UpdateMusicStream(Music music); // Updates buffers for music streaming
void StopMusicStream(Music music); // Stop music playing
void PauseMusicStream(Music music); // Pause music playing
void ResumeMusicStream(Music music); // Resume playing paused music
void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds)
void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
float GetMusicTimeLength(Music music); // Get music time length (in seconds)
float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
// AudioStream management functions
AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
void PlayAudioStream(AudioStream stream); // Play audio stream
void PauseAudioStream(AudioStream stream); // Pause audio stream
void ResumeAudioStream(AudioStream stream); // Resume audio stream
bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing
void StopAudioStream(AudioStream stream); // Stop audio stream
void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level)
void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
#ifdef __cplusplus
}
#endif
#endif // RAUDIO_H

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,567 +0,0 @@
/*******************************************************************************************
*
* rcamera - Basic camera system for multiple camera modes
*
* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables)
*
* CONFIGURATION:
*
* #define CAMERA_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
* #define CAMERA_STANDALONE
* 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
* Marc Palau: Initial implementation (2014)
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2015-2021 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
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Types and Structures Definition
// NOTE: Below types are required for CAMERA_STANDALONE usage
//----------------------------------------------------------------------------------
#if defined(CAMERA_STANDALONE)
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// 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 type; // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
} Camera3D;
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera system modes
typedef enum {
CAMERA_CUSTOM = 0,
CAMERA_FREE,
CAMERA_ORBITAL,
CAMERA_FIRST_PERSON,
CAMERA_THIRD_PERSON
} CameraMode;
// Camera projection modes
typedef enum {
CAMERA_PERSPECTIVE = 0,
CAMERA_ORTHOGRAPHIC
} CameraProjection;
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
#if defined(CAMERA_STANDALONE)
void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available)
void UpdateCamera(Camera *camera); // Update camera position for selected mode
void SetCameraPanControl(int keyPan); // Set camera pan key to combine with mouse movement (free camera)
void SetCameraAltControl(int keyAlt); // Set camera alt key to combine with mouse movement (free camera)
void SetCameraSmoothZoomControl(int szoomKey); // Set camera smooth zoom key to combine with mouse (free camera)
void SetCameraMoveControls(int keyFront, int keyBack,
int keyRight, int keyLeft,
int keyUp, int keyDown); // Set camera move controls (1st person and 3rd person cameras)
#endif
#ifdef __cplusplus
}
#endif
#endif // CAMERA_H
/***********************************************************************************
*
* CAMERA IMPLEMENTATION
*
************************************************************************************/
#if defined(CAMERA_IMPLEMENTATION)
#include <math.h> // Required for: sinf(), cosf(), sqrtf()
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef PI
#define PI 3.14159265358979323846
#endif
#ifndef DEG2RAD
#define DEG2RAD (PI/180.0f)
#endif
#ifndef RAD2DEG
#define RAD2DEG (180.0f/PI)
#endif
// Camera mouse movement sensitivity
#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f
// FREE_CAMERA
#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f
#define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f
#define CAMERA_FREE_DISTANCE_MAX_CLAMP 120.0f
#define CAMERA_FREE_MIN_CLAMP 85.0f
#define CAMERA_FREE_MAX_CLAMP -85.0f
#define CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY 0.05f
#define CAMERA_FREE_PANNING_DIVIDER 5.1f
// ORBITAL_CAMERA
#define CAMERA_ORBITAL_SPEED 0.01f // Radians per frame
// FIRST_PERSON
//#define CAMERA_FIRST_PERSON_MOUSE_SENSITIVITY 0.003f
#define CAMERA_FIRST_PERSON_FOCUS_DISTANCE 25.0f
#define CAMERA_FIRST_PERSON_MIN_CLAMP 89.0f
#define CAMERA_FIRST_PERSON_MAX_CLAMP -89.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
// THIRD_PERSON
//#define CAMERA_THIRD_PERSON_MOUSE_SENSITIVITY 0.003f
#define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f
#define CAMERA_THIRD_PERSON_MIN_CLAMP 5.0f
#define CAMERA_THIRD_PERSON_MAX_CLAMP -85.0f
#define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f }
// PLAYER (used by camera)
#define PLAYER_MOVEMENT_SENSITIVITY 20.0f
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Camera move modes (first person and third person cameras)
typedef enum {
MOVE_FRONT = 0,
MOVE_BACK,
MOVE_RIGHT,
MOVE_LEFT,
MOVE_UP,
MOVE_DOWN
} CameraMove;
// Camera global state context data [56 bytes]
typedef struct {
unsigned int mode; // Current camera mode
float targetDistance; // Camera distance from position to target
float playerEyesPosition; // Player eyes position from ground (in meters)
Vector2 angle; // Camera angle in plane XZ
Vector2 previousMousePosition; // Previous mouse position
// Camera movement control keys
int moveControl[6]; // Move controls (CAMERA_FIRST_PERSON)
int smoothZoomControl; // Smooth zoom control key
int altControl; // Alternative control key
int panControl; // Pan view control key
} CameraData;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static CameraData CAMERA = { // Global CAMERA state context
.mode = 0,
.targetDistance = 0,
.playerEyesPosition = 1.85f,
.angle = { 0 },
.previousMousePosition = { 0 },
.moveControl = { 'W', 'S', 'D', 'A', 'E', 'Q' },
.smoothZoomControl = 341, // raylib: KEY_LEFT_CONTROL
.altControl = 342, // raylib: KEY_LEFT_ALT
.panControl = 2 // raylib: MOUSE_BUTTON_MIDDLE
};
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
#if defined(CAMERA_STANDALONE)
// NOTE: Camera controls depend on some raylib input functions
static void EnableCursor() {} // Unlock cursor
static void DisableCursor() {} // Lock cursor
static int IsKeyDown(int key) { return 0; }
static int IsMouseButtonDown(int button) { return 0;}
static float GetMouseWheelMove() { return 0.0f; }
static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
#endif
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Select camera mode (multiple camera modes available)
void SetCameraMode(Camera camera, int mode)
{
Vector3 v1 = camera.position;
Vector3 v2 = camera.target;
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
float dz = v2.z - v1.z;
CAMERA.targetDistance = sqrtf(dx*dx + dy*dy + dz*dz); // Distance to target
// Camera angle calculation
CAMERA.angle.x = atan2f(dx, dz); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
CAMERA.angle.y = atan2f(dy, sqrtf(dx*dx + dz*dz)); // Camera angle in plane XY (0 aligned with X, move positive CW)
CAMERA.playerEyesPosition = camera.position.y; // Init player eyes position to camera Y position
CAMERA.previousMousePosition = GetMousePosition(); // Init mouse position
// Lock cursor for first person and third person cameras
if ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)) DisableCursor();
else EnableCursor();
CAMERA.mode = mode;
}
// Update camera depending on selected mode
// NOTE: Camera controls depend on some raylib functions:
// System: EnableCursor(), DisableCursor()
// Mouse: IsMouseButtonDown(), GetMousePosition(), GetMouseWheelMove()
// Keys: IsKeyDown()
void UpdateCamera(Camera *camera)
{
static int swingCounter = 0; // Used for 1st person swinging movement
// TODO: Compute CAMERA.targetDistance and CAMERA.angle here (?)
// Mouse movement detection
Vector2 mousePositionDelta = { 0.0f, 0.0f };
Vector2 mousePosition = GetMousePosition();
float mouseWheelMove = GetMouseWheelMove();
// Keys input detection
// TODO: Input detection is raylib-dependant, it could be moved outside the module
bool keyPan = IsMouseButtonDown(CAMERA.panControl);
bool keyAlt = IsKeyDown(CAMERA.altControl);
bool szoomKey = IsKeyDown(CAMERA.smoothZoomControl);
bool direction[6] = { IsKeyDown(CAMERA.moveControl[MOVE_FRONT]),
IsKeyDown(CAMERA.moveControl[MOVE_BACK]),
IsKeyDown(CAMERA.moveControl[MOVE_RIGHT]),
IsKeyDown(CAMERA.moveControl[MOVE_LEFT]),
IsKeyDown(CAMERA.moveControl[MOVE_UP]),
IsKeyDown(CAMERA.moveControl[MOVE_DOWN]) };
if (CAMERA.mode != CAMERA_CUSTOM)
{
mousePositionDelta.x = mousePosition.x - CAMERA.previousMousePosition.x;
mousePositionDelta.y = mousePosition.y - CAMERA.previousMousePosition.y;
CAMERA.previousMousePosition = mousePosition;
}
// Support for multiple automatic camera modes
// NOTE: In case of CAMERA_CUSTOM nothing happens here, user must update it manually
switch (CAMERA.mode)
{
case CAMERA_FREE: // Camera free controls, using standard 3d-content-creation scheme
{
// Camera zoom
if ((CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
}
// Camera looking down
else if ((camera->position.y > camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
}
else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
// if (camera->target.y < 0) camera->target.y = -0.001;
}
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
{
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
}
// Camera looking up
else if ((camera->position.y < camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
}
else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
// if (camera->target.y > 0) camera->target.y = 0.001;
}
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
{
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
}
// Input keys checks
if (keyPan)
{
if (keyAlt) // Alternative key behaviour
{
if (szoomKey)
{
// Camera smooth zoom
CAMERA.targetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
}
else
{
// Camera rotation
CAMERA.angle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY;
CAMERA.angle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY;
// Angle clamp
if (CAMERA.angle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD;
else if (CAMERA.angle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD;
}
}
else
{
// Camera panning
camera->target.x += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.z += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(CAMERA.angle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
}
}
// Update camera position with changes
camera->position.x = -sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance + camera->target.y;
camera->position.z = -cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break;
case CAMERA_ORBITAL: // Camera just orbits around target, only zoom allowed
{
CAMERA.angle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
// Camera distance clamp
if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
// Update camera position with changes
camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
camera->position.y = ((CAMERA.angle.y <= 0.0f)? 1 : -1)*sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break;
case CAMERA_FIRST_PERSON: // Camera moves as in a first-person game, controls are configurable
{
camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
// Camera orientation calculation
CAMERA.angle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
CAMERA.angle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp
if (CAMERA.angle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
else if (CAMERA.angle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
// Calculate translation matrix
Matrix matTranslation = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, (CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER),
0.0f, 0.0f, 0.0f, 1.0f };
// Calculate rotation matrix
Matrix matRotation = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
float cosz = cosf(0.0f);
float sinz = sinf(0.0f);
float cosy = cosf(-(PI*2 - CAMERA.angle.x));
float siny = sinf(-(PI*2 - CAMERA.angle.x));
float cosx = cosf(-(PI*2 - CAMERA.angle.y));
float sinx = sinf(-(PI*2 - CAMERA.angle.y));
matRotation.m0 = cosz*cosy;
matRotation.m4 = (cosz*siny*sinx) - (sinz*cosx);
matRotation.m8 = (cosz*siny*cosx) + (sinz*sinx);
matRotation.m1 = sinz*cosy;
matRotation.m5 = (sinz*siny*sinx) + (cosz*cosx);
matRotation.m9 = (sinz*siny*cosx) - (cosz*sinx);
matRotation.m2 = -siny;
matRotation.m6 = cosy*sinx;
matRotation.m10= cosy*cosx;
// Multiply translation and rotation matrices
Matrix matTransform = { 0 };
matTransform.m0 = matTranslation.m0*matRotation.m0 + matTranslation.m1*matRotation.m4 + matTranslation.m2*matRotation.m8 + matTranslation.m3*matRotation.m12;
matTransform.m1 = matTranslation.m0*matRotation.m1 + matTranslation.m1*matRotation.m5 + matTranslation.m2*matRotation.m9 + matTranslation.m3*matRotation.m13;
matTransform.m2 = matTranslation.m0*matRotation.m2 + matTranslation.m1*matRotation.m6 + matTranslation.m2*matRotation.m10 + matTranslation.m3*matRotation.m14;
matTransform.m3 = matTranslation.m0*matRotation.m3 + matTranslation.m1*matRotation.m7 + matTranslation.m2*matRotation.m11 + matTranslation.m3*matRotation.m15;
matTransform.m4 = matTranslation.m4*matRotation.m0 + matTranslation.m5*matRotation.m4 + matTranslation.m6*matRotation.m8 + matTranslation.m7*matRotation.m12;
matTransform.m5 = matTranslation.m4*matRotation.m1 + matTranslation.m5*matRotation.m5 + matTranslation.m6*matRotation.m9 + matTranslation.m7*matRotation.m13;
matTransform.m6 = matTranslation.m4*matRotation.m2 + matTranslation.m5*matRotation.m6 + matTranslation.m6*matRotation.m10 + matTranslation.m7*matRotation.m14;
matTransform.m7 = matTranslation.m4*matRotation.m3 + matTranslation.m5*matRotation.m7 + matTranslation.m6*matRotation.m11 + matTranslation.m7*matRotation.m15;
matTransform.m8 = matTranslation.m8*matRotation.m0 + matTranslation.m9*matRotation.m4 + matTranslation.m10*matRotation.m8 + matTranslation.m11*matRotation.m12;
matTransform.m9 = matTranslation.m8*matRotation.m1 + matTranslation.m9*matRotation.m5 + matTranslation.m10*matRotation.m9 + matTranslation.m11*matRotation.m13;
matTransform.m10 = matTranslation.m8*matRotation.m2 + matTranslation.m9*matRotation.m6 + matTranslation.m10*matRotation.m10 + matTranslation.m11*matRotation.m14;
matTransform.m11 = matTranslation.m8*matRotation.m3 + matTranslation.m9*matRotation.m7 + matTranslation.m10*matRotation.m11 + matTranslation.m11*matRotation.m15;
matTransform.m12 = matTranslation.m12*matRotation.m0 + matTranslation.m13*matRotation.m4 + matTranslation.m14*matRotation.m8 + matTranslation.m15*matRotation.m12;
matTransform.m13 = matTranslation.m12*matRotation.m1 + matTranslation.m13*matRotation.m5 + matTranslation.m14*matRotation.m9 + matTranslation.m15*matRotation.m13;
matTransform.m14 = matTranslation.m12*matRotation.m2 + matTranslation.m13*matRotation.m6 + matTranslation.m14*matRotation.m10 + matTranslation.m15*matRotation.m14;
matTransform.m15 = matTranslation.m12*matRotation.m3 + matTranslation.m13*matRotation.m7 + matTranslation.m14*matRotation.m11 + matTranslation.m15*matRotation.m15;
camera->target.x = camera->position.x - matTransform.m12;
camera->target.y = camera->position.y - matTransform.m13;
camera->target.z = camera->position.z - matTransform.m14;
// If movement detected (some key pressed), increase swinging
for (int i = 0; i < 6; i++) if (direction[i]) { swingCounter++; break; }
// Camera position update
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
camera->position.y = CAMERA.playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
} break;
case CAMERA_THIRD_PERSON: // Camera moves as in a third-person game, following target at a distance, controls are configurable
{
camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
// Camera orientation calculation
CAMERA.angle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
CAMERA.angle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp
if (CAMERA.angle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
else if (CAMERA.angle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
// Camera zoom
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
// Camera distance clamp
if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
if (CAMERA.angle.y <= 0.0f) camera->position.y = sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
else camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break;
case CAMERA_CUSTOM: break;
default: break;
}
}
// Set camera pan key to combine with mouse movement (free camera)
void SetCameraPanControl(int keyPan) { CAMERA.panControl = keyPan; }
// Set camera alt key to combine with mouse movement (free camera)
void SetCameraAltControl(int keyAlt) { CAMERA.altControl = keyAlt; }
// Set camera smooth zoom key to combine with mouse (free camera)
void SetCameraSmoothZoomControl(int szoomKey) { CAMERA.smoothZoomControl = szoomKey; }
// Set camera move controls (1st person and 3rd person cameras)
void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int keyLeft, int keyUp, int keyDown)
{
CAMERA.moveControl[MOVE_FRONT] = keyFront;
CAMERA.moveControl[MOVE_BACK] = keyBack;
CAMERA.moveControl[MOVE_RIGHT] = keyRight;
CAMERA.moveControl[MOVE_LEFT] = keyLeft;
CAMERA.moveControl[MOVE_UP] = keyUp;
CAMERA.moveControl[MOVE_DOWN] = keyDown;
}
#endif // CAMERA_IMPLEMENTATION

View file

@ -1,566 +0,0 @@
/**********************************************************************************************
*
* rgestures - Gestures system, gestures processing based on input events (touch/mouse)
*
* NOTE: Memory footprint of this library is aproximately 128 bytes (global variables)
*
* CONFIGURATION:
*
* #define GESTURES_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
* #define GESTURES_STANDALONE
* 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-2021 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
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef MAX_TOUCH_POINTS
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
// NOTE: Below types are required for GESTURES_STANDALONE usage
//----------------------------------------------------------------------------------
// Boolean type
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
typedef enum bool { false, true } bool;
#endif
#if !defined(RL_VECTOR2_TYPE)
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
#endif
#if defined(GESTURES_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
} Gesture;
#endif
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];
} GestureEvent;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#ifdef __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)
#if defined(GESTURES_STANDALONE)
void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
bool IsGestureDetected(int gesture); // Check if a gesture have been detected
int GetGestureDetected(void); // Get latest detected gesture
float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
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
#ifdef __cplusplus
}
#endif
#endif // GESTURES_H
/***********************************************************************************
*
* GESTURES IMPLEMENTATION
*
************************************************************************************/
#if defined(GESTURES_IMPLEMENTATION)
#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()
#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
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define FORCE_TO_SWIPE 0.0005f // 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 MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f)
#define TAP_TIMEOUT 300 // Tap minimum time, measured in milliseconds
#define PINCH_TIMEOUT 300 // Pinch minimum time, measured in milliseconds
#define 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
int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions)
} Touch;
struct {
bool resetRequired; // HOLD reset to get first touch point again
double timeDuration; // HOLD duration in milliseconds
} 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 {
bool start; // SWIPE used to define when start measuring GESTURES.Swipe.timeDuration
double timeDuration; // SWIPE 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
};
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static float rgVector2Angle(Vector2 initialPosition, Vector2 finalPosition);
static float rgVector2Distance(Vector2 v1, Vector2 v2);
static double rgGetCurrentTime(void);
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Enable only desired getures to be detected
void SetGesturesEnabled(unsigned int flags)
{
GESTURES.enabledFlags = flags;
}
// Check if a gesture have been detected
bool IsGestureDetected(int gesture)
{
if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true;
else return false;
}
// Process gesture event and translate it into gestures
void ProcessGestureEvent(GestureEvent event)
{
// 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
// 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.upPosition = GESTURES.Touch.downPositionA;
GESTURES.Touch.eventTime = rgGetCurrentTime();
GESTURES.Touch.firstId = event.pointId[0];
GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f };
}
else if (event.touchAction == TOUCH_ACTION_UP)
{
if (GESTURES.current == GESTURE_DRAG) GESTURES.Touch.upPosition = event.position[0];
// NOTE: GESTURES.Drag.intensity dependend 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.timeDuration));
GESTURES.Swipe.start = false;
// Detect GESTURE_SWIPE
if ((GESTURES.Drag.intensity > FORCE_TO_SWIPE) && (GESTURES.Touch.firstId == event.pointId[0]))
{
// NOTE: Angle should be inverted in Y
GESTURES.Drag.angle = 360.0f - rgVector2Angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right
else if ((GESTURES.Drag.angle > 30) && (GESTURES.Drag.angle < 120)) GESTURES.current = GESTURE_SWIPE_UP; // Up
else if ((GESTURES.Drag.angle > 120) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left
else if ((GESTURES.Drag.angle > 210) && (GESTURES.Drag.angle < 300)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down
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.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f };
GESTURES.Touch.pointCount = 0;
}
else if (event.touchAction == TOUCH_ACTION_MOVE)
{
if (GESTURES.current == GESTURE_DRAG) GESTURES.Touch.eventTime = rgGetCurrentTime();
if (!GESTURES.Swipe.start)
{
GESTURES.Swipe.timeDuration = rgGetCurrentTime();
GESTURES.Swipe.start = true;
}
GESTURES.Touch.moveDownPositionA = event.position[0];
if (GESTURES.current == GESTURE_HOLD)
{
if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0];
GESTURES.Hold.resetRequired = false;
// Detect GESTURE_DRAG
if (rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_DRAG)
{
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.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.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.downPositionA = GESTURES.Touch.moveDownPositionA;
GESTURES.Touch.downPositionB = GESTURES.Touch.moveDownPositionB;
GESTURES.Touch.moveDownPositionA = event.position[0];
GESTURES.Touch.moveDownPositionB = event.position[1];
GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x;
GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y;
if ((rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.downPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH))
{
if ((rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) - GESTURES.Pinch.distance) < 0) 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;
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)
{
// 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();
}
if (((rgGetCurrentTime() - GESTURES.Touch.eventTime) > TAP_TIMEOUT) && (GESTURES.current == GESTURE_DRAG) && (GESTURES.Touch.pointCount < 2))
{
GESTURES.current = GESTURE_HOLD;
GESTURES.Hold.timeDuration = rgGetCurrentTime();
GESTURES.Hold.resetRequired = true;
}
// 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)
{
// Get current gesture only if enabled
return (GESTURES.enabledFlags & GESTURES.current);
}
// Hold time measured in ms
float GetGestureHoldDuration(void)
{
// NOTE: time is calculated on current gesture HOLD
double time = 0.0;
if (GESTURES.current == GESTURE_HOLD) time = rgGetCurrentTime() - GESTURES.Hold.timeDuration;
return (float)time;
}
// Get drag vector (between initial touch point to current)
Vector2 GetGestureDragVector(void)
{
// NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE
return GESTURES.Drag.vector;
}
// Get drag angle
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
float GetGestureDragAngle(void)
{
// NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP
return GESTURES.Drag.angle;
}
// Get distance between two pinch points
Vector2 GetGesturePinchVector(void)
{
// NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE
return GESTURES.Pinch.vector;
}
// Get angle beween two pinch points
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
float GetGesturePinchAngle(void)
{
// NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE
return GESTURES.Pinch.angle;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
// Get angle from two-points vector with X-axis
static float rgVector2Angle(Vector2 v1, Vector2 v2)
{
float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
if (angle < 0) angle += 360.0f;
return angle;
}
// Calculate distance between two Vector2
static float rgVector2Distance(Vector2 v1, Vector2 v2)
{
float result;
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
result = (float)sqrt(dx*dx + dy*dy);
return result;
}
// Time measure returned are milliseconds
static double rgGetCurrentTime(void)
{
double time = 0;
#if defined(_WIN32)
unsigned long long int clockFrequency, currentTime;
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
QueryPerformanceCounter(&currentTime);
time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
#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
time = ((double)nowTime/1000000.0); // Time in miliseconds
#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
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
time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif
return time;
}
#endif // GESTURES_IMPLEMENTATION

File diff suppressed because it is too large Load diff

View file

@ -1,751 +0,0 @@
/**********************************************************************************************
*
* rmem - raylib memory pool and objects pool
*
* A quick, efficient, and minimal free list and arena-based allocator
*
* PURPOSE:
* - A quicker, efficient memory allocator alternative to 'malloc' and friends.
* - Reduce the possibilities of memory leaks for beginner developers using Raylib.
* - Being able to flexibly range check memory if necessary.
*
* CONFIGURATION:
*
* #define RMEM_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.
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2019 Kevin 'Assyrianic' Yonan (@assyrianic) and reviewed by 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 RMEM_H
#define RMEM_H
#include <inttypes.h>
#include <stdbool.h>
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
#define RMEMAPI __declspec(dllexport) // We are building library as a Win32 shared library (.dll)
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
#define RMEMAPI __declspec(dllimport) // We are using library as a Win32 shared library (.dll)
#else
#define RMEMAPI // We are building or using library as a static library (or Linux shared library)
#endif
#define RMEM_VERSION "v1.3" // changelog at bottom of header.
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Memory Pool
typedef struct MemNode MemNode;
struct MemNode {
size_t size;
MemNode *next, *prev;
};
// Freelist implementation
typedef struct AllocList {
MemNode *head, *tail;
size_t len;
} AllocList;
// Arena allocator.
typedef struct Arena {
uintptr_t mem, offs;
size_t size;
} Arena;
enum {
MEMPOOL_BUCKET_SIZE = 8,
MEMPOOL_BUCKET_BITS = (sizeof(uintptr_t) >> 1) + 1,
MEM_SPLIT_THRESHOLD = sizeof(uintptr_t) * 4
};
typedef struct MemPool {
AllocList large, buckets[MEMPOOL_BUCKET_SIZE];
Arena arena;
} MemPool;
// Object Pool
typedef struct ObjPool {
uintptr_t mem, offs;
size_t objSize, freeBlocks, memSize;
} ObjPool;
// Double-Ended Stack aka Deque
typedef struct BiStack {
uintptr_t mem, front, back;
size_t size;
} BiStack;
#if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Functions Declaration - Memory Pool
//------------------------------------------------------------------------------------
RMEMAPI MemPool CreateMemPool(size_t bytes);
RMEMAPI MemPool CreateMemPoolFromBuffer(void *buf, size_t bytes);
RMEMAPI void DestroyMemPool(MemPool *mempool);
RMEMAPI void *MemPoolAlloc(MemPool *mempool, size_t bytes);
RMEMAPI void *MemPoolRealloc(MemPool *mempool, void *ptr, size_t bytes);
RMEMAPI void MemPoolFree(MemPool *mempool, void *ptr);
RMEMAPI void MemPoolCleanUp(MemPool *mempool, void **ptrref);
RMEMAPI void MemPoolReset(MemPool *mempool);
RMEMAPI size_t GetMemPoolFreeMemory(const MemPool mempool);
//------------------------------------------------------------------------------------
// Functions Declaration - Object Pool
//------------------------------------------------------------------------------------
RMEMAPI ObjPool CreateObjPool(size_t objsize, size_t len);
RMEMAPI ObjPool CreateObjPoolFromBuffer(void *buf, size_t objsize, size_t len);
RMEMAPI void DestroyObjPool(ObjPool *objpool);
RMEMAPI void *ObjPoolAlloc(ObjPool *objpool);
RMEMAPI void ObjPoolFree(ObjPool *objpool, void *ptr);
RMEMAPI void ObjPoolCleanUp(ObjPool *objpool, void **ptrref);
//------------------------------------------------------------------------------------
// Functions Declaration - Double-Ended Stack
//------------------------------------------------------------------------------------
RMEMAPI BiStack CreateBiStack(size_t len);
RMEMAPI BiStack CreateBiStackFromBuffer(void *buf, size_t len);
RMEMAPI void DestroyBiStack(BiStack *destack);
RMEMAPI void *BiStackAllocFront(BiStack *destack, size_t len);
RMEMAPI void *BiStackAllocBack(BiStack *destack, size_t len);
RMEMAPI void BiStackResetFront(BiStack *destack);
RMEMAPI void BiStackResetBack(BiStack *destack);
RMEMAPI void BiStackResetAll(BiStack *destack);
RMEMAPI intptr_t BiStackMargins(BiStack destack);
#ifdef __cplusplus
}
#endif
#endif // RMEM_H
/***********************************************************************************
*
* RMEM IMPLEMENTATION
*
************************************************************************************/
#if defined(RMEM_IMPLEMENTATION)
#include <stdio.h> // Required for:
#include <stdlib.h> // Required for:
#include <string.h> // Required for:
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
// Make sure restrict type qualifier for pointers is defined
// NOTE: Not supported by C++, it is a C only keyword
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) || defined(_MSC_VER)
#ifndef restrict
#define restrict __restrict
#endif
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static inline size_t __AlignSize(const size_t size, const size_t align)
{
return (size + (align - 1)) & -align;
}
static MemNode *__SplitMemNode(MemNode *const node, const size_t bytes)
{
uintptr_t n = ( uintptr_t )node;
MemNode *const r = ( MemNode* )(n + (node->size - bytes));
node->size -= bytes;
r->size = bytes;
return r;
}
static void __InsertMemNodeBefore(AllocList *const list, MemNode *const insert, MemNode *const curr)
{
insert->next = curr;
if (curr->prev==NULL) list->head = insert;
else
{
insert->prev = curr->prev;
curr->prev->next = insert;
}
curr->prev = insert;
}
static void __ReplaceMemNode(MemNode *const old, MemNode *const replace)
{
replace->prev = old->prev;
replace->next = old->next;
if( old->prev != NULL )
old->prev->next = replace;
if( old->next != NULL )
old->next->prev = replace;
}
static MemNode *__RemoveMemNode(AllocList *const list, MemNode *const node)
{
if (node->prev != NULL) node->prev->next = node->next;
else
{
list->head = node->next;
if (list->head != NULL) list->head->prev = NULL;
else list->tail = NULL;
}
if (node->next != NULL) node->next->prev = node->prev;
else
{
list->tail = node->prev;
if (list->tail != NULL) list->tail->next = NULL;
else list->head = NULL;
}
list->len--;
return node;
}
static MemNode *__FindMemNode(AllocList *const list, const size_t bytes)
{
for (MemNode *node = list->head; node != NULL; node = node->next)
{
if (node->size < bytes) continue;
// close in size - reduce fragmentation by not splitting.
else if (node->size <= bytes + MEM_SPLIT_THRESHOLD) return __RemoveMemNode(list, node);
else return __SplitMemNode(node, bytes);
}
return NULL;
}
static void __InsertMemNode(MemPool *const mempool, AllocList *const list, MemNode *const node, const bool is_bucket)
{
if (list->head == NULL)
{
list->head = node;
list->len++;
}
else
{
for (MemNode *iter = list->head; iter != NULL; iter = iter->next)
{
if (( uintptr_t )iter == mempool->arena.offs)
{
mempool->arena.offs += iter->size;
__RemoveMemNode(list, iter);
iter = list->head;
if (iter == NULL) {
list->head = node;
return;
}
}
const uintptr_t inode = ( uintptr_t )node;
const uintptr_t iiter = ( uintptr_t )iter;
const uintptr_t iter_end = iiter + iter->size;
const uintptr_t node_end = inode + node->size;
if (iter==node) return;
else if (iter < node)
{
// node was coalesced prior.
if (iter_end > inode) return;
else if (iter_end==inode && !is_bucket)
{
// if we can coalesce, do so.
iter->size += node->size;
return;
}
else if (iter->next == NULL)
{
// we reached the end of the free list -> append the node
iter->next = node;
node->prev = iter;
list->len++;
return;
}
}
else if (iter > node)
{
// Address sort, lowest to highest aka ascending order.
if (iiter < node_end) return;
else if (iter==list->head && !is_bucket)
{
if (iter_end==inode) iter->size += node->size;
else if (node_end==iiter)
{
node->size += list->head->size;
node->next = list->head->next;
node->prev = NULL;
list->head = node;
}
else
{
node->next = iter;
node->prev = NULL;
iter->prev = node;
list->head = node;
list->len++;
}
return;
}
else if (iter_end==inode && !is_bucket)
{
// if we can coalesce, do so.
iter->size += node->size;
return;
}
else
{
__InsertMemNodeBefore(list, node, iter);
list->len++;
return;
}
}
}
}
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Memory Pool
//----------------------------------------------------------------------------------
MemPool CreateMemPool(const size_t size)
{
MemPool mempool = { 0 };
if (size == 0) return mempool;
else
{
// Align the mempool size to at least the size of an alloc node.
uint8_t *const restrict buf = malloc(size*sizeof *buf);
if (buf==NULL) return mempool;
else
{
mempool.arena.size = size;
mempool.arena.mem = ( uintptr_t )buf;
mempool.arena.offs = mempool.arena.mem + mempool.arena.size;
return mempool;
}
}
}
MemPool CreateMemPoolFromBuffer(void *const restrict buf, const size_t size)
{
MemPool mempool = { 0 };
if ((size == 0) || (buf == NULL) || (size <= sizeof(MemNode))) return mempool;
else
{
mempool.arena.size = size;
mempool.arena.mem = ( uintptr_t )buf;
mempool.arena.offs = mempool.arena.mem + mempool.arena.size;
return mempool;
}
}
void DestroyMemPool(MemPool *const restrict mempool)
{
if (mempool->arena.mem == 0) return;
else
{
void *const restrict ptr = ( void* )mempool->arena.mem;
free(ptr);
*mempool = (MemPool){ 0 };
}
}
void *MemPoolAlloc(MemPool *const mempool, const size_t size)
{
if ((size == 0) || (size > mempool->arena.size)) return NULL;
else
{
MemNode *new_mem = NULL;
const size_t ALLOC_SIZE = __AlignSize(size + sizeof *new_mem, sizeof(intptr_t));
const size_t BUCKET_SLOT = (ALLOC_SIZE >> MEMPOOL_BUCKET_BITS) - 1;
// If the size is small enough, let's check if our buckets has a fitting memory block.
if (BUCKET_SLOT < MEMPOOL_BUCKET_SIZE)
{
new_mem = __FindMemNode(&mempool->buckets[BUCKET_SLOT], ALLOC_SIZE);
}
else if (mempool->large.head != NULL)
{
new_mem = __FindMemNode(&mempool->large, ALLOC_SIZE);
}
if (new_mem == NULL)
{
// not enough memory to support the size!
if ((mempool->arena.offs - ALLOC_SIZE) < mempool->arena.mem) return NULL;
else
{
// Couldn't allocate from a freelist, allocate from available mempool.
// Subtract allocation size from the mempool.
mempool->arena.offs -= ALLOC_SIZE;
// Use the available mempool space as the new node.
new_mem = ( MemNode* )mempool->arena.offs;
new_mem->size = ALLOC_SIZE;
}
}
// Visual of the allocation block.
// --------------
// | mem size | lowest addr of block
// | next node | 12 byte (32-bit) header
// | prev node | 24 byte (64-bit) header
// |------------|
// | alloc'd |
// | memory |
// | space | highest addr of block
// --------------
new_mem->next = new_mem->prev = NULL;
uint8_t *const restrict final_mem = ( uint8_t* )new_mem + sizeof *new_mem;
return memset(final_mem, 0, new_mem->size - sizeof *new_mem);
}
}
void *MemPoolRealloc(MemPool *const restrict mempool, void *const ptr, const size_t size)
{
if (size > mempool->arena.size) return NULL;
// NULL ptr should make this work like regular Allocation.
else if (ptr == NULL) return MemPoolAlloc(mempool, size);
else if ((uintptr_t)ptr - sizeof(MemNode) < mempool->arena.mem) return NULL;
else
{
MemNode *const node = ( MemNode* )(( uint8_t* )ptr - sizeof *node);
const size_t NODE_SIZE = sizeof *node;
uint8_t *const resized_block = MemPoolAlloc(mempool, size);
if (resized_block == NULL) return NULL;
else
{
MemNode *const resized = ( MemNode* )(resized_block - sizeof *resized);
memmove(resized_block, ptr, (node->size > resized->size)? (resized->size - NODE_SIZE) : (node->size - NODE_SIZE));
MemPoolFree(mempool, ptr);
return resized_block;
}
}
}
void MemPoolFree(MemPool *const restrict mempool, void *const ptr)
{
const uintptr_t p = ( uintptr_t )ptr;
if ((ptr == NULL) || (p - sizeof(MemNode) < mempool->arena.mem)) return;
else
{
// Behind the actual pointer data is the allocation info.
const uintptr_t block = p - sizeof(MemNode);
MemNode *const mem_node = ( MemNode* )block;
const size_t BUCKET_SLOT = (mem_node->size >> MEMPOOL_BUCKET_BITS) - 1;
// Make sure the pointer data is valid.
if ((block < mempool->arena.offs) ||
((block - mempool->arena.mem) > mempool->arena.size) ||
(mem_node->size == 0) ||
(mem_node->size > mempool->arena.size)) return;
// If the mem_node is right at the arena offs, then merge it back to the arena.
else if (block == mempool->arena.offs)
{
mempool->arena.offs += mem_node->size;
}
else
{
// try to place it into bucket or large freelist.
struct AllocList *const l = (BUCKET_SLOT < MEMPOOL_BUCKET_SIZE) ? &mempool->buckets[BUCKET_SLOT] : &mempool->large;
__InsertMemNode(mempool, l, mem_node, (BUCKET_SLOT < MEMPOOL_BUCKET_SIZE));
}
}
}
void MemPoolCleanUp(MemPool *const restrict mempool, void **const ptrref)
{
if ((ptrref == NULL) || (*ptrref == NULL)) return;
else
{
MemPoolFree(mempool, *ptrref);
*ptrref = NULL;
}
}
size_t GetMemPoolFreeMemory(const MemPool mempool)
{
size_t total_remaining = mempool.arena.offs - mempool.arena.mem;
for (MemNode *n=mempool.large.head; n != NULL; n = n->next) total_remaining += n->size;
for (size_t i=0; i<MEMPOOL_BUCKET_SIZE; i++) for (MemNode *n = mempool.buckets[i].head; n != NULL; n = n->next) total_remaining += n->size;
return total_remaining;
}
void MemPoolReset(MemPool *const mempool)
{
mempool->large.head = mempool->large.tail = NULL;
mempool->large.len = 0;
for (size_t i = 0; i < MEMPOOL_BUCKET_SIZE; i++)
{
mempool->buckets[i].head = mempool->buckets[i].tail = NULL;
mempool->buckets[i].len = 0;
}
mempool->arena.offs = mempool->arena.mem + mempool->arena.size;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Object Pool
//----------------------------------------------------------------------------------
ObjPool CreateObjPool(const size_t objsize, const size_t len)
{
ObjPool objpool = { 0 };
if ((len == 0) || (objsize == 0)) return objpool;
else
{
const size_t aligned_size = __AlignSize(objsize, sizeof(size_t));
uint8_t *const restrict buf = calloc(len, aligned_size);
if (buf == NULL) return objpool;
objpool.objSize = aligned_size;
objpool.memSize = objpool.freeBlocks = len;
objpool.mem = ( uintptr_t )buf;
for (size_t i=0; i<objpool.freeBlocks; i++)
{
size_t *const restrict index = ( size_t* )(objpool.mem + (i*aligned_size));
*index = i + 1;
}
objpool.offs = objpool.mem;
return objpool;
}
}
ObjPool CreateObjPoolFromBuffer(void *const restrict buf, const size_t objsize, const size_t len)
{
ObjPool objpool = { 0 };
// If the object size isn't large enough to align to a size_t, then we can't use it.
const size_t aligned_size = __AlignSize(objsize, sizeof(size_t));
if ((buf == NULL) || (len == 0) || (objsize < sizeof(size_t)) || (objsize*len != aligned_size*len)) return objpool;
else
{
objpool.objSize = aligned_size;
objpool.memSize = objpool.freeBlocks = len;
objpool.mem = (uintptr_t)buf;
for (size_t i=0; i<objpool.freeBlocks; i++)
{
size_t *const restrict index = ( size_t* )(objpool.mem + (i*aligned_size));
*index = i + 1;
}
objpool.offs = objpool.mem;
return objpool;
}
}
void DestroyObjPool(ObjPool *const restrict objpool)
{
if (objpool->mem == 0) return;
else
{
void *const restrict ptr = ( void* )objpool->mem;
free(ptr);
*objpool = (ObjPool){0};
}
}
void *ObjPoolAlloc(ObjPool *const objpool)
{
if (objpool->freeBlocks > 0)
{
// For first allocation, head points to the very first index.
// Head = &pool[0];
// ret = Head == ret = &pool[0];
size_t *const restrict block = ( size_t* )objpool->offs;
objpool->freeBlocks--;
// after allocating, we set head to the address of the index that *Head holds.
// Head = &pool[*Head * pool.objsize];
objpool->offs = (objpool->freeBlocks != 0)? objpool->mem + (*block*objpool->objSize) : 0;
return memset(block, 0, objpool->objSize);
}
else return NULL;
}
void ObjPoolFree(ObjPool *const restrict objpool, void *const ptr)
{
uintptr_t block = (uintptr_t)ptr;
if ((ptr == NULL) || (block < objpool->mem) || (block > objpool->mem + objpool->memSize*objpool->objSize)) return;
else
{
// When we free our pointer, we recycle the pointer space to store the previous index and then we push it as our new head.
// *p = index of Head in relation to the buffer;
// Head = p;
size_t *const restrict index = ( size_t* )block;
*index = (objpool->offs != 0)? (objpool->offs - objpool->mem)/objpool->objSize : objpool->memSize;
objpool->offs = block;
objpool->freeBlocks++;
}
}
void ObjPoolCleanUp(ObjPool *const restrict objpool, void **const restrict ptrref)
{
if (ptrref == NULL) return;
else
{
ObjPoolFree(objpool, *ptrref);
*ptrref = NULL;
}
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Double-Ended Stack
//----------------------------------------------------------------------------------
BiStack CreateBiStack(const size_t len)
{
BiStack destack = { 0 };
if (len == 0) return destack;
uint8_t *const buf = malloc(len*sizeof *buf);
if (buf==NULL) return destack;
destack.size = len;
destack.mem = ( uintptr_t )buf;
destack.front = destack.mem;
destack.back = destack.mem + len;
return destack;
}
BiStack CreateBiStackFromBuffer(void *const buf, const size_t len)
{
BiStack destack = { 0 };
if (len == 0 || buf == NULL) return destack;
else
{
destack.size = len;
destack.mem = destack.front = ( uintptr_t )buf;
destack.back = destack.mem + len;
return destack;
}
}
void DestroyBiStack(BiStack *const restrict destack)
{
if (destack->mem == 0) return;
else
{
uint8_t *const restrict buf = ( uint8_t* )destack->mem;
free(buf);
*destack = (BiStack){0};
}
}
void *BiStackAllocFront(BiStack *const restrict destack, const size_t len)
{
if (destack->mem == 0) return NULL;
else
{
const size_t ALIGNED_LEN = __AlignSize(len, sizeof(uintptr_t));
// front end arena is too high!
if (destack->front + ALIGNED_LEN >= destack->back) return NULL;
else
{
uint8_t *const restrict ptr = ( uint8_t* )destack->front;
destack->front += ALIGNED_LEN;
return ptr;
}
}
}
void *BiStackAllocBack(BiStack *const restrict destack, const size_t len)
{
if (destack->mem == 0) return NULL;
else
{
const size_t ALIGNED_LEN = __AlignSize(len, sizeof(uintptr_t));
// back end arena is too low
if (destack->back - ALIGNED_LEN <= destack->front) return NULL;
else
{
destack->back -= ALIGNED_LEN;
uint8_t *const restrict ptr = ( uint8_t* )destack->back;
return ptr;
}
}
}
void BiStackResetFront(BiStack *const destack)
{
if (destack->mem == 0) return;
else destack->front = destack->mem;
}
void BiStackResetBack(BiStack *const destack)
{
if (destack->mem == 0) return;
else destack->back = destack->mem + destack->size;
}
void BiStackResetAll(BiStack *const destack)
{
BiStackResetBack(destack);
BiStackResetFront(destack);
}
inline intptr_t BiStackMargins(const BiStack destack)
{
return destack.back - destack.front;
}
#endif // RMEM_IMPLEMENTATION
/*******
* Changelog
* v1.0: First Creation.
* v1.1: bug patches for the mempool and addition of object pool.
* v1.2: addition of bidirectional arena.
* v1.3:
* optimizations of allocators.
* renamed 'Stack' to 'Arena'.
* replaced certain define constants with an anonymous enum.
* refactored MemPool to no longer require active or deferred defragging.
********/

View file

@ -1,81 +0,0 @@
/**********************************************************************************************
*
* raylib.utils - Some common utility functions
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2021 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
#endif
#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
#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)
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// Nop...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#ifdef __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!
#endif
#ifdef __cplusplus
}
#endif
#endif // UTILS_H