This commit is contained in:
Jak Barnes 2019-04-20 12:45:21 +01:00
commit 0e1078c13d
22 changed files with 32547 additions and 30230 deletions

28
BINDINGS.md Normal file
View File

@ -0,0 +1,28 @@
### raylib bindings
Some people ported raylib to other languages in form of bindings or wrappers to the library, here is a list with the ones I'm aware of:
- [raylib](https://github.com/raysan5/raylib) : raylib **C/C++** version (default)
- [raylib-lua](https://github.com/raysan5/raylib-lua) : raylib **Lua** binding
- [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) : raylib **Lua** ffi binding
- [raylib-go](https://github.com/gen2brain/raylib-go) : raylib **Go** binding
- [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) : raylib **Nim** binding
- [cray](https://gitlab.com/Zatherz/cray) - raylib **Crystal** binding
- [Graphics::Raylib](https://metacpan.org/pod/Graphics::Raylib) : raylib **Perl** wrapper
- [raylib-pascal](https://github.com/drezgames/raylib-pascal) - raylib **Pascal** binding
- [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) : raylib **C#** binding
- [RaylibSharp](https://github.com/TheLumaio/RaylibSharp) : raylib **C#** binding
- [raylib-ruby-ffi](https://github.com/D3nX/raylib-ruby-ffi) : raylib **Ruby** binding
- [raylib-rs](https://github.com/deltaphc/raylib-rs) : raylib **Rust** binding
- [raylib-py](https://github.com/overdev/raylib-py) : raylib **Python** binding
- [raylib-haskell](https://github.com/DevJac/raylib-haskell) : raylib **Haskell** binding
- [raylib-java](https://github.com/XoanaIO/raylib-java) : raylib **Java** binding
- [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) : raylib **ChaiScript** binding
- [node-raylib](https://github.com/RobLoach/node-raylib) : **Node.js** raylib binding
- *[raylib flat-assembler Usage example]()*
- *[raylib COBOL Usage example](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)*
Usually, raylib bindings follow the convention: `raylib-{language}`
Let me know if you're writing a new binding for raylib, I will list it here and I usually
provide the icon/logo for that new language binding.

View File

@ -55,35 +55,6 @@ To open new issue for raylib (bug, enhancement, discussion...), just try to foll
- Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry - Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry
if you cannot test all the platforms. if you cannot test all the platforms.
### raylib bindings
Some people ported raylib to other languages in form of bindings or wrappers to the library, here is a list with the ones I'm aware of:
- [raylib](https://github.com/raysan5/raylib) : raylib **C/C++** version (default)
- [raylib-lua](https://github.com/raysan5/raylib-lua) : raylib **Lua** binding
- [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) : raylib **Lua** ffi binding
- [raylib-go](https://github.com/gen2brain/raylib-go) : raylib **Go** binding
- [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) : raylib **Nim** binding
- [cray](https://gitlab.com/Zatherz/cray) - raylib **Crystal** binding
- [Graphics::Raylib](https://metacpan.org/pod/Graphics::Raylib) : raylib **Perl** wrapper
- [raylib-pascal](https://github.com/drezgames/raylib-pascal) - raylib **Pascal** binding
- [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) : raylib **C#** binding
- [RaylibSharp](https://github.com/TheLumaio/RaylibSharp) : raylib **C#** binding
- [raylib-ruby-ffi](https://github.com/D3nX/raylib-ruby-ffi) : raylib **Ruby** binding
- [raylib-rs](https://github.com/deltaphc/raylib-rs) : raylib **Rust** binding
- [raylib-py](https://github.com/overdev/raylib-py) : raylib **Python** binding
- [raylib-haskell](https://github.com/DevJac/raylib-haskell) : raylib **Haskell** binding
- [raylib-java](https://github.com/XoanaIO/raylib-java) : raylib **Java** binding
- [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) : raylib **ChaiScript** binding
- [node-raylib](https://github.com/RobLoach/node-raylib) : **Node.js** raylib binding
- *[raylib flat-assembler Usage example]()*
- *[raylib COBOL Usage example](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)*
Usually, raylib bindings follow the convention: `raylib-{language}`
Let me know if you're writing a new binding for raylib, I will list it here and I usually
provide the icon/logo for that new language binding.
### Contact information ### Contact information
If you have any doubt, don't hesitate to [contact me](mailto:ray@raylib.com)!. If you have any doubt, don't hesitate to [contact me](mailto:ray@raylib.com)!.

View File

@ -0,0 +1,380 @@
# format=pipe
RaylibIsAwesome|SuperStefkaGeanyTags|OpenSourceHaveFun|
InitWindow|void|(int width, int height, const char *title);|
CloseWindow|void|(void);|
IsWindowReady|bool|(void);|
WindowShouldClose|bool|(void);|
IsWindowMinimized|bool(void);|
ToggleFullscreen|void|(void);|
SetWindowIcon|void|(Image image);|
SetWindowTitle|void|(const char *title);|
SetWindowPosition|void|(int x, int y);|
SetWindowMonitor|void|(int monitor);|
SetWindowMinSize|void|(int width, int height);|
SetWindowSize|void|(int width, int height);|
GetScreenWidth|int|(void);|
GetScreenHeight|int|(void);|
ShowCursor|void|(void);|
HideCursor|void|(void);|
IsCursorHidden|bool|(void);|
EnableCursor|void|(void);
DisableCursor|void|(void);|
ClearBackground|void|(Color color);|
BeginDrawing|void|(void);|
EndDrawing|void|(void);|
BeginMode2D|void|(Camera2D camera);|
EndMode2D|void|(void);
BeginMode3D|void|(Camera3D camera);|
EndMode3D|void|(void);|
BeginTextureMode|void|(RenderTexture2D target);|
EndTextureMode|void|(void);|
GetMouseRay|Ray|(Vector2 mousePosition, Camera camera);|
GetWorldToScreen|Vector2|(Vector3 position, Camera camera);|
GetCameraMatrix|Matrix|(Camera camera);|
SetTargetFPS|void|(int fps);|
GetFPS|int|(void);|
GetFrameTime|float|(void);|
GetTime|double|(void);|
ColorToInt|int|(Color color);|
ColorNormalize|Vector4|(Color color);|
ColorToHSV|Vector3|(Color color);|
GetColor|Color|(int hexValue);|
Fade|Color|(Color color, float alpha);|
ShowLogo|void|(void);|
SetConfigFlags|void|(unsigned char flags);|
SetTraceLog|void|(unsigned char types);|
TraceLog|void|(int logType, const char *text, ...);|
TakeScreenshot|void|(const char *fileName);|
GetRandomValue|int|(int min, int max);|
IsFileExtension|bool|(const char *fileName, const char *ext);|
GetExtension|const char *|(const char *fileName);|
GetFileName|const char *|(const char *filePath);|
GetDirectoryPath|const char *|(const char *fileName);|
GetWorkingDirectory|const char *|(void);|
ChangeDirectory|bool|(const char *dir);|
IsFileDropped|bool|(void);|
GetDroppedFiles|char **|(int *count);|
ClearDroppedFiles|void|(void);|
StorageSaveValue|void|(int position, int value);|
StorageLoadValue|int|(int position);|
IsKeyPressed|bool|(int key);|
IsKeyDown|bool|(int key);|
IsKeyReleased|bool|(int key);|
IsKeyUp|bool|(int key);|
GetKeyPressed|int|(void);|
SetExitKey|void|(int key);|
IsGamepadAvailable|bool|(int gamepad);|
IsGamepadName|bool|(int gamepad, const char *name);|
GetGamepadName|const char *|(int gamepad);|
IsGamepadButtonPressed|bool|(int gamepad, int button);|
IsGamepadButtonDown|bool|(int gamepad, int button);|
IsGamepadButtonReleased|bool|(int gamepad, int button);|
IsGamepadButtonUp|bool|(int gamepad, int button);|
GetGamepadButtonPressed|int|(void);|
GetGamepadAxisCount|int|(int gamepad);|
GetGamepadAxisMovement|float|(int gamepad, int axis);|
IsMouseButtonPressed|bool|(int button);|
IsMouseButtonDown|bool|(int button);|
IsMouseButtonReleased|bool|(int button);|
IsMouseButtonUp|bool|(int button);|
GetMouseX|int|(void);|
GetMouseY|int|(void);|
GetMousePosition|Vector2|(void);|
SetMousePosition|void|(Vector2 position);|
GetMouseWheelMove|int|(void);|
GetTouchX|int|(void);|
GetTouchY|int|(void);|
GetTouchPosition|Vector2|(int index);|
SetGesturesEnabled|void|(unsigned int gestureFlags);|
IsGestureDetected|bool|(int gesture);|
GetGestureDetected|int|(void);|
GetTouchPointsCount|int|(void);|
GetGestureHoldDuration|float|(void);|
GetGestureDragVector|Vector2|(void);|
GetGestureDragAngle|float|(void);|
GetGesturePinchVector|Vector2|(void);|
GetGesturePinchAngle|float|(void);|
SetCameraMode|void|(Camera camera, int mode);|
UpdateCamera|void|(Camera *camera);|
SetCameraPanControl|void|(int panKey);|
SetCameraAltControl|void|(int altKey);|
SetCameraSmoothZoomControl|void|(int szKey);|
SetCameraMoveControls|void|(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey);|
DrawPixel|void|(int posX, int posY, Color color);|
DrawPixelV|void|(Vector2 position, Color color);
DrawLine|void|(int startPosX, int startPosY, int endPosX, int endPosY, Color color);
DrawLineV|void|(Vector2 startPos, Vector2 endPos, Color color);|
DrawLineEx|void|(Vector2 startPos, Vector2 endPos, float thick, Color color);|
DrawLineBezier|void|(Vector2 startPos, Vector2 endPos, float thick, Color color);|
DrawCircle|void|(int centerX, int centerY, float radius, Color color);|
DrawCircleGradient|void|(int centerX, int centerY, float radius, Color color1, Color color2);|
DrawCircleV|void|(Vector2 center, float radius, Color color);|
DrawCircleLines|void|(int centerX, int centerY, float radius, Color color);|
DrawRectangle|void|(int posX, int posY, int width, int height, Color color);|
DrawRectangleV|void|(Vector2 position, Vector2 size, Color color);|
DrawRectangleRec|void|(Rectangle rec, Color color);|
DrawRectanglePro|void|(Rectangle rec, Vector2 origin, float rotation, Color color);|
DrawRectangleGradientV|void|(int posX, int posY, int width, int height, Color color1, Color color2);|
DrawRectangleGradientH|void|(int posX, int posY, int width, int height, Color color1, Color color2);|
DrawRectangleGradientEx|void|(Rectangle rec, Color col1, Color col2, Color col3, Color col4);|
DrawRectangleLines|void|(int posX, int posY, int width, int height, Color color);|
DrawRectangleLinesEx|void|(Rectangle rec, int lineThick, Color color);|
DrawTriangle|void|(Vector2 v1, Vector2 v2, Vector2 v3, Color color);|
DrawTriangleLines|void|(Vector2 v1, Vector2 v2, Vector2 v3, Color color);|
DrawPoly|void|(Vector2 center, int sides, float radius, float rotation, Color color);|
DrawPolyEx|void|(Vector2 *points, int numPoints, Color color);|
DrawPolyExLines|void|(Vector2 *points, int numPoints, Color color);|
CheckCollisionRecs|bool|(Rectangle rec1, Rectangle rec2);|
CheckCollisionCircles|bool|(Vector2 center1, float radius1, Vector2 center2, float radius2);|
CheckCollisionCircleRec|bool|(Vector2 center, float radius, Rectangle rec);|
GetCollisionRec|Rectangle|(Rectangle rec1, Rectangle rec2);|
CheckCollisionPointRec|bool|(Vector2 point, Rectangle rec);|
CheckCollisionPointCircle|bool|(Vector2 point, Vector2 center, float radius);|
CheckCollisionPointTriangle|bool|(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3);|
LoadImage|Image|(const char *fileName);|
LoadImageEx|Image|(Color *pixels, int width, int height);|
LoadImagePro|Image|(void *data, int width, int height, int format);|
LoadImageRaw|Image|(const char *fileName, int width, int height, int format, int headerSize);|
ExportImage|void|(const char *fileName, Image image);|
LoadTexture|Texture2D|(const char *fileName);|
LoadTextureFromImage|Texture2D|(Image image);|
RenderTexture2D LoadRenderTexture(int width, int height);|
UnloadImage|void|(Image image);|
UnloadTexture|void|(Texture2D texture);|
UnloadRenderTexture|void|(RenderTexture2D target);|
GetImageData|Color *|(Image image);|
GetImageDataNormalized|Vector4 *|(Image image);|
GetPixelDataSize|int|(int width, int height, int format);|
GetTextureData|Image|(Texture2D texture);|
UpdateTexture|void|(Texture2D texture, const void *pixels);|
ImageCopy|Image|(Image image);|
ImageToPOT|void|(Image *image, Color fillColor);|
ImageFormat|void|(Image *image, int newFormat);|
ImageAlphaMask|void|(Image *image, Image alphaMask);|
ImageAlphaClear|void|(Image *image, Color color, float threshold);|
ImageAlphaCrop|void|(Image *image, float threshold);|
ImageAlphaPremultiply|void|(Image *image);|
ImageCrop|void|(Image *image, Rectangle crop);|
ImageResize|void|(Image *image, int newWidth, int newHeight);|
ImageResizeNN|void|(Image *image, int newWidth,int newHeight);|
ImageResizeCanvas|void|(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color color);|
ImageMipmaps|void|(Image *image);|
ImageDither|void|(Image *image, int rBpp, int gBpp, int bBpp, int aBpp);|
ImageText|Image|(const char *text, int fontSize, Color color);|
ImageTextEx|Image|(Font font, const char *text, float fontSize, float spacing, Color tint);|
ImageDraw|void|(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec);|
ImageDrawRectangle|void|(Image *dst, Vector2 position, Rectangle rec, Color color);|
ImageDrawText|void|(Image *dst, Vector2 position, const char *text, int fontSize, Color color);|
ImageDrawTextEx|void|(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color);|
ImageFlipVertical|void|(Image *image);|
ImageFlipHorizontal|void|(Image *image);|
ImageRotateCW|void|(Image *image);|
ImageRotateCCW|void|(Image *image);|
ImageColorTint|void|(Image *image, Color color);|
ImageColorInvert|void|(Image *image);|
ImageColorGrayscale|void|(Image *image);|
ImageColorContrast|void|(Image *image, float contrast);|
ImageColorBrightness|void|(Image *image, int brightness);|
ImageColorReplace|void|(Image *image, Color color, Color replace);|
GenImageColor|void|(int width, int height, Color color);|
GenImageGradientV|void|(int width, int height, Color top, Color bottom);|
GenImageGradientH|void|(int width, int height, Color left, Color right);|
GenImageGradientRadial|void|(int width, int height, float density, Color inner, Color outer);|
GenImageChecked|void|(int width, int height, int checksX, int checksY, Color col1, Color col2);|
GenImageWhiteNoise|void|(int width, int height, float factor);|
GenImagePerlinNoise|void|(int width, int height, int offsetX, int offsetY, float scale);|
GenImageCellular|void|(int width, int height, int tileSize);|
GenTextureMipmaps|void|(Texture2D *texture);|
SetTextureFilter|void|(Texture2D texture, int filterMode);|
SetTextureWrap|void|(Texture2D texture, int wrapMode);|
DrawTexture|void|(Texture2D texture, int posX, int posY, Color tint);|
DrawTextureV|void|(Texture2D texture, Vector2 position, Color tint);|
DrawTextureEx|void|(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);|
DrawTextureRec|void|(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint);|
DrawTexturePro|void|(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint);|
GetFontDefault|Font|(void);|
LoadFont|Font|(const char *fileName);|
LoadFontEx|Font|(const char *fileName, int fontSize, int charsCount, int *fontChars);|
LoadFontData|CharInfo *|(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf);|
GenImageFontAtlas|Image|(CharInfo *chars, int fontSize, int charsCount, int padding, int packMethod);|
UnloadFont|void|(Font font);|
DrawFPS|void|(int posX, int posY);|
DrawText|void|(const char *text, int posX, int posY, int fontSize, Color color);|
DrawTextEx|void|(Font font, const char* text, Vector2 position, float fontSize, float spacing, Color tint);|
MeasureText|int|(const char *text, int fontSize);|
MeasureTextEx|Vector2|(Font font, const char *text, float fontSize, float spacing);|
FormatText|const char *|(const char *text, ...);|
SubText|const char *|(const char *text, int position, int length);|
GetGlyphIndex|int|(Font font, int character);|
DrawLine3D|void|(Vector3 startPos, Vector3 endPos, Color color);|
DrawCircle3D|void|(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color);|
DrawCube|void|(Vector3 position, float width, float height, float length, Color color);|
DrawCubeV|void|(Vector3 position, Vector3 size, Color color);|
DrawCubeWires|void|(Vector3 position, float width, float height, float length, Color color);|
DrawCubeTexture|void|(Texture2D texture, Vector3 position, float width, float height, float length, Color color);|
DrawSphere|void|(Vector3 centerPos, float radius, Color color);|
DrawSphereEx|void|(Vector3 centerPos, float radius, int rings, int slices, Color color);|
DrawSphereWires|void|(Vector3 centerPos, float radius, int rings, int slices, Color color);|
DrawCylinder|void|(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);|
DrawCylinderWires|void|(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);|
DrawPlane|void|(Vector3 centerPos, Vector2 size, Color color);|
DrawRay|void|(Ray ray, Color color);|
DrawGrid|void|(int slices, float spacing);|
DrawGizmo|void|(Vector3 position);|
LoadModel|Model|(const char *fileName);|
LoadModelFromMesh|Model|(Mesh mesh);|
UnloadModel|void|(Model model);|
LoadMesh|Mesh|(const char *fileName);|
UnloadMesh|void|(Mesh *mesh);|
ExportMesh|void|(const char *fileName, Mesh mesh);|
MeshBoundingBox|BoundingBox|(Mesh mesh);|
MeshTangents|void|(Mesh *mesh);|
MeshBinormals|void|(Mesh *mesh);|
GenMeshPlane|Mesh|(float width, float length, int resX, int resZ);|
GenMeshCube|Mesh|(float width, float height, float length);|
GenMeshSphere|Mesh|(float radius, int rings, int slices);|
GenMeshHemiSphere|Mesh|(float radius, int rings, int slices);|
GenMeshCylinder|Mesh|(float radius, float height, int slices);|
GenMeshTorus|Mesh|(float radius, float size, int radSeg, int sides);|
GenMeshKnot|Mesh|(float radius, float size, int radSeg, int sides);|
GenMeshHeightmap|Mesh|(Image heightmap, Vector3 size);|
GenMeshCubicmap|Mesh|(Image cubicmap, Vector3 cubeSize);|
LoadMaterial|Material|(const char *fileName);|
LoadMaterialDefault|Material|(void);|
UnloadMaterial|void|(Material material);|
DrawModel|void|(Model model, Vector3 position, float scale, Color tint);|
DrawModelEx|void|(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);|
DrawModelWires|void|(Model model, Vector3 position, float scale, Color tint);|
DrawModelWiresEx|void|(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);|
DrawBoundingBox|void|(BoundingBox box, Color color);|
DrawBillboard|void|(Camera camera, Texture2D texture, Vector3 center, float size, Color tint);|
DrawBillboardRec|void|(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint);|
CheckCollisionSpheres|bool|(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);|
CheckCollisionBoxes|bool|(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);|
CheckCollisionBoxSphere|bool|(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere);|
CheckCollisionRaySphere|bool|(Ray ray, Vector3 spherePosition, float sphereRadius);|
CheckCollisionRaySphereEx|bool|(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint);|
CheckCollisionRayBox|bool|(Ray ray, Vector3 minBBox, Vector3 maxBBox);|
GetCollisionRayModel|RayHitInfo|(Ray ray, Model *model);|
GetCollisionRayTriangle|RayHitInfo|(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3);|
GetCollisionRayGround|RayHitInfo|(Ray ray, float groundHeight);|
LoadText|char *|(const char *fileName);|
LoadShader|Shader|(char *vsFileName, char *fsFileName);|
LoadShaderCode|Shader|(char *vsCode, char *fsCode);|
UnloadShader|void|(Shader shader);|
GetShaderDefault|Shader|(void);|
GetTextureDefault|Texture2D|(void);|
GetShaderLocation|int|(Shader shader, const char *uniformName);|
SetShaderValue|void|(Shader shader, int uniformLoc, float *value, int size);|
SetShaderValuei|void|(Shader shader, int uniformLoc, int *value, int size);|
SetShaderValueMatrix|void|(Shader shader, int uniformLoc, Matrix mat);|
SetMatrixProjection|void|(Matrix proj);|
SetMatrixModelview|void|(Matrix view);|
GetMatrixModelview|Matrix|();|
BeginShaderMode|void|(Shader shader);|
EndShaderMode|void|(void);|
BeginBlendMode|void|(int mode);|
EndBlendMode|void|(void);|
GetVrDeviceInfo|VrDeviceInfo|(int vrDeviceType);|
InitVrSimulator|void|(VrDeviceInfo info);|
CloseVrSimulator|void|(void);|
IsVrSimulatorReady|bool|(void);|
UpdateVrTracking|void|(Camera *camera);|
ToggleVrMode|void|(void);|
BeginVrDrawing|void|(void);|
EndVrDrawing|void|(void);|
InitAudioDevice|void|(void);|
CloseAudioDevice|void|(void);|
IsAudioDeviceReady|bool|(void);|
SetMasterVolume|void|(float volume);|
LoadWave|Wave|(const char *fileName);|
LoadWaveEx|Wave|(float *data, int sampleCount, int sampleRate, int sampleSize, int channels);|
LoadSound|Sound|(const char *fileName);|
LoadSoundFromWave|Sound|(Wave wave);|
UpdateSound|void|(Sound sound, void *data, int numSamples);|
UnloadWave|void|(Wave wave);|
UnloadSound|void|(Sound sound);|
PlaySound|void|(Sound sound);|
PauseSound|void|(Sound sound);|
ResumeSound|void|(Sound sound);|
StopSound|void|(Sound sound);|
IsSoundPlaying|bool|(Sound sound);|
SetSoundVolume|void|(Sound sound, float volume);|
SetSoundPitch|void|(Sound sound, float pitch);|
WaveFormat|void|(Wave *wave, int sampleRate, int sampleSize, int channels);|
WaveCopy|Wave|(Wave wave);|
WaveCrop|void|(Wave *wave, int initSample, int finalSample);|
GetWaveData|float *|(Wave wave);|
LoadMusicStream|Music|(const char *fileName);|
UnloadMusicStream|void|(Music music);|
PlayMusicStream|void|(Music music);|
UpdateMusicStream|void|(Music music);|
StopMusicStream|void|(Music music);|
PauseMusicStream|void|(Music music);|
ResumeMusicStream|void|(Music music);|
IsMusicPlaying|bool|(Music music);|
SetMusicVolume|void|(Music music, float volume);|
SetMusicPitch|void|(Music music, float pitch);|
SetMusicLoopCount|void|(Music music, float count);|
GetMusicTimeLength|float|(Music music);|
GetMusicTimePlayed|float|(Music music);|
InitAudioStream|AudioStream|(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels);|
UpdateAudioStream|void|(AudioStream stream, void *data, int numSamples);|
CloseAudioStream|void|(AudioStream stream);|
IsAudioBufferProcessed|bool|(AudioStream stream);|
PlayAudioStream|void|(AudioStream stream);|
PauseAudioStream|void|(AudioStream stream);|
ResumeAudioStream|void|(AudioStream stream);|
StopAudioStream|void|(AudioStream stream);|
Color|struct||
Rectangle|struct||
Vector2|struct||
Vector3|struct||
Vector4|struct||
Quaternion|struct||
Matrix|struct||
Image|struct||
Texture|struct||
RenderTexture|struct||
CharInfo|struct||
Font|struct||
Camera|struct||
Camera2D|struct||
Mesh|struct||
Shader|struct||
MaterialMap|struct||
Material|struct||
Model|struct||
Ray|struct||
RayHitInfo|struct||
Wave|struct||
Sound|struct||
Music|struct||
AudioStream|struct||
LIGHTGRAY|#define||
GRAY|#define||
DARKGRAY|#define||
YELLOW|#define||
GOLD|#define||
ORANGE|#define||
PINK|#define||
RED|#define||
MAROON|#define||
GREEN|#define||
LIME|#define||
DARKGREEN|#define||
SKYBLUE|#define||
BLUE|#define||
DARKBLUE|#define||
PURPLE|#define||
VIOLET|#define||
DARKPURPLE|#define||
BEIGE|#define||
BROWN|#define||
DARKBROWN|#define||
WHITE|#define||
BLACK|#define||
BLANK|#define||
MAGENTA|#define||
RAYWHITE|#define||

View File

@ -246,7 +246,7 @@
<ClInclude Include="..\..\..\src\external\glad.h" /> <ClInclude Include="..\..\..\src\external\glad.h" />
<ClInclude Include="..\..\..\src\external\jar_mod.h" /> <ClInclude Include="..\..\..\src\external\jar_mod.h" />
<ClInclude Include="..\..\..\src\external\jar_xm.h" /> <ClInclude Include="..\..\..\src\external\jar_xm.h" />
<ClInclude Include="..\..\..\src\external\mini_al.h" /> <ClInclude Include="..\..\..\src\external\miniaudio.h" />
<ClInclude Include="..\..\..\src\external\stb_image.h" /> <ClInclude Include="..\..\..\src\external\stb_image.h" />
<ClInclude Include="..\..\..\src\external\stb_image_resize.h" /> <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
<ClInclude Include="..\..\..\src\external\stb_image_write.h" /> <ClInclude Include="..\..\..\src\external\stb_image_write.h" />

View File

@ -174,7 +174,7 @@
<ClInclude Include="..\..\..\src\external\glad.h" /> <ClInclude Include="..\..\..\src\external\glad.h" />
<ClInclude Include="..\..\..\src\external\jar_mod.h" /> <ClInclude Include="..\..\..\src\external\jar_mod.h" />
<ClInclude Include="..\..\..\src\external\jar_xm.h" /> <ClInclude Include="..\..\..\src\external\jar_xm.h" />
<ClInclude Include="..\..\..\src\external\mini_al.h" /> <ClInclude Include="..\..\..\src\external\miniaudio.h" />
<ClInclude Include="..\..\..\src\external\stb_image.h" /> <ClInclude Include="..\..\..\src\external\stb_image.h" />
<ClInclude Include="..\..\..\src\external\stb_image_resize.h" /> <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
<ClInclude Include="..\..\..\src\external\stb_image_write.h" /> <ClInclude Include="..\..\..\src\external\stb_image_write.h" />

View File

@ -49,7 +49,7 @@ if(USE_AUDIO)
set(sources ${raylib_sources}) set(sources ${raylib_sources})
else() else()
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)") MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
set(INCLUDE_AUDIO_MODULE 0) set(RAYLIB_MODULE_AUDIO 0)
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/raudio.c) list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/raudio.c)
set(sources ${raylib_sources}) set(sources ${raylib_sources})
endif() endif()

View File

@ -42,7 +42,7 @@
.PHONY: all clean install uninstall .PHONY: all clean install uninstall
# Define required raylib variables # Define required raylib variables
RAYLIB_VERSION = 2.0.0 RAYLIB_VERSION = 2.4.0
RAYLIB_API_VERSION = 2 RAYLIB_API_VERSION = 2
# See below for alternatives. # See below for alternatives.
@ -59,9 +59,15 @@ RAYLIB_LIBTYPE ?= STATIC
# Build mode for library: DEBUG or RELEASE # Build mode for library: DEBUG or RELEASE
RAYLIB_BUILD_MODE ?= RELEASE RAYLIB_BUILD_MODE ?= RELEASE
# Included raylib audio module on compilation # Include raylib modules on compilation
# NOTE: Some programs like tools could not require audio support # NOTE: Some programs like tools could not require those modules
INCLUDE_AUDIO_MODULE ?= TRUE RAYLIB_MODULE_AUDIO ?= TRUE
RAYLIB_MODULE_MODELS ?= TRUE
RAYLIB_MODULE_RAYGUI ?= FALSE
RAYLIB_MODULE_PHYSAC ?= FALSE
RAYLIB_MODULE_RAYGUI_PATH ?= .
RAYLIB_MODULE_PHYSAC_PATH ?= .
# Use external GLFW library instead of rglfw module # Use external GLFW library instead of rglfw module
# TODO: Review usage of examples on Linux. # TODO: Review usage of examples on Linux.
@ -179,33 +185,12 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif endif
endif endif
# RAYLIB_RELEASE_PATH points to library build path, right now # Define raylib source code path
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src RAYLIB_SRC_PATH ?= $(RAYLIB_PATH)/src
# Define output directory for compiled library # Define output directory for compiled library, defaults to src directory
ifeq ($(PLATFORM),PLATFORM_DESKTOP) # NOTE: If externally provided, make sure directory exists
ifeq ($(PLATFORM_OS),WINDOWS) RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)\mingw\i686-w64-mingw32\lib
endif
ifeq ($(PLATFORM_OS),LINUX)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
endif
ifeq ($(PLATFORM_OS),OSX)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
endif
ifeq ($(PLATFORM_OS),BSD)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/src/android/$(ANDROID_ARCH_NAME)
endif
# Define raylib graphics api depending on selected platform # Define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@ -393,7 +378,6 @@ OBJS = core.o \
shapes.o \ shapes.o \
textures.o \ textures.o \
text.o \ text.o \
models.o \
utils.o utils.o
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@ -401,10 +385,18 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
OBJS += rglfw.o OBJS += rglfw.o
endif endif
endif endif
ifeq ($(RAYLIB_MODULE_MODELS),TRUE)
ifeq ($(INCLUDE_AUDIO_MODULE),TRUE) OBJS += models.o
endif
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
OBJS += raudio.o OBJS += raudio.o
endif endif
ifeq ($(RAYLIB_MODULE_RAYGUI),TRUE)
OBJS += raygui.o
endif
ifeq ($(RAYLIB_MODULE_PHYSAC),TRUE)
OBJS += physac.o
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)
OBJS += external/android/native_app_glue/android_native_app_glue.o OBJS += external/android/native_app_glue/android_native_app_glue.o
@ -442,11 +434,6 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
emcc -O1 $(OBJS) -o $(RAYLIB_RELEASE_PATH)/libraylib.bc emcc -O1 $(OBJS) -o $(RAYLIB_RELEASE_PATH)/libraylib.bc
@echo "raylib library generated (libraylib.bc)!" @echo "raylib library generated (libraylib.bc)!"
else else
ifeq ($(PLATFORM_OS),WINDOWS)
if not exist $(RAYLIB_RELEASE_PATH) mkdir $(RAYLIB_RELEASE_PATH)
else
mkdir -p $(RAYLIB_RELEASE_PATH)
endif
ifeq ($(RAYLIB_LIBTYPE),SHARED) ifeq ($(RAYLIB_LIBTYPE),SHARED)
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
@ -509,7 +496,7 @@ core.o : core.c raylib.h rlgl.h utils.h raymath.h camera.h gestures.h
# Compile rglfw module # Compile rglfw module
rglfw.o : rglfw.c rglfw.o : rglfw.c
$(CC) $(GLFW_CFLAGS) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS) $(CC) -c $< $(CFLAGS) $(GLFW_CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
# Compile shapes module # Compile shapes module
shapes.o : shapes.c raylib.h rlgl.h shapes.o : shapes.c raylib.h rlgl.h
@ -523,6 +510,10 @@ textures.o : textures.c raylib.h rlgl.h utils.h
text.o : text.c raylib.h utils.h text.o : text.c raylib.h utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
# Compile utils module
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Compile models module # Compile models module
models.o : models.c raylib.h rlgl.h raymath.h models.o : models.c raylib.h rlgl.h raymath.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
@ -531,9 +522,19 @@ models.o : models.c raylib.h rlgl.h raymath.h
raudio.o : raudio.c raylib.h raudio.o : raudio.c raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Compile utils module # Compile raygui module
utils.o : utils.c utils.h # NOTE: raygui header should be distributed with raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) raygui.o : raygui.c raygui.h
@echo #define RAYGUI_IMPLEMENTATION > raygui.c
@echo #include "$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h" > raygui.c
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -DRAYGUI_IMPLEMENTATION
# Compile physac module
# NOTE: physac header should be distributed with raylib.h
physac.o : physac.c physac.h
@echo #define PHYSAC_IMPLEMENTATION > physac.c
@echo #include "$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h" > physac.c
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -DRAYGUI_IMPLEMENTATION
# Install generated and needed files to desired directories. # Install generated and needed files to desired directories.

View File

@ -92,6 +92,8 @@
// Check if config flags have been externally provided on compilation line // Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS) #if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#else
#define RAYLIB_VERSION "2.5"
#endif #endif
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L #if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
@ -178,15 +180,14 @@
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow() #include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow()
#endif #endif
#endif #endif
#if defined(__linux__) #if defined(__linux__)
#include <linux/limits.h> // for NAME_MAX and PATH_MAX defines #include <linux/limits.h> // for NAME_MAX and PATH_MAX defines
#define MAX_FILEPATH_LENGTH PATH_MAX // Use Linux define (4096) #define MAX_FILEPATH_LENGTH PATH_MAX // Use Linux define (4096)
#else #else
#define MAX_FILEPATH_LENGTH 256 // Use common value #define MAX_FILEPATH_LENGTH 512 // Use common value
#endif #endif
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
@ -779,24 +780,23 @@ void ToggleFullscreen(void)
} }
// Set icon for window (only PLATFORM_DESKTOP) // Set icon for window (only PLATFORM_DESKTOP)
// NOTE: Image must be in RGBA format, 8bit per channel
void SetWindowIcon(Image image) void SetWindowIcon(Image image)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
Image imicon = ImageCopy(image); if (image.format == UNCOMPRESSED_R8G8B8A8)
ImageFormat(&imicon, UNCOMPRESSED_R8G8B8A8); {
GLFWimage icon[1] = { 0 };
GLFWimage icon[1] = { 0 }; icon[0].width = image.width;
icon[0].height = image.height;
icon[0].pixels = (unsigned char *)image.data;
icon[0].width = imicon.width; // NOTE 1: We only support one image icon
icon[0].height = imicon.height; // NOTE 2: The specified image data is copied before this function returns
icon[0].pixels = (unsigned char *)imicon.data; glfwSetWindowIcon(window, 1, icon);
}
// NOTE 1: We only support one image icon else TraceLog(LOG_WARNING, "Window icon image must be in R8G8B8A8 pixel format");
// NOTE 2: The specified image data is copied before this function returns
glfwSetWindowIcon(window, 1, icon);
// TODO: Support multi-image icons --> image.mipmaps
UnloadImage(imicon);
#endif #endif
} }
@ -1674,37 +1674,26 @@ const char *GetFileName(const char *filePath)
// Get filename string without extension (memory should be freed) // Get filename string without extension (memory should be freed)
const char *GetFileNameWithoutExt(const char *filePath) const char *GetFileNameWithoutExt(const char *filePath)
{ {
char *result, *lastDot, *lastSep; #define MAX_FILENAMEWITHOUTEXT_LENGTH 64
char nameDot = '.'; // Default filename to extension separator character static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH];
char pathSep = '/'; // Default filepath separator character memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
// Error checks and allocate string strcpy(fileName, GetFileName(filePath)); // Get filename with extension
if (filePath == NULL) return NULL;
// Try to allocate new string, same size as original int len = strlen(fileName);
// NOTE: By default strlen() does not count the '\0' character
if ((result = (char *)malloc(strlen(filePath) + 1)) == NULL) return NULL;
strcpy(result, filePath); // Make a copy of the string for (int i = 0; (i < len) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++)
// NOTE: strrchr() returns a pointer to the last occurrence of character
lastDot = strrchr(result, nameDot);
lastSep = (pathSep == 0)? NULL : strrchr(result, pathSep);
if (lastDot != NULL) // Check if it has an extension separator...
{ {
if (lastSep != NULL) // ...and it's before the extenstion separator... if (fileName[i] == '.')
{ {
if (lastSep < lastDot) // NOTE: We break on first '.' found
{ fileName[i] = '\0';
*lastDot = '\0'; // ...then remove it break;
}
} }
else *lastDot = '\0'; // Has extension separator with no path separator
} }
return result; // Return the modified string return fileName;
} }
// Get directory for a given fileName (with path) // Get directory for a given fileName (with path)
@ -3449,7 +3438,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
dropFilesPath[i] = (char *)malloc(sizeof(char)*MAX_FILEPATH_LENGTH); // Max path length using MAX_FILEPATH_LENGTH set to 256 char dropFilesPath[i] = (char *)malloc(sizeof(char)*MAX_FILEPATH_LENGTH);
strcpy(dropFilesPath[i], paths[i]); strcpy(dropFilesPath[i], paths[i]);
} }

29952
src/external/mini_al.h vendored

File diff suppressed because it is too large Load Diff

31816
src/external/miniaudio.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -285,6 +285,12 @@ void DrawCubeWires(Vector3 position, float width, float height, float length, Co
rlPopMatrix(); rlPopMatrix();
} }
// Draw cube wires (vector version)
void DrawCubeWiresV(Vector3 position, Vector3 size, Color color)
{
DrawCubeWires(position, size.x, size.y, size.z, color);
}
// Draw cube // Draw cube
// NOTE: Cube position is the center position // NOTE: Cube position is the center position
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color) void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raudio - A simple and easy-to-use audio library based on mini_al * raudio - A simple and easy-to-use audio library based on miniaudio
* *
* FEATURES: * FEATURES:
* - Manage audio device (init/close) * - Manage audio device (init/close)
@ -26,7 +26,7 @@
* supported by default, to remove support, just comment unrequired #define in this module * supported by default, to remove support, just comment unrequired #define in this module
* *
* DEPENDENCIES: * DEPENDENCIES:
* mini_al.h - Audio device management lib (https://github.com/dr-soft/mini_al) * 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/) * 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_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) * dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)
@ -35,7 +35,7 @@
* *
* CONTRIBUTORS: * CONTRIBUTORS:
* David Reid (github: @mackron) (Nov. 2017): * David Reid (github: @mackron) (Nov. 2017):
* - Complete port to mini_al library * - Complete port to miniaudio library
* *
* Joshua Reisenauer (github: @kd7tck) (2015) * Joshua Reisenauer (github: @kd7tck) (2015)
* - XM audio module support (jar_xm) * - XM audio module support (jar_xm)
@ -77,11 +77,9 @@
#include "utils.h" // Required for: fopen() Android mapping #include "utils.h" // Required for: fopen() Android mapping
#endif #endif
#define MAL_NO_SDL #define MA_NO_JACK
#define MAL_NO_JACK #define MINIAUDIO_IMPLEMENTATION
#define MAL_NO_OPENAL #include "external/miniaudio.h" // miniaudio library
#define MINI_AL_IMPLEMENTATION
#include "external/mini_al.h" // mini_al audio library
#undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro #undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
@ -208,9 +206,9 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// mini_al AudioBuffer Functionality // miniaudio AudioBuffer Functionality
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define DEVICE_FORMAT mal_format_f32 #define DEVICE_FORMAT ma_format_f32
#define DEVICE_CHANNELS 2 #define DEVICE_CHANNELS 2
#define DEVICE_SAMPLE_RATE 44100 #define DEVICE_SAMPLE_RATE 44100
@ -220,7 +218,7 @@ typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioB
// NOTE: Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed // NOTE: Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed
typedef struct rAudioBuffer rAudioBuffer; typedef struct rAudioBuffer rAudioBuffer;
struct rAudioBuffer { struct rAudioBuffer {
mal_dsp dsp; // Required for format conversion ma_pcm_converter dsp; // Required for format conversion
float volume; float volume;
float pitch; float pitch;
bool playing; bool playing;
@ -239,26 +237,26 @@ struct rAudioBuffer {
// NOTE: This system should probably be redesigned // NOTE: This system should probably be redesigned
#define AudioBuffer rAudioBuffer #define AudioBuffer rAudioBuffer
// mini_al global variables // miniaudio global variables
static mal_context context; static ma_context context;
static mal_device device; static ma_device device;
static mal_mutex audioLock; static ma_mutex audioLock;
static bool isAudioInitialized = MAL_FALSE; static bool isAudioInitialized = MA_FALSE;
static float masterVolume = 1.0f; static float masterVolume = 1.0f;
// Audio buffers are tracked in a linked list // Audio buffers are tracked in a linked list
static AudioBuffer *firstAudioBuffer = NULL; static AudioBuffer *firstAudioBuffer = NULL;
static AudioBuffer *lastAudioBuffer = NULL; static AudioBuffer *lastAudioBuffer = NULL;
// mini_al functions declaration // miniaudio functions declaration
static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message); static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut); static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData); static ma_uint32 OnAudioBufferDSPRead(ma_pcm_converter *pDSP, void *pFramesOut, ma_uint32 frameCount, void *pUserData);
static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume); static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume);
// AudioBuffer management functions declaration // AudioBuffer management functions declaration
// NOTE: Those functions are not exposed by raylib... for the moment // NOTE: Those functions are not exposed by raylib... for the moment
AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage); AudioBuffer *CreateAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 bufferSizeInFrames, AudioBufferUsage usage);
void DeleteAudioBuffer(AudioBuffer *audioBuffer); void DeleteAudioBuffer(AudioBuffer *audioBuffer);
bool IsAudioBufferPlaying(AudioBuffer *audioBuffer); bool IsAudioBufferPlaying(AudioBuffer *audioBuffer);
void PlayAudioBuffer(AudioBuffer *audioBuffer); void PlayAudioBuffer(AudioBuffer *audioBuffer);
@ -270,35 +268,34 @@ void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch);
void TrackAudioBuffer(AudioBuffer *audioBuffer); void TrackAudioBuffer(AudioBuffer *audioBuffer);
void UntrackAudioBuffer(AudioBuffer *audioBuffer); void UntrackAudioBuffer(AudioBuffer *audioBuffer);
// Log callback function // Log callback function
static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message) static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message)
{ {
(void)pContext; (void)pContext;
(void)pDevice; (void)pDevice;
TraceLog(LOG_ERROR, message); // All log messages from mini_al are errors TraceLog(LOG_ERROR, message); // All log messages from miniaudio are errors
} }
// Sending audio data to device callback function // Sending audio data to device callback function
static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut) static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount)
{ {
// This is where all of the mixing takes place. // This is where all of the mixing takes place.
(void)pDevice; (void)pDevice;
// Mixing is basically just an accumulation. We need to initialize the output buffer to 0. // Mixing is basically just an accumulation. We need to initialize the output buffer to 0.
memset(pFramesOut, 0, frameCount*pDevice->channels*mal_get_bytes_per_sample(pDevice->format)); memset(pFramesOut, 0, frameCount*pDevice->playback.channels*ma_get_bytes_per_sample(pDevice->playback.format));
// Using a mutex here for thread-safety which makes things not real-time. This is unlikely to be necessary for this project, but may // Using a mutex here for thread-safety which makes things not real-time. This is unlikely to be necessary for this project, but may
// want to consider how you might want to avoid this. // want to consider how you might want to avoid this.
mal_mutex_lock(&audioLock); ma_mutex_lock(&audioLock);
{ {
for (AudioBuffer *audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next) for (AudioBuffer *audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next)
{ {
// Ignore stopped or paused sounds. // Ignore stopped or paused sounds.
if (!audioBuffer->playing || audioBuffer->paused) continue; if (!audioBuffer->playing || audioBuffer->paused) continue;
mal_uint32 framesRead = 0; ma_uint32 framesRead = 0;
for (;;) for (;;)
{ {
if (framesRead > frameCount) if (framesRead > frameCount)
@ -310,21 +307,21 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
if (framesRead == frameCount) break; if (framesRead == frameCount) break;
// Just read as much data as we can from the stream. // Just read as much data as we can from the stream.
mal_uint32 framesToRead = (frameCount - framesRead); ma_uint32 framesToRead = (frameCount - framesRead);
while (framesToRead > 0) while (framesToRead > 0)
{ {
float tempBuffer[1024]; // 512 frames for stereo. float tempBuffer[1024]; // 512 frames for stereo.
mal_uint32 framesToReadRightNow = framesToRead; ma_uint32 framesToReadRightNow = framesToRead;
if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS) if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS)
{ {
framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS; framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS;
} }
mal_uint32 framesJustRead = (mal_uint32)mal_dsp_read(&audioBuffer->dsp, framesToReadRightNow, tempBuffer, audioBuffer->dsp.pUserData); ma_uint32 framesJustRead = (ma_uint32)ma_pcm_converter_read(&audioBuffer->dsp, tempBuffer, framesToReadRightNow);
if (framesJustRead > 0) if (framesJustRead > 0)
{ {
float *framesOut = (float *)pFramesOut + (framesRead*device.channels); float *framesOut = (float *)pFramesOut + (framesRead*device.playback.channels);
float *framesIn = tempBuffer; float *framesIn = tempBuffer;
MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume); MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
@ -357,18 +354,16 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
} }
} }
mal_mutex_unlock(&audioLock); ma_mutex_unlock(&audioLock);
return frameCount; // We always output the same number of frames that were originally requested.
} }
// DSP read from audio buffer callback function // DSP read from audio buffer callback function
static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData) static ma_uint32 OnAudioBufferDSPRead(ma_pcm_converter *pDSP, void *pFramesOut, ma_uint32 frameCount, void *pUserData)
{ {
AudioBuffer *audioBuffer = (AudioBuffer *)pUserData; AudioBuffer *audioBuffer = (AudioBuffer *)pUserData;
mal_uint32 subBufferSizeInFrames = (audioBuffer->bufferSizeInFrames > 1)? audioBuffer->bufferSizeInFrames/2 : audioBuffer->bufferSizeInFrames; ma_uint32 subBufferSizeInFrames = (audioBuffer->bufferSizeInFrames > 1)? audioBuffer->bufferSizeInFrames/2 : audioBuffer->bufferSizeInFrames;
mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames; ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
if (currentSubBufferIndex > 1) if (currentSubBufferIndex > 1)
{ {
@ -381,10 +376,10 @@ static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, voi
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0]; isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1]; isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
mal_uint32 frameSizeInBytes = mal_get_bytes_per_sample(audioBuffer->dsp.formatConverterIn.config.formatIn)*audioBuffer->dsp.formatConverterIn.config.channels; ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(audioBuffer->dsp.formatConverterIn.config.formatIn)*audioBuffer->dsp.formatConverterIn.config.channels;
// Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0. // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0.
mal_uint32 framesRead = 0; ma_uint32 framesRead = 0;
for (;;) for (;;)
{ {
// We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For // We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For
@ -398,21 +393,21 @@ static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, voi
if (isSubBufferProcessed[currentSubBufferIndex]) break; if (isSubBufferProcessed[currentSubBufferIndex]) break;
} }
mal_uint32 totalFramesRemaining = (frameCount - framesRead); ma_uint32 totalFramesRemaining = (frameCount - framesRead);
if (totalFramesRemaining == 0) break; if (totalFramesRemaining == 0) break;
mal_uint32 framesRemainingInOutputBuffer; ma_uint32 framesRemainingInOutputBuffer;
if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
{ {
framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos; framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
} }
else else
{ {
mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex; ma_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer); framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
} }
mal_uint32 framesToRead = totalFramesRemaining; ma_uint32 framesToRead = totalFramesRemaining;
if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer; if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
memcpy((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes); memcpy((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
@ -437,7 +432,7 @@ static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, voi
} }
// Zero-fill excess. // Zero-fill excess.
mal_uint32 totalFramesRemaining = (frameCount - framesRead); ma_uint32 totalFramesRemaining = (frameCount - framesRead);
if (totalFramesRemaining > 0) if (totalFramesRemaining > 0)
{ {
memset((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes); memset((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
@ -453,16 +448,16 @@ static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, voi
// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation. // This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function. // NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume) static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume)
{ {
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
{ {
for (mal_uint32 iChannel = 0; iChannel < device.channels; ++iChannel) for (ma_uint32 iChannel = 0; iChannel < device.playback.channels; ++iChannel)
{ {
float *frameOut = framesOut + (iFrame*device.channels); float *frameOut = framesOut + (iFrame*device.playback.channels);
const float *frameIn = framesIn + (iFrame*device.channels); const float *frameIn = framesIn + (iFrame*device.playback.channels);
frameOut[iChannel] += frameIn[iChannel]*masterVolume*localVolume; frameOut[iChannel] += (frameIn[iChannel]*masterVolume*localVolume);
} }
} }
} }
@ -474,54 +469,64 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 f
void InitAudioDevice(void) void InitAudioDevice(void)
{ {
// Context. // Context.
mal_context_config contextConfig = mal_context_config_init(OnLog); ma_context_config contextConfig = ma_context_config_init();
mal_result result = mal_context_init(NULL, 0, &contextConfig, &context); contextConfig.logCallback = OnLog;
if (result != MAL_SUCCESS) ma_result result = ma_context_init(NULL, 0, &contextConfig, &context);
if (result != MA_SUCCESS)
{ {
TraceLog(LOG_ERROR, "Failed to initialize audio context"); TraceLog(LOG_ERROR, "Failed to initialize audio context");
return; return;
} }
// Device. Using the default device. Format is floating point because it simplifies mixing. // Device. Using the default device. Format is floating point because it simplifies mixing.
mal_device_config deviceConfig = mal_device_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, OnSendAudioDataToDevice); ma_device_config config = ma_device_config_init(ma_device_type_playback);
config.playback.pDeviceID = NULL; // NULL for the default playback device.
config.playback.format = DEVICE_FORMAT;
config.playback.channels = DEVICE_CHANNELS;
config.capture.pDeviceID = NULL; // NULL for the default capture device.
config.capture.format = ma_format_s16;
config.capture.channels = 1;
config.sampleRate = DEVICE_SAMPLE_RATE;
config.dataCallback = OnSendAudioDataToDevice;
config.pUserData = NULL;
result = mal_device_init(&context, mal_device_type_playback, NULL, &deviceConfig, NULL, &device); result = ma_device_init(&context, &config, &device);
if (result != MAL_SUCCESS) if (result != MA_SUCCESS)
{ {
TraceLog(LOG_ERROR, "Failed to initialize audio playback device"); TraceLog(LOG_ERROR, "Failed to initialize audio playback device");
mal_context_uninit(&context); ma_context_uninit(&context);
return; return;
} }
// Keep the device running the whole time. May want to consider doing something a bit smarter and only have the device running // Keep the device running the whole time. May want to consider doing something a bit smarter and only have the device running
// while there's at least one sound being played. // while there's at least one sound being played.
result = mal_device_start(&device); result = ma_device_start(&device);
if (result != MAL_SUCCESS) if (result != MA_SUCCESS)
{ {
TraceLog(LOG_ERROR, "Failed to start audio playback device"); TraceLog(LOG_ERROR, "Failed to start audio playback device");
mal_device_uninit(&device); ma_device_uninit(&device);
mal_context_uninit(&context); ma_context_uninit(&context);
return; return;
} }
// Mixing happens on a seperate thread which means we need to synchronize. I'm using a mutex here to make things simple, but may // Mixing happens on a seperate thread which means we need to synchronize. I'm using a mutex here to make things simple, but may
// want to look at something a bit smarter later on to keep everything real-time, if that's necessary. // want to look at something a bit smarter later on to keep everything real-time, if that's necessary.
if (mal_mutex_init(&context, &audioLock) != MAL_SUCCESS) if (ma_mutex_init(&context, &audioLock) != MA_SUCCESS)
{ {
TraceLog(LOG_ERROR, "Failed to create mutex for audio mixing"); TraceLog(LOG_ERROR, "Failed to create mutex for audio mixing");
mal_device_uninit(&device); ma_device_uninit(&device);
mal_context_uninit(&context); ma_context_uninit(&context);
return; return;
} }
TraceLog(LOG_INFO, "Audio device initialized successfully: %s", device.name); TraceLog(LOG_INFO, "Audio device initialized successfully");
TraceLog(LOG_INFO, "Audio backend: mini_al / %s", mal_get_backend_name(context.backend)); TraceLog(LOG_INFO, "Audio backend: miniaudio / %s", ma_get_backend_name(context.backend));
TraceLog(LOG_INFO, "Audio format: %s -> %s", mal_get_format_name(device.format), mal_get_format_name(device.internalFormat)); TraceLog(LOG_INFO, "Audio format: %s -> %s", ma_get_format_name(device.playback.format), ma_get_format_name(device.playback.internalFormat));
TraceLog(LOG_INFO, "Audio channels: %d -> %d", device.channels, device.internalChannels); TraceLog(LOG_INFO, "Audio channels: %d -> %d", device.playback.channels, device.playback.internalChannels);
TraceLog(LOG_INFO, "Audio sample rate: %d -> %d", device.sampleRate, device.internalSampleRate); TraceLog(LOG_INFO, "Audio sample rate: %d -> %d", device.sampleRate, device.playback.internalSampleRate);
TraceLog(LOG_INFO, "Audio buffer size: %d", device.bufferSizeInFrames); TraceLog(LOG_INFO, "Audio buffer size: %d", device.playback.internalBufferSizeInFrames);
isAudioInitialized = MAL_TRUE; isAudioInitialized = MA_TRUE;
} }
// Close the audio device for all contexts // Close the audio device for all contexts
@ -533,9 +538,9 @@ void CloseAudioDevice(void)
return; return;
} }
mal_mutex_uninit(&audioLock); ma_mutex_uninit(&audioLock);
mal_device_uninit(&device); ma_device_uninit(&device);
mal_context_uninit(&context); ma_context_uninit(&context);
TraceLog(LOG_INFO, "Audio device closed successfully"); TraceLog(LOG_INFO, "Audio device closed successfully");
} }
@ -560,9 +565,9 @@ void SetMasterVolume(float volume)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Create a new audio buffer. Initially filled with silence // Create a new audio buffer. Initially filled with silence
AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage) AudioBuffer *CreateAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 bufferSizeInFrames, AudioBufferUsage usage)
{ {
AudioBuffer *audioBuffer = (AudioBuffer *)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*mal_get_bytes_per_sample(format)), 1); AudioBuffer *audioBuffer = (AudioBuffer *)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*ma_get_bytes_per_sample(format)), 1);
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to allocate memory for audio buffer"); TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to allocate memory for audio buffer");
@ -570,7 +575,7 @@ AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
} }
// We run audio data through a format converter. // We run audio data through a format converter.
mal_dsp_config dspConfig; ma_pcm_converter_config dspConfig;
memset(&dspConfig, 0, sizeof(dspConfig)); memset(&dspConfig, 0, sizeof(dspConfig));
dspConfig.formatIn = format; dspConfig.formatIn = format;
dspConfig.formatOut = DEVICE_FORMAT; dspConfig.formatOut = DEVICE_FORMAT;
@ -580,20 +585,21 @@ AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
dspConfig.sampleRateOut = DEVICE_SAMPLE_RATE; dspConfig.sampleRateOut = DEVICE_SAMPLE_RATE;
dspConfig.onRead = OnAudioBufferDSPRead; dspConfig.onRead = OnAudioBufferDSPRead;
dspConfig.pUserData = audioBuffer; dspConfig.pUserData = audioBuffer;
dspConfig.allowDynamicSampleRate = MAL_TRUE; // <-- Required for pitch shifting. dspConfig.allowDynamicSampleRate = MA_TRUE; // <-- Required for pitch shifting.
mal_result resultMAL = mal_dsp_init(&dspConfig, &audioBuffer->dsp); ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp);
if (resultMAL != MAL_SUCCESS)
if (result != MA_SUCCESS)
{ {
TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to create data conversion pipeline"); TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to create data conversion pipeline");
free(audioBuffer); free(audioBuffer);
return NULL; return NULL;
} }
audioBuffer->volume = 1; audioBuffer->volume = 1.0f;
audioBuffer->pitch = 1; audioBuffer->pitch = 1.0f;
audioBuffer->playing = 0; audioBuffer->playing = false;
audioBuffer->paused = 0; audioBuffer->paused = false;
audioBuffer->looping = 0; audioBuffer->looping = false;
audioBuffer->usage = usage; audioBuffer->usage = usage;
audioBuffer->bufferSizeInFrames = bufferSizeInFrames; audioBuffer->bufferSizeInFrames = bufferSizeInFrames;
audioBuffer->frameCursorPos = 0; audioBuffer->frameCursorPos = 0;
@ -696,7 +702,7 @@ void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume)
{ {
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
TraceLog(LOG_ERROR, "SetAudioBufferVolume() : No audio buffer"); TraceLog(LOG_WARNING, "SetAudioBufferVolume() : No audio buffer");
return; return;
} }
@ -708,24 +714,24 @@ void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch)
{ {
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
TraceLog(LOG_ERROR, "SetAudioBufferPitch() : No audio buffer"); TraceLog(LOG_WARNING, "SetAudioBufferPitch() : No audio buffer");
return; return;
} }
float pitchMul = pitch / audioBuffer->pitch; float pitchMul = pitch/audioBuffer->pitch;
// Pitching is just an adjustment of the sample rate. Note that this changes the duration of the sound - higher pitches // Pitching is just an adjustment of the sample rate. Note that this changes the duration of the sound - higher pitches
// will make the sound faster; lower pitches make it slower. // will make the sound faster; lower pitches make it slower.
mal_uint32 newOutputSampleRate = (mal_uint32)((float)audioBuffer->dsp.src.config.sampleRateOut / pitchMul); ma_uint32 newOutputSampleRate = (ma_uint32)((float)audioBuffer->dsp.src.config.sampleRateOut / pitchMul);
audioBuffer->pitch *= (float)audioBuffer->dsp.src.config.sampleRateOut / newOutputSampleRate; audioBuffer->pitch *= (float)audioBuffer->dsp.src.config.sampleRateOut / newOutputSampleRate;
mal_dsp_set_output_sample_rate(&audioBuffer->dsp, newOutputSampleRate); ma_pcm_converter_set_output_sample_rate(&audioBuffer->dsp, newOutputSampleRate);
} }
// Track audio buffer to linked list next position // Track audio buffer to linked list next position
void TrackAudioBuffer(AudioBuffer *audioBuffer) void TrackAudioBuffer(AudioBuffer *audioBuffer)
{ {
mal_mutex_lock(&audioLock); ma_mutex_lock(&audioLock);
{ {
if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer; if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer;
@ -738,13 +744,13 @@ void TrackAudioBuffer(AudioBuffer *audioBuffer)
lastAudioBuffer = audioBuffer; lastAudioBuffer = audioBuffer;
} }
mal_mutex_unlock(&audioLock); ma_mutex_unlock(&audioLock);
} }
// Untrack audio buffer from linked list // Untrack audio buffer from linked list
void UntrackAudioBuffer(AudioBuffer *audioBuffer) void UntrackAudioBuffer(AudioBuffer *audioBuffer)
{ {
mal_mutex_lock(&audioLock); ma_mutex_lock(&audioLock);
{ {
if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next; if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next;
@ -757,7 +763,7 @@ void UntrackAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->next = NULL; audioBuffer->next = NULL;
} }
mal_mutex_unlock(&audioLock); ma_mutex_unlock(&audioLock);
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -828,7 +834,7 @@ Sound LoadSoundFromWave(Wave wave)
if (wave.data != NULL) if (wave.data != NULL)
{ {
// When using mini_al we need to do our own mixing. To simplify this we need convert the format of each sound to be consistent with // When using miniaudio we need to do our own mixing. To simplify this we need convert the format of each sound to be consistent with
// the format used to open the playback device. We can do this two ways: // the format used to open the playback device. We can do this two ways:
// //
// 1) Convert the whole sound in one go at load time (here). // 1) Convert the whole sound in one go at load time (here).
@ -836,16 +842,16 @@ Sound LoadSoundFromWave(Wave wave)
// //
// I have decided on the first option because it offloads work required for the format conversion to the to the loading stage. // I have decided on the first option because it offloads work required for the format conversion to the to the loading stage.
// The downside to this is that it uses more memory if the original sound is u8 or s16. // The downside to this is that it uses more memory if the original sound is u8 or s16.
mal_format formatIn = ((wave.sampleSize == 8)? mal_format_u8 : ((wave.sampleSize == 16)? mal_format_s16 : mal_format_f32)); ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32));
mal_uint32 frameCountIn = wave.sampleCount/wave.channels; ma_uint32 frameCountIn = wave.sampleCount/wave.channels;
mal_uint32 frameCount = (mal_uint32)mal_convert_frames(NULL, DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, formatIn, wave.channels, wave.sampleRate, frameCountIn); ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, formatIn, wave.channels, wave.sampleRate, frameCountIn);
if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to get frame count for format conversion"); if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to get frame count for format conversion");
AudioBuffer* audioBuffer = CreateAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, frameCount, AUDIO_BUFFER_USAGE_STATIC); AudioBuffer* audioBuffer = CreateAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, frameCount, AUDIO_BUFFER_USAGE_STATIC);
if (audioBuffer == NULL) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to create audio buffer"); if (audioBuffer == NULL) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to create audio buffer");
frameCount = (mal_uint32)mal_convert_frames(audioBuffer->buffer, audioBuffer->dsp.formatConverterIn.config.formatIn, audioBuffer->dsp.formatConverterIn.config.channels, audioBuffer->dsp.src.config.sampleRateIn, wave.data, formatIn, wave.channels, wave.sampleRate, frameCountIn); frameCount = (ma_uint32)ma_convert_frames(audioBuffer->buffer, audioBuffer->dsp.formatConverterIn.config.formatIn, audioBuffer->dsp.formatConverterIn.config.channels, audioBuffer->dsp.src.config.sampleRateIn, wave.data, formatIn, wave.channels, wave.sampleRate, frameCountIn);
if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Format conversion failed"); if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Format conversion failed");
sound.audioBuffer = audioBuffer; sound.audioBuffer = audioBuffer;
@ -885,7 +891,7 @@ void UpdateSound(Sound sound, const void *data, int samplesCount)
StopAudioBuffer(audioBuffer); StopAudioBuffer(audioBuffer);
// TODO: May want to lock/unlock this since this data buffer is read at mixing time. // TODO: May want to lock/unlock this since this data buffer is read at mixing time.
memcpy(audioBuffer->buffer, data, samplesCount*audioBuffer->dsp.formatConverterIn.config.channels*mal_get_bytes_per_sample(audioBuffer->dsp.formatConverterIn.config.formatIn)); memcpy(audioBuffer->buffer, data, samplesCount*audioBuffer->dsp.formatConverterIn.config.channels*ma_get_bytes_per_sample(audioBuffer->dsp.formatConverterIn.config.formatIn));
} }
// Export wave data to file // Export wave data to file
@ -999,12 +1005,12 @@ void SetSoundPitch(Sound sound, float pitch)
// Convert wave data to desired format // Convert wave data to desired format
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
{ {
mal_format formatIn = ((wave->sampleSize == 8)? mal_format_u8 : ((wave->sampleSize == 16)? mal_format_s16 : mal_format_f32)); ma_format formatIn = ((wave->sampleSize == 8)? ma_format_u8 : ((wave->sampleSize == 16)? ma_format_s16 : ma_format_f32));
mal_format formatOut = (( sampleSize == 8)? mal_format_u8 : (( sampleSize == 16)? mal_format_s16 : mal_format_f32)); ma_format formatOut = (( sampleSize == 8)? ma_format_u8 : (( sampleSize == 16)? ma_format_s16 : ma_format_f32));
mal_uint32 frameCountIn = wave->sampleCount; // Is wave->sampleCount actually the frame count? That terminology needs to change, if so. ma_uint32 frameCountIn = wave->sampleCount; // Is wave->sampleCount actually the frame count? That terminology needs to change, if so.
mal_uint32 frameCount = (mal_uint32)mal_convert_frames(NULL, formatOut, channels, sampleRate, NULL, formatIn, wave->channels, wave->sampleRate, frameCountIn); ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, formatOut, channels, sampleRate, NULL, formatIn, wave->channels, wave->sampleRate, frameCountIn);
if (frameCount == 0) if (frameCount == 0)
{ {
TraceLog(LOG_ERROR, "WaveFormat() : Failed to get frame count for format conversion."); TraceLog(LOG_ERROR, "WaveFormat() : Failed to get frame count for format conversion.");
@ -1013,7 +1019,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
void *data = malloc(frameCount*channels*(sampleSize/8)); void *data = malloc(frameCount*channels*(sampleSize/8));
frameCount = (mal_uint32)mal_convert_frames(data, formatOut, channels, sampleRate, wave->data, formatIn, wave->channels, wave->sampleRate, frameCountIn); frameCount = (ma_uint32)ma_convert_frames(data, formatOut, channels, sampleRate, wave->data, formatIn, wave->channels, wave->sampleRate, frameCountIn);
if (frameCount == 0) if (frameCount == 0)
{ {
TraceLog(LOG_ERROR, "WaveFormat() : Format conversion failed."); TraceLog(LOG_ERROR, "WaveFormat() : Format conversion failed.");
@ -1288,7 +1294,7 @@ void PlayMusicStream(Music music)
// // NOTE: In case window is minimized, music stream is stopped, // // NOTE: In case window is minimized, music stream is stopped,
// // just make sure to play again on window restore // // just make sure to play again on window restore
// if (IsMusicPlaying(music)) PlayMusicStream(music); // if (IsMusicPlaying(music)) PlayMusicStream(music);
mal_uint32 frameCursorPos = audioBuffer->frameCursorPos; ma_uint32 frameCursorPos = audioBuffer->frameCursorPos;
PlayAudioStream(music->stream); // <-- This resets the cursor position. PlayAudioStream(music->stream); // <-- This resets the cursor position.
@ -1513,10 +1519,10 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
stream.channels = 1; // Fallback to mono channel stream.channels = 1; // Fallback to mono channel
} }
mal_format formatIn = ((stream.sampleSize == 8)? mal_format_u8 : ((stream.sampleSize == 16)? mal_format_s16 : mal_format_f32)); ma_format formatIn = ((stream.sampleSize == 8)? ma_format_u8 : ((stream.sampleSize == 16)? ma_format_s16 : ma_format_f32));
// The size of a streaming buffer must be at least double the size of a period. // The size of a streaming buffer must be at least double the size of a period.
unsigned int periodSize = device.bufferSizeInFrames/device.periods; unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods;
unsigned int subBufferSize = AUDIO_BUFFER_SIZE; unsigned int subBufferSize = AUDIO_BUFFER_SIZE;
if (subBufferSize < periodSize) subBufferSize = periodSize; if (subBufferSize < periodSize) subBufferSize = periodSize;
@ -1557,7 +1563,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1])
{ {
mal_uint32 subBufferToUpdate; ma_uint32 subBufferToUpdate;
if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1])
{ {
@ -1571,21 +1577,21 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
subBufferToUpdate = (audioBuffer->isSubBufferProcessed[0])? 0 : 1; subBufferToUpdate = (audioBuffer->isSubBufferProcessed[0])? 0 : 1;
} }
mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2; ma_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate); unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
// Does this API expect a whole buffer to be updated in one go? Assuming so, but if not will need to change this logic. // Does this API expect a whole buffer to be updated in one go? Assuming so, but if not will need to change this logic.
if (subBufferSizeInFrames >= (mal_uint32)samplesCount/stream.channels) if (subBufferSizeInFrames >= (ma_uint32)samplesCount/stream.channels)
{ {
mal_uint32 framesToWrite = subBufferSizeInFrames; ma_uint32 framesToWrite = subBufferSizeInFrames;
if (framesToWrite > ((mal_uint32)samplesCount/stream.channels)) framesToWrite = (mal_uint32)samplesCount/stream.channels; if (framesToWrite > ((ma_uint32)samplesCount/stream.channels)) framesToWrite = (ma_uint32)samplesCount/stream.channels;
mal_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8); ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
memcpy(subBuffer, data, bytesToWrite); memcpy(subBuffer, data, bytesToWrite);
// Any leftover frames should be filled with zeros. // Any leftover frames should be filled with zeros.
mal_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite; ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
if (leftoverFrameCount > 0) if (leftoverFrameCount > 0)
{ {

View File

@ -11,7 +11,7 @@
* - Manage raw audio context * - Manage raw audio context
* *
* DEPENDENCIES: * DEPENDENCIES:
* mini_al.h - Audio device management lib (https://github.com/dr-soft/mini_al) * 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/) * 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_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) * dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)

View File

@ -1240,6 +1240,7 @@ RLAPI Color *GetImageData(Image image);
RLAPI Vector4 *GetImageDataNormalized(Image image); // Get pixel data from image as Vector4 array (float normalized) RLAPI Vector4 *GetImageDataNormalized(Image image); // Get pixel data from image as Vector4 array (float normalized)
RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
RLAPI Image GetScreenData(void); // Get pixel data from screen buffer and return an Image (screenshot)
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
// Image manipulation functions // Image manipulation functions
@ -1352,6 +1353,7 @@ RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, floa
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version)
RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters

View File

@ -563,7 +563,10 @@ int GetPixelDataSize(int width, int height, int format);// Get pixel data size i
#define SUPPORT_VR_SIMULATOR #define SUPPORT_VR_SIMULATOR
#define SUPPORT_DISTORTION_SHADER #define SUPPORT_DISTORTION_SHADER
#else #else
#include "config.h" // rlgl module configuration // Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#endif
#endif #endif
#include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on LoadText()] #include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on LoadText()]

View File

@ -182,6 +182,15 @@ Image LoadImage(const char *fileName)
{ {
Image image = { 0 }; Image image = { 0 };
#if defined(SUPPORT_FILEFORMAT_PNG) || \
defined(SUPPORT_FILEFORMAT_BMP) || \
defined(SUPPORT_FILEFORMAT_TGA) || \
defined(SUPPORT_FILEFORMAT_GIF) || \
defined(SUPPORT_FILEFORMAT_PIC) || \
defined(SUPPORT_FILEFORMAT_PSD)
#define STBI_REQUIRED
#endif
#if defined(SUPPORT_FILEFORMAT_PNG) #if defined(SUPPORT_FILEFORMAT_PNG)
if ((IsFileExtension(fileName, ".png")) if ((IsFileExtension(fileName, ".png"))
#else #else
@ -207,6 +216,7 @@ Image LoadImage(const char *fileName)
#endif #endif
) )
{ {
#if defined(STBI_REQUIRED)
int imgWidth = 0; int imgWidth = 0;
int imgHeight = 0; int imgHeight = 0;
int imgBpp = 0; int imgBpp = 0;
@ -229,6 +239,7 @@ Image LoadImage(const char *fileName)
else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8; else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8;
else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8; else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8;
} }
#endif
} }
#if defined(SUPPORT_FILEFORMAT_HDR) #if defined(SUPPORT_FILEFORMAT_HDR)
else if (IsFileExtension(fileName, ".hdr")) else if (IsFileExtension(fileName, ".hdr"))
@ -729,6 +740,20 @@ Image GetTextureData(Texture2D texture)
return image; return image;
} }
// Get pixel data from GPU frontbuffer and return an Image (screenshot)
RLAPI Image GetScreenData(void)
{
Image image = { 0 };
image.width = GetScreenWidth();
image.height = GetScreenHeight();
image.mipmaps = 1;
image.format = UNCOMPRESSED_R8G8B8A8;
image.data = rlReadScreenPixels(image.width, image.height);
return image;
}
// Update GPU texture with new data // Update GPU texture with new data
// NOTE: pixels data must match texture.format // NOTE: pixels data must match texture.format
void UpdateTexture(Texture2D texture, const void *pixels) void UpdateTexture(Texture2D texture, const void *pixels)
@ -1157,8 +1182,6 @@ void ImageAlphaPremultiply(Image *image)
ImageFormat(image, prevFormat); ImageFormat(image, prevFormat);
} }
#if defined(SUPPORT_IMAGE_MANIPULATION) #if defined(SUPPORT_IMAGE_MANIPULATION)
// Load cubemap from image, multiple image cubemap layouts supported // Load cubemap from image, multiple image cubemap layouts supported
TextureCubemap LoadTextureCubemap(Image image, int layoutType) TextureCubemap LoadTextureCubemap(Image image, int layoutType)
@ -1387,22 +1410,56 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
// NOTE: Resize offset is relative to the top-left corner of the original image // NOTE: Resize offset is relative to the top-left corner of the original image
void ImageResizeCanvas(Image *image, int newWidth,int newHeight, int offsetX, int offsetY, Color color) void ImageResizeCanvas(Image *image, int newWidth,int newHeight, int offsetX, int offsetY, Color color)
{ {
Image imTemp = GenImageColor(newWidth, newHeight, color);
Rectangle srcRec = { 0.0f, 0.0f, (float)image->width, (float)image->height };
Rectangle dstRec = { (float)offsetX, (float)offsetY, (float)srcRec.width, (float)srcRec.height };
// TODO: Review different scaling situations // TODO: Review different scaling situations
if ((newWidth > image->width) && (newHeight > image->height)) if ((newWidth != image->width) || (newHeight != image->height))
{ {
ImageDraw(&imTemp, *image, srcRec, dstRec); if ((newWidth > image->width) && (newHeight > image->height))
ImageFormat(&imTemp, image->format); {
UnloadImage(*image); Image imTemp = GenImageColor(newWidth, newHeight, color);
*image = imTemp;
} Rectangle srcRec = { 0.0f, 0.0f, (float)image->width, (float)image->height };
else Rectangle dstRec = { (float)offsetX, (float)offsetY, (float)srcRec.width, (float)srcRec.height };
{
// TODO: ImageCrop(), define proper cropping rectangle ImageDraw(&imTemp, *image, srcRec, dstRec);
ImageFormat(&imTemp, image->format);
UnloadImage(*image);
*image = imTemp;
}
else if ((newWidth < image->width) && (newHeight < image->height))
{
Rectangle crop = { (float)offsetX, (float)offsetY, newWidth, newHeight };
ImageCrop(image, crop);
}
else // One side is bigger and the other is smaller
{
Image imTemp = GenImageColor(newWidth, newHeight, color);
Rectangle srcRec = { 0.0f, 0.0f, (float)image->width, (float)image->height };
Rectangle dstRec = { (float)offsetX, (float)offsetY, (float)newWidth, (float)newHeight };
if (newWidth < image->width)
{
srcRec.x = offsetX;
srcRec.width = newWidth;
dstRec.x = 0.0f;
}
if (newHeight < image->height)
{
srcRec.y = offsetY;
srcRec.height = newHeight;
dstRec.y = 0.0f;
}
// TODO: ImageDraw() could be buggy?
ImageDraw(&imTemp, *image, srcRec, dstRec);
ImageFormat(&imTemp, image->format);
UnloadImage(*image);
*image = imTemp;
}
} }
} }

View File

@ -30,9 +30,13 @@
* *
**********************************************************************************************/ **********************************************************************************************/
#include "config.h"
#include "raylib.h" // WARNING: Required for: LogType enum #include "raylib.h" // WARNING: Required for: LogType enum
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#endif
#include "utils.h" #include "utils.h"
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)

View File

@ -26,7 +26,7 @@
# Define required raylib variables # Define required raylib variables
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
PLATFORM ?= PLATFORM_DESKTOP PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH = ../.. RAYLIB_PATH ?= ../..
PROJECT_NAME ?= advance_game PROJECT_NAME ?= advance_game
# Default path for raylib on Raspberry Pi, if installed in different path, update it! # Default path for raylib on Raspberry Pi, if installed in different path, update it!
@ -58,7 +58,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(UNAMEOS),Linux) ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX PLATFORM_OS=LINUX
endif endif
ifeq ($(UNAMEOS),FreeBSD) ifeq ($(UNAMEOS),FreeBSD)
PLATFORM_OS=BSD PLATFORM_OS=BSD
endif endif
ifeq ($(UNAMEOS),OpenBSD) ifeq ($(UNAMEOS),OpenBSD)
@ -209,7 +209,7 @@ endif
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),FREEBSD) ifeq ($(PLATFORM_OS),BSD)
INCLUDE_PATHS += -I/usr/local/include INCLUDE_PATHS += -I/usr/local/include
LDFLAGS += -L. -Lsrc -L/usr/local/lib LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif endif
@ -249,8 +249,8 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev # NOTE: Required packages: libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
endif endif
ifeq ($(PLATFORM_OS),FREEBSD) ifeq ($(PLATFORM_OS),BSD)
# Libraries for FreeBSD desktop compiling # Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
# NOTE: Required packages: mesa-libs # NOTE: Required packages: mesa-libs
LDLIBS = -lraylib -lGL -lpthread -lm LDLIBS = -lraylib -lGL -lpthread -lm

View File

@ -70,7 +70,9 @@ APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) # Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC RAYLIB_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\$(ANDROID_ARCH_NAME)
# Library path for libraylib.s/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\src
# Shared libs must be added to APK if required # Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries # NOTE: Generated NativeLoader.java automatically load those libraries
@ -104,7 +106,7 @@ CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION) CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
# Paths containing required header files # Paths containing required header files
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external/android/native_app_glue INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external/android/native_app_glue
# Linker options # Linker options
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a

View File

@ -70,7 +70,9 @@ APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) # Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC RAYLIB_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\$(ANDROID_ARCH_NAME)
# Library path for libraylib.s/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\src
# Shared libs must be added to APK if required # Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries # NOTE: Generated NativeLoader.java automatically load those libraries
@ -104,7 +106,7 @@ CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION) CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
# Paths containing required header files # Paths containing required header files
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external/android/native_app_glue INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external/android/native_app_glue
# Linker options # Linker options
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a

View File

@ -70,7 +70,9 @@ APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) # Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC RAYLIB_LIBTYPE ?= STATIC
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\release\libs\android\$(ANDROID_ARCH_NAME)
# Library path for libraylib.s/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\src
# Shared libs must be added to APK if required # Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries # NOTE: Generated NativeLoader.java automatically load those libraries
@ -104,7 +106,7 @@ CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION) CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
# Paths containing required header files # Paths containing required header files
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external/android/native_app_glue INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external/android/native_app_glue
# Linker options # Linker options
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a