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
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
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\jar_mod.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_resize.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\jar_mod.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_resize.h" />
<ClInclude Include="..\..\..\src\external\stb_image_write.h" />

View File

@ -49,7 +49,7 @@ if(USE_AUDIO)
set(sources ${raylib_sources})
else()
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)
set(sources ${raylib_sources})
endif()

View File

@ -42,7 +42,7 @@
.PHONY: all clean install uninstall
# Define required raylib variables
RAYLIB_VERSION = 2.0.0
RAYLIB_VERSION = 2.4.0
RAYLIB_API_VERSION = 2
# See below for alternatives.
@ -59,9 +59,15 @@ RAYLIB_LIBTYPE ?= STATIC
# Build mode for library: DEBUG or RELEASE
RAYLIB_BUILD_MODE ?= RELEASE
# Included raylib audio module on compilation
# NOTE: Some programs like tools could not require audio support
INCLUDE_AUDIO_MODULE ?= TRUE
# Include raylib modules on compilation
# NOTE: Some programs like tools could not require those modules
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
# TODO: Review usage of examples on Linux.
@ -179,33 +185,12 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif
endif
# RAYLIB_RELEASE_PATH points to library build path, right now
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
# Define raylib source code path
RAYLIB_SRC_PATH ?= $(RAYLIB_PATH)/src
# Define output directory for compiled library
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
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 output directory for compiled library, defaults to src directory
# NOTE: If externally provided, make sure directory exists
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
# Define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@ -393,7 +378,6 @@ OBJS = core.o \
shapes.o \
textures.o \
text.o \
models.o \
utils.o
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@ -401,10 +385,18 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
OBJS += rglfw.o
endif
endif
ifeq ($(INCLUDE_AUDIO_MODULE),TRUE)
ifeq ($(RAYLIB_MODULE_MODELS),TRUE)
OBJS += models.o
endif
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
OBJS += raudio.o
endif
ifeq ($(RAYLIB_MODULE_RAYGUI),TRUE)
OBJS += raygui.o
endif
ifeq ($(RAYLIB_MODULE_PHYSAC),TRUE)
OBJS += physac.o
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
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
@echo "raylib library generated (libraylib.bc)!"
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 ($(PLATFORM),PLATFORM_DESKTOP)
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
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
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
$(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
models.o : models.c raylib.h rlgl.h raymath.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
@ -530,10 +521,20 @@ models.o : models.c raylib.h rlgl.h raymath.h
# Compile audio module
raudio.o : raudio.c raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Compile utils module
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Compile raygui module
# NOTE: raygui header should be distributed with raylib.h
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.

View File

@ -92,6 +92,8 @@
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#else
#define RAYLIB_VERSION "2.5"
#endif
#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
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow()
#endif
#endif
#if defined(__linux__)
#include <linux/limits.h> // for NAME_MAX and PATH_MAX defines
#define MAX_FILEPATH_LENGTH PATH_MAX // Use Linux define (4096)
#include <linux/limits.h> // for NAME_MAX and PATH_MAX defines
#define MAX_FILEPATH_LENGTH PATH_MAX // Use Linux define (4096)
#else
#define MAX_FILEPATH_LENGTH 256 // Use common value
#define MAX_FILEPATH_LENGTH 512 // Use common value
#endif
#if defined(PLATFORM_ANDROID)
@ -779,24 +780,23 @@ void ToggleFullscreen(void)
}
// Set icon for window (only PLATFORM_DESKTOP)
// NOTE: Image must be in RGBA format, 8bit per channel
void SetWindowIcon(Image image)
{
#if defined(PLATFORM_DESKTOP)
Image imicon = ImageCopy(image);
ImageFormat(&imicon, UNCOMPRESSED_R8G8B8A8);
if (image.format == 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;
icon[0].height = imicon.height;
icon[0].pixels = (unsigned char *)imicon.data;
// NOTE 1: We only support one image icon
// 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);
// NOTE 1: We only support one image icon
// NOTE 2: The specified image data is copied before this function returns
glfwSetWindowIcon(window, 1, icon);
}
else TraceLog(LOG_WARNING, "Window icon image must be in R8G8B8A8 pixel format");
#endif
}
@ -1674,37 +1674,26 @@ const char *GetFileName(const char *filePath)
// Get filename string without extension (memory should be freed)
const char *GetFileNameWithoutExt(const char *filePath)
{
char *result, *lastDot, *lastSep;
char nameDot = '.'; // Default filename to extension separator character
char pathSep = '/'; // Default filepath separator character
// Error checks and allocate string
if (filePath == NULL) return NULL;
// Try to allocate new string, same size as original
// 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
// 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...
#define MAX_FILENAMEWITHOUTEXT_LENGTH 64
static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH];
memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
strcpy(fileName, GetFileName(filePath)); // Get filename with extension
int len = strlen(fileName);
for (int i = 0; (i < len) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++)
{
if (lastSep != NULL) // ...and it's before the extenstion separator...
if (fileName[i] == '.')
{
if (lastSep < lastDot)
{
*lastDot = '\0'; // ...then remove it
}
// NOTE: We break on first '.' found
fileName[i] = '\0';
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)
@ -3449,7 +3438,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
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]);
}

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();
}
// Draw cube wires (vector version)
void DrawCubeWiresV(Vector3 position, Vector3 size, Color color)
{
DrawCubeWires(position, size.x, size.y, size.z, color);
}
// Draw cube
// NOTE: Cube position is the center position
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:
* - Manage audio device (init/close)
@ -26,7 +26,7 @@
* supported by default, to remove support, just comment unrequired #define in this module
*
* 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/)
* 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)
@ -35,7 +35,7 @@
*
* CONTRIBUTORS:
* David Reid (github: @mackron) (Nov. 2017):
* - Complete port to mini_al library
* - Complete port to miniaudio library
*
* Joshua Reisenauer (github: @kd7tck) (2015)
* - XM audio module support (jar_xm)
@ -77,11 +77,9 @@
#include "utils.h" // Required for: fopen() Android mapping
#endif
#define MAL_NO_SDL
#define MAL_NO_JACK
#define MAL_NO_OPENAL
#define MINI_AL_IMPLEMENTATION
#include "external/mini_al.h" // mini_al audio library
#define MA_NO_JACK
#define MINIAUDIO_IMPLEMENTATION
#include "external/miniaudio.h" // miniaudio library
#undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro
#include <stdlib.h> // Required for: malloc(), free()
@ -208,9 +206,9 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo
#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_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
typedef struct rAudioBuffer rAudioBuffer;
struct rAudioBuffer {
mal_dsp dsp; // Required for format conversion
ma_pcm_converter dsp; // Required for format conversion
float volume;
float pitch;
bool playing;
@ -239,26 +237,26 @@ struct rAudioBuffer {
// NOTE: This system should probably be redesigned
#define AudioBuffer rAudioBuffer
// mini_al global variables
static mal_context context;
static mal_device device;
static mal_mutex audioLock;
static bool isAudioInitialized = MAL_FALSE;
// miniaudio global variables
static ma_context context;
static ma_device device;
static ma_mutex audioLock;
static bool isAudioInitialized = MA_FALSE;
static float masterVolume = 1.0f;
// Audio buffers are tracked in a linked list
static AudioBuffer *firstAudioBuffer = NULL;
static AudioBuffer *lastAudioBuffer = NULL;
// mini_al functions declaration
static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message);
static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut);
static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData);
static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume);
// miniaudio functions declaration
static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
static ma_uint32 OnAudioBufferDSPRead(ma_pcm_converter *pDSP, void *pFramesOut, ma_uint32 frameCount, void *pUserData);
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume);
// AudioBuffer management functions declaration
// 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);
bool IsAudioBufferPlaying(AudioBuffer *audioBuffer);
void PlayAudioBuffer(AudioBuffer *audioBuffer);
@ -270,35 +268,34 @@ void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch);
void TrackAudioBuffer(AudioBuffer *audioBuffer);
void UntrackAudioBuffer(AudioBuffer *audioBuffer);
// 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)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
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.
(void)pDevice;
// 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
// 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)
{
// Ignore stopped or paused sounds.
if (!audioBuffer->playing || audioBuffer->paused) continue;
mal_uint32 framesRead = 0;
ma_uint32 framesRead = 0;
for (;;)
{
if (framesRead > frameCount)
@ -310,21 +307,21 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
if (framesRead == frameCount) break;
// Just read as much data as we can from the stream.
mal_uint32 framesToRead = (frameCount - framesRead);
ma_uint32 framesToRead = (frameCount - framesRead);
while (framesToRead > 0)
{
float tempBuffer[1024]; // 512 frames for stereo.
mal_uint32 framesToReadRightNow = framesToRead;
ma_uint32 framesToReadRightNow = framesToRead;
if (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)
{
float *framesOut = (float *)pFramesOut + (framesRead*device.channels);
float *framesOut = (float *)pFramesOut + (framesRead*device.playback.channels);
float *framesIn = tempBuffer;
MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
@ -357,18 +354,16 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
}
}
mal_mutex_unlock(&audioLock);
return frameCount; // We always output the same number of frames that were originally requested.
ma_mutex_unlock(&audioLock);
}
// 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;
mal_uint32 subBufferSizeInFrames = (audioBuffer->bufferSizeInFrames > 1)? audioBuffer->bufferSizeInFrames/2 : audioBuffer->bufferSizeInFrames;
mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
ma_uint32 subBufferSizeInFrames = (audioBuffer->bufferSizeInFrames > 1)? audioBuffer->bufferSizeInFrames/2 : audioBuffer->bufferSizeInFrames;
ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
if (currentSubBufferIndex > 1)
{
@ -381,10 +376,10 @@ static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, voi
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
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.
mal_uint32 framesRead = 0;
ma_uint32 framesRead = 0;
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;
}
mal_uint32 totalFramesRemaining = (frameCount - framesRead);
ma_uint32 totalFramesRemaining = (frameCount - framesRead);
if (totalFramesRemaining == 0) break;
mal_uint32 framesRemainingInOutputBuffer;
ma_uint32 framesRemainingInOutputBuffer;
if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
{
framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
}
else
{
mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
ma_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
}
mal_uint32 framesToRead = totalFramesRemaining;
ma_uint32 framesToRead = totalFramesRemaining;
if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
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.
mal_uint32 totalFramesRemaining = (frameCount - framesRead);
ma_uint32 totalFramesRemaining = (frameCount - framesRead);
if (totalFramesRemaining > 0)
{
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.
// 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);
const float *frameIn = framesIn + (iFrame*device.channels);
float *frameOut = framesOut + (iFrame*device.playback.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)
{
// Context.
mal_context_config contextConfig = mal_context_config_init(OnLog);
mal_result result = mal_context_init(NULL, 0, &contextConfig, &context);
if (result != MAL_SUCCESS)
ma_context_config contextConfig = ma_context_config_init();
contextConfig.logCallback = OnLog;
ma_result result = ma_context_init(NULL, 0, &contextConfig, &context);
if (result != MA_SUCCESS)
{
TraceLog(LOG_ERROR, "Failed to initialize audio context");
return;
}
// 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);
if (result != MAL_SUCCESS)
result = ma_device_init(&context, &config, &device);
if (result != MA_SUCCESS)
{
TraceLog(LOG_ERROR, "Failed to initialize audio playback device");
mal_context_uninit(&context);
ma_context_uninit(&context);
return;
}
// 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.
result = mal_device_start(&device);
if (result != MAL_SUCCESS)
result = ma_device_start(&device);
if (result != MA_SUCCESS)
{
TraceLog(LOG_ERROR, "Failed to start audio playback device");
mal_device_uninit(&device);
mal_context_uninit(&context);
ma_device_uninit(&device);
ma_context_uninit(&context);
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
// 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");
mal_device_uninit(&device);
mal_context_uninit(&context);
ma_device_uninit(&device);
ma_context_uninit(&context);
return;
}
TraceLog(LOG_INFO, "Audio device initialized successfully: %s", device.name);
TraceLog(LOG_INFO, "Audio backend: mini_al / %s", mal_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 channels: %d -> %d", device.channels, device.internalChannels);
TraceLog(LOG_INFO, "Audio sample rate: %d -> %d", device.sampleRate, device.internalSampleRate);
TraceLog(LOG_INFO, "Audio buffer size: %d", device.bufferSizeInFrames);
isAudioInitialized = MAL_TRUE;
TraceLog(LOG_INFO, "Audio device initialized successfully");
TraceLog(LOG_INFO, "Audio backend: miniaudio / %s", ma_get_backend_name(context.backend));
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.playback.channels, device.playback.internalChannels);
TraceLog(LOG_INFO, "Audio sample rate: %d -> %d", device.sampleRate, device.playback.internalSampleRate);
TraceLog(LOG_INFO, "Audio buffer size: %d", device.playback.internalBufferSizeInFrames);
isAudioInitialized = MA_TRUE;
}
// Close the audio device for all contexts
@ -533,9 +538,9 @@ void CloseAudioDevice(void)
return;
}
mal_mutex_uninit(&audioLock);
mal_device_uninit(&device);
mal_context_uninit(&context);
ma_mutex_uninit(&audioLock);
ma_device_uninit(&device);
ma_context_uninit(&context);
TraceLog(LOG_INFO, "Audio device closed successfully");
}
@ -560,9 +565,9 @@ void SetMasterVolume(float volume)
//----------------------------------------------------------------------------------
// 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)
{
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.
mal_dsp_config dspConfig;
ma_pcm_converter_config dspConfig;
memset(&dspConfig, 0, sizeof(dspConfig));
dspConfig.formatIn = 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.onRead = OnAudioBufferDSPRead;
dspConfig.pUserData = audioBuffer;
dspConfig.allowDynamicSampleRate = MAL_TRUE; // <-- Required for pitch shifting.
mal_result resultMAL = mal_dsp_init(&dspConfig, &audioBuffer->dsp);
if (resultMAL != MAL_SUCCESS)
dspConfig.allowDynamicSampleRate = MA_TRUE; // <-- Required for pitch shifting.
ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp);
if (result != MA_SUCCESS)
{
TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to create data conversion pipeline");
free(audioBuffer);
return NULL;
}
audioBuffer->volume = 1;
audioBuffer->pitch = 1;
audioBuffer->playing = 0;
audioBuffer->paused = 0;
audioBuffer->looping = 0;
audioBuffer->volume = 1.0f;
audioBuffer->pitch = 1.0f;
audioBuffer->playing = false;
audioBuffer->paused = false;
audioBuffer->looping = false;
audioBuffer->usage = usage;
audioBuffer->bufferSizeInFrames = bufferSizeInFrames;
audioBuffer->frameCursorPos = 0;
@ -696,7 +702,7 @@ void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume)
{
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "SetAudioBufferVolume() : No audio buffer");
TraceLog(LOG_WARNING, "SetAudioBufferVolume() : No audio buffer");
return;
}
@ -708,24 +714,24 @@ void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch)
{
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "SetAudioBufferPitch() : No audio buffer");
TraceLog(LOG_WARNING, "SetAudioBufferPitch() : No audio buffer");
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
// 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;
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
void TrackAudioBuffer(AudioBuffer *audioBuffer)
{
mal_mutex_lock(&audioLock);
ma_mutex_lock(&audioLock);
{
if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer;
@ -738,13 +744,13 @@ void TrackAudioBuffer(AudioBuffer *audioBuffer)
lastAudioBuffer = audioBuffer;
}
mal_mutex_unlock(&audioLock);
ma_mutex_unlock(&audioLock);
}
// Untrack audio buffer from linked list
void UntrackAudioBuffer(AudioBuffer *audioBuffer)
{
mal_mutex_lock(&audioLock);
ma_mutex_lock(&audioLock);
{
if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next;
@ -757,7 +763,7 @@ void UntrackAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->next = NULL;
}
mal_mutex_unlock(&audioLock);
ma_mutex_unlock(&audioLock);
}
//----------------------------------------------------------------------------------
@ -828,7 +834,7 @@ Sound LoadSoundFromWave(Wave wave)
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:
//
// 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.
// 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));
mal_uint32 frameCountIn = wave.sampleCount/wave.channels;
ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32));
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");
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");
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");
sound.audioBuffer = audioBuffer;
@ -885,7 +891,7 @@ void UpdateSound(Sound sound, const void *data, int samplesCount)
StopAudioBuffer(audioBuffer);
// 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
@ -999,12 +1005,12 @@ void SetSoundPitch(Sound sound, float pitch)
// Convert wave data to desired format
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));
mal_format formatOut = (( sampleSize == 8)? mal_format_u8 : (( 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));
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)
{
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));
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)
{
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,
// // just make sure to play again on window restore
// if (IsMusicPlaying(music)) PlayMusicStream(music);
mal_uint32 frameCursorPos = audioBuffer->frameCursorPos;
ma_uint32 frameCursorPos = audioBuffer->frameCursorPos;
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
}
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.
unsigned int periodSize = device.bufferSizeInFrames/device.periods;
unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods;
unsigned int subBufferSize = AUDIO_BUFFER_SIZE;
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])
{
mal_uint32 subBufferToUpdate;
ma_uint32 subBufferToUpdate;
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;
}
mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
ma_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
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.
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);
// Any leftover frames should be filled with zeros.
mal_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
if (leftoverFrameCount > 0)
{

View File

@ -11,7 +11,7 @@
* - Manage raw audio context
*
* 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/)
* 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)

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 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 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
// 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 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 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 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
@ -1564,9 +1566,9 @@ RLAPI Socket *SocketAccept(Socket *server, SocketConfig *config);
RLAPI int SocketSetChannel(Socket *socket, int channel, const IPAddress *address);
RLAPI void SocketUnsetChannel(Socket *socket, int channel);
// UDP DataPacket API
RLAPI SocketDataPacket *AllocPacket(int size);
RLAPI int ResizePacket(SocketDataPacket *packet, int newsize);
// UDP DataPacket API
RLAPI SocketDataPacket *AllocPacket(int size);
RLAPI int ResizePacket(SocketDataPacket *packet, int newsize);
RLAPI void FreePacket(SocketDataPacket *packet);
RLAPI SocketDataPacket** AllocPacketList(int count, int size);
RLAPI void FreePacketList(SocketDataPacket **packets);
@ -1612,4 +1614,4 @@ uint64_t PacketRead64(Packet *packet);
}
#endif
#endif // RAYLIB_H
#endif // RAYLIB_H

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_DISTORTION_SHADER
#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
#include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on LoadText()]

View File

@ -1299,8 +1299,8 @@ void SocketUnsetChannel(Socket *socket, int channel)
}
}
/* Allocate/free a single UDP packet 'size' bytes long.
The new packet is returned, or NULL if the function ran out of memory.
/* Allocate/free a single UDP packet 'size' bytes long.
The new packet is returned, or NULL if the function ran out of memory.
*/
SocketDataPacket *AllocPacket(int size)
{
@ -1349,10 +1349,10 @@ void FreePacket(SocketDataPacket *packet)
}
}
/* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
each 'size' bytes long.
A pointer to the packet array is returned, or NULL if the function ran out
of memory.
/* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
each 'size' bytes long.
A pointer to the packet array is returned, or NULL if the function ran out
of memory.
*/
SocketDataPacket **AllocPacketList(int howmany, int size)
{

View File

@ -181,6 +181,15 @@ static Image LoadASTC(const char *fileName); // Load ASTC file
Image LoadImage(const char *fileName)
{
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 ((IsFileExtension(fileName, ".png"))
@ -207,6 +216,7 @@ Image LoadImage(const char *fileName)
#endif
)
{
#if defined(STBI_REQUIRED)
int imgWidth = 0;
int imgHeight = 0;
int imgBpp = 0;
@ -229,6 +239,7 @@ Image LoadImage(const char *fileName)
else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8;
else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8;
}
#endif
}
#if defined(SUPPORT_FILEFORMAT_HDR)
else if (IsFileExtension(fileName, ".hdr"))
@ -729,6 +740,20 @@ Image GetTextureData(Texture2D texture)
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
// NOTE: pixels data must match texture.format
void UpdateTexture(Texture2D texture, const void *pixels)
@ -1157,8 +1182,6 @@ void ImageAlphaPremultiply(Image *image)
ImageFormat(image, prevFormat);
}
#if defined(SUPPORT_IMAGE_MANIPULATION)
// Load cubemap from image, multiple image cubemap layouts supported
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
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
if ((newWidth != image->width) || (newHeight != image->height))
{
if ((newWidth > image->width) && (newHeight > image->height))
{
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 };
if ((newWidth > image->width) && (newHeight > image->height))
{
ImageDraw(&imTemp, *image, srcRec, dstRec);
ImageFormat(&imTemp, image->format);
UnloadImage(*image);
*image = imTemp;
}
else
{
// 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
// 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"
#if defined(PLATFORM_ANDROID)

View File

@ -26,7 +26,7 @@
# Define required raylib variables
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
PLATFORM ?= PLATFORM_DESKTOP
RAYLIB_PATH = ../..
RAYLIB_PATH ?= ../..
PROJECT_NAME ?= advance_game
# 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)
PLATFORM_OS=LINUX
endif
ifeq ($(UNAMEOS),FreeBSD)
ifeq ($(UNAMEOS),FreeBSD)
PLATFORM_OS=BSD
endif
ifeq ($(UNAMEOS),OpenBSD)
@ -209,7 +209,7 @@ endif
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),FREEBSD)
ifeq ($(PLATFORM_OS),BSD)
INCLUDE_PATHS += -I/usr/local/include
LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif
@ -249,8 +249,8 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
endif
ifeq ($(PLATFORM_OS),FREEBSD)
# Libraries for FreeBSD desktop compiling
ifeq ($(PLATFORM_OS),BSD)
# Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
# NOTE: Required packages: mesa-libs
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)
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
# 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)
# 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
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)
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
# 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)
# 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
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)
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
# 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)
# 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
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a