From f1bcfc1352f73b9da98601f6b67cd15853b1cb8f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Nov 2016 12:14:55 +0100 Subject: Corrected bug on GenTextureMipmaps() texture.mipmaps value needs to be updated, so, texture must be passed by reference instead of by value --- src/raylib.h | 2 +- src/rlgl.c | 30 ++++++++++++++++++------------ src/rlgl.h | 2 +- src/textures.c | 8 ++++---- 4 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/raylib.h b/src/raylib.h index 6d67051e..d28b07a3 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -802,7 +802,7 @@ RLAPI void ImageColorInvert(Image *image); RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) -RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture +RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture RLAPI void SetTextureFilter(Texture2D texture, int filterMode); // Set texture scaling filter mode RLAPI void SetTextureWrap(Texture2D texture, int wrapMode); // Set texture wrapping mode diff --git a/src/rlgl.c b/src/rlgl.c index b567f8fd..629d7967 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1719,15 +1719,15 @@ void rlglUpdateTexture(unsigned int id, int width, int height, int format, void } // Generate mipmap data for selected texture -void rlglGenerateMipmaps(Texture2D texture) +void rlglGenerateMipmaps(Texture2D *texture) { - glBindTexture(GL_TEXTURE_2D, texture.id); + glBindTexture(GL_TEXTURE_2D, texture->id); // Check if texture is power-of-two (POT) bool texIsPOT = false; - if (((texture.width > 0) && ((texture.width & (texture.width - 1)) == 0)) && - ((texture.height > 0) && ((texture.height & (texture.height - 1)) == 0))) texIsPOT = true; + if (((texture->width > 0) && ((texture->width & (texture->width - 1)) == 0)) && + ((texture->height > 0) && ((texture->height & (texture->height - 1)) == 0))) texIsPOT = true; if ((texIsPOT) || (npotSupported)) { @@ -1737,13 +1737,13 @@ void rlglGenerateMipmaps(Texture2D texture) // NOTE: data size is reallocated to fit mipmaps data // NOTE: CPU mipmap generation only supports RGBA 32bit data - int mipmapCount = GenerateMipmaps(data, texture.width, texture.height); + int mipmapCount = GenerateMipmaps(data, texture->width, texture->height); - int size = texture.width*texture.height*4; // RGBA 32bit only + int size = texture->width*texture->height*4; // RGBA 32bit only int offset = size; - int mipWidth = texture.width/2; - int mipHeight = texture.height/2; + int mipWidth = texture->width/2; + int mipHeight = texture->height/2; // Load the mipmaps for (int level = 1; level < mipmapCount; level++) @@ -1757,23 +1757,29 @@ void rlglGenerateMipmaps(Texture2D texture) mipHeight /= 2; } - TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", texture.id); + TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", texture->id); // NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data free(data); + texture->mipmaps = mipmapCount + 1; #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) //glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorythm: GL_FASTEST, GL_NICEST, GL_DONT_CARE glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically - TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture.id); + TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture->id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps + + #define MIN(a,b) (((a)<(b))?(a):(b)) + #define MAX(a,b) (((a)>(b))?(a):(b)) + + texture->mipmaps = 1 + floor(log2(MAX(texture->width, texture->height))); #endif } - else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture.id); + else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/src/rlgl.h b/src/rlgl.h index 7d328a52..bc12db0f 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -371,7 +371,7 @@ void rlglLoadExtensions(void *loader); // Load OpenGL extensions unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data -void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture +void rlglGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer) diff --git a/src/textures.c b/src/textures.c index af59d035..126adad3 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1516,14 +1516,14 @@ void ImageColorBrightness(Image *image, int brightness) } // Generate GPU mipmaps for a texture -void GenTextureMipmaps(Texture2D texture) +void GenTextureMipmaps(Texture2D *texture) { #if PLATFORM_WEB - int potWidth = GetNextPOT(texture.width); - int potHeight = GetNextPOT(texture.height); + int potWidth = GetNextPOT(texture->width); + int potHeight = GetNextPOT(texture->height); // Check if texture is POT - if ((potWidth != texture.width) || (potHeight != texture.height)) + if ((potWidth != texture->width) || (potHeight != texture->height)) { TraceLog(WARNING, "Limited NPOT support, no mipmaps available for NPOT textures"); } -- cgit v1.2.3 From b8481369f7209804d70220a29ba2efbd6171d7a9 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Nov 2016 12:15:58 +0100 Subject: Reviewed some lua examples and added new ones --- examples/audio_module_playing.lua | 31 ++----- examples/core_3d_camera_first_person.lua | 11 ++- examples/core_3d_camera_free.lua | 11 +-- examples/core_3d_picking.lua | 8 +- examples/core_input_gamepad.lua | 134 +++++++++++++++++++++++++++---- examples/core_world_screen.lua | 7 +- examples/models_billboard.lua | 9 +-- examples/models_cubicmap.lua | 8 +- examples/models_heightmap.lua | 7 +- examples/rlua_execute_file.c | 4 +- examples/shaders_custom_uniform.lua | 14 ++-- examples/shaders_model_shader.c | 4 +- examples/shaders_model_shader.lua | 6 +- examples/shaders_postprocessing.lua | 10 +-- examples/shaders_standard_lighting.lua | 10 +-- examples/text_bmfont_unordered.lua | 57 +++++++++++++ examples/text_ttf_loading.c | 16 ++-- examples/text_ttf_loading.lua | 118 +++++++++++++++++++++++++++ src/rlua.h | 77 +++++++++++------- 19 files changed, 402 insertions(+), 140 deletions(-) create mode 100644 examples/text_bmfont_unordered.lua create mode 100644 examples/text_ttf_loading.lua (limited to 'src') diff --git a/examples/audio_module_playing.lua b/examples/audio_module_playing.lua index 3c5ad641..7c675424 100644 --- a/examples/audio_module_playing.lua +++ b/examples/audio_module_playing.lua @@ -37,13 +37,6 @@ for i = MAX_CIRCLES, 1, -1 do circles[i].color = colors[GetRandomValue(1, 14)] end --- Load postprocessing bloom shader -local shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/bloom.fs") - --- Create a RenderTexture2D to be used for render to texture -local target = LoadRenderTexture(screenWidth, screenHeight) - local xm = LoadMusicStream("resources/audio/mini1111.xm") PlayMusicStream(xm) @@ -83,22 +76,11 @@ while not WindowShouldClose() do -- Detect window close button or ESC key --------------------------------------------------------------------------------------- BeginDrawing() - ClearBackground(BLACK) - - BeginTextureMode(target) -- Enable drawing to texture - - for i = MAX_CIRCLES, 1, -1 do - DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha)) - end - - EndTextureMode() -- End drawing to texture (now we have a texture available for next passes) + ClearBackground(RAYWHITE) - BeginShaderMode(shader) - - -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) - DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE) - - EndShaderMode() + for i = MAX_CIRCLES, 1, -1 do + DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha)) + end -- Draw time bar DrawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, LIGHTGRAY) @@ -111,10 +93,7 @@ end -- De-Initialization ------------------------------------------------------------------------------------------- -UnloadShader(shader) -- Unload shader -UnloadRenderTexture(target) -- Unload render texture - -UnloadMusicStream(xm) -- Unload music stream buffers from RAM +UnloadMusicStream(xm) -- Unload music stream buffers from RAM CloseAudioDevice() -- Close audio device (music streaming is automatically stopped) diff --git a/examples/core_3d_camera_first_person.lua b/examples/core_3d_camera_first_person.lua index 800c3c2a..22ccdc5c 100644 --- a/examples/core_3d_camera_first_person.lua +++ b/examples/core_3d_camera_first_person.lua @@ -19,7 +19,7 @@ local screenHeight = 450 InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person") -- Define the camera to look into our 3d world (position, target, up vector) -local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 60.0) +local camera = Camera(Vector3(4.0, 2.0, 4.0), Vector3(0.0, 1.8, 0.0), Vector3(0.0, 1.0, 0.0), 60.0) -- Generates some random columns local heights = {} @@ -34,17 +34,16 @@ end local playerPosition = Vector3(4.0, 2.0, 4.0) -- Define player position -SetCameraMode(CameraMode.FIRST_PERSON) -- Set a first person camera mode -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.FIRST_PERSON) -- Set a first person camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key +while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera, playerPosition = UpdateCameraPlayer(camera, playerPosition) -- Update camera and player position + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/core_3d_camera_free.lua b/examples/core_3d_camera_free.lua index 244aad6b..57fa7a12 100644 --- a/examples/core_3d_camera_free.lua +++ b/examples/core_3d_camera_free.lua @@ -18,26 +18,23 @@ InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free") -- Define the camera to look into our 3d world local camera = {} -camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position +camera.position = Vector3(10.0, 10.0, 10.0) -- Camera position camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target) camera.fovy = 45.0 -- Camera field-of-view Y local cubePosition = Vector3(0.0, 0.0, 0.0) -SetCameraMode(CameraMode.FREE) -- Set a free camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/core_3d_picking.lua b/examples/core_3d_picking.lua index 1adee67c..230f5756 100644 --- a/examples/core_3d_picking.lua +++ b/examples/core_3d_picking.lua @@ -30,18 +30,16 @@ local ray = Ray(Vector3(0, 0, 0), Vector3(0, 0, 0)) -- Picking line ray local collision = false -SetCameraMode(CameraMode.FREE) -- Set a free camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then -- NOTE: This function is NOT WORKING properly! diff --git a/examples/core_input_gamepad.lua b/examples/core_input_gamepad.lua index 78d9b84e..ade3f00f 100644 --- a/examples/core_input_gamepad.lua +++ b/examples/core_input_gamepad.lua @@ -19,8 +19,8 @@ local screenHeight = 450 InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input") -local ballPosition = Vector2(screenWidth/2, screenHeight/2) -local gamepadMovement = Vector2(0, 0) +local texPs3Pad = LoadTexture("resources/ps3.png") +local texXboxPad = LoadTexture("resources/xbox.png") SetTargetFPS(60) -- Set target frames-per-second ------------------------------------------------------------------------------------------- @@ -29,18 +29,7 @@ SetTargetFPS(60) -- Set target frames-per-second while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - if (IsGamepadAvailable(GAMEPAD.PLAYER1)) then - gamepadMovement.x = GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_X) - gamepadMovement.y = GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_Y) - - ballPosition.x = ballPosition.x + gamepadMovement.x - ballPosition.y = ballPosition.y - gamepadMovement.y - - if (IsGamepadButtonPressed(GAMEPAD.PLAYER1, GAMEPAD.BUTTON_A)) then - ballPosition.x = screenWidth/2 - ballPosition.y = screenHeight/2 - end - end + -- ... --------------------------------------------------------------------------------------- -- Draw @@ -49,9 +38,117 @@ while not WindowShouldClose() do -- Detect window close button or ESC key ClearBackground(RAYWHITE) - DrawText("move the ball with gamepad", 10, 10, 20, DARKGRAY) + if (IsGamepadAvailable(GAMEPAD.PLAYER1)) then + DrawText(string.format("GP1: %s", GetGamepadName(GAMEPAD.PLAYER1)), 10, 10, 10, BLACK) + + if (IsGamepadName(GAMEPAD.PLAYER1, "Xbox 360 Controller")) then + DrawTexture(texXboxPad, 0, 0, DARKGRAY) + + -- Draw buttons: xbox home + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_HOME)) then DrawCircle(394, 89, 19, RED) end + + -- Draw buttons: basic + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_START)) then DrawCircle(436, 150, 9, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_SELECT)) then DrawCircle(352, 150, 9, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_X)) then DrawCircle(501, 151, 15, BLUE) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_A)) then DrawCircle(536, 187, 15, LIME) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_B)) then DrawCircle(572, 151, 15, MAROON) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_Y)) then DrawCircle(536, 115, 15, GOLD) end + + -- Draw buttons: d-pad + DrawRectangle(317, 202, 19, 71, BLACK) + DrawRectangle(293, 228, 69, 19, BLACK) + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_UP)) then DrawRectangle(317, 202, 19, 26, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_DOWN)) then DrawRectangle(317, 202 + 45, 19, 26, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_LEFT)) then DrawRectangle(292, 228, 25, 19, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_RIGHT)) then DrawRectangle(292 + 44, 228, 26, 19, RED) end + + -- Draw buttons: left-right back + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_LB)) then DrawCircle(259, 61, 20, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_RB)) then DrawCircle(536, 61, 20, RED) end + + -- Draw axis: left joystick + DrawCircle(259, 152, 39, BLACK) + DrawCircle(259, 152, 34, LIGHTGRAY) + DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_X)*20), + 152 - (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_Y)*20), 25, BLACK) + + -- Draw axis: right joystick + DrawCircle(461, 237, 38, BLACK) + DrawCircle(461, 237, 33, LIGHTGRAY) + DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RIGHT_X)*20), + 237 - (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RIGHT_Y)*20), 25, BLACK) - DrawCircleV(ballPosition, 50, MAROON) + -- Draw axis: left-right triggers + DrawRectangle(170, 30, 15, 70, GRAY) + DrawRectangle(604, 30, 15, 70, GRAY) + DrawRectangle(170, 30, 15, (((1.0 + GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LT))/2.0)*70), RED) + DrawRectangle(604, 30, 15, (((1.0 + GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RT))/2.0)*70), RED) + + --DrawText(FormatText("Xbox axis LT: %02.02f", GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LT)), 10, 40, 10, BLACK) + --DrawText(FormatText("Xbox axis RT: %02.02f", GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RT)), 10, 60, 10, BLACK) + elseif (IsGamepadName(GAMEPAD.PLAYER1, "PLAYSTATION(R)3 Controller")) then + DrawTexture(texPs3Pad, 0, 0, DARKGRAY) + + -- Draw buttons: ps + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_PS)) then DrawCircle(396, 222, 13, RED) end + + -- Draw buttons: basic + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_SELECT)) then DrawRectangle(328, 170, 32, 13, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_START)) then DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_TRIANGLE)) then DrawCircle(557, 144, 13, LIME) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_CIRCLE)) then DrawCircle(586, 173, 13, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_CROSS)) then DrawCircle(557, 203, 13, VIOLET) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_SQUARE)) then DrawCircle(527, 173, 13, PINK) end + + -- Draw buttons: d-pad + DrawRectangle(225, 132, 24, 84, BLACK) + DrawRectangle(195, 161, 84, 25, BLACK) + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_UP)) then DrawRectangle(225, 132, 24, 29, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_DOWN)) then DrawRectangle(225, 132 + 54, 24, 30, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_LEFT)) then DrawRectangle(195, 161, 30, 25, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_RIGHT)) then DrawRectangle(195 + 54, 161, 30, 25, RED) end + + -- Draw buttons: left-right back buttons + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_L1)) then DrawCircle(239, 82, 20, RED) end + if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_R1)) then DrawCircle(557, 82, 20, RED) end + + -- Draw axis: left joystick + DrawCircle(319, 255, 35, BLACK) + DrawCircle(319, 255, 31, LIGHTGRAY) + DrawCircle(319 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_LEFT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_LEFT_Y)*20), 25, BLACK) + + -- Draw axis: right joystick + DrawCircle(475, 255, 35, BLACK) + DrawCircle(475, 255, 31, LIGHTGRAY) + DrawCircle(475 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_RIGHT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_RIGHT_Y)*20), 25, BLACK) + + -- Draw axis: left-right triggers + DrawRectangle(169, 48, 15, 70, GRAY) + DrawRectangle(611, 48, 15, 70, GRAY) + DrawRectangle(169, 48, 15, (((1.0 - GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_L2))/2.0)*70), RED) + DrawRectangle(611, 48, 15, (((1.0 - GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_R2))/2.0)*70), RED) + else + DrawText("- GENERIC GAMEPAD -", 280, 180, 20, GRAY) + + -- TODO: Draw generic gamepad + end + + DrawText(string.format("DETECTED AXIS [%i]:", GetGamepadAxisCount(GAMEPAD.PLAYER1)), 10, 50, 10, MAROON) + + for i = 1, GetGamepadAxisCount(GAMEPAD.PLAYER1) do -- Iterate along all the rectangles + DrawText(string.format("AXIS %i: %.02f", i, GetGamepadAxisMovement(GAMEPAD.PLAYER1, i)), 20, 70 + 20*i, 10, DARKGRAY) + end + + if (GetGamepadButtonPressed() ~= -1) then DrawText(string.format("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED) + else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY) end + else + DrawText("GP1: NOT DETECTED", 10, 10, 10, GRAY) + + DrawTexture(texXboxPad, 0, 0, LIGHTGRAY) + end EndDrawing() --------------------------------------------------------------------------------------- @@ -59,5 +156,8 @@ end -- De-Initialization ------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context +UnloadTexture(texPs3Pad) -- Unload gamepad texture +UnloadTexture(texXboxPad) -- Unload gamepad texture + +CloseWindow() -- Close window and OpenGL context ------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_world_screen.lua b/examples/core_world_screen.lua index 51f2cdbf..48b617dd 100644 --- a/examples/core_world_screen.lua +++ b/examples/core_world_screen.lua @@ -23,10 +23,7 @@ local cubePosition = Vector3(0.0, 0.0, 0.0) local cubeScreenPosition = Vector2(0, 0) -SetCameraMode(CameraMode.FREE) -- Set a free camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ---------------------------------------------------------------------------------------- @@ -35,7 +32,7 @@ SetTargetFPS(60) -- Set our game to run at 60 frames-per- while not WindowShouldClose() do -- Detect window close button or ESC key -- Update ------------------------------------------------------------------------------------ - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera -- Calculate cube screen space position (with a little offset to be in top) cubeScreenPosition = GetWorldToScreen(Vector3(cubePosition.x, cubePosition.y + 2.5, cubePosition.z), camera) diff --git a/examples/models_billboard.lua b/examples/models_billboard.lua index 457198e6..9d81f6ce 100644 --- a/examples/models_billboard.lua +++ b/examples/models_billboard.lua @@ -22,19 +22,16 @@ local camera = Camera(Vector3(5.0, 4.0, 5.0), Vector3(0.0, 2.0, 0.0), Vector3(0. local bill = LoadTexture("resources/billboard.png") -- Our texture billboard local billPosition = Vector3(0.0, 2.0, 0.0) -- Position where draw billboard -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/models_cubicmap.lua b/examples/models_cubicmap.lua index bae3bac2..79faafc9 100644 --- a/examples/models_cubicmap.lua +++ b/examples/models_cubicmap.lua @@ -31,18 +31,16 @@ local mapPosition = Vector3(-16.0, 0.0, -8.0) -- Set model position UnloadImage(image) -- Unload cubesmap image from RAM, already uploaded to VRAM -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our custom camera position -SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/models_heightmap.lua b/examples/models_heightmap.lua index 4240f8b7..efcbfb4b 100644 --- a/examples/models_heightmap.lua +++ b/examples/models_heightmap.lua @@ -27,17 +27,16 @@ local mapPosition = Vector3(-8.0, 0.0, -8.0) -- Set model position (d UnloadImage(image) -- Unload heightmap image from RAM, already uploaded to VRAM -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our custom camera position +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ---------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/rlua_execute_file.c b/examples/rlua_execute_file.c index f2d7114e..a91ce42f 100644 --- a/examples/rlua_execute_file.c +++ b/examples/rlua_execute_file.c @@ -66,6 +66,8 @@ int main() // ExecuteLuaFile("text_format_text.lua"); // OK! NOTE: Use lua string.format() instead of raylib FormatText() // ExecuteLuaFile("text_font_select.lua"); // OK! // ExecuteLuaFile("text_writing_anim.lua"); // OK! + // ExecuteLuaFile("text_ttf_loading.lua"); // ISSUE: Attempt to index a SpriteFont value (local 'font') + // ExecuteLuaFile("text_bmfont_unordered.lua"); // OK! // ExecuteLuaFile("models_geometric_shapes.lua"); // OK! // ExecuteLuaFile("models_box_collisions.lua"); // OK! // ExecuteLuaFile("models_billboard.lua"); // OK! @@ -81,7 +83,7 @@ int main() // ExecuteLuaFile("audio_music_stream.lua"); // OK! // ExecuteLuaFile("audio_module_playing.lua"); // OK! // ExecuteLuaFile("audio_raw_stream.lua"); // ERROR: UpdateAudioStream() - + // De-Initialization //-------------------------------------------------------------------------------------- CloseLuaDevice(); // Close Lua device and free resources diff --git a/examples/shaders_custom_uniform.lua b/examples/shaders_custom_uniform.lua index 3a8bbae5..dafd3b84 100644 --- a/examples/shaders_custom_uniform.lua +++ b/examples/shaders_custom_uniform.lua @@ -47,15 +47,13 @@ local swirlCenter = { screenWidth/2, screenHeight/2 } local target = LoadRenderTexture(screenWidth, screenHeight) -- Setup orbital camera -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key +while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- local mousePosition = GetMousePosition() @@ -66,7 +64,7 @@ while not WindowShouldClose() do -- Detect window close button or ESC key -- Send new value to the shader to be used on drawing SetShaderValue(shader, swirlCenterLoc, swirlCenter) - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw @@ -75,13 +73,13 @@ while not WindowShouldClose() do -- Detect window close button or ESC key ClearBackground(RAYWHITE) - BeginTextureMode(target) -- Enable drawing to texture + BeginTextureMode(target) -- Enable drawing to texture Begin3dMode(camera) DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - DrawGrid(10, 1.0) -- Draw a grid + DrawGrid(10, 1.0) -- Draw a grid End3dMode() diff --git a/examples/shaders_model_shader.c b/examples/shaders_model_shader.c index 26de4922..51e9c1b3 100644 --- a/examples/shaders_model_shader.c +++ b/examples/shaders_model_shader.c @@ -42,7 +42,7 @@ int main() Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - SetCameraMode(camera, CAMERA_FREE); // Set an orbital camera mode + SetCameraMode(camera, CAMERA_FREE); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -52,7 +52,7 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdateCamera(&camera); // Update internal camera and our camera + UpdateCamera(&camera); // Update camera //---------------------------------------------------------------------------------- // Draw diff --git a/examples/shaders_model_shader.lua b/examples/shaders_model_shader.lua index d1436a7e..38f0fd30 100644 --- a/examples/shaders_model_shader.lua +++ b/examples/shaders_model_shader.lua @@ -39,9 +39,7 @@ dwarf.material.texDiffuse = texture -- Bind texture to model local position = Vector3(0.0, 0.0, 0.0) -- Set model position -- Setup orbital camera -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- @@ -50,7 +48,7 @@ SetTargetFPS(60) -- Set our game to run at 60 frames-pe while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/shaders_postprocessing.lua b/examples/shaders_postprocessing.lua index f20f31ec..7dfac816 100644 --- a/examples/shaders_postprocessing.lua +++ b/examples/shaders_postprocessing.lua @@ -41,18 +41,16 @@ local shader = LoadShader("resources/shaders/glsl330/base.vs", local target = LoadRenderTexture(screenWidth, screenHeight) -- Setup orbital camera -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key +while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/shaders_standard_lighting.lua b/examples/shaders_standard_lighting.lua index 2f3700ff..1d4dcfcf 100644 --- a/examples/shaders_standard_lighting.lua +++ b/examples/shaders_standard_lighting.lua @@ -60,18 +60,16 @@ pointLight.diffuse = Color(100, 100, 255, 255) pointLight.radius = 3.0 -- Setup orbital camera -SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode -SetCameraPosition(camera.position) -- Set internal camera position to match our camera position -SetCameraTarget(camera.target) -- Set internal camera target to match our camera target +SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second +SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ------------------------------------------------------------------------------------------- -- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key +while not WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update internal camera and our camera + camera = UpdateCamera(camera) -- Update camera --------------------------------------------------------------------------------------- -- Draw diff --git a/examples/text_bmfont_unordered.lua b/examples/text_bmfont_unordered.lua new file mode 100644 index 00000000..f324ca19 --- /dev/null +++ b/examples/text_bmfont_unordered.lua @@ -0,0 +1,57 @@ +------------------------------------------------------------------------------------------- +-- +-- raylib [text] example - BMFont unordered chars loading and drawing +-- +-- This example has been created using raylib 1.6 (www.raylib.com) +-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +-- +-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) +-- +------------------------------------------------------------------------------------------- + +-- Initialization +------------------------------------------------------------------------------------------- +local screenWidth = 800 +local screenHeight = 450 + +InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont unordered loading and drawing") + +-- NOTE: Using chars outside the [32..127] limits! +-- NOTE: If a character is not found in the font, it just renders a space +local msg = "ASCII extended characters:\n¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ\nÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæ\nçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + +-- NOTE: Loaded font has an unordered list of characters (chars in the range 32..255) +local font = LoadSpriteFont("resources/fonts/pixantiqua.fnt") -- BMFont (AngelCode) + +SetTargetFPS(60) +------------------------------------------------------------------------------------------- + +-- Main game loop +while not WindowShouldClose() do -- Detect window close button or ESC key + -- Update + --------------------------------------------------------------------------------------- + -- TODO: Update variables here... + --------------------------------------------------------------------------------------- + + -- Draw + --------------------------------------------------------------------------------------- + BeginDrawing() + + ClearBackground(RAYWHITE) + + DrawText("Font name: PixAntiqua", 40, 50, 20, GRAY) + DrawText(string.format("Font base size: %i", font.size), 40, 80, 20, GRAY) + DrawText(string.format("Font chars number: %i", font.numChars), 40, 110, 20, GRAY) + + DrawTextEx(font, msg, Vector2(40, 180), font.size, 0, MAROON) + + EndDrawing() + --------------------------------------------------------------------------------------- +end + +-- De-Initialization +------------------------------------------------------------------------------------------- +UnloadSpriteFont(font) -- AngelCode SpriteFont unloading + +CloseWindow() -- Close window and OpenGL context +------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_ttf_loading.c b/examples/text_ttf_loading.c index b614023f..918209dd 100644 --- a/examples/text_ttf_loading.c +++ b/examples/text_ttf_loading.c @@ -20,17 +20,22 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [text] example - ttf loading"); - const char msg1[50] = "TTF SpriteFont"; + const char msg[50] = "TTF SpriteFont"; // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) // TTF SpriteFont loading with custom generation parameters SpriteFont font = LoadSpriteFontTTF("resources/fonts/KAISG.ttf", 96, 0, 0); + + // Generate mipmap levels to use trilinear filtering + // NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR + GenTextureMipmaps(&font.texture); float fontSize = font.size; Vector2 fontPosition = { 40, screenHeight/2 + 50 }; Vector2 textSize; + SetTextureFilter(font.texture, FILTER_POINT); int currentFontFilter = 0; // FILTER_POINT int count = 0; @@ -59,12 +64,12 @@ int main() } else if (IsKeyPressed(KEY_THREE)) { - // NOTE: Trilinear filter not supported in font because there are not mipmap levels + // NOTE: Trilinear filter won't be noticed on 2D drawing SetTextureFilter(font.texture, FILTER_TRILINEAR); - //currentFontFilter = 2; + currentFontFilter = 2; } - textSize = MeasureTextEx(font, msg1, fontSize, 0); + textSize = MeasureTextEx(font, msg, fontSize, 0); if (IsKeyDown(KEY_LEFT)) fontPosition.x -= 10; else if (IsKeyDown(KEY_RIGHT)) fontPosition.x += 10; @@ -94,7 +99,7 @@ int main() DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, GRAY); DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, DARKGRAY); - DrawTextEx(font, msg1, fontPosition, fontSize, 0, BLACK); + DrawTextEx(font, msg, fontPosition, fontSize, 0, BLACK); // TODO: It seems texSize measurement is not accurate due to chars offsets... //DrawRectangleLines(fontPosition.x, fontPosition.y, textSize.x, textSize.y, RED); @@ -106,6 +111,7 @@ int main() if (currentFontFilter == 0) DrawText("POINT", 570, 400, 20, BLACK); else if (currentFontFilter == 1) DrawText("BILINEAR", 570, 400, 20, BLACK); + else if (currentFontFilter == 2) DrawText("TRILINEAR", 570, 400, 20, BLACK); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/text_ttf_loading.lua b/examples/text_ttf_loading.lua new file mode 100644 index 00000000..26443212 --- /dev/null +++ b/examples/text_ttf_loading.lua @@ -0,0 +1,118 @@ +------------------------------------------------------------------------------------------- +-- +-- raylib [text] example - TTF loading and usage +-- +-- This example has been created using raylib 1.6 (www.raylib.com) +-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +-- +-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) +-- +------------------------------------------------------------------------------------------- + +-- Initialization +------------------------------------------------------------------------------------------- +local screenWidth = 800; +local screenHeight = 450; + +InitWindow(screenWidth, screenHeight, "raylib [text] example - ttf loading") + +local msg = "TTF SpriteFont" + +-- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + +-- TTF SpriteFont loading with custom generation parameters +local font = LoadSpriteFontTTF("resources/fonts/KAISG.ttf", 96, 0, 0) + +-- Generate mipmap levels to use trilinear filtering +-- NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR +--font.texture = GenTextureMipmaps(font.texture) -- ISSUE: attempt to index a SpriteFont value (local 'font') + +local fontSize = font.size +local fontPosition = Vector2(40, screenHeight/2 + 50) +local textSize + +SetTextureFilter(font.texture, TextureFilter.POINT) +local currentFontFilter = 0 -- Default: FILTER_POINT + +local count = 0 +local droppedFiles + +SetTargetFPS(60) +------------------------------------------------------------------------------------------- + +-- Main game loop +while not WindowShouldClose() do -- Detect window close button or ESC key + -- Update + --------------------------------------------------------------------------------------- + fontSize = fontSize + GetMouseWheelMove()*4.0 + + -- Choose font texture filter method + if (IsKeyPressed(KEY.ONE)) then + SetTextureFilter(font.texture, TextureFilter.POINT) + currentFontFilter = 0 + elseif (IsKeyPressed(KEY.TWO)) then + SetTextureFilter(font.texture, TextureFilter.BILINEAR) + currentFontFilter = 1 + elseif (IsKeyPressed(KEY.THREE)) then + -- NOTE: Trilinear filter won't be noticed on 2D drawing + SetTextureFilter(font.texture, TextureFilter.TRILINEAR) + currentFontFilter = 2 + end + + textSize = MeasureTextEx(font, msg, fontSize, 0) + + if (IsKeyDown(KEY.LEFT)) then fontPosition.x = fontPosition.x - 10 + elseif (IsKeyDown(KEY.RIGHT)) then fontPosition.x = fontPosition.x + 10 + end + + -- Load a dropped TTF file dynamically (at current fontSize) + if (IsFileDropped()) then + droppedFiles = GetDroppedFiles() + count = #droppedFiles + + if (count == 1) then -- Only support one ttf file dropped + UnloadSpriteFont(font) + font = LoadSpriteFontTTF(droppedFiles[1], fontSize, 0, 0) + ClearDroppedFiles() + end + end + --------------------------------------------------------------------------------------- + + -- Draw + --------------------------------------------------------------------------------------- + BeginDrawing() + + ClearBackground(RAYWHITE) + + DrawText("Use mouse wheel to change font size", 20, 20, 10, GRAY) + DrawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, GRAY) + DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, GRAY) + DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, DARKGRAY) + + DrawTextEx(font, msg, fontPosition, fontSize, 0, BLACK) + + -- TODO: It seems texSize measurement is not accurate due to chars offsets... + --DrawRectangleLines(fontPosition.x, fontPosition.y, textSize.x, textSize.y, RED) + + DrawRectangle(0, screenHeight - 80, screenWidth, 80, LIGHTGRAY) + DrawText(string.format("Font size: %02.02f", fontSize), 20, screenHeight - 50, 10, DARKGRAY) + DrawText(string.format("Text size: [%02.02f, %02.02f]", textSize.x, textSize.y), 20, screenHeight - 30, 10, DARKGRAY) + DrawText("CURRENT TEXTURE FILTER:", 250, 400, 20, GRAY) + + if (currentFontFilter == 0) then DrawText("POINT", 570, 400, 20, BLACK) + elseif (currentFontFilter == 1) then DrawText("BILINEAR", 570, 400, 20, BLACK) + elseif (currentFontFilter == 2) then DrawText("TRILINEAR", 570, 400, 20, BLACK) + end + + EndDrawing() + --------------------------------------------------------------------------------------- +end + +-- De-Initialization +------------------------------------------------------------------------------------------- +UnloadSpriteFont(font) -- SpriteFont unloading + +ClearDroppedFiles() -- Clear internal buffers + +CloseWindow() -- Close window and OpenGL context +------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/rlua.h b/src/rlua.h index c801a328..961ed1c1 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -2105,8 +2105,9 @@ int lua_ImageColorBrightness(lua_State* L) int lua_GenTextureMipmaps(lua_State* L) { Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - GenTextureMipmaps(arg1); - return 0; + GenTextureMipmaps(&arg1); + LuaPush_Texture2D(L, arg1); + return 1; } int lua_SetTextureFilter(lua_State* L) @@ -4096,24 +4097,36 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("RIGHT_BUTTON", 1); LuaSetEnum("MIDDLE_BUTTON", 2); LuaEndEnum("MOUSE"); - + LuaStartEnum(); LuaSetEnum("PLAYER1", 0); LuaSetEnum("PLAYER2", 1); LuaSetEnum("PLAYER3", 2); LuaSetEnum("PLAYER4", 3); - LuaSetEnum("PS3_BUTTON_A", 2); - LuaSetEnum("PS3_BUTTON_B", 1); - LuaSetEnum("PS3_BUTTON_X", 3); - LuaSetEnum("PS3_BUTTON_Y", 4); - LuaSetEnum("PS3_BUTTON_R1", 7); - LuaSetEnum("PS3_BUTTON_R2", 5); + LuaSetEnum("PS3_BUTTON_TRIANGLE", 0); + LuaSetEnum("PS3_BUTTON_CIRCLE", 1); + LuaSetEnum("PS3_BUTTON_CROSS", 2); + LuaSetEnum("PS3_BUTTON_SQUARE", 3); LuaSetEnum("PS3_BUTTON_L1", 6); - LuaSetEnum("PS3_BUTTON_L2", 8); + LuaSetEnum("PS3_BUTTON_R1", 7); + LuaSetEnum("PS3_BUTTON_L2", 4); + LuaSetEnum("PS3_BUTTON_R2", 5); + LuaSetEnum("PS3_BUTTON_START", 8); LuaSetEnum("PS3_BUTTON_SELECT", 9); - LuaSetEnum("PS3_BUTTON_START", 10); - + LuaSetEnum("PS3_BUTTON_UP", 24); + LuaSetEnum("PS3_BUTTON_RIGHT", 25); + LuaSetEnum("PS3_BUTTON_DOWN", 26); + LuaSetEnum("PS3_BUTTON_LEFT", 27); + LuaSetEnum("PS3_BUTTON_PS", 12); + LuaSetEnum("PS3_AXIS_LEFT_X", 0); + LuaSetEnum("PS3_AXIS_LEFT_Y", 1); + LuaSetEnum("PS3_AXIS_RIGHT_X", 2); + LuaSetEnum("PS3_AXIS_RIGHT_Y", 5); + LuaSetEnum("PS3_AXIS_L2", 3); // [1..-1] (pressure-level) + LuaSetEnum("PS3_AXIS_R2", 4); // [1..-1] (pressure-level) + +// Xbox360 USB Controller Buttons LuaSetEnum("XBOX_BUTTON_A", 0); LuaSetEnum("XBOX_BUTTON_B", 1); LuaSetEnum("XBOX_BUTTON_X", 2); @@ -4122,25 +4135,26 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("XBOX_BUTTON_RB", 5); LuaSetEnum("XBOX_BUTTON_SELECT", 6); LuaSetEnum("XBOX_BUTTON_START", 7); - -#if defined(PLATFORM_RPI) - LuaSetEnum("XBOX_AXIS_DPAD_X", 7); - LuaSetEnum("XBOX_AXIS_DPAD_Y", 6); - LuaSetEnum("XBOX_AXIS_RIGHT_X", 3); - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 4); - LuaSetEnum("XBOX_AXIS_LT", 2); - LuaSetEnum("XBOX_AXIS_RT", 5); -#else LuaSetEnum("XBOX_BUTTON_UP", 10); + LuaSetEnum("XBOX_BUTTON_RIGHT", 11); LuaSetEnum("XBOX_BUTTON_DOWN", 12); LuaSetEnum("XBOX_BUTTON_LEFT", 13); - LuaSetEnum("XBOX_BUTTON_RIGHT", 11); - LuaSetEnum("XBOX_AXIS_RIGHT_X", 4); - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 3); - LuaSetEnum("XBOX_AXIS_LT_RT", 2); + LuaSetEnum("XBOX_BUTTON_HOME", 8); +#if defined(PLATFORM_RPI) + LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) + LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [-1..1] (up->down) + LuaSetEnum("XBOX_AXIS_RIGHT_X", 3); // [-1..1] (left->right) + LuaSetEnum("XBOX_AXIS_RIGHT_Y", 4); // [-1..1] (up->down) + LuaSetEnum("XBOX_AXIS_LT", 2); // [-1..1] (pressure-level) + LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) +#else + LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) + LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [1..-1] (up->down) + LuaSetEnum("XBOX_AXIS_RIGHT_X", 2); // [-1..1] (left->right) + LuaSetEnum("XBOX_AXIS_RIGHT_Y", 3); // [1..-1] (up->down) + LuaSetEnum("XBOX_AXIS_LT", 4); // [-1..1] (pressure-level) + LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) #endif - LuaSetEnum("XBOX_AXIS_LEFT_X", 0); - LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); LuaEndEnum("GAMEPAD"); lua_pushglobaltable(L); @@ -4204,6 +4218,15 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("DIRECTIONAL", LIGHT_DIRECTIONAL); LuaSetEnum("SPOT", LIGHT_SPOT); LuaEndEnum("LightType"); + + LuaStartEnum(); + LuaSetEnum("POINT", FILTER_POINT); + LuaSetEnum("BILINEAR", FILTER_BILINEAR); + LuaSetEnum("TRILINEAR", FILTER_TRILINEAR); + LuaSetEnum("ANISOTROPIC_4X", FILTER_ANISOTROPIC_4X); + LuaSetEnum("ANISOTROPIC_8X", FILTER_ANISOTROPIC_8X); + LuaSetEnum("ANISOTROPIC_16X", FILTER_ANISOTROPIC_16X); + LuaEndEnum("TextureFilter"); LuaStartEnum(); LuaSetEnum("NONE", GESTURE_NONE); -- cgit v1.2.3 From 46ce30a2ebff0ce716adf9e291818d9477cccbbf Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 24 Nov 2016 19:02:34 +0100 Subject: Corrected bugs for OpenGL 1.1 backend --- src/rlgl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/rlgl.c b/src/rlgl.c index 629d7967..47e2a57d 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -318,6 +318,7 @@ static bool texCompETC1Supported = false; // ETC1 texture compression support static bool texCompETC2Supported = false; // ETC2/EAC texture compression support static bool texCompPVRTSupported = false; // PVR texture compression support static bool texCompASTCSupported = false; // ASTC texture compression support +#endif // Extension supported flag: Anisotropic filtering static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support @@ -325,7 +326,6 @@ static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supp // Extension supported flag: Clamp mirror wrap mode static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported -#endif #if defined(RLGL_OCULUS_SUPPORT) // OVR device variables @@ -1733,7 +1733,7 @@ void rlglGenerateMipmaps(Texture2D *texture) { #if defined(GRAPHICS_API_OPENGL_11) // Compute required mipmaps - void *data = rlglReadTexturePixels(texture); + void *data = rlglReadTexturePixels(*texture); // NOTE: data size is reallocated to fit mipmaps data // NOTE: CPU mipmap generation only supports RGBA 32bit data -- cgit v1.2.3 From f5d792e5514188da56bb35c205e058bca473a300 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 25 Nov 2016 22:26:36 +0100 Subject: Update Lua naming Replaced LUA by Lua --- CHANGELOG | 2 +- README.md | 4 ++-- ROADMAP.md | 2 +- src/raylib.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/CHANGELOG b/CHANGELOG index 8b51d799..71f3d071 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,7 +11,7 @@ NOTE: It includes some interesting new features and is a stepping stone towards raylib future. HUGE changes: -[rlua] LUA BINDING: Complete raylib LUA binding, ALL raylib functions ported to LUA plus the +60 code examples. +[rlua] Lua BINDING: Complete raylib Lua binding, ALL raylib functions ported to Lua plus the +60 code examples. [audio] COMPLETE REDESIGN: Improved music support and also raw audio data processing and playing, +20 new functions added. [physac] COMPLETE REWRITE: Improved performance, functionality and simplified usage, moved to own repository and added multiple examples! diff --git a/README.md b/README.md index 0af5ae04..a5ed70f1 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ notes on raylib 1.6 On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features: -Complete raylib LUA binding. All raylib functions plus the +60 code examples have been ported to LUA, now LUA users can enjoy coding videogames in LUA while using all the internal power of raylib. This addition also open the doors to LUA scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to LUA scripts while keep using raylib functionality. +Complete raylib Lua binding. All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality. Completely redesigned audio module. Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. FLAC file format support has also been added. In the same line, OpenAL Soft backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more! @@ -272,7 +272,7 @@ contributing (in some way or another) to make raylib project better. Huge thanks - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game. - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system. - Marcelo Paez (paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo! - - [Ghassan Al-Mashareqa](https://github.com/ghassanpl) for his amazing contribution with raylib LUA module, I just work over his code to implement [rlua](https://github.com/raysan5/raylib/blob/master/src/rlua.h) + - [Ghassan Al-Mashareqa](https://github.com/ghassanpl) for his amazing contribution with raylib Lua module, I just work over his code to implement [rlua](https://github.com/raysan5/raylib/blob/master/src/rlua.h) - [Teodor Stoenescu](https://github.com/teodor-stoenescu) for his improvements on OBJ object loading. Please, if I forget someone in this list, excuse me and write me an email to remind me to add you! diff --git a/ROADMAP.md b/ROADMAP.md index 4c153d78..a7d51f0d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -17,7 +17,7 @@ raylib 1.x raylib 1.6 - [DONE] LUA scripting support (raylib lua wrapper) + [DONE] Lua scripting support (raylib Lua wrapper) [DONE] Redesigned audio module raylib 1.5 diff --git a/src/raylib.h b/src/raylib.h index d28b07a3..8f69438f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -19,7 +19,7 @@ * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Custom color palette for fancy visuals on raywhite background * Minimal external dependencies (GLFW3, OpenGL, OpenAL) -* Complete binding for LUA [rlua] +* Complete binding for Lua [rlua] * * External libs: * GLFW3 (www.glfw.org) for window/context management and input [core] -- cgit v1.2.3 From 377dcb025fb6957f73263e1913dfc5f29ba21a58 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 5 Dec 2016 01:14:18 +0100 Subject: Corrected some warnings --- src/audio.c | 16 ++++++++------ src/camera.h | 70 ++++++++++++++++++++++++++++++---------------------------- src/core.c | 4 ++-- src/gestures.h | 12 +++++----- src/models.c | 6 +++-- src/raymath.h | 16 +++++++------- src/rlgl.c | 10 ++++++--- src/shapes.c | 15 +++++++------ src/text.c | 33 +++++++++++++-------------- src/textures.c | 25 +++++++++++---------- 10 files changed, 108 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 49aca4b0..eef07154 100644 --- a/src/audio.c +++ b/src/audio.c @@ -411,6 +411,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* TODO: Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -420,6 +421,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); @@ -604,7 +606,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) // Copy a wave to a new wave Wave WaveCopy(Wave wave) { - Wave newWave; + Wave newWave = { 0 }; if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char)); else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short)); @@ -822,8 +824,8 @@ void UpdateMusicStream(Music music) if (processed > 0) { bool active = true; - short pcm[AUDIO_BUFFER_SIZE]; - float pcmf[AUDIO_BUFFER_SIZE]; + short pcm[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) + float pcmf[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) int numBuffersToProcess = processed; int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, @@ -952,7 +954,7 @@ float GetMusicTimePlayed(Music music) float secondsPlayed = 0.0f; unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; - secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); + secondsPlayed = (float)(samplesPlayed/(music->stream.sampleRate*music->stream.channels)); return secondsPlayed; } @@ -1004,17 +1006,17 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un { if (stream.sampleSize == 8) { - unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; + unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate); } else if (stream.sampleSize == 16) { - short pcm[AUDIO_BUFFER_SIZE] = { 0 }; + short pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate); } else if (stream.sampleSize == 32) { - float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; + float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate); } } diff --git a/src/camera.h b/src/camera.h index 33220390..cf542288 100644 --- a/src/camera.h +++ b/src/camera.h @@ -223,15 +223,15 @@ void SetCameraMode(Camera camera, int mode) float dy = v2.y - v1.y; float dz = v2.z - v1.z; - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); + cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz); Vector2 distance = { 0.0f, 0.0f }; - distance.x = sqrt(dx*dx + dz*dz); - distance.y = sqrt(dx*dx + dy*dy); + distance.x = sqrtf(dx*dx + dz*dz); + distance.y = sqrtf(dx*dx + dy*dy); // Camera angle calculation - cameraAngle.x = asin(fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) - cameraAngle.y = -asin(fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) + cameraAngle.x = asinf(fabsf(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) + cameraAngle.y = -asinf(fabsf(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) // NOTE: Just testing what cameraAngle means //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW) @@ -285,10 +285,10 @@ void UpdateCamera(Camera *camera) { HideCursor(); - if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y }); - else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 }); - else if (mousePosition.x > (screenWidth - screenHeight/3)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y }); - else if (mousePosition.y > (screenHeight - screenHeight/3)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 }); + if (mousePosition.x < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y }); + else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 }); + else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y }); + else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 }); else { mousePositionDelta.x = mousePosition.x - previousMousePosition.x; @@ -321,6 +321,7 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; } // Camera looking down + // TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) { camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; @@ -341,6 +342,7 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; } // Camera looking up + // TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) { camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; @@ -385,9 +387,9 @@ void UpdateCamera(Camera *camera) else { // Camera panning - camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); } } @@ -404,19 +406,19 @@ void UpdateCamera(Camera *camera) case CAMERA_FIRST_PERSON: case CAMERA_THIRD_PERSON: { - camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] - - sin(cameraAngle.x)*direction[MOVE_FRONT] - - cos(cameraAngle.x)*direction[MOVE_LEFT] + - cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; + camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] - + sinf(cameraAngle.x)*direction[MOVE_FRONT] - + cosf(cameraAngle.x)*direction[MOVE_LEFT] + + cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; - camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] - - sin(cameraAngle.y)*direction[MOVE_BACK] + + camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - + sinf(cameraAngle.y)*direction[MOVE_BACK] + 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; - camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] - - cos(cameraAngle.x)*direction[MOVE_FRONT] + - sin(cameraAngle.x)*direction[MOVE_LEFT] - - sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; + camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - + cosf(cameraAngle.x)*direction[MOVE_FRONT] + + sinf(cameraAngle.x)*direction[MOVE_LEFT] - + sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; bool isMoving = false; // Required for swinging @@ -439,9 +441,9 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; // Camera is always looking at player - camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); + camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cosf(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x); camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y; - camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); + camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sinf(cameraAngle.x); } else // CAMERA_FIRST_PERSON { @@ -450,18 +452,18 @@ void UpdateCamera(Camera *camera) else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD; // Camera is always looking at player - camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; - camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; - camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; if (isMoving) swingCounter++; // Camera position update // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position' - camera->position.y = playerEyesPosition - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; - camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; - camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; } } break; default: break; @@ -473,10 +475,10 @@ void UpdateCamera(Camera *camera) (cameraMode == CAMERA_THIRD_PERSON)) { // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target... - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; + if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; + else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; + camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; } } diff --git a/src/core.c b/src/core.c index 241772ec..7fa20979 100644 --- a/src/core.c +++ b/src/core.c @@ -779,7 +779,7 @@ float GetFrameTime(void) // As we are operate quite a lot with frameTime, // it could be no stable, so we round it before passing it around // NOTE: There are still problems with high framerates (>500fps) - double roundedFrameTime = round(frameTime*10000)/10000.0; + double roundedFrameTime = round(frameTime*10000)/10000.0; return (float)roundedFrameTime; // Time in seconds to run a frame } @@ -1089,7 +1089,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera) QuaternionTransform(&worldPos, matProj); // Calculate normalized device coordinates (inverted y) - Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.z }; + Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w }; // Calculate 2d screen position vector Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() }; diff --git a/src/gestures.h b/src/gestures.h index 481ef317..19b09269 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -179,7 +179,7 @@ static int tapCounter = 0; // TAP counter (one tap implies // Hold gesture variables static bool resetHold = false; // HOLD reset to get first touch point again -static float timeHold = 0.0f; // HOLD duration in milliseconds +static double timeHold = 0.0f; // HOLD duration in milliseconds // Drag gesture variables static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) @@ -423,11 +423,11 @@ float GetGestureHoldDuration(void) { // NOTE: time is calculated on current gesture HOLD - float time = 0.0f; + double time = 0.0; - if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; + if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold; - return time; + return (float)time; } // Get drag vector (between initial touch point to current) @@ -474,7 +474,7 @@ static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) { float angle; - angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); + angle = atan2f(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); if (angle < 0) angle += 360.0f; @@ -489,7 +489,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2) float dx = v2.x - v1.x; float dy = v2.y - v1.y; - result = sqrt(dx*dx + dy*dy); + result = (float)sqrt(dx*dx + dy*dy); return result; } diff --git a/src/models.c b/src/models.c index 48f8b813..97c84abc 100644 --- a/src/models.c +++ b/src/models.c @@ -707,6 +707,7 @@ Model LoadModelFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -716,6 +717,7 @@ Model LoadModelFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); @@ -1517,8 +1519,8 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box) t[3] = (box.max.y - ray.position.y)/ray.direction.y; t[4] = (box.min.z - ray.position.z)/ray.direction.z; t[5] = (box.max.z - ray.position.z)/ray.direction.z; - t[6] = fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); - t[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); + t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); + t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); collision = !(t[7] < 0 || t[6] > t[7]); diff --git a/src/raymath.h b/src/raymath.h index 10eabb6b..3cd1394e 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -222,16 +222,16 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v) { Vector3 result; - float min = fabs(v.x); + float min = fabsf(v.x); Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; - if (fabs(v.y) < min) + if (fabsf(v.y) < min) { - min = fabs(v.y); + min = fabsf(v.y); cardinalAxis = (Vector3){0.0f, 1.0f, 0.0f}; } - if(fabs(v.z) < min) + if(fabsf(v.z) < min) { cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f}; } @@ -256,7 +256,7 @@ RMDEF float VectorLength(const Vector3 v) { float length; - length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z); + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); return length; } @@ -284,7 +284,7 @@ RMDEF void VectorNormalize(Vector3 *v) length = VectorLength(*v); - if (length == 0) length = 1.0f; + if (length == 0.0f) length = 1.0f; ilength = 1.0f/length; @@ -302,7 +302,7 @@ RMDEF float VectorDistance(Vector3 v1, Vector3 v2) float dy = v2.y - v1.y; float dz = v2.z - v1.z; - result = sqrt(dx*dx + dy*dy + dz*dz); + result = sqrtf(dx*dx + dy*dy + dz*dz); return result; } @@ -590,7 +590,7 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle) float x = axis.x, y = axis.y, z = axis.z; - float length = sqrt(x*x + y*y + z*z); + float length = sqrtf(x*x + y*y + z*z); if ((length != 1.0f) && (length != 0.0f)) { diff --git a/src/rlgl.c b/src/rlgl.c index 47e2a57d..83cc7050 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -902,6 +902,10 @@ void rlDisableTexture(void) #if defined(GRAPHICS_API_OPENGL_11) glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); +#else + // NOTE: If quads batch limit is reached, + // we force a draw call and next batch starts + if (quads.vCounter/4 >= MAX_QUADS_BATCH) rlglDraw(); #endif } @@ -922,11 +926,11 @@ void rlTextureParameters(unsigned int id, int param, int value) case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; case RL_TEXTURE_ANISOTROPIC_FILTER: { - if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); + if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); else if (maxAnisotropicLevel > 0.0f) { TraceLog(WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, maxAnisotropicLevel); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); } else TraceLog(WARNING, "Anisotropic filtering not supported"); } break; @@ -1776,7 +1780,7 @@ void rlglGenerateMipmaps(Texture2D *texture) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) - texture->mipmaps = 1 + floor(log2(MAX(texture->width, texture->height))); + texture->mipmaps = 1 + (int)floor(log2(MAX(texture->width, texture->height))); #endif } else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id); diff --git a/src/shapes.c b/src/shapes.c index 70aad59a..3d3333c1 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -453,16 +453,17 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) int recCenterX = rec.x + rec.width/2; int recCenterY = rec.y + rec.height/2; - float dx = fabs(center.x - recCenterX); - float dy = fabs(center.y - recCenterY); + float dx = fabsf(center.x - recCenterX); + float dy = fabsf(center.y - recCenterY); - if (dx > (rec.width/2 + radius)) { return false; } - if (dy > (rec.height/2 + radius)) { return false; } + if (dx > ((float)rec.width/2.0f + radius)) { return false; } + if (dy > ((float)rec.height/2.0f + radius)) { return false; } - if (dx <= (rec.width/2)) { return true; } - if (dy <= (rec.height/2)) { return true; } + if (dx <= ((float)rec.width/2.0f)) { return true; } + if (dy <= ((float)rec.height/2.0f)) { return true; } - float cornerDistanceSq = (dx - rec.width/2)*(dx - rec.width/2) + (dy - rec.height/2)*(dy - rec.height/2); + float cornerDistanceSq = (dx - (float)rec.width/2.0f)*(dx - (float)rec.width/2.0f) + + (dy - (float)rec.height/2.0f)*(dy - (float)rec.height/2.0f); return (cornerDistanceSq <= (radius*radius)); } diff --git a/src/text.c b/src/text.c index c394889e..27b0a9ce 100644 --- a/src/text.c +++ b/src/text.c @@ -367,7 +367,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines - textOffsetY += ((spriteFont.size + spriteFont.size/2)*scaleFactor); + textOffsetY += (int)((spriteFont.size + spriteFont.size/2)*scaleFactor); textOffsetX = 0; } else @@ -394,8 +394,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); - if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (spriteFont.charRecs[index].width*scaleFactor + spacing); - else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing); + if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing); + else textOffsetX += (int)(spriteFont.charAdvanceX[index]*scaleFactor + spacing); } } } @@ -460,14 +460,14 @@ int MeasureText(const char *text, int fontSize) Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) { int len = strlen(text); - int tempLen = 0; // Used to count longer text line num chars + int tempLen = 0; // Used to count longer text line num chars int lenCounter = 0; - int textWidth = 0; - int tempTextWidth = 0; // Used to count longer text line width + float textWidth = 0; + float tempTextWidth = 0; // Used to count longer text line width - int textHeight = spriteFont.size; - float scaleFactor = fontSize/spriteFont.size; + float textHeight = (float)spriteFont.size; + float scaleFactor = fontSize/(float)spriteFont.size; for (int i = 0; i < len; i++) { @@ -485,7 +485,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; - textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines + textHeight += ((float)spriteFont.size*1.5f); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; @@ -494,8 +494,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (tempTextWidth < textWidth) tempTextWidth = textWidth; Vector2 vec; - vec.x = (float)tempTextWidth*scaleFactor + (tempLen - 1)*spacing; // Adds chars spacing to measure - vec.y = (float)textHeight*scaleFactor; + vec.x = tempTextWidth*scaleFactor + (float)((tempLen - 1)*spacing); // Adds chars spacing to measure + vec.y = textHeight*scaleFactor; return vec; } @@ -504,10 +504,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i // NOTE: Uses default font void DrawFPS(int posX, int posY) { - char buffer[20]; - // NOTE: We are rendering fps every second for better viewing on high framerates - // TODO: Not working properly on ANDROID and RPI + // TODO: Not working properly on ANDROID and RPI (for high framerates) static float fps = 0.0f; static int counter = 0; @@ -520,12 +518,11 @@ void DrawFPS(int posX, int posY) else { fps = GetFPS(); - refreshRate = fps; + refreshRate = (int)fps; counter = 0; } - - sprintf(buffer, "%2.0f FPS", fps); - DrawText(buffer, posX, posY, 20, LIME); + + DrawText(FormatText("%2.0f FPS", fps), posX, posY, 20, LIME); } //---------------------------------------------------------------------------------- diff --git a/src/textures.c b/src/textures.c index 126adad3..631468f9 100644 --- a/src/textures.c +++ b/src/textures.c @@ -317,6 +317,7 @@ Image LoadImageFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* TODO: Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -326,7 +327,7 @@ Image LoadImageFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } - + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); } @@ -1100,18 +1101,18 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight) Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color)); // EDIT: added +1 to account for an early rounding problem - int x_ratio = (int)((image->width<<16)/newWidth) + 1; - int y_ratio = (int)((image->height<<16)/newHeight) + 1; + int xRatio = (int)((image->width << 16)/newWidth) + 1; + int yRatio = (int)((image->height << 16)/newHeight) + 1; int x2, y2; - for (int i = 0; i < newHeight; i++) + for (int y = 0; y < newHeight; y++) { - for (int j = 0; j < newWidth; j++) + for (int x = 0; x < newWidth; x++) { - x2 = ((j*x_ratio) >> 16); - y2 = ((i*y_ratio) >> 16); + x2 = ((x*xRatio) >> 16); + y2 = ((y*yRatio) >> 16); - output[(i*newWidth) + j] = pixels[(y2*image->width) + x2] ; + output[(y*newWidth) + x] = pixels[(y2*image->width) + x2] ; } } @@ -1584,7 +1585,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V rlEnableTexture(texture.id); rlPushMatrix(); - rlTranslatef(destRec.x, destRec.y, 0); + rlTranslatef((float)destRec.x, (float)destRec.y, 0); rlRotatef(rotation, 0, 0, 1); rlTranslatef(-origin.x, -origin.y, 0); @@ -1598,15 +1599,15 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V // Bottom-right corner for texture and quad rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); - rlVertex2f(0.0f, destRec.height); + rlVertex2f(0.0f, (float)destRec.height); // Top-right corner for texture and quad rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); - rlVertex2f(destRec.width, destRec.height); + rlVertex2f((float)destRec.width, (float)destRec.height); // Top-left corner for texture and quad rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height); - rlVertex2f(destRec.width, 0.0f); + rlVertex2f((float)destRec.width, 0.0f); rlEnd(); rlPopMatrix(); -- cgit v1.2.3 From d5c0f9d3867887f86d754a031c7572ca76dcffd9 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Dec 2016 10:15:44 +0100 Subject: Replaced log2() function by equivalent log2() is not available in some standard C library implementations --- src/rlgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/rlgl.c b/src/rlgl.c index 83cc7050..c694dcdc 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1780,7 +1780,7 @@ void rlglGenerateMipmaps(Texture2D *texture) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) - texture->mipmaps = 1 + (int)floor(log2(MAX(texture->width, texture->height))); + texture->mipmaps = 1 + (int)floor(log(MAX(texture->width, texture->height))/log(2)); #endif } else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id); -- cgit v1.2.3 From 06b8727d70b4eb4ca6d7a295d0702b6f322b89c3 Mon Sep 17 00:00:00 2001 From: Joel Davis Date: Wed, 14 Dec 2016 23:58:15 -0800 Subject: Moved viewport code into SetupViewport so high-DPI fix can be applied to EndTextureMode --- src/core.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 241772ec..40bf3990 100644 --- a/src/core.c +++ b/src/core.c @@ -264,6 +264,7 @@ static void SwapBuffers(void); // Copy back buffer to f static void LogoAnimation(void); // Plays raylib logo appearing animation #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable +static void SetupViewport(void); #endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) @@ -744,8 +745,7 @@ void EndTextureMode(void) rlDisableRenderTexture(); // Disable render target // Set viewport to default framebuffer size (screen size) - // TODO: consider possible viewport offsets - rlViewport(0, 0, GetScreenWidth(), GetScreenHeight()); + SetupViewport(); rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlLoadIdentity(); // Reset current matrix (PROJECTION) @@ -1776,19 +1776,8 @@ static void InitGraphicsDevice(int width, int height) // NOTE: screenWidth and screenHeight not used, just stored as globals rlglInit(screenWidth, screenHeight); -#ifdef __APPLE__ - // Get framebuffer size of current window - // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer - // is automatically reasized to adapt to new DPI. - // When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback() - int fbWidth, fbHeight; - glfwGetFramebufferSize(window, &fbWidth, &fbHeight); - rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY); -#else - // Initialize screen viewport (area of the screen that you will actually draw to) - // NOTE: Viewport must be recalculated if screen is resized - rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY); -#endif + // Setup default viewport + SetupViewport(); // Initialize internal projection and modelview matrices // NOTE: Default to orthographic projection mode with top-left corner at (0,0) @@ -1805,6 +1794,23 @@ static void InitGraphicsDevice(int width, int height) #endif } +static void SetupViewport(void) +{ +#ifdef __APPLE__ + // Get framebuffer size of current window + // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer + // is automatically reasized to adapt to new DPI. + // When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback() + int fbWidth, fbHeight; + glfwGetFramebufferSize(window, &fbWidth, &fbHeight); + rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY); +#else + // Initialize screen viewport (area of the screen that you will actually draw to) + // NOTE: Viewport must be recalculated if screen is resized + rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY); +#endif +} + // Compute framebuffer size relative to screen size and display size // NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified static void SetupFramebufferSize(int displayWidth, int displayHeight) -- cgit v1.2.3 From 814507906f56f346d35ca95e7d9888213d3e5974 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 17 Dec 2016 19:05:40 +0100 Subject: Improving rRES custom format support -IN PROGRESS- Start removing old rRES functions. --- src/audio.c | 116 +------------------------------------------------ src/core.c | 7 +-- src/models.c | 85 ------------------------------------ src/raylib.h | 4 -- src/textures.c | 134 ++------------------------------------------------------- src/utils.c | 42 ------------------ 6 files changed, 9 insertions(+), 379 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index eef07154..4435b760 100644 --- a/src/audio.c +++ b/src/audio.c @@ -52,8 +52,7 @@ #include // Required for: va_list, va_start(), vfprintf(), va_end() #else #include "raylib.h" - #include "utils.h" // Required for: DecompressData() - // NOTE: Includes Android fopen() function map + #include "utils.h" // Required for: fopen() Android mapping, TraceLog() #endif #include "AL/al.h" // OpenAL basic header @@ -324,119 +323,6 @@ Sound LoadSoundFromWave(Wave wave) return sound; } -// Load sound to memory from rRES file (raylib Resource) -// TODO: Maybe rresName could be directly a char array with all the data? -Sound LoadSoundFromRES(const char *rresName, int resId) -{ - Sound sound = { 0 }; - -#if defined(AUDIO_STANDALONE) - TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode"); -#else - - bool found = false; - - char id[4]; // rRES file identifier - unsigned char version; // rRES file version and subversion - char useless; // rRES header reserved data - short numRes; - - ResInfoHeader infoHeader; - - FILE *rresFile = fopen(rresName, "rb"); - - if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName); - else - { - // Read rres file (basic file check - id) - fread(&id[0], sizeof(char), 1, rresFile); - fread(&id[1], sizeof(char), 1, rresFile); - fread(&id[2], sizeof(char), 1, rresFile); - fread(&id[3], sizeof(char), 1, rresFile); - fread(&version, sizeof(char), 1, rresFile); - fread(&useless, sizeof(char), 1, rresFile); - - if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S')) - { - TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName); - } - else - { - // Read number of resources embedded - fread(&numRes, sizeof(short), 1, rresFile); - - for (int i = 0; i < numRes; i++) - { - fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile); - - if (infoHeader.id == resId) - { - found = true; - - // Check data is of valid SOUND type - if (infoHeader.type == 1) // SOUND data type - { - // TODO: Check data compression type - // NOTE: We suppose compression type 2 (DEFLATE - default) - - // Reading SOUND parameters - Wave wave; - short sampleRate, bps; - char channels, reserved; - - fread(&sampleRate, sizeof(short), 1, rresFile); // Sample rate (frequency) - fread(&bps, sizeof(short), 1, rresFile); // Bits per sample - fread(&channels, 1, 1, rresFile); // Channels (1 - mono, 2 - stereo) - fread(&reserved, 1, 1, rresFile); // - - wave.sampleRate = sampleRate; - wave.sampleSize = bps; - wave.channels = (short)channels; - - unsigned char *data = malloc(infoHeader.size); - - fread(data, infoHeader.size, 1, rresFile); - - wave.data = DecompressData(data, infoHeader.size, infoHeader.srcSize); - - free(data); - - sound = LoadSoundFromWave(wave); - - // Sound is loaded, we can unload wave data - UnloadWave(wave); - } - else TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName); - } - else - { - // Depending on type, skip the right amount of parameters - /* TODO: Review - switch (infoHeader.type) - { - case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters - case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters - case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review) - case 3: break; // TEXT: No parameters - case 4: break; // RAW: No parameters - default: break; - } - */ - - // Jump DATA to read next infoHeader - fseek(rresFile, infoHeader.size, SEEK_CUR); - } - } - } - - fclose(rresFile); - } - - if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId); -#endif - return sound; -} - // Unload Wave data void UnloadWave(Wave wave) { diff --git a/src/core.c b/src/core.c index 455417d2..1e03b757 100644 --- a/src/core.c +++ b/src/core.c @@ -42,13 +42,14 @@ * **********************************************************************************************/ -#include "raylib.h" // raylib main header +#include "raylib.h" + #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 -#include "utils.h" // Includes Android fopen map, InitAssetManager(), TraceLog() +#include "utils.h" // Required for: fopen() Android mapping, TraceLog() #define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation) #define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint) -#include "raymath.h" // Required for Vector3 and Matrix functions +#include "raymath.h" // Required for: Vector3 and Matrix functions #define GESTURES_IMPLEMENTATION #include "gestures.h" // Gestures detection functionality diff --git a/src/models.c b/src/models.c index 97c84abc..7edf8750 100644 --- a/src/models.c +++ b/src/models.c @@ -648,91 +648,6 @@ Model LoadModelEx(Mesh data, bool dynamic) return model; } -// Load a 3d model from rRES file (raylib Resource) -Model LoadModelFromRES(const char *rresName, int resId) -{ - Model model = { 0 }; - bool found = false; - - char id[4]; // rRES file identifier - unsigned char version; // rRES file version and subversion - char useless; // rRES header reserved data - short numRes; - - ResInfoHeader infoHeader; - - FILE *rresFile = fopen(rresName, "rb"); - - if (rresFile == NULL) - { - TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName); - } - else - { - // Read rres file (basic file check - id) - fread(&id[0], sizeof(char), 1, rresFile); - fread(&id[1], sizeof(char), 1, rresFile); - fread(&id[2], sizeof(char), 1, rresFile); - fread(&id[3], sizeof(char), 1, rresFile); - fread(&version, sizeof(char), 1, rresFile); - fread(&useless, sizeof(char), 1, rresFile); - - if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S')) - { - TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName); - } - else - { - // Read number of resources embedded - fread(&numRes, sizeof(short), 1, rresFile); - - for (int i = 0; i < numRes; i++) - { - fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile); - - if (infoHeader.id == resId) - { - found = true; - - // Check data is of valid MODEL type - if (infoHeader.type == 8) - { - // TODO: Load model data - } - else - { - TraceLog(WARNING, "[%s] Required resource do not seem to be a valid MODEL resource", rresName); - } - } - else - { - // Depending on type, skip the right amount of parameters - /* Review - switch (infoHeader.type) - { - case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters - case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters - case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review) - case 3: break; // TEXT: No parameters - case 4: break; // RAW: No parameters - default: break; - } - */ - - // Jump DATA to read next infoHeader - fseek(rresFile, infoHeader.size, SEEK_CUR); - } - } - } - - fclose(rresFile); - } - - if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId); - - return model; -} - // Load a heightmap image as a 3d model // NOTE: model map size is defined in generic units Model LoadHeightmap(Image heightmap, Vector3 size) diff --git a/src/raylib.h b/src/raylib.h index 8f69438f..e7d2b74a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -770,10 +770,8 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) @@ -857,7 +855,6 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) RLAPI void UnloadModel(Model model); // Unload 3d model from memory @@ -933,7 +930,6 @@ RLAPI Wave LoadWave(const char *fileName); // Load wa RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) RLAPI Sound LoadSound(const char *fileName); // Load sound to memory RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound diff --git a/src/textures.c b/src/textures.c index 631468f9..92b22317 100644 --- a/src/textures.c +++ b/src/textures.c @@ -37,11 +37,10 @@ #include // Required for: strcmp(), strrchr(), strncmp() #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 - // Required: rlglLoadTexture() rlDeleteTextures(), - // rlglGenerateMipmaps(), some funcs for DrawTexturePro() + // Required for: rlglLoadTexture() rlDeleteTextures(), + // rlglGenerateMipmaps(), some funcs for DrawTexturePro() -#include "utils.h" // rRES data decompression utility function - // NOTE: Includes Android fopen function map +#include "utils.h" // Required for: fopen() Android mapping, TraceLog() // Support only desired texture formats, by default: JPEG, PNG, BMP, TGA //#define STBI_NO_JPEG // Image format .jpg and .jpeg @@ -216,7 +215,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int fread(image.data, size, 1, rawFile); - // TODO: Check if data have been read + // TODO: Check if data has been read image.width = width; image.height = height; @@ -229,119 +228,6 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int return image; } -// Load an image from rRES file (raylib Resource) -// TODO: Review function to support multiple color modes -Image LoadImageFromRES(const char *rresName, int resId) -{ - Image image = { 0 }; - bool found = false; - - char id[4]; // rRES file identifier - unsigned char version; // rRES file version and subversion - char useless; // rRES header reserved data - short numRes; - - ResInfoHeader infoHeader; - - FILE *rresFile = fopen(rresName, "rb"); - - if (rresFile == NULL) - { - TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName); - } - else - { - // Read rres file (basic file check - id) - fread(&id[0], sizeof(char), 1, rresFile); - fread(&id[1], sizeof(char), 1, rresFile); - fread(&id[2], sizeof(char), 1, rresFile); - fread(&id[3], sizeof(char), 1, rresFile); - fread(&version, sizeof(char), 1, rresFile); - fread(&useless, sizeof(char), 1, rresFile); - - if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S')) - { - TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName); - } - else - { - // Read number of resources embedded - fread(&numRes, sizeof(short), 1, rresFile); - - for (int i = 0; i < numRes; i++) - { - fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile); - - if (infoHeader.id == resId) - { - found = true; - - // Check data is of valid IMAGE type - if (infoHeader.type == 0) // IMAGE data type - { - // TODO: Check data compression type - // NOTE: We suppose compression type 2 (DEFLATE - default) - - short imgWidth, imgHeight; - char colorFormat, mipmaps; - - fread(&imgWidth, sizeof(short), 1, rresFile); // Image width - fread(&imgHeight, sizeof(short), 1, rresFile); // Image height - fread(&colorFormat, 1, 1, rresFile); // Image data color format (default: RGBA 32 bit) - fread(&mipmaps, 1, 1, rresFile); // Mipmap images included (default: 0) - - image.width = (int)imgWidth; - image.height = (int)imgHeight; - - unsigned char *compData = malloc(infoHeader.size); - - fread(compData, infoHeader.size, 1, rresFile); - - unsigned char *imgData = DecompressData(compData, infoHeader.size, infoHeader.srcSize); - - // TODO: Review color mode - //image.data = (unsigned char *)malloc(sizeof(unsigned char)*imgWidth*imgHeight*4); - image.data = imgData; - - //free(imgData); - - free(compData); - - TraceLog(INFO, "[%s] Image loaded successfully from resource, size: %ix%i", rresName, image.width, image.height); - } - else - { - TraceLog(WARNING, "[%s] Required resource do not seem to be a valid IMAGE resource", rresName); - } - } - else - { - // Depending on type, skip the right amount of parameters - /* TODO: Review - switch (infoHeader.type) - { - case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters - case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters - case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review) - case 3: break; // TEXT: No parameters - case 4: break; // RAW: No parameters - default: break; - } - */ - // Jump DATA to read next infoHeader - fseek(rresFile, infoHeader.size, SEEK_CUR); - } - } - } - - fclose(rresFile); - } - - if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId); - - return image; -} - // Load an image as texture into GPU memory Texture2D LoadTexture(const char *fileName) { @@ -378,18 +264,6 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat) return texture; } -// Load an image as texture from rRES file (raylib Resource) -Texture2D LoadTextureFromRES(const char *rresName, int resId) -{ - Texture2D texture; - - Image image = LoadImageFromRES(rresName, resId); - texture = LoadTextureFromImage(image); - UnloadImage(image); - - return texture; -} - // Load a texture from image data // NOTE: image is not unloaded, it must be done manually Texture2D LoadTextureFromImage(Image image) diff --git a/src/utils.c b/src/utils.c index 640c5720..8fedcaad 100644 --- a/src/utils.c +++ b/src/utils.c @@ -49,9 +49,6 @@ #include "external/stb_image_write.h" // Required for: stbi_write_png() #endif -#include "external/tinfl.c" // Required for: tinfl_decompress_mem_to_mem() - // NOTE: DEFLATE algorythm data decompression - #define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing //---------------------------------------------------------------------------------- @@ -75,45 +72,6 @@ static int android_close(void *cookie); // Module Functions Definition - Utilities //---------------------------------------------------------------------------------- -// Data decompression function -// NOTE: Allocated data MUST be freed! -unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize) -{ - int tempUncompSize; - unsigned char *pUncomp; - - // Allocate buffer to hold decompressed data - pUncomp = (mz_uint8 *)malloc((size_t)uncompSize); - - // Check correct memory allocation - if (pUncomp == NULL) - { - TraceLog(WARNING, "Out of memory while decompressing data"); - } - else - { - // Decompress data - tempUncompSize = tinfl_decompress_mem_to_mem(pUncomp, (size_t)uncompSize, data, compSize, 1); - - if (tempUncompSize == -1) - { - TraceLog(WARNING, "Data decompression failed"); - free(pUncomp); - } - - if (uncompSize != (int)tempUncompSize) - { - TraceLog(WARNING, "Expected uncompressed size do not match, data may be corrupted"); - TraceLog(WARNING, " -- Expected uncompressed size: %i", uncompSize); - TraceLog(WARNING, " -- Returned uncompressed size: %i", tempUncompSize); - } - - TraceLog(INFO, "Data decompressed successfully from %u bytes to %u bytes", (mz_uint32)compSize, (mz_uint32)tempUncompSize); - } - - return pUncomp; -} - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) // Creates a bitmap (BMP) file from an array of pixel data // NOTE: This function is not explicitly available to raylib users -- cgit v1.2.3 From 4a9b77dd705790ec1c15fb139afdcc7093c8e2ad Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 20 Dec 2016 00:33:45 +0100 Subject: Corrected bug sound playing twice Samples count was not properly calculated on WAV loading --- src/audio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 4435b760..a9c07c39 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1083,11 +1083,13 @@ static Wave LoadWAV(const char *fileName) // Read in the sound data into the soundData variable fread(wave.data, waveData.subChunkSize, 1, wavFile); - // Now we set the variables that we need later - wave.sampleCount = waveData.subChunkSize; + // Store wave parameters wave.sampleRate = waveFormat.sampleRate; wave.sampleSize = waveFormat.bitsPerSample; wave.channels = waveFormat.numChannels; + + // NOTE: subChunkSize comes in bytes, we need to translate it to number of samples + wave.sampleCount = waveData.subChunkSize/(waveFormat.bitsPerSample/8); TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels); } -- cgit v1.2.3 From c394708c438440db1b756bfe7e86a15341a43cb7 Mon Sep 17 00:00:00 2001 From: Saggi Mizrahi Date: Thu, 22 Dec 2016 03:19:49 +0200 Subject: Change UpdateSound() to accept const void * The function means to accept a const * so let's declare it. Will allow passing const buffers in games. Also constness is next to godliness! Signed-off-by: Saggi Mizrahi --- src/audio.c | 2 +- src/audio.h | 2 +- src/raylib.h | 17 +++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index a9c07c39..aa89de02 100644 --- a/src/audio.c +++ b/src/audio.c @@ -342,7 +342,7 @@ void UnloadSound(Sound sound) // Update sound buffer with new data // NOTE: data must match sound.format -void UpdateSound(Sound sound, void *data, int numSamples) +void UpdateSound(Sound sound, const void *data, int numSamples) { ALint sampleRate, sampleSize, channels; alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); diff --git a/src/audio.h b/src/audio.h index 2b3c5933..db1bb694 100644 --- a/src/audio.h +++ b/src/audio.h @@ -115,7 +115,7 @@ Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, in Sound LoadSound(const char *fileName); // Load sound to memory Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +void UpdateSound(Sound sound, const void *data, int numSamples); // Update sound buffer with new data void UnloadWave(Wave wave); // Unload wave data void UnloadSound(Sound sound); // Unload sound void PlaySound(Sound sound); // Play a sound diff --git a/src/raylib.h b/src/raylib.h index e7d2b74a..fff0c928 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -549,7 +549,7 @@ typedef enum { // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { +typedef enum { FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_BILINEAR, // Linear filtering FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) @@ -581,12 +581,12 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, - CAMERA_FREE, - CAMERA_ORBITAL, - CAMERA_FIRST_PERSON, - CAMERA_THIRD_PERSON +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON } CameraMode; // Head Mounted Display devices @@ -930,7 +930,8 @@ RLAPI Wave LoadWave(const char *fileName); // Load wa RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) RLAPI Sound LoadSound(const char *fileName); // Load sound to memory RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data +RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound -- cgit v1.2.3 From b2d4cd66a72fd765daa64c27f6a8e529d3d18e2d Mon Sep 17 00:00:00 2001 From: Saggi Mizrahi Date: Thu, 22 Dec 2016 03:20:27 +0200 Subject: Fix warnings in lua binding Signed-off-by: Saggi Mizrahi --- src/rlua.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/rlua.h b/src/rlua.h index 961ed1c1..10a75e3a 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -133,6 +133,7 @@ RLUADEF void CloseLuaDevice(void); // De-initialize Lua system #define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud) #define LuaGetArgument_string luaL_checkstring +#define LuaGetArgument_ptr (void *)luaL_checkinteger #define LuaGetArgument_int (int)luaL_checkinteger #define LuaGetArgument_unsigned (unsigned)luaL_checkinteger #define LuaGetArgument_char (char)luaL_checkinteger @@ -1198,7 +1199,7 @@ int lua_GetGamepadName(lua_State* L) // TODO: Return gamepad name id int arg1 = LuaGetArgument_int(L, 1); - char * result = GetGamepadName(arg1); + const char * result = GetGamepadName(arg1); //lua_pushboolean(L, result); return 1; } @@ -2863,7 +2864,7 @@ int lua_LoadWaveEx(lua_State* L) { // TODO: Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); - int arg1 = 0; + float * arg1 = 0; int arg2 = LuaGetArgument_int(L, 2); int arg3 = LuaGetArgument_int(L, 3); int arg4 = LuaGetArgument_int(L, 4); @@ -2904,7 +2905,7 @@ int lua_UpdateSound(lua_State* L) Sound arg1 = LuaGetArgument_Sound(L, 1); const char * arg2 = LuaGetArgument_string(L, 2); - int * arg3 = LuaGetArgument_int(L, 3); + int arg3 = LuaGetArgument_int(L, 3); UpdateSound(arg1, arg2, arg3); return 0; } -- cgit v1.2.3 From 1aa775eca8d5fbacb3d5b19143ca08c6b9eca65d Mon Sep 17 00:00:00 2001 From: Saggi Mizrahi Date: Thu, 22 Dec 2016 03:21:04 +0200 Subject: Fix physac.h building on linux Signed-off-by: Saggi Mizrahi --- src/physac.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/physac.h b/src/physac.h index e807ffa6..d958c701 100644 --- a/src/physac.h +++ b/src/physac.h @@ -239,9 +239,10 @@ PHYSACDEF void ClosePhysics(void); // Functions required to query time on Windows int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); -#elif defined(__linux) +#elif defined(__linux) || defined(PLATFORM_WEB) #include // Required for: timespec #include // Required for: clock_gettime() + #include #endif //---------------------------------------------------------------------------------- @@ -266,7 +267,7 @@ PHYSACDEF void ClosePhysics(void); static unsigned int usedMemory = 0; // Total allocated dynamic memory static bool physicsThreadEnabled = false; // Physics thread enabled state static double currentTime = 0; // Current time in milliseconds -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB) static double baseTime = 0; // Android and RPI platforms base time #endif static double startTime = 0; // Start time in milliseconds @@ -1942,7 +1943,7 @@ static double GetCurrentTime(void) { double time = 0; - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) + #if defined(_WIN32) unsigned long long int clockFrequency, currentTime; QueryPerformanceFrequency(&clockFrequency); @@ -1951,7 +1952,7 @@ static double GetCurrentTime(void) time = (double)((double)currentTime/clockFrequency)*1000; #endif - #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) + #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; -- cgit v1.2.3 From 5de597579feff50ab63ba4285984b64473241c46 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 01:58:56 +0100 Subject: Complete review of audio module --- examples/audio_module_playing.c | 2 +- examples/audio_music_stream.c | 2 +- examples/audio_raw_stream.c | 12 +- src/audio.c | 375 ++++++++++++++++++++-------------------- src/audio.h | 11 +- 5 files changed, 202 insertions(+), 200 deletions(-) (limited to 'src') diff --git a/examples/audio_module_playing.c b/examples/audio_module_playing.c index 4582a561..08ae2b05 100644 --- a/examples/audio_module_playing.c +++ b/examples/audio_module_playing.c @@ -86,7 +86,7 @@ int main() } // Get timePlayed scaled to bar dimensions - timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2; + timePlayed = GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40); // Color circles animation for (int i = MAX_CIRCLES - 1; (i >= 0) && !pause; i--) diff --git a/examples/audio_music_stream.c b/examples/audio_music_stream.c index dc9d4355..9c1ca4df 100644 --- a/examples/audio_music_stream.c +++ b/examples/audio_music_stream.c @@ -58,7 +58,7 @@ int main() } // Get timePlayed scaled to bar dimensions (400 pixels) - timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4; + timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400; //---------------------------------------------------------------------------------- // Draw diff --git a/examples/audio_raw_stream.c b/examples/audio_raw_stream.c index c044a7e0..d1fd1794 100644 --- a/examples/audio_raw_stream.c +++ b/examples/audio_raw_stream.c @@ -16,7 +16,7 @@ #include // Required for: malloc(), free() #include // Required for: sinf() -#define MAX_SAMPLES 20000 +#define MAX_SAMPLES 22050 int main() { @@ -29,15 +29,15 @@ int main() InitAudioDevice(); // Initialize audio device - // Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono) - AudioStream stream = InitAudioStream(22050, 32, 1); + // Init raw audio stream (sample rate: 22050, sample size: 16bit-short, channels: 1-mono) + AudioStream stream = InitAudioStream(22050, 16, 1); // Fill audio stream with some samples (sine wave) - float *data = (float *)malloc(sizeof(float)*MAX_SAMPLES); + short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES); for (int i = 0; i < MAX_SAMPLES; i++) { - data[i] = sinf(((2*PI*(float)i)/2)*DEG2RAD); + data[i] = (short)(sinf(((2*PI*(float)i)/2)*DEG2RAD)*32000); } // NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop @@ -87,7 +87,7 @@ int main() for (int i = 0; i < GetScreenWidth(); i++) { position.x = i; - position.y = 250 + 50*data[i]; + position.y = 250 + 50*data[i]/32000; DrawPixelV(position, RED); } diff --git a/src/audio.c b/src/audio.c index aa89de02..04ff90da 100644 --- a/src/audio.c +++ b/src/audio.c @@ -19,6 +19,10 @@ * Module Configuration Flags: * AUDIO_STANDALONE - Use this module as standalone library (independently of raylib) * +* Some design decisions: +* Support only up to two channels: MONO and STEREO (for additional channels, AL_EXT_MCFORMATS) +* Support only the following sample sizes: 8bit PCM and 16bit PCM (for additional size, AL_EXT_FLOAT32) +* * Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions: * XM audio module support (jar_xm) * MOD audio module support (jar_mod) @@ -57,19 +61,15 @@ #include "AL/al.h" // OpenAL basic header #include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) +//#include "AL/alext.h" // OpenAL extensions header, required for AL_EXT_FLOAT32 and AL_EXT_MCFORMATS + +// OpenAL extension: AL_EXT_FLOAT32 - Support for 32bit float samples +// OpenAL extension: AL_EXT_MCFORMATS - Support for multi-channel formats (Quad, 5.1, 6.1, 7.1) #include // Required for: malloc(), free() #include // Required for: strcmp(), strncmp() #include // Required for: FILE, fopen(), fclose(), fread() -// Tokens defined by OpenAL extension: AL_EXT_float32 -#ifndef AL_FORMAT_MONO_FLOAT32 - #define AL_FORMAT_MONO_FLOAT32 0x10010 -#endif -#ifndef AL_FORMAT_STEREO_FLOAT32 - #define AL_FORMAT_STEREO_FLOAT32 0x10011 -#endif - //#define STB_VORBIS_HEADER_ONLY #include "external/stb_vorbis.h" // OGG loading functions @@ -92,11 +92,11 @@ //---------------------------------------------------------------------------------- #define MAX_STREAM_BUFFERS 2 // Number of buffers for each audio stream -// NOTE: Music buffer size is defined by number of samples, independent of sample size +// NOTE: Music buffer size is defined by number of samples, independent of sample size and channels number // After some math, considering a sampleRate of 48000, a buffer refill rate of 1/60 seconds // and double-buffering system, I concluded that a 4096 samples buffer should be enough // In case of music-stalls, just increase this number -#define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. short: 32Kb) +#define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. 16bit, Mono: 8Kb) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -211,7 +211,7 @@ bool IsAudioDeviceReady(void) // Module Functions Definition - Sounds loading and playing (.WAV) //---------------------------------------------------------------------------------- -// Load wave data from file into RAM +// Load wave data from file Wave LoadWave(const char *fileName) { Wave wave = { 0 }; @@ -224,19 +224,18 @@ Wave LoadWave(const char *fileName) return wave; } -// Load wave data from float array data (32bit) -Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels) +// Load wave data from raw array data +Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels) { Wave wave; wave.data = data; wave.sampleCount = sampleCount; wave.sampleRate = sampleRate; - wave.sampleSize = 32; + wave.sampleSize = sampleSize; wave.channels = channels; - // NOTE: Copy wave data to work with, - // user is responsible of input data to free + // NOTE: Copy wave data to work with, user is responsible of input data to free Wave cwave = WaveCopy(wave); WaveFormat(&cwave, sampleRate, sampleSize, channels); @@ -244,7 +243,7 @@ Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, in return cwave; } -// Load sound to memory +// Load sound from file // NOTE: The entire file is loaded to memory to be played (no-streaming) Sound LoadSound(const char *fileName) { @@ -274,7 +273,7 @@ Sound LoadSoundFromWave(Wave wave) { case 8: format = AL_FORMAT_MONO8; break; case 16: format = AL_FORMAT_MONO16; break; - case 32: format = AL_FORMAT_MONO_FLOAT32; break; + case 32: //format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break; } } @@ -284,7 +283,7 @@ Sound LoadSoundFromWave(Wave wave) { case 8: format = AL_FORMAT_STEREO8; break; case 16: format = AL_FORMAT_STEREO16; break; - case 32: format = AL_FORMAT_STEREO_FLOAT32; break; + case 32: //format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break; } } @@ -305,7 +304,7 @@ Sound LoadSoundFromWave(Wave wave) ALuint buffer; alGenBuffers(1, &buffer); // Generate pointer to buffer - unsigned int dataSize = wave.sampleCount*wave.sampleSize/8; // Size in bytes + unsigned int dataSize = wave.sampleCount*wave.sampleSize/8*wave.channels; // Size in bytes // Upload sound data to buffer alBufferData(buffer, format, wave.data, dataSize, wave.sampleRate); @@ -313,7 +312,7 @@ Sound LoadSoundFromWave(Wave wave) // Attach sound buffer to source alSourcei(source, AL_BUFFER, buffer); - TraceLog(INFO, "[SND ID %i][BUFR ID %i] Sound data loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", source, buffer, wave.sampleRate, wave.sampleSize, wave.channels); + TraceLog(INFO, "[SND ID %i][BUFR ID %i] Sound data loaded successfully (%i Hz, %i bit, %s)", source, buffer, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); sound.source = source; sound.buffer = buffer; @@ -323,7 +322,7 @@ Sound LoadSoundFromWave(Wave wave) return sound; } -// Unload Wave data +// Unload wave data void UnloadWave(Wave wave) { free(wave.data); @@ -346,14 +345,14 @@ void UpdateSound(Sound sound, const void *data, int numSamples) { ALint sampleRate, sampleSize, channels; alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); - alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format - alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format + alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format + alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate); TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize); TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels); - unsigned int dataSize = numSamples*sampleSize/8; // Size of data in bytes + unsigned int dataSize = numSamples*sampleSize/8*channels; // Size of data in bytes alSourceStop(sound.source); // Stop sound alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update @@ -435,69 +434,86 @@ void SetSoundPitch(Sound sound, float pitch) } // Convert wave data to desired format -// TODO: Consider channels (mono - stereo) void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) { + // Format sample rate + if (wave->sampleRate != sampleRate) wave->sampleRate = sampleRate; + + // Format sample size + // NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit if (wave->sampleSize != sampleSize) { - float *samples = GetWaveData(*wave); //Color *pixels = GetImageData(*image); - - free(wave->data); + void *data = malloc(wave->sampleCount*wave->channels*sampleSize/8); - wave->sampleSize = sampleSize; - - //sample *= 4.0f; // Arbitrary gain to get reasonable output volume... - //if (sample > 1.0f) sample = 1.0f; - //if (sample < -1.0f) sample = -1.0f; - - if (sampleSize == 8) + for (int i = 0; i < wave->sampleCount; i++) { - wave->data = (unsigned char *)malloc(wave->sampleCount*sizeof(unsigned char)); - - for (int i = 0; i < wave->sampleCount; i++) + for (int j = 0; j < wave->channels; j++) { - ((unsigned char *)wave->data)[i] = (unsigned char)((float)samples[i]*127 + 128); + if (sampleSize == 8) + { + if (wave->sampleSize == 16) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float)(((short *)wave->data)[wave->channels*i + j])/32767.0f)*256); + else if (wave->sampleSize == 32) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float *)wave->data)[wave->channels*i + j]*127.0f + 127); + } + else if (sampleSize == 16) + { + if (wave->sampleSize == 8) ((short *)data)[wave->channels*i + j] = (short)(((float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f)*32767); + else if (wave->sampleSize == 32) ((short *)data)[wave->channels*i + j] = (short)((((float *)wave->data)[wave->channels*i + j])*32767); + } + else if (sampleSize == 32) + { + if (wave->sampleSize == 8) ((float *)data)[wave->channels*i + j] = (float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f; + else if (wave->sampleSize == 16) ((float *)data)[wave->channels*i + j] = (float)(((short *)wave->data)[wave->channels*i + j])/32767.0f; + } } } - else if (sampleSize == 16) + + wave->sampleSize = sampleSize; + free(wave->data); + wave->data = data; + } + + // Format channels (interlaced mode) + // NOTE: Only supported mono <--> stereo + if (wave->channels != channels) + { + void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8); + + if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information) { - wave->data = (short *)malloc(wave->sampleCount*sizeof(short)); - for (int i = 0; i < wave->sampleCount; i++) { - ((short *)wave->data)[i] = (short)((float)samples[i]*32000); // SHRT_MAX = 32767 + for (int j = 0; j < channels; j++) + { + if (wave->sampleSize == 8) ((unsigned char *)data)[channels*i + j] = ((unsigned char *)wave->data)[i]; + else if (wave->sampleSize == 16) ((short *)data)[channels*i + j] = ((short *)wave->data)[i]; + else if (wave->sampleSize == 32) ((float *)data)[channels*i + j] = ((float *)wave->data)[i]; + } } } - else if (sampleSize == 32) + else if ((wave->channels == 2) && (channels == 1)) // stereo ---> mono (mix stereo channels) { - wave->data = (float *)malloc(wave->sampleCount*sizeof(float)); - - for (int i = 0; i < wave->sampleCount; i++) + for (int i = 0, j = 0; i < wave->sampleCount; i++, j += 2) { - ((float *)wave->data)[i] = (float)samples[i]; + if (wave->sampleSize == 8) ((unsigned char *)data)[i] = (((unsigned char *)wave->data)[j] + ((unsigned char *)wave->data)[j + 1])/2; + else if (wave->sampleSize == 16) ((short *)data)[i] = (((short *)wave->data)[j] + ((short *)wave->data)[j + 1])/2; + else if (wave->sampleSize == 32) ((float *)data)[i] = (((float *)wave->data)[j] + ((float *)wave->data)[j + 1])/2.0f; } } - else TraceLog(WARNING, "Wave formatting: Sample size not supported"); - free(samples); - } - - // NOTE: Only supported 1 or 2 channels (mono or stereo) - if ((channels > 0) && (channels < 3) && (wave->channels != channels)) - { - // TODO: Add/remove channels interlaced data if required... + // TODO: Add/remove additional interlaced channels + + wave->channels = channels; + free(wave->data); + wave->data = data; } } // Copy a wave to a new wave Wave WaveCopy(Wave wave) { - Wave newWave = { 0 }; + Wave newWave = { 0 }; - if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char)); - else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short)); - else if (wave.sampleSize == 32) newWave.data = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float)); - else TraceLog(WARNING, "Wave sample size not supported for copy"); + newWave.data = malloc(wave.sampleCount*wave.channels*wave.sampleSize/8); if (newWave.data != NULL) { @@ -520,35 +536,32 @@ void WaveCrop(Wave *wave, int initSample, int finalSample) if ((initSample >= 0) && (initSample < finalSample) && (finalSample > 0) && (finalSample < wave->sampleCount)) { - // TODO: Review cropping (it could be simplified...) + int sampleCount = finalSample - initSample; - float *samples = GetWaveData(*wave); - float *cropSamples = (float *)malloc((finalSample - initSample)*sizeof(float)); + void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8); + + memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8); - for (int i = initSample; i < finalSample; i++) cropSamples[i] = samples[i]; - free(wave->data); - wave->data = cropSamples; - int sampleSize = wave->sampleSize; - wave->sampleSize = 32; - - WaveFormat(wave, wave->sampleRate, sampleSize, wave->channels); + wave->data = data; } else TraceLog(WARNING, "Wave crop range out of bounds"); } // Get samples data from wave as a floats array // NOTE: Returned sample values are normalized to range [-1..1] -// TODO: Consider multiple channels (mono - stereo) float *GetWaveData(Wave wave) { - float *samples = (float *)malloc(wave.sampleCount*sizeof(float)); + float *samples = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float)); for (int i = 0; i < wave.sampleCount; i++) { - if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f; - else if (wave.sampleSize == 16) samples[i] = (float)((short *)wave.data)[i]/32767.0f; - else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i]; + for (int j = 0; j < wave.channels; j++) + { + if (wave.sampleSize == 8) samples[wave.channels*i + j] = (float)(((unsigned char *)wave.data)[wave.channels*i + j] - 127)/256.0f; + else if (wave.sampleSize == 16) samples[wave.channels*i + j] = (float)((short *)wave.data)[wave.channels*i + j]/32767.0f; + else if (wave.sampleSize == 32) samples[wave.channels*i + j] = ((float *)wave.data)[wave.channels*i + j]; + } } return samples; @@ -572,11 +585,10 @@ Music LoadMusicStream(const char *fileName) else { stb_vorbis_info info = stb_vorbis_get_info(music->ctxOgg); // Get Ogg file info - //float totalLengthSeconds = stb_vorbis_stream_length_in_seconds(music->ctxOgg); - // TODO: Support 32-bit sampleSize OGGs + // OGG bit rate defaults to 16 bit, it's enough for compressed format music->stream = InitAudioStream(info.sample_rate, 16, info.channels); - music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg)*info.channels; + music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg); music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_OGG; music->loop = true; // We loop by default @@ -584,7 +596,6 @@ Music LoadMusicStream(const char *fileName) TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels); TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required); - } } else if (strcmp(GetExtension(fileName), "flac") == 0) @@ -614,7 +625,7 @@ Music LoadMusicStream(const char *fileName) jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops // NOTE: Only stereo is supported for XM - music->stream = InitAudioStream(48000, 32, 2); + music->stream = InitAudioStream(48000, 16, 2); music->totalSamples = (unsigned int)jar_xm_get_remaining_samples(music->ctxXm); music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_MODULE_XM; @@ -637,8 +648,8 @@ Music LoadMusicStream(const char *fileName) music->ctxType = MUSIC_MODULE_MOD; music->loop = true; - TraceLog(INFO, "[%s] MOD number of samples: %i", fileName, music->samplesLeft); - TraceLog(INFO, "[%s] MOD track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); + TraceLog(DEBUG, "[%s] MOD number of samples: %i", fileName, music->samplesLeft); + TraceLog(DEBUG, "[%s] MOD track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); } else TraceLog(WARNING, "[%s] MOD file could not be opened", fileName); } @@ -682,7 +693,6 @@ void ResumeMusicStream(Music music) } // Stop music playing (close stream) -// TODO: Restart XM context void StopMusicStream(Music music) { alSourceStop(music->stream.source); @@ -690,7 +700,7 @@ void StopMusicStream(Music music) switch (music->ctxType) { case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break; - case MUSIC_MODULE_XM: break; + case MUSIC_MODULE_XM: /* TODO: Restart XM context */ break; case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break; default: break; } @@ -710,70 +720,43 @@ void UpdateMusicStream(Music music) if (processed > 0) { bool active = true; - short pcm[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) - float pcmf[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) - int numBuffersToProcess = processed; + + // NOTE: Using dynamic allocation because it could require more than 16KB + void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1); + int numBuffersToProcess = processed; int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, // individual L or R for ogg shorts for (int i = 0; i < numBuffersToProcess; i++) { + if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; + else numSamples = music->samplesLeft; + + // TODO: Really don't like ctxType thingy... switch (music->ctxType) { case MUSIC_AUDIO_OGG: { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; - else numSamples = music->samplesLeft; - - // NOTE: Returns the number of samples to process (should be the same as numSamples -> it is) - int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, numSamples); - - // TODO: Review stereo channels Ogg, not enough samples served! - UpdateAudioStream(music->stream, pcm, numSamplesOgg*music->stream.channels); - music->samplesLeft -= (numSamplesOgg*music->stream.channels); + // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) + int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, numSamples*music->stream.channels); } break; case MUSIC_AUDIO_FLAC: { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; - else numSamples = music->samplesLeft; - - int pcmi[AUDIO_BUFFER_SIZE]; - - // NOTE: Returns the number of samples to process (should be the same as numSamples) - unsigned int numSamplesFlac = (unsigned int)drflac_read_s32(music->ctxFlac, numSamples, pcmi); + // NOTE: Returns the number of samples to process + unsigned int numSamplesFlac = (unsigned int)drflac_read_s32(music->ctxFlac, numSamples/2, (int *)pcm); - UpdateAudioStream(music->stream, pcmi, numSamplesFlac*music->stream.channels); - music->samplesLeft -= (numSamples*music->stream.channels); - - } break; - case MUSIC_MODULE_XM: - { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; - else numSamples = music->samplesLeft; - - // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample) - jar_xm_generate_samples(music->ctxXm, pcmf, numSamples); - UpdateAudioStream(music->stream, pcmf, numSamples*2); // Using 32bit PCM data - music->samplesLeft -= numSamples; - - //TraceLog(INFO, "Samples left: %i", music->samplesLeft); - - } break; - case MUSIC_MODULE_MOD: - { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; - else numSamples = music->samplesLeft; - - // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo) - jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); - UpdateAudioStream(music->stream, pcm, numSamples*2); - music->samplesLeft -= numSamples; + // TODO: Samples should be provided as 16 bit instead of 32 bit! } break; + case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, numSamples); break; + case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break; default: break; } + + UpdateAudioStream(music->stream, pcm, numSamples); + music->samplesLeft -= numSamples; if (music->samplesLeft <= 0) { @@ -789,7 +772,6 @@ void UpdateMusicStream(Music music) if (!active) { StopMusicStream(music); // Stop music (and reset) - if (music->loop) PlayMusicStream(music); // Play again } else @@ -798,6 +780,8 @@ void UpdateMusicStream(Music music) // just make sure to play again on window restore if (state != AL_PLAYING) PlayMusicStream(music); } + + free(pcm); } } @@ -840,7 +824,7 @@ float GetMusicTimePlayed(Music music) float secondsPlayed = 0.0f; unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; - secondsPlayed = (float)(samplesPlayed/(music->stream.sampleRate*music->stream.channels)); + secondsPlayed = (float)samplesPlayed/music->stream.sampleRate; return secondsPlayed; } @@ -852,30 +836,36 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un stream.sampleRate = sampleRate; stream.sampleSize = sampleSize; - stream.channels = channels; + + // Only mono and stereo channels are supported, more channels require AL_EXT_MCFORMATS extension + if ((channels > 0) && (channels < 3)) stream.channels = channels; + else + { + TraceLog(WARNING, "Init audio stream: Number of channels not supported: %i", channels); + stream.channels = 1; // Fallback to mono channel + } // Setup OpenAL format - if (channels == 1) + if (stream.channels == 1) { switch (sampleSize) { case 8: stream.format = AL_FORMAT_MONO8; break; case 16: stream.format = AL_FORMAT_MONO16; break; - case 32: stream.format = AL_FORMAT_MONO_FLOAT32; break; + case 32: //stream.format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break; } } - else if (channels == 2) + else if (stream.channels == 2) { switch (sampleSize) { case 8: stream.format = AL_FORMAT_STEREO8; break; case 16: stream.format = AL_FORMAT_STEREO16; break; - case 32: stream.format = AL_FORMAT_STEREO_FLOAT32; break; + case 32: //stream.format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break; } } - else TraceLog(WARNING, "Init audio stream: Number of channels not supported: %i", channels); // Create an audio source alGenSources(1, &stream.source); @@ -888,28 +878,19 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un alGenBuffers(MAX_STREAM_BUFFERS, stream.buffers); // Initialize buffer with zeros by default + // NOTE: Using dynamic allocation because it requires more than 16KB + void *pcm = calloc(AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, 1); + for (int i = 0; i < MAX_STREAM_BUFFERS; i++) { - if (stream.sampleSize == 8) - { - unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) - alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate); - } - else if (stream.sampleSize == 16) - { - short pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) - alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate); - } - else if (stream.sampleSize == 32) - { - float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; // TODO: Dynamic allocation (uses more than 16KB of stack) - alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate); - } + alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, stream.sampleRate); } + + free(pcm); alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers); - TraceLog(INFO, "[AUD ID %i] Audio stream loaded successfully", stream.source); + TraceLog(INFO, "[AUD ID %i] Audio stream loaded successfully (%i Hz, %i bit, %s)", stream.source, stream.sampleRate, stream.sampleSize, (stream.channels == 1) ? "Mono" : "Stereo"); return stream; } @@ -940,8 +921,8 @@ void CloseAudioStream(AudioStream stream) } // Update audio stream buffers with data -// NOTE: Only one buffer per call -void UpdateAudioStream(AudioStream stream, void *data, int numSamples) +// NOTE: Only updates one buffer per call +void UpdateAudioStream(AudioStream stream, const void *data, int numSamples) { ALuint buffer = 0; alSourceUnqueueBuffers(stream.source, 1, &buffer); @@ -949,10 +930,7 @@ void UpdateAudioStream(AudioStream stream, void *data, int numSamples) // Check if any buffer was available for unqueue if (alGetError() != AL_INVALID_VALUE) { - if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate); - else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate); - else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate); - + alBufferData(buffer, stream.format, data, numSamples*stream.channels*stream.sampleSize/8, stream.sampleRate); alSourceQueueBuffers(stream.source, 1, &buffer); } } @@ -1007,7 +985,7 @@ static Wave LoadWAV(const char *fileName) char chunkID[4]; int chunkSize; char format[4]; - } RiffHeader; + } WavRiffHeader; typedef struct { char subChunkID[4]; @@ -1018,16 +996,16 @@ static Wave LoadWAV(const char *fileName) int byteRate; short blockAlign; short bitsPerSample; - } WaveFormat; + } WavFormat; typedef struct { char subChunkID[4]; int subChunkSize; - } WaveData; + } WavData; - RiffHeader riffHeader; - WaveFormat waveFormat; - WaveData waveData; + WavRiffHeader wavRiffHeader; + WavFormat wavFormat; + WavData wavData; Wave wave = { 0 }; FILE *wavFile; @@ -1042,56 +1020,70 @@ static Wave LoadWAV(const char *fileName) else { // Read in the first chunk into the struct - fread(&riffHeader, sizeof(RiffHeader), 1, wavFile); + fread(&wavRiffHeader, sizeof(WavRiffHeader), 1, wavFile); // Check for RIFF and WAVE tags - if (strncmp(riffHeader.chunkID, "RIFF", 4) || - strncmp(riffHeader.format, "WAVE", 4)) + if (strncmp(wavRiffHeader.chunkID, "RIFF", 4) || + strncmp(wavRiffHeader.format, "WAVE", 4)) { TraceLog(WARNING, "[%s] Invalid RIFF or WAVE Header", fileName); } else { // Read in the 2nd chunk for the wave info - fread(&waveFormat, sizeof(WaveFormat), 1, wavFile); + fread(&wavFormat, sizeof(WavFormat), 1, wavFile); // Check for fmt tag - if ((waveFormat.subChunkID[0] != 'f') || (waveFormat.subChunkID[1] != 'm') || - (waveFormat.subChunkID[2] != 't') || (waveFormat.subChunkID[3] != ' ')) + if ((wavFormat.subChunkID[0] != 'f') || (wavFormat.subChunkID[1] != 'm') || + (wavFormat.subChunkID[2] != 't') || (wavFormat.subChunkID[3] != ' ')) { TraceLog(WARNING, "[%s] Invalid Wave format", fileName); } else { // Check for extra parameters; - if (waveFormat.subChunkSize > 16) fseek(wavFile, sizeof(short), SEEK_CUR); + if (wavFormat.subChunkSize > 16) fseek(wavFile, sizeof(short), SEEK_CUR); // Read in the the last byte of data before the sound file - fread(&waveData, sizeof(WaveData), 1, wavFile); + fread(&wavData, sizeof(WavData), 1, wavFile); // Check for data tag - if ((waveData.subChunkID[0] != 'd') || (waveData.subChunkID[1] != 'a') || - (waveData.subChunkID[2] != 't') || (waveData.subChunkID[3] != 'a')) + if ((wavData.subChunkID[0] != 'd') || (wavData.subChunkID[1] != 'a') || + (wavData.subChunkID[2] != 't') || (wavData.subChunkID[3] != 'a')) { TraceLog(WARNING, "[%s] Invalid data header", fileName); } else { // Allocate memory for data - wave.data = (unsigned char *)malloc(sizeof(unsigned char)*waveData.subChunkSize); + wave.data = (unsigned char *)malloc(sizeof(unsigned char)*wavData.subChunkSize); // Read in the sound data into the soundData variable - fread(wave.data, waveData.subChunkSize, 1, wavFile); + fread(wave.data, wavData.subChunkSize, 1, wavFile); // Store wave parameters - wave.sampleRate = waveFormat.sampleRate; - wave.sampleSize = waveFormat.bitsPerSample; - wave.channels = waveFormat.numChannels; + wave.sampleRate = wavFormat.sampleRate; + wave.sampleSize = wavFormat.bitsPerSample; + wave.channels = wavFormat.numChannels; + + // NOTE: Only support up to 16 bit sample sizes + if (wave.sampleSize > 16) + { + WaveFormat(&wave, wave.sampleRate, 16, wave.channels); + TraceLog(WARNING, "[%s] WAV sample size (%ibit) not supported, converted to 16bit", fileName, wave.sampleSize); + } + + // NOTE: Only support up to 2 channels (mono, stereo) + if (wave.channels > 2) + { + WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); + TraceLog(WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); + } // NOTE: subChunkSize comes in bytes, we need to translate it to number of samples - wave.sampleCount = waveData.subChunkSize/(waveFormat.bitsPerSample/8); + wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels; - TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels); + TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); } } } @@ -1137,7 +1129,7 @@ static Wave LoadOGG(const char *fileName) TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained); - TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels); + TraceLog(INFO, "[%s] OGG file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); stb_vorbis_close(oggFile); } @@ -1156,9 +1148,20 @@ static Wave LoadFLAC(const char *fileName) wave.data = drflac_open_and_decode_file_s32(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); wave.sampleCount = (int)totalSampleCount; - wave.sampleSize = 32; + wave.sampleSize = 32; // 32 bit per sample (float) + + // NOTE: By default, dr_flac returns 32bit float samples, needs to be converted to 16bit + WaveFormat(&wave, wave.sampleRate, 16, wave.channels); + + // NOTE: Only support up to 2 channels (mono, stereo) + if (wave.channels > 2) + { + WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); + TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); + } if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName); + else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); return wave; } diff --git a/src/audio.h b/src/audio.h index db1bb694..6f0c235a 100644 --- a/src/audio.h +++ b/src/audio.h @@ -110,12 +110,11 @@ void InitAudioDevice(void); // Initialize au void CloseAudioDevice(void); // Close the audio device and context bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -Wave LoadWave(const char *fileName); // Load wave data from file into RAM -Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -Sound LoadSound(const char *fileName); // Load sound to memory -Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -void UpdateSound(Sound sound, const void *data, int numSamples); // Update sound buffer with new data +Wave LoadWave(const char *fileName); // Load wave data from file +Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +Sound LoadSound(const char *fileName); // Load sound from file +Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data void UnloadWave(Wave wave); // Unload wave data void UnloadSound(Sound sound); // Unload sound void PlaySound(Sound sound); // Play a sound -- cgit v1.2.3 From d8bf84f118cd311dbbc81e7183f8cd3e8d2d7e27 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 01:59:23 +0100 Subject: Added mesh loading functions --- src/models.c | 74 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/models.c b/src/models.c index 7edf8750..a2043913 100644 --- a/src/models.c +++ b/src/models.c @@ -611,30 +611,57 @@ void DrawLight(Light light) } } -// Load a 3d model (from file) -Model LoadModel(const char *fileName) +// Load mesh from file +Mesh LoadMesh(const char *fileName) { - Model model = { 0 }; + Mesh mesh = { 0 }; - // TODO: Initialize default data for model in case loading fails, maybe a cube? + if (strcmp(GetExtension(fileName), "obj") == 0) mesh = LoadOBJ(fileName); + else TraceLog(WARNING, "[%s] Mesh extension not recognized, it can't be loaded", fileName); - if (strcmp(GetExtension(fileName), "obj") == 0) model.mesh = LoadOBJ(fileName); - else TraceLog(WARNING, "[%s] Model extension not recognized, it can't be loaded", fileName); + if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded"); + else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) + + // TODO: Initialize default mesh data in case loading fails, maybe a cube? - if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded"); - else - { - rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model) + return mesh; +} - model.transform = MatrixIdentity(); - model.material = LoadDefaultMaterial(); - } +// Load mesh from vertex data +// NOTE: All vertex data arrays must be same size: numVertex +Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData) +{ + Mesh mesh = { 0 }; + + mesh.vertexCount = numVertex; + mesh.triangleCount = numVertex/3; + mesh.vertices = vData; + mesh.texcoords = vtData; + mesh.texcoords2 = NULL; + mesh.normals = vnData; + mesh.tangents = NULL; + mesh.colors = (unsigned char *)cData; + mesh.indices = NULL; + + rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) + + return mesh; +} + +// Load model from file +Model LoadModel(const char *fileName) +{ + Model model = { 0 }; + + model.mesh = LoadMesh(fileName); + model.transform = MatrixIdentity(); + model.material = LoadDefaultMaterial(); return model; } -// Load a 3d model (from vertex data) -Model LoadModelEx(Mesh data, bool dynamic) +// Load model from mesh data +Model LoadModelFromMesh(Mesh data, bool dynamic) { Model model = { 0 }; @@ -648,7 +675,7 @@ Model LoadModelEx(Mesh data, bool dynamic) return model; } -// Load a heightmap image as a 3d model +// Load heightmap model from image data // NOTE: model map size is defined in generic units Model LoadHeightmap(Image heightmap, Vector3 size) { @@ -664,7 +691,7 @@ Model LoadHeightmap(Image heightmap, Vector3 size) return model; } -// Load a map image as a 3d model (cubes based) +// Load cubes-based map model from image data Model LoadCubicmap(Image cubicmap) { Model model = { 0 }; @@ -678,15 +705,20 @@ Model LoadCubicmap(Image cubicmap) return model; } + +// Unload mesh from memory (RAM and/or VRAM) +void UnloadMesh(Mesh *mesh) +{ + rlglUnloadMesh(mesh); +} -// Unload 3d model from memory (mesh and material) +// Unload model from memory (RAM and/or VRAM) void UnloadModel(Model model) { - rlglUnloadMesh(&model.mesh); - + UnloadMesh(&model.mesh); UnloadMaterial(model.material); - TraceLog(INFO, "Unloaded model data from RAM and VRAM"); + TraceLog(INFO, "Unloaded model data (mesh and material) from RAM and VRAM"); } // Load material data (from file) -- cgit v1.2.3 From 6d6c542a1dabfddc988c20de669c8a5e4d9b04a0 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 02:00:36 +0100 Subject: Review some functions for consistency Removed: LoadTextureEx() Added: LoadImagePro() --- src/textures.c | 239 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 118 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/textures.c b/src/textures.c index 92b22317..7fd4a3d5 100644 --- a/src/textures.c +++ b/src/textures.c @@ -93,7 +93,7 @@ static Image LoadASTC(const char *fileName); // Load ASTC file // Module Functions Definition //---------------------------------------------------------------------------------- -// Load an image into CPU memory (RAM) +// Load image from file into CPU memory (RAM) Image LoadImage(const char *fileName) { Image image; @@ -142,16 +142,13 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"pvr") == 0) image = LoadPVR(fileName); else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); - if (image.data != NULL) - { - TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height); - } - else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName); + if (image.data != NULL) TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height); + else TraceLog(WARNING, "[%s] Image could not be loaded", fileName); return image; } -// Load image data from Color array data (RGBA - 32bit) +// Load image from Color array data (RGBA - 32bit) // NOTE: Creates a copy of pixels data array Image LoadImageEx(Color *pixels, int width, int height) { @@ -178,7 +175,22 @@ Image LoadImageEx(Color *pixels, int width, int height) return image; } -// Load an image from RAW file +// Load image from raw data with parameters +// NOTE: This functions does not make a copy of data +Image LoadImagePro(void *data, int width, int height, int format) +{ + Image image; + + image.data = data; + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = format; + + return image; +} + +// Load an image from RAW file data Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize) { Image image; @@ -228,7 +240,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int return image; } -// Load an image as texture into GPU memory +// Load texture from file into GPU memory (VRAM) Texture2D LoadTexture(const char *fileName) { Texture2D texture; @@ -249,21 +261,6 @@ Texture2D LoadTexture(const char *fileName) return texture; } -// Load a texture from raw data into GPU memory -Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat) -{ - Texture2D texture; - - texture.width = width; - texture.height = height; - texture.mipmaps = 1; - texture.format = textureFormat; - - texture.id = rlglLoadTexture(data, width, height, textureFormat, 1); - - return texture; -} - // Load a texture from image data // NOTE: image is not unloaded, it must be done manually Texture2D LoadTextureFromImage(Image image) @@ -287,7 +284,7 @@ Texture2D LoadTextureFromImage(Image image) return texture; } -// Load a texture to be used for rendering +// Load texture for rendering (framebuffer) RenderTexture2D LoadRenderTexture(int width, int height) { RenderTexture2D target = rlglLoadRenderTexture(width, height); @@ -304,7 +301,7 @@ void UnloadImage(Image image) //TraceLog(INFO, "Unloaded image data"); } -// Unload texture from GPU memory +// Unload texture from GPU memory (VRAM) void UnloadTexture(Texture2D texture) { if (texture.id != 0) @@ -315,102 +312,12 @@ void UnloadTexture(Texture2D texture) } } -// Unload render texture from GPU memory +// Unload render texture from GPU memory (VRAM) void UnloadRenderTexture(RenderTexture2D target) { if (target.id != 0) rlDeleteRenderTextures(target); } -// Set texture scaling filter mode -void SetTextureFilter(Texture2D texture, int filterMode) -{ - switch (filterMode) - { - case FILTER_POINT: - { - if (texture.mipmaps > 1) - { - // RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps) - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST); - - // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); - } - else - { - // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_NEAREST); - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); - } - } break; - case FILTER_BILINEAR: - { - if (texture.mipmaps > 1) - { - // RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps) - // Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps) - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST); - - // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); - } - else - { - // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); - } - } break; - case FILTER_TRILINEAR: - { - if (texture.mipmaps > 1) - { - // RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps) - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR); - - // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); - } - else - { - TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id); - - // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps - rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); - rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); - } - } break; - case FILTER_ANISOTROPIC_4X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 4); break; - case FILTER_ANISOTROPIC_8X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 8); break; - case FILTER_ANISOTROPIC_16X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 16); break; - default: break; - } -} - -// Set texture wrapping mode -void SetTextureWrap(Texture2D texture, int wrapMode) -{ - switch (wrapMode) - { - case WRAP_REPEAT: - { - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_REPEAT); - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_REPEAT); - } break; - case WRAP_CLAMP: - { - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP); - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP); - } break; - case WRAP_MIRROR: - { - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP_MIRROR); - rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP_MIRROR); - } break; - default: break; - } -} - // Get pixel data from image in the form of Color struct array Color *GetImageData(Image image) { @@ -529,6 +436,13 @@ Image GetTextureData(Texture2D texture) return image; } +// Update GPU texture with new data +// NOTE: pixels data must match texture.format +void UpdateTexture(Texture2D texture, const void *pixels) +{ + rlglUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels); +} + // Convert image data to desired format void ImageFormat(Image *image, int newFormat) { @@ -1408,11 +1322,94 @@ void GenTextureMipmaps(Texture2D *texture) #endif } -// Update GPU texture with new data -// NOTE: pixels data must match texture.format -void UpdateTexture(Texture2D texture, void *pixels) +// Set texture scaling filter mode +void SetTextureFilter(Texture2D texture, int filterMode) { - rlglUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels); + switch (filterMode) + { + case FILTER_POINT: + { + if (texture.mipmaps > 1) + { + // RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps) + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST); + + // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); + } + else + { + // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_NEAREST); + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); + } + } break; + case FILTER_BILINEAR: + { + if (texture.mipmaps > 1) + { + // RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps) + // Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps) + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST); + + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); + } + else + { + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); + } + } break; + case FILTER_TRILINEAR: + { + if (texture.mipmaps > 1) + { + // RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps) + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR); + + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); + } + else + { + TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id); + + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps + rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); + rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); + } + } break; + case FILTER_ANISOTROPIC_4X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 4); break; + case FILTER_ANISOTROPIC_8X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 8); break; + case FILTER_ANISOTROPIC_16X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 16); break; + default: break; + } +} + +// Set texture wrapping mode +void SetTextureWrap(Texture2D texture, int wrapMode) +{ + switch (wrapMode) + { + case WRAP_REPEAT: + { + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_REPEAT); + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_REPEAT); + } break; + case WRAP_CLAMP: + { + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP); + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP); + } break; + case WRAP_MIRROR: + { + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP_MIRROR); + rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP_MIRROR); + } break; + default: break; + } } // Draw a Texture2D -- cgit v1.2.3 From 852f3d4fd0eec8fcebcf39dfc19b2ccc5b008ba3 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 02:01:13 +0100 Subject: Review comments and formatting --- src/core.c | 2 +- src/raylib.h | 110 ++++++++++++++++++++++++++++++++--------------------------- src/rlgl.c | 6 ++-- src/rlgl.h | 2 +- src/text.c | 12 +++---- 5 files changed, 70 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 1e03b757..4793e26a 100644 --- a/src/core.c +++ b/src/core.c @@ -1194,7 +1194,7 @@ const char *GetGamepadName(int gamepad) if (gamepadReady[gamepad]) return glfwGetJoystickName(gamepad); else return NULL; #elif defined(PLATFORM_RPI) - if (gamepadReady[gamepad]) ioctl(gamepadStream[gamepad], JSIOCGNAME(64), &gamepadName); + if (gamepadReady[gamepad]) ioctl(gamepadStream[gamepad], JSIOCGNAME(64), &gamepadName); return gamepadName; #else diff --git a/src/raylib.h b/src/raylib.h index fff0c928..6fd960dc 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -351,7 +351,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Image; // Texture2D type, bpp always RGBA (32bit) @@ -361,12 +361,12 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Texture2D; // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { - unsigned int id; // Render texture (fbo) id + unsigned int id; // OpenGL Framebuffer Object (FBO) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; @@ -767,19 +767,19 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) +RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image @@ -792,7 +792,8 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, + float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint @@ -815,9 +816,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont -RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters @@ -853,40 +854,48 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -RLAPI void UnloadModel(Model model); // Unload 3d model from memory - -RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL) -RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM - -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file +RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data +RLAPI Model LoadModel(const char *fileName); // Load model from file +RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data +RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data +RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) +RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) + +RLAPI Material LoadMaterial(const char *fileName); // Load material from file +RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, + Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, + Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetStandardShader(void); // Get standard shader @@ -926,12 +935,11 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM -RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -RLAPI Sound LoadSound(const char *fileName); // Load sound to memory -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -961,7 +969,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/src/rlgl.c b/src/rlgl.c index c694dcdc..ae28d9b6 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1690,7 +1690,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) } // Update already loaded texture in GPU with new data -void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data) +void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void *data) { glBindTexture(GL_TEXTURE_2D, id); @@ -2423,7 +2423,7 @@ Texture2D GetDefaultTexture(void) return texture; } -// Load a custom shader and bind default locations +// Load shader from files and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName) { Shader shader = { 0 }; @@ -2455,7 +2455,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName) return shader; } -// Unload a custom shader from memory +// Unload shader from GPU memory (VRAM) void UnloadShader(Shader shader) { if (shader.id != 0) diff --git a/src/rlgl.h b/src/rlgl.h index bc12db0f..b7c9df00 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -370,7 +370,7 @@ void rlglLoadExtensions(void *loader); // Load OpenGL extensions unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) -void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data +void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void *data); // Update GPU texture with new data void rlglGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids diff --git a/src/text.c b/src/text.c index 27b0a9ce..f97b581d 100644 --- a/src/text.c +++ b/src/text.c @@ -249,7 +249,7 @@ SpriteFont GetDefaultFont() return defaultFont; } -// Load a SpriteFont image into GPU memory +// Load SpriteFont from file into GPU memory (VRAM) SpriteFont LoadSpriteFont(const char *fileName) { // Default hardcoded values for ttf file loading @@ -280,7 +280,7 @@ SpriteFont LoadSpriteFont(const char *fileName) return spriteFont; } -// Load SpriteFont from TTF file with custom parameters +// Load SpriteFont from TTF font file with generation parameters // NOTE: You can pass an array with desired characters, those characters should be available in the font // if array is NULL, default char set is selected 32..126 SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars) @@ -311,7 +311,7 @@ SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, i return spriteFont; } -// Unload SpriteFont from GPU memory +// Unload SpriteFont from GPU memory (VRAM) void UnloadSpriteFont(SpriteFont spriteFont) { // NOTE: Make sure spriteFont is not default font (fallback) @@ -460,13 +460,13 @@ int MeasureText(const char *text, int fontSize) Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) { int len = strlen(text); - int tempLen = 0; // Used to count longer text line num chars + int tempLen = 0; // Used to count longer text line num chars int lenCounter = 0; float textWidth = 0; - float tempTextWidth = 0; // Used to count longer text line width + float tempTextWidth = 0; // Used to count longer text line width - float textHeight = (float)spriteFont.size; + float textHeight = (float)spriteFont.size; float scaleFactor = fontSize/(float)spriteFont.size; for (int i = 0; i < len; i++) -- cgit v1.2.3 From 14cdd7fbfff43dbdb869a74dbe846ac38afef532 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 20:41:36 +0100 Subject: Added raw image file reading data check --- src/textures.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/textures.c b/src/textures.c index 7fd4a3d5..8b223ed0 100644 --- a/src/textures.c +++ b/src/textures.c @@ -225,14 +225,22 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int default: TraceLog(WARNING, "Image format not suported"); break; } - fread(image.data, size, 1, rawFile); + int bytes = fread(image.data, size, 1, rawFile); - // TODO: Check if data has been read - - image.width = width; - image.height = height; - image.mipmaps = 0; - image.format = format; + // Check if data has been read successfully + if (bytes < size) + { + TraceLog(WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName); + + if (image.data != NULL) free(image.data); + } + else + { + image.width = width; + image.height = height; + image.mipmaps = 0; + image.format = format; + } fclose(rawFile); } @@ -983,7 +991,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) Color srcCol, dstCol; // Blit pixels, copy source image into destination - // TODO: Probably out-of-bounds blitting could be considering here instead of so much cropping... + // TODO: Probably out-of-bounds blitting could be considered here instead of so much cropping... for (int j = dstRec.y; j < (dstRec.y + dstRec.height); j++) { for (int i = dstRec.x; i < (dstRec.x + dstRec.width); i++) -- cgit v1.2.3 From a27be5f2a96810e5dd23cccf52c7a461431ee32c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Dec 2016 20:42:22 +0100 Subject: Added support for gamepads on PLATFORM_WEB Feature NOT TESTED yet... --- src/core.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 4793e26a..a210df56 100644 --- a/src/core.c +++ b/src/core.c @@ -263,9 +263,9 @@ static bool GetMouseButtonStatus(int button); // Returns if a mouse bu static void PollInputEvents(void); // Register user events static void SwapBuffers(void); // Copy back buffer to front buffers static void LogoAnimation(void); // Plays raylib logo appearing animation +static void SetupViewport(void); // Set viewport parameters #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable -static void SetupViewport(void); #endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) @@ -292,6 +292,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #if defined(PLATFORM_WEB) static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData); static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); +static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); #endif #if defined(PLATFORM_RPI) @@ -346,9 +347,9 @@ void InitWindow(int width, int height, const char *title) emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback); emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback); - // TODO: Add gamepad support (not provided by GLFW3 on emscripten) - //emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenInputCallback); - //emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback); + // Support gamepad (not provided by GLFW3 on emscripten) + emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback); + emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback); #endif mousePosition.x = (float)screenWidth/2.0f; @@ -1795,6 +1796,7 @@ static void InitGraphicsDevice(int width, int height) #endif } +// Set viewport parameters static void SetupViewport(void) { #ifdef __APPLE__ @@ -1941,7 +1943,7 @@ static bool GetMouseButtonStatus(int button) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) return glfwGetMouseButton(window, button); #elif defined(PLATFORM_ANDROID) - // TODO: Check for virtual mouse + // TODO: Check for virtual mouse? return false; #elif defined(PLATFORM_RPI) // NOTE: Mouse buttons states are filled in PollInputEvents() @@ -1987,8 +1989,6 @@ static void PollInputEvents(void) currentMouseWheelY = 0; #endif -// NOTE: GLFW3 joystick functionality not available in web -// TODO: Support joysticks using emscripten API #if defined(PLATFORM_DESKTOP) // Check if gamepads are ready // NOTE: We do it here in case of disconection @@ -2041,6 +2041,47 @@ static void PollInputEvents(void) glfwPollEvents(); // Register keyboard/mouse events (callbacks)... and window events! #endif +// Gamepad support using emscripten API +// NOTE: GLFW3 joystick functionality not available in web +#if defined(PLATFORM_WEB) + // Get number of gamepads connected + int numGamepads = emscripten_get_num_gamepads(); + + for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++) + { + // Register previous gamepad button states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k]; + + EmscriptenGamepadEvent gamepadState; + + int result = emscripten_get_gamepad_status(i, &gamepadState); + + if (result == EMSCRIPTEN_RESULT_SUCCESS) + { + // Register buttons data for every connected gamepad + for (int j = 0; (j < gamepadState.numButtons) && (j < MAX_GAMEPAD_BUTTONS); j++) + { + if (gamepadState.digitalButton[j] == 1) + { + currentGamepadState[i][j] = 1; + lastGamepadButtonPressed = j; + } + else currentGamepadState[i][j] = 0; + + //printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); + } + + // Register axis data for every connected gamepad + for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++) + { + gamepadAxisState[i][j] = gamepadState.axis[j]; + } + + gamepadAxisCount = gamepadState.numAxes; + } + } +#endif + #if defined(PLATFORM_ANDROID) // Register previous keys states // NOTE: Android supports up to 260 keys @@ -2487,6 +2528,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #endif #if defined(PLATFORM_WEB) + +// Register fullscreen change events static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData) { //isFullscreen: int e->isFullscreen @@ -2510,7 +2553,7 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte return 0; } -// Web: Get input events +// Register touch input events static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) { /* @@ -2574,6 +2617,26 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent return 1; } + +// Register connected/disconnected gamepads events +static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) +{ + /* + printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n", + eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state", + gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); + + for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]); + for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); + */ + + if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true; + else gamepadReady[gamepadEvent->index] = false; + + // TODO: Test gamepadEvent->index + + return 0; +} #endif #if defined(PLATFORM_RPI) -- cgit v1.2.3 From 5da815234c850dd1f1517e89854bbbed4eeb02e8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 26 Dec 2016 10:52:57 +0100 Subject: Improved FLAC audio support --- examples/resources/audio/tanatana.flac | Bin 0 -> 100733 bytes src/audio.c | 25 +-- src/external/dr_flac.h | 323 +++++++++++++++++++++++++-------- 3 files changed, 255 insertions(+), 93 deletions(-) create mode 100644 examples/resources/audio/tanatana.flac (limited to 'src') diff --git a/examples/resources/audio/tanatana.flac b/examples/resources/audio/tanatana.flac new file mode 100644 index 00000000..dfe735cd Binary files /dev/null and b/examples/resources/audio/tanatana.flac differ diff --git a/src/audio.c b/src/audio.c index 04ff90da..3a4ca3df 100644 --- a/src/audio.c +++ b/src/audio.c @@ -593,6 +593,7 @@ Music LoadMusicStream(const char *fileName) music->ctxType = MUSIC_AUDIO_OGG; music->loop = true; // We loop by default + TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels); TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required); @@ -606,11 +607,12 @@ Music LoadMusicStream(const char *fileName) else { music->stream = InitAudioStream(music->ctxFlac->sampleRate, music->ctxFlac->bitsPerSample, music->ctxFlac->channels); - music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount; + music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount/music->ctxFlac->channels; music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_FLAC; music->loop = true; // We loop by default + TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate); TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample); TraceLog(DEBUG, "[%s] FLAC channels: %i", fileName, music->ctxFlac->channels); @@ -745,9 +747,7 @@ void UpdateMusicStream(Music music) case MUSIC_AUDIO_FLAC: { // NOTE: Returns the number of samples to process - unsigned int numSamplesFlac = (unsigned int)drflac_read_s32(music->ctxFlac, numSamples/2, (int *)pcm); - - // TODO: Samples should be provided as 16 bit instead of 32 bit! + unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, numSamples*music->stream.channels, (short *)pcm); } break; case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, numSamples); break; @@ -1145,21 +1145,14 @@ static Wave LoadFLAC(const char *fileName) // Decode an entire FLAC file in one go uint64_t totalSampleCount; - wave.data = drflac_open_and_decode_file_s32(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); - - wave.sampleCount = (int)totalSampleCount; - wave.sampleSize = 32; // 32 bit per sample (float) + wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); - // NOTE: By default, dr_flac returns 32bit float samples, needs to be converted to 16bit - WaveFormat(&wave, wave.sampleRate, 16, wave.channels); + wave.sampleCount = (int)totalSampleCount/wave.channels; + wave.sampleSize = 16; // NOTE: Only support up to 2 channels (mono, stereo) - if (wave.channels > 2) - { - WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); - TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); - } - + if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels); + if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName); else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); diff --git a/src/external/dr_flac.h b/src/external/dr_flac.h index d7b66f20..d2bebea5 100644 --- a/src/external/dr_flac.h +++ b/src/external/dr_flac.h @@ -1,5 +1,5 @@ // FLAC audio decoder. Public domain. See "unlicense" statement at the end of this file. -// dr_flac - v0.4 - 2016-09-29 +// dr_flac - v0.4c - 2016-12-26 // // David Reid - mackron@gmail.com @@ -105,18 +105,32 @@ #include #include -#ifndef DR_BOOL_DEFINED -#define DR_BOOL_DEFINED -#ifdef _WIN32 -typedef char drBool8; -typedef int drBool32; +#ifndef DR_SIZED_TYPES_DEFINED +#define DR_SIZED_TYPES_DEFINED +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef signed char dr_int8; +typedef unsigned char dr_uint8; +typedef signed short dr_int16; +typedef unsigned short dr_uint16; +typedef signed int dr_int32; +typedef unsigned int dr_uint32; +typedef signed __int64 dr_int64; +typedef unsigned __int64 dr_uint64; #else #include -typedef int8_t drBool8; -typedef int32_t drBool32; +typedef int8_t dr_int8; +typedef uint8_t dr_uint8; +typedef int16_t dr_int16; +typedef uint16_t dr_uint16; +typedef int32_t dr_int32; +typedef uint32_t dr_uint32; +typedef int64_t dr_int64; +typedef uint64_t dr_uint64; #endif -#define DR_TRUE 1 -#define DR_FALSE 0 +typedef dr_int8 dr_bool8; +typedef dr_int32 dr_bool32; +#define DR_TRUE 1 +#define DR_FALSE 0 #endif // As data is read from the client it is placed into an internal buffer for fast access. This controls the @@ -262,7 +276,7 @@ typedef struct { char catalog[128]; uint64_t leadInSampleCount; - drBool32 isCD; + dr_bool32 isCD; uint8_t trackCount; const uint8_t* pTrackData; } cuesheet; @@ -305,7 +319,7 @@ typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t by // // The offset will never be negative. Whether or not it is relative to the beginning or current position is determined // by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current. -typedef drBool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); +typedef dr_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); // Callback for when a metadata block is read. // @@ -546,6 +560,10 @@ void drflac_close(drflac* pFlac); // seeked. uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* pBufferOut); +// Same as drflac_read_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit. Note +// that this is lossey. +uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut); + // Seeks to the sample at the given index. // // pFlac [in] The decoder. @@ -558,7 +576,7 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* pBuffer // // When seeking, you will likely want to ensure it's rounded to a multiple of the channel count. You can do this with // something like drflac_seek_to_sample(pFlac, (mySampleIndex + (mySampleIndex % pFlac->channels))) -drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex); +dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex); @@ -607,14 +625,17 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl // // Do not call this function on a broadcast type of stream (like internet radio streams and whatnot). int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); #ifndef DR_FLAC_NO_STDIO // Same as drflac_open_and_decode_s32() except opens the decoder from a file. int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); #endif // Same as drflac_open_and_decode_s32() except opens the decoder from a block of memory. int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); // Frees data returned by drflac_open_and_decode_*(). void drflac_free(void* pSampleDataReturnedByOpenAndDecode); @@ -684,7 +705,7 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui //// Endian Management //// -static DRFLAC_INLINE drBool32 drflac__is_little_endian() +static DRFLAC_INLINE dr_bool32 drflac__is_little_endian() { int n = 1; return (*(char*)&n) == 1; @@ -817,7 +838,7 @@ static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n) #define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0])) #define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line) -static DRFLAC_INLINE drBool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) +static DRFLAC_INLINE dr_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) { // Fast path. Try loading straight from L2. if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { @@ -871,7 +892,7 @@ static DRFLAC_INLINE drBool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) } } -static drBool32 drflac__reload_cache(drflac_bs* bs) +static dr_bool32 drflac__reload_cache(drflac_bs* bs) { // Fast path. Try just moving the next value in the L2 cache to the L1 cache. if (drflac__reload_l1_cache_from_l2(bs)) { @@ -907,7 +928,7 @@ static void drflac__reset_cache(drflac_bs* bs) bs->unalignedCache = 0; } -static drBool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) +static dr_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) { if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) { bs->consumedBits += bitsToSeek; @@ -958,7 +979,7 @@ static drBool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) } } -static drBool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32_t* pResultOut) +static dr_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32_t* pResultOut) { assert(bs != NULL); assert(pResultOut != NULL); @@ -999,7 +1020,7 @@ static drBool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32 } } -static drBool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t* pResult) +static dr_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1018,7 +1039,7 @@ static drBool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t return DR_TRUE; } -static drBool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64_t* pResultOut) +static dr_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64_t* pResultOut) { assert(bitCount <= 64); assert(bitCount > 32); @@ -1039,7 +1060,7 @@ static drBool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64 // Function below is unused, but leaving it here in case I need to quickly add it again. #if 0 -static drBool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t* pResultOut) +static dr_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t* pResultOut) { assert(bitCount <= 64); @@ -1056,7 +1077,7 @@ static drBool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t } #endif -static drBool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16_t* pResult) +static dr_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1072,7 +1093,7 @@ static drBool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16 return DR_TRUE; } -static drBool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t* pResult) +static dr_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1088,7 +1109,7 @@ static drBool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t return DR_TRUE; } -static drBool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t* pResult) +static dr_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1104,7 +1125,7 @@ static drBool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t return DR_TRUE; } -static drBool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* pResult) +static dr_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1121,7 +1142,7 @@ static drBool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* } -static inline drBool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) +static inline dr_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) { unsigned int zeroCounter = 0; while (bs->cache == 0) { @@ -1169,7 +1190,7 @@ static inline drBool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned in -static drBool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) +static dr_bool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) { assert(bs != NULL); assert(offsetFromStart > 0); @@ -1214,7 +1235,7 @@ static drBool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) } -static drBool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberOut) +static dr_bool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberOut) { assert(bs != NULL); assert(pNumberOut != NULL); @@ -1267,7 +1288,7 @@ static drBool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberO -static DRFLAC_INLINE drBool32 drflac__read_and_seek_rice(drflac_bs* bs, uint8_t m) +static DRFLAC_INLINE dr_bool32 drflac__read_and_seek_rice(drflac_bs* bs, uint8_t m) { unsigned int unused; if (!drflac__seek_past_next_set_bit(bs, &unused)) { @@ -1520,7 +1541,7 @@ static DRFLAC_INLINE int32_t drflac__calculate_prediction_64(uint32_t order, int // iteration. The prediction is done at the end, and there's an annoying branch I'd like to avoid so the main function is defined // as a #define - sue me! #define DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(funcName, predictionFunc) \ -static drBool32 funcName (drflac_bs* bs, uint32_t count, uint8_t riceParam, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) \ +static dr_bool32 funcName (drflac_bs* bs, uint32_t count, uint8_t riceParam, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) \ { \ assert(bs != NULL); \ assert(count > 0); \ @@ -1630,7 +1651,7 @@ DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(drflac__decode_samples_with_res // Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. -static drBool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t count, uint8_t riceParam) +static dr_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t count, uint8_t riceParam) { assert(bs != NULL); assert(count > 0); @@ -1644,7 +1665,7 @@ static drBool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t cou return DR_TRUE; } -static drBool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, uint32_t bitsPerSample, uint32_t count, uint8_t unencodedBitsPerSample, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) +static dr_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, uint32_t bitsPerSample, uint32_t count, uint8_t unencodedBitsPerSample, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) { assert(bs != NULL); assert(count > 0); @@ -1671,7 +1692,7 @@ static drBool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, u // Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called // when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be ignored. The // and parameters are used to determine how many residual values need to be decoded. -static drBool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bitsPerSample, uint32_t blockSize, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bitsPerSample, uint32_t blockSize, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples) { assert(bs != NULL); assert(blockSize != 0); @@ -1755,7 +1776,7 @@ static drBool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bit // Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called // when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be set to 0. The // and parameters are used to determine how many residual values need to be decoded. -static drBool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize, uint32_t order) +static dr_bool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize, uint32_t order) { assert(bs != NULL); assert(blockSize != 0); @@ -1823,7 +1844,7 @@ static drBool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize } -static drBool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) { // Only a single sample needs to be decoded here. int32_t sample; @@ -1840,7 +1861,7 @@ static drBool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSi return DR_TRUE; } -static drBool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) { for (uint32_t i = 0; i < blockSize; ++i) { int32_t sample; @@ -1854,7 +1875,7 @@ static drBool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSi return DR_TRUE; } -static drBool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) { short lpcCoefficientsTable[5][4] = { {0, 0, 0, 0}, @@ -1882,7 +1903,7 @@ static drBool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, return DR_TRUE; } -static drBool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) { // Warm up samples. for (uint8_t i = 0; i < lpcOrder; ++i) { @@ -1925,7 +1946,7 @@ static drBool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, u } -static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfoBitsPerSample, drflac_frame_header* header) +static dr_bool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfoBitsPerSample, drflac_frame_header* header) { assert(bs != NULL); assert(header != NULL); @@ -1983,7 +2004,7 @@ static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfo } - drBool32 isVariableBlockSize = blockingStrategy == 1; + dr_bool32 isVariableBlockSize = blockingStrategy == 1; if (isVariableBlockSize) { uint64_t sampleNumber; if (!drflac__read_utf8_coded_number(bs, &sampleNumber)) { @@ -2055,7 +2076,7 @@ static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfo return DR_TRUE; } -static drBool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) +static dr_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) { uint8_t header; if (!drflac__read_uint8(bs, 8, &header)) { @@ -2105,7 +2126,7 @@ static drBool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSu return DR_TRUE; } -static drBool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, int32_t* pDecodedSamplesOut) +static dr_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, int32_t* pDecodedSamplesOut) { assert(bs != NULL); assert(frame != NULL); @@ -2155,7 +2176,7 @@ static drBool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int return DR_TRUE; } -static drBool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) +static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) { assert(bs != NULL); assert(frame != NULL); @@ -2249,7 +2270,7 @@ static DRFLAC_INLINE uint8_t drflac__get_channel_count_from_channel_assignment(i return lookup[channelAssignment]; } -static drBool32 drflac__decode_frame(drflac* pFlac) +static dr_bool32 drflac__decode_frame(drflac* pFlac) { // This function should be called while the stream is sitting on the first byte after the frame header. memset(pFlac->currentFrame.subframes, 0, sizeof(pFlac->currentFrame.subframes)); @@ -2273,7 +2294,7 @@ static drBool32 drflac__decode_frame(drflac* pFlac) return DR_TRUE; } -static drBool32 drflac__seek_frame(drflac* pFlac) +static dr_bool32 drflac__seek_frame(drflac* pFlac) { int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); for (int i = 0; i < channelCount; ++i) @@ -2287,7 +2308,7 @@ static drBool32 drflac__seek_frame(drflac* pFlac) return drflac__seek_bits(&pFlac->bs, (DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7) + 16); } -static drBool32 drflac__read_and_decode_next_frame(drflac* pFlac) +static dr_bool32 drflac__read_and_decode_next_frame(drflac* pFlac) { assert(pFlac != NULL); @@ -2324,24 +2345,24 @@ static void drflac__get_current_frame_sample_range(drflac* pFlac, uint64_t* pFir } } -static drBool32 drflac__seek_to_first_frame(drflac* pFlac) +static dr_bool32 drflac__seek_to_first_frame(drflac* pFlac) { assert(pFlac != NULL); - drBool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); + dr_bool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); memset(&pFlac->currentFrame, 0, sizeof(pFlac->currentFrame)); return result; } -static DRFLAC_INLINE drBool32 drflac__seek_to_next_frame(drflac* pFlac) +static DRFLAC_INLINE dr_bool32 drflac__seek_to_next_frame(drflac* pFlac) { // This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. assert(pFlac != NULL); return drflac__seek_frame(pFlac); } -static drBool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t sampleIndex) { assert(pFlac != NULL); @@ -2372,7 +2393,7 @@ static drBool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t return DR_TRUE; } -static drBool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t sampleIndex) { if (!drflac__seek_to_frame_containing_sample(pFlac, sampleIndex)) { return DR_FALSE; @@ -2398,7 +2419,7 @@ static drBool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t samp } -static drBool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t sampleIndex) { assert(pFlac != NULL); @@ -2508,7 +2529,7 @@ typedef struct uint64_t totalSampleCount; uint16_t maxBlockSize; uint64_t runningFilePos; - drBool32 hasMetadataBlocks; + dr_bool32 hasMetadataBlocks; #ifndef DR_FLAC_NO_OGG uint32_t oggSerial; @@ -2525,7 +2546,7 @@ static DRFLAC_INLINE void drflac__decode_block_header(uint32_t blockHeader, uint *blockSize = (blockHeader & 0xFFFFFF); } -static DRFLAC_INLINE drBool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize) +static DRFLAC_INLINE dr_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize) { uint32_t blockHeader; if (onRead(pUserData, &blockHeader, 4) != 4) { @@ -2536,7 +2557,7 @@ static DRFLAC_INLINE drBool32 drflac__read_and_decode_block_header(drflac_read_p return DR_TRUE; } -drBool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) +dr_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) { // min/max block size. uint32_t blockSizes; @@ -2579,7 +2600,7 @@ drBool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drfla return DR_TRUE; } -drBool32 drflac__read_and_decode_metadata(drflac* pFlac) +dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac) { assert(pFlac != NULL); @@ -2823,7 +2844,7 @@ drBool32 drflac__read_and_decode_metadata(drflac* pFlac) return DR_TRUE; } -drBool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { (void)onSeek; @@ -2869,7 +2890,7 @@ drBool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc } #ifndef DR_FLAC_NO_OGG -static DRFLAC_INLINE drBool32 drflac_ogg__is_capture_pattern(uint8_t pattern[4]) +static DRFLAC_INLINE dr_bool32 drflac_ogg__is_capture_pattern(uint8_t pattern[4]) { return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S'; } @@ -2889,7 +2910,7 @@ static DRFLAC_INLINE uint32_t drflac_ogg__get_page_body_size(drflac_ogg_page_hea return pageBodySize; } -drBool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) +dr_bool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) { if (onRead(pUserData, &pHeader->structureVersion, 1) != 1 || pHeader->structureVersion != 0) { return DR_FALSE; // Unknown structure version. Possibly corrupt stream. @@ -2920,7 +2941,7 @@ drBool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onR return DR_TRUE; } -drBool32 drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) +dr_bool32 drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) { uint8_t id[4]; if (onRead(pUserData, id, 4) != 4) { @@ -2961,7 +2982,7 @@ static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, return bytesActuallyRead; } -static drBool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset, drflac_seek_origin origin) +static dr_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset, drflac_seek_origin origin) { if (origin == drflac_seek_origin_start) { @@ -3000,7 +3021,7 @@ static drBool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset } } -static drBool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs) { drflac_ogg_page_header header; for (;;) @@ -3049,12 +3070,12 @@ static uint8_t drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, uint return iSeg; } -static drBool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) { // The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. for (;;) // <-- Loop over pages. { - drBool32 atEndOfPage = DR_FALSE; + dr_bool32 atEndOfPage = DR_FALSE; uint8_t bytesRemainingInSeg; uint8_t iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg); @@ -3099,7 +3120,7 @@ static drBool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) } } -static drBool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) { // The bitstream should be sitting on the first byte just after the header of the frame. @@ -3148,7 +3169,7 @@ static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytes return bytesRead; } -static drBool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) { drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; assert(oggbs != NULL); @@ -3204,7 +3225,7 @@ static drBool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_ori return DR_TRUE; } -drBool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) +dr_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) { drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + pFlac->maxBlockSize*pFlac->channels); @@ -3327,7 +3348,7 @@ drBool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) } -drBool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { // Pre: The bit stream should be sitting just past the 4-byte OggS capture pattern. @@ -3491,7 +3512,7 @@ drBool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onR } #endif -drBool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { if (pInit == NULL || onRead == NULL || onSeek == NULL) { return DR_FALSE; @@ -3610,7 +3631,7 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData); } -static drBool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) { assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); @@ -3651,7 +3672,7 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt return (size_t)bytesRead; } -static drBool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) { assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); @@ -3727,7 +3748,7 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by return bytesToRead; } -static drBool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) { drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; assert(memoryStream != NULL); @@ -4107,7 +4128,32 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO return samplesRead; } -drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) +uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut) +{ + // This reads samples in 2 passes and can probably be optimized. + uint64_t samplesRead = 0; + + while (samplesToRead > 0) { + int32_t samples32[4096]; + uint64_t samplesJustRead = drflac_read_s32(pFlac, samplesToRead > 4096 ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) { + break; // Reached the end. + } + + // s32 -> s16 + for (uint64_t i = 0; i < samplesJustRead; ++i) { + pBufferOut[i] = (int16_t)(samples32[i] >> 16); + } + + samplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + + return samplesRead; +} + +dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) { if (pFlac == NULL) { return DR_FALSE; @@ -4147,7 +4193,7 @@ drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) //// High Level APIs //// -int32_t* drflac__full_decode_and_close(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) +int32_t* drflac__full_decode_and_close_s32(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) { assert(pFlac != NULL); @@ -4218,6 +4264,77 @@ on_error: return NULL; } +int16_t* drflac__full_decode_and_close_s16(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) +{ + assert(pFlac != NULL); + + int16_t* pSampleData = NULL; + uint64_t totalSampleCount = pFlac->totalSampleCount; + + if (totalSampleCount == 0) + { + int16_t buffer[4096]; + + size_t sampleDataBufferSize = sizeof(buffer); + pSampleData = (int16_t*)malloc(sampleDataBufferSize); + if (pSampleData == NULL) { + goto on_error; + } + + uint64_t samplesRead; + while ((samplesRead = (uint64_t)drflac_read_s16(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0) + { + if (((totalSampleCount + samplesRead) * sizeof(int16_t)) > sampleDataBufferSize) { + sampleDataBufferSize *= 2; + int16_t* pNewSampleData = (int16_t*)realloc(pSampleData, sampleDataBufferSize); + if (pNewSampleData == NULL) { + free(pSampleData); + goto on_error; + } + + pSampleData = pNewSampleData; + } + + memcpy(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(int16_t))); + totalSampleCount += samplesRead; + } + + // At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to + // protect those ears from random noise! + memset(pSampleData + totalSampleCount, 0, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(int16_t))); + } + else + { + uint64_t dataSize = totalSampleCount * sizeof(int16_t); + if (dataSize > SIZE_MAX) { + goto on_error; // The decoded data is too big. + } + + pSampleData = (int16_t*)malloc((size_t)dataSize); // <-- Safe cast as per the check above. + if (pSampleData == NULL) { + goto on_error; + } + + uint64_t samplesDecoded = drflac_read_s16(pFlac, pFlac->totalSampleCount, pSampleData); + if (samplesDecoded != pFlac->totalSampleCount) { + free(pSampleData); + goto on_error; // Something went wrong when decoding the FLAC stream. + } + } + + + if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; + if (channelsOut) *channelsOut = pFlac->channels; + if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount; + + drflac_close(pFlac); + return pSampleData; + +on_error: + drflac_close(pFlac); + return NULL; +} + int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) { // Safety. @@ -4230,7 +4347,22 @@ int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc on return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + // Safety. + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } #ifndef DR_FLAC_NO_STDIO @@ -4245,7 +4377,21 @@ int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* cha return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open_file(filename); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } #endif @@ -4260,7 +4406,21 @@ int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, un return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } void drflac_free(void* pSampleDataReturnedByOpenAndDecode) @@ -4305,6 +4465,15 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui // REVISION HISTORY // +// v0.4c - 2016-12-26 +// - Add support for signed 16-bit integer PCM decoding. +// +// v0.4b - 2016-10-23 +// - A minor change to dr_bool8 and dr_bool32 types. +// +// v0.4a - 2016-10-11 +// - Rename drBool32 to dr_bool32 for styling consistency. +// // v0.4 - 2016-09-29 // - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type. // - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32() -- cgit v1.2.3 From e7464d5fc376783912da9086a4bf49d2d5759135 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 27 Dec 2016 17:37:35 +0100 Subject: Review some formatting and naming - Renamed WritePNG() to SavePNG() for consistency with other file loading functions - Renamed WriteBitmap() to SaveBMP() for consistency with other file loading functions - Redesigned SaveBMP() to use stb_image_write --- src/audio.c | 18 +++++++++--------- src/core.c | 5 +++-- src/rlgl.c | 8 ++++---- src/text.c | 6 +++--- src/utils.c | 60 +++++++++--------------------------------------------------- src/utils.h | 8 ++++---- 6 files changed, 32 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 3a4ca3df..944d1b9d 100644 --- a/src/audio.c +++ b/src/audio.c @@ -985,7 +985,7 @@ static Wave LoadWAV(const char *fileName) char chunkID[4]; int chunkSize; char format[4]; - } WavRiffHeader; + } WAVRiffHeader; typedef struct { char subChunkID[4]; @@ -996,16 +996,16 @@ static Wave LoadWAV(const char *fileName) int byteRate; short blockAlign; short bitsPerSample; - } WavFormat; + } WAVFormat; typedef struct { char subChunkID[4]; int subChunkSize; - } WavData; + } WAVData; - WavRiffHeader wavRiffHeader; - WavFormat wavFormat; - WavData wavData; + WAVRiffHeader wavRiffHeader; + WAVFormat wavFormat; + WAVData wavData; Wave wave = { 0 }; FILE *wavFile; @@ -1020,7 +1020,7 @@ static Wave LoadWAV(const char *fileName) else { // Read in the first chunk into the struct - fread(&wavRiffHeader, sizeof(WavRiffHeader), 1, wavFile); + fread(&wavRiffHeader, sizeof(WAVRiffHeader), 1, wavFile); // Check for RIFF and WAVE tags if (strncmp(wavRiffHeader.chunkID, "RIFF", 4) || @@ -1031,7 +1031,7 @@ static Wave LoadWAV(const char *fileName) else { // Read in the 2nd chunk for the wave info - fread(&wavFormat, sizeof(WavFormat), 1, wavFile); + fread(&wavFormat, sizeof(WAVFormat), 1, wavFile); // Check for fmt tag if ((wavFormat.subChunkID[0] != 'f') || (wavFormat.subChunkID[1] != 'm') || @@ -1045,7 +1045,7 @@ static Wave LoadWAV(const char *fileName) if (wavFormat.subChunkSize > 16) fseek(wavFile, sizeof(short), SEEK_CUR); // Read in the the last byte of data before the sound file - fread(&wavData, sizeof(WavData), 1, wavFile); + fread(&wavData, sizeof(WAVData), 1, wavFile); // Check for data tag if ((wavData.subChunkID[0] != 'd') || (wavData.subChunkID[1] != 'a') || diff --git a/src/core.c b/src/core.c index a210df56..147010f5 100644 --- a/src/core.c +++ b/src/core.c @@ -2139,7 +2139,7 @@ static void TakeScreenshot(void) sprintf(buffer, "screenshot%03i.png", shotNum); // Save image as PNG - WritePNG(buffer, imgData, renderWidth, renderHeight, 4); + SavePNG(buffer, imgData, renderWidth, renderHeight, 4); free(imgData); @@ -2818,7 +2818,8 @@ static void InitMouse(void) // if too much time passes between reads, queue gets full and new events override older ones... static void *MouseThread(void *arg) { - const unsigned char XSIGN = 1<<4, YSIGN = 1<<5; + const unsigned char XSIGN = (1 << 4); + const unsigned char YSIGN = (1 << 5); typedef struct { char buttons; diff --git a/src/rlgl.c b/src/rlgl.c index ae28d9b6..cb1ac709 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -192,7 +192,7 @@ //---------------------------------------------------------------------------------- // Dynamic vertex buffers (position + texcoords + colors + indices arrays) -typedef struct { +typedef struct DynamicBuffer { int vCounter; // vertex position counter to process (and draw) from full buffer int tcCounter; // vertex texcoord counter to process (and draw) from full buffer int cCounter; // vertex color counter to process (and draw) from full buffer @@ -211,7 +211,7 @@ typedef struct { // Draw call type // NOTE: Used to track required draw-calls, organized by texture -typedef struct { +typedef struct DrawCall { int vertexCount; GLuint vaoId; GLuint textureId; @@ -226,7 +226,7 @@ typedef struct { } DrawCall; // Head-Mounted-Display device parameters -typedef struct { +typedef struct VrDeviceInfo { int hResolution; // HMD horizontal resolution in pixels int vResolution; // HMD vertical resolution in pixels float hScreenSize; // HMD horizontal size in meters @@ -240,7 +240,7 @@ typedef struct { } VrDeviceInfo; // VR Stereo rendering configuration for simulator -typedef struct { +typedef struct VrStereoConfig { RenderTexture2D stereoFbo; // VR stereo rendering framebuffer Shader distortionShader; // VR stereo rendering distortion shader //Rectangle eyesViewport[2]; // VR stereo rendering eyes viewports diff --git a/src/text.c b/src/text.c index f97b581d..74d5940b 100644 --- a/src/text.c +++ b/src/text.c @@ -53,7 +53,7 @@ #define MAX_FORMATTEXT_LENGTH 64 #define MAX_SUBTEXT_LENGTH 64 -#define BIT_CHECK(a,b) ((a) & (1<<(b))) +#define BIT_CHECK(a,b) ((a) & (1 << (b))) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -948,7 +948,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int return font; } - fread(ttfBuffer, 1, 1<<25, ttfFile); + fread(ttfBuffer, 1, 1 << 25, ttfFile); if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character"); @@ -983,7 +983,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int font.texture = LoadTextureFromImage(image); - //WritePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2); + //SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2); UnloadImage(image); // Unloads dataGrayAlpha diff --git a/src/utils.c b/src/utils.c index 8fedcaad..711ffab3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -42,13 +42,16 @@ #include // Required for: malloc(), free() #include // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen() #include // Required for: va_list, va_start(), vfprintf(), va_end() -//#include // Required for: strlen(), strrchr(), strcmp() +#include // Required for: strlen(), strrchr(), strcmp() #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #define STB_IMAGE_WRITE_IMPLEMENTATION - #include "external/stb_image_write.h" // Required for: stbi_write_png() + #include "external/stb_image_write.h" // Required for: stbi_write_bmp(), stbi_write_png() #endif +#define RRES_IMPLEMENTATION +#include "rres.h" + #define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing //---------------------------------------------------------------------------------- @@ -73,59 +76,14 @@ static int android_close(void *cookie); //---------------------------------------------------------------------------------- #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) -// Creates a bitmap (BMP) file from an array of pixel data -// NOTE: This function is not explicitly available to raylib users -void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int height) +// Creates a BMP image file from an array of pixel data +void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize) { - int filesize = 54 + 3*width*height; - - unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header - unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header - - bmpFileHeader[2] = (unsigned char)(filesize); - bmpFileHeader[3] = (unsigned char)(filesize>>8); - bmpFileHeader[4] = (unsigned char)(filesize>>16); - bmpFileHeader[5] = (unsigned char)(filesize>>24); - - bmpInfoHeader[4] = (unsigned char)(width); - bmpInfoHeader[5] = (unsigned char)(width>>8); - bmpInfoHeader[6] = (unsigned char)(width>>16); - bmpInfoHeader[7] = (unsigned char)(width>>24); - bmpInfoHeader[8] = (unsigned char)(height); - bmpInfoHeader[9] = (unsigned char)(height>>8); - bmpInfoHeader[10] = (unsigned char)(height>>16); - bmpInfoHeader[11] = (unsigned char)(height>>24); - - FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode - - if (bmpFile == NULL) - { - TraceLog(WARNING, "[%s] BMP file could not be created", fileName); - } - else - { - // NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer - fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data - fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data - - // Write pixel data to file - for (int y = 0; y < height ; y++) - { - for (int x = 0; x < width; x++) - { - fputc(imgData[(x*4)+2 + (y*width*4)], bmpFile); - fputc(imgData[(x*4)+1 + (y*width*4)], bmpFile); - fputc(imgData[(x*4) + (y*width*4)], bmpFile); - } - } - } - - fclose(bmpFile); // Close bitmap file + stbi_write_bmp(fileName, width, height, compSize, imgData); } // Creates a PNG image file from an array of pixel data -// NOTE: Uses stb_image_write -void WritePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize) +void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize) { stbi_write_png(fileName, width, height, compSize, imgData, width*compSize); } diff --git a/src/utils.h b/src/utils.h index 045b0692..e0db51fe 100644 --- a/src/utils.h +++ b/src/utils.h @@ -31,6 +31,8 @@ #include // Required for: AAssetManager #endif +#include "rres.h" + //---------------------------------------------------------------------------------- // Some basic Defines //---------------------------------------------------------------------------------- @@ -66,11 +68,9 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize); - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) -void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int height); -void WritePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize); +void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize); +void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize); #endif void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message -- cgit v1.2.3 From bf3a213e44e8de1f61aeadc692c50290d3852a98 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 27 Dec 2016 17:40:59 +0100 Subject: Some functions review and additions - Improved ImageCopy() to support compressed formats - Renaming file-formats header structs for consistency - Review variables naming on ImageDither() for consistency - Improved LoadImagePro() to make a copy of data - Preliminary support of rRES file format on LoadImage() --- src/textures.c | 305 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 168 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/src/textures.c b/src/textures.c index 8b223ed0..6538c316 100644 --- a/src/textures.c +++ b/src/textures.c @@ -141,6 +141,17 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"ktx") == 0) image = LoadKTX(fileName); else if (strcmp(GetExtension(fileName),"pvr") == 0) image = LoadPVR(fileName); else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); + else if (strcmp(GetExtension(fileName),"rres") == 0) + { + RRESData rres = LoadResource(fileName); + + // NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps + + if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName); + + UnloadResource(rres); + } if (image.data != NULL) TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height); else TraceLog(WARNING, "[%s] Image could not be loaded", fileName); @@ -176,18 +187,20 @@ Image LoadImageEx(Color *pixels, int width, int height) } // Load image from raw data with parameters -// NOTE: This functions does not make a copy of data +// NOTE: This functions makes a copy of provided data Image LoadImagePro(void *data, int width, int height, int format) { - Image image; + Image srcImage = { 0 }; + + srcImage.data = data; + srcImage.width = width; + srcImage.height = height; + srcImage.mipmaps = 1; + srcImage.format = format; - image.data = data; - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = format; + Image dstImage = ImageCopy(srcImage); - return image; + return dstImage; } // Load an image from RAW file data @@ -669,11 +682,11 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) // NOTE: We will store the dithered data as unsigned short (16bpp) image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - Color oldpixel = WHITE; - Color newpixel = WHITE; + Color oldPixel = WHITE; + Color newPixel = WHITE; - int error_r, error_g, error_b; - unsigned short pixel_r, pixel_g, pixel_b, pixel_a; // Used for 16bit pixel composition + int rError, gError, bError; + unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -681,57 +694,57 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) { for (int x = 0; x < image->width; x++) { - oldpixel = pixels[y*image->width + x]; + oldPixel = pixels[y*image->width + x]; // NOTE: New pixel obtained by bits truncate, it would be better to round values (check ImageFormat()) - newpixel.r = oldpixel.r>>(8 - rBpp); // R bits - newpixel.g = oldpixel.g>>(8 - gBpp); // G bits - newpixel.b = oldpixel.b>>(8 - bBpp); // B bits - newpixel.a = oldpixel.a>>(8 - aBpp); // A bits (not used on dithering) + newPixel.r = oldPixel.r >> (8 - rBpp); // R bits + newPixel.g = oldPixel.g >> (8 - gBpp); // G bits + newPixel.b = oldPixel.b >> (8 - bBpp); // B bits + newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering) // NOTE: Error must be computed between new and old pixel but using same number of bits! // We want to know how much color precision we have lost... - error_r = (int)oldpixel.r - (int)(newpixel.r<<(8 - rBpp)); - error_g = (int)oldpixel.g - (int)(newpixel.g<<(8 - gBpp)); - error_b = (int)oldpixel.b - (int)(newpixel.b<<(8 - bBpp)); + rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp)); + gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp)); + bError = (int)oldPixel.b - (int)(newPixel.b << (8 - bBpp)); - pixels[y*image->width + x] = newpixel; + pixels[y*image->width + x] = newPixel; // NOTE: Some cases are out of the array and should be ignored if (x < (image->width - 1)) { - pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)error_r*7.0f/16), 0xff); - pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)error_g*7.0f/16), 0xff); - pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)error_b*7.0f/16), 0xff); + pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)rError*7.0f/16), 0xff); + pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)gError*7.0f/16), 0xff); + pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)bError*7.0f/16), 0xff); } if ((x > 0) && (y < (image->height - 1))) { - pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)error_r*3.0f/16), 0xff); - pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)error_g*3.0f/16), 0xff); - pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)error_b*3.0f/16), 0xff); + pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)rError*3.0f/16), 0xff); + pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)gError*3.0f/16), 0xff); + pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)bError*3.0f/16), 0xff); } if (y < (image->height - 1)) { - pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)error_r*5.0f/16), 0xff); - pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)error_g*5.0f/16), 0xff); - pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)error_b*5.0f/16), 0xff); + pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)rError*5.0f/16), 0xff); + pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)gError*5.0f/16), 0xff); + pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)bError*5.0f/16), 0xff); } if ((x < (image->width - 1)) && (y < (image->height - 1))) { - pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)error_r*1.0f/16), 0xff); - pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)error_g*1.0f/16), 0xff); - pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)error_b*1.0f/16), 0xff); + pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)rError*1.0f/16), 0xff); + pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)gError*1.0f/16), 0xff); + pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)bError*1.0f/16), 0xff); } - pixel_r = (unsigned short)newpixel.r; - pixel_g = (unsigned short)newpixel.g; - pixel_b = (unsigned short)newpixel.b; - pixel_a = (unsigned short)newpixel.a; + rPixel = (unsigned short)newPixel.r; + gPixel = (unsigned short)newPixel.g; + bPixel = (unsigned short)newPixel.b; + aPixel = (unsigned short)newPixel.a; - ((unsigned short *)image->data)[y*image->width + x] = (pixel_r<<(gBpp + bBpp + aBpp)) | (pixel_g<<(bBpp + aBpp)) | (pixel_b<data)[y*image->width + x] = (rPixel << (gBpp + bBpp + aBpp)) | (gPixel << (bBpp + aBpp)) | (bPixel << aBpp) | aPixel; } } @@ -788,24 +801,37 @@ Image ImageCopy(Image image) { Image newImage; - int size = image.width*image.height; + int byteSize = image.width*image.height; switch (image.format) { - case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) - case UNCOMPRESSED_GRAY_ALPHA: newImage.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels) - case UNCOMPRESSED_R5G6B5: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp - case UNCOMPRESSED_R8G8B8: newImage.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp - case UNCOMPRESSED_R5G5B5A1: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (1 bit alpha) - case UNCOMPRESSED_R4G4B4A4: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (4 bit alpha) - case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp - default: TraceLog(WARNING, "Image format not suported for copy"); break; + case UNCOMPRESSED_GRAYSCALE: break; // 8 bpp (1 byte) + case UNCOMPRESSED_GRAY_ALPHA: // 16 bpp + case UNCOMPRESSED_R5G6B5: // 16 bpp + case UNCOMPRESSED_R5G5B5A1: // 16 bpp + case UNCOMPRESSED_R4G4B4A4: byteSize *= 2; break; // 16 bpp (2 bytes) + case UNCOMPRESSED_R8G8B8: byteSize *= 3; break; // 24 bpp (3 bytes) + case UNCOMPRESSED_R8G8B8A8: byteSize *= 4; break; // 32 bpp (4 bytes) + case COMPRESSED_DXT3_RGBA: + case COMPRESSED_DXT5_RGBA: + case COMPRESSED_ETC2_EAC_RGBA: + case COMPRESSED_ASTC_4x4_RGBA: break; // 8 bpp (1 byte) + case COMPRESSED_DXT1_RGB: + case COMPRESSED_DXT1_RGBA: + case COMPRESSED_ETC1_RGB: + case COMPRESSED_ETC2_RGB: + case COMPRESSED_PVRT_RGB: + case COMPRESSED_PVRT_RGBA: byteSize /= 2; break; // 4 bpp + case COMPRESSED_ASTC_8x8_RGBA: byteSize /= 4; break;// 2 bpp + default: TraceLog(WARNING, "Image format not recognized"); break; } + newImage.data = malloc(byteSize); + if (newImage.data != NULL) { // NOTE: Size must be provided in bytes - memcpy(newImage.data, image.data, size); + memcpy(newImage.data, image.data, byteSize); newImage.width = image.width; newImage.height = image.height; @@ -1524,7 +1550,7 @@ static Image LoadDDS(const char *fileName) unsigned int gBitMask; unsigned int bBitMask; unsigned int aBitMask; - } ddsPixelFormat; + } DDSPixelFormat; // DDS Header (124 bytes) typedef struct { @@ -1536,13 +1562,13 @@ static Image LoadDDS(const char *fileName) unsigned int depth; unsigned int mipmapCount; unsigned int reserved1[11]; - ddsPixelFormat ddspf; + DDSPixelFormat ddspf; unsigned int caps; unsigned int caps2; unsigned int caps3; unsigned int caps4; unsigned int reserved2; - } ddsHeader; + } DDSHeader; Image image; @@ -1571,33 +1597,33 @@ static Image LoadDDS(const char *fileName) } else { - ddsHeader header; + DDSHeader ddsHeader; // Get the image header - fread(&header, sizeof(ddsHeader), 1, ddsFile); + fread(&ddsHeader, sizeof(DDSHeader), 1, ddsFile); - TraceLog(DEBUG, "[%s] DDS file header size: %i", fileName, sizeof(ddsHeader)); - TraceLog(DEBUG, "[%s] DDS file pixel format size: %i", fileName, header.ddspf.size); - TraceLog(DEBUG, "[%s] DDS file pixel format flags: 0x%x", fileName, header.ddspf.flags); - TraceLog(DEBUG, "[%s] DDS file format: 0x%x", fileName, header.ddspf.fourCC); - TraceLog(DEBUG, "[%s] DDS file bit count: 0x%x", fileName, header.ddspf.rgbBitCount); + TraceLog(DEBUG, "[%s] DDS file header size: %i", fileName, sizeof(DDSHeader)); + TraceLog(DEBUG, "[%s] DDS file pixel format size: %i", fileName, ddsHeader.ddspf.size); + TraceLog(DEBUG, "[%s] DDS file pixel format flags: 0x%x", fileName, ddsHeader.ddspf.flags); + TraceLog(DEBUG, "[%s] DDS file format: 0x%x", fileName, ddsHeader.ddspf.fourCC); + TraceLog(DEBUG, "[%s] DDS file bit count: 0x%x", fileName, ddsHeader.ddspf.rgbBitCount); - image.width = header.width; - image.height = header.height; - image.mipmaps = 1; // Default value, could be changed (header.mipmapCount) + image.width = ddsHeader.width; + image.height = ddsHeader.height; + image.mipmaps = 1; // Default value, could be changed (ddsHeader.mipmapCount) - if (header.ddspf.rgbBitCount == 16) // 16bit mode, no compressed + if (ddsHeader.ddspf.rgbBitCount == 16) // 16bit mode, no compressed { - if (header.ddspf.flags == 0x40) // no alpha channel + if (ddsHeader.ddspf.flags == 0x40) // no alpha channel { image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile); image.format = UNCOMPRESSED_R5G6B5; } - else if (header.ddspf.flags == 0x41) // with alpha channel + else if (ddsHeader.ddspf.flags == 0x41) // with alpha channel { - if (header.ddspf.aBitMask == 0x8000) // 1bit alpha + if (ddsHeader.ddspf.aBitMask == 0x8000) // 1bit alpha { image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile); @@ -1614,7 +1640,7 @@ static Image LoadDDS(const char *fileName) image.format = UNCOMPRESSED_R5G5B5A1; } - else if (header.ddspf.aBitMask == 0xf000) // 4bit alpha + else if (ddsHeader.ddspf.aBitMask == 0xf000) // 4bit alpha { image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile); @@ -1633,7 +1659,7 @@ static Image LoadDDS(const char *fileName) } } } - if (header.ddspf.flags == 0x40 && header.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed + if (ddsHeader.ddspf.flags == 0x40 && ddsHeader.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed { // NOTE: not sure if this case exists... image.data = (unsigned char *)malloc(image.width*image.height*3*sizeof(unsigned char)); @@ -1641,7 +1667,7 @@ static Image LoadDDS(const char *fileName) image.format = UNCOMPRESSED_R8G8B8; } - else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed + else if (ddsHeader.ddspf.flags == 0x41 && ddsHeader.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed { image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); fread(image.data, image.width*image.height*4, 1, ddsFile); @@ -1660,27 +1686,27 @@ static Image LoadDDS(const char *fileName) image.format = UNCOMPRESSED_R8G8B8A8; } - else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0)) // Compressed + else if (((ddsHeader.ddspf.flags == 0x04) || (ddsHeader.ddspf.flags == 0x05)) && (ddsHeader.ddspf.fourCC > 0)) // Compressed { int bufsize; // Calculate data size, including all mipmaps - if (header.mipmapCount > 1) bufsize = header.pitchOrLinearSize*2; - else bufsize = header.pitchOrLinearSize; + if (ddsHeader.mipmapCount > 1) bufsize = ddsHeader.pitchOrLinearSize*2; + else bufsize = ddsHeader.pitchOrLinearSize; - TraceLog(DEBUG, "Pitch or linear size: %i", header.pitchOrLinearSize); + TraceLog(DEBUG, "Pitch or linear size: %i", ddsHeader.pitchOrLinearSize); image.data = (unsigned char*)malloc(bufsize*sizeof(unsigned char)); fread(image.data, 1, bufsize, ddsFile); - image.mipmaps = header.mipmapCount; + image.mipmaps = ddsHeader.mipmapCount; - switch (header.ddspf.fourCC) + switch (ddsHeader.ddspf.fourCC) { case FOURCC_DXT1: { - if (header.ddspf.flags == 0x04) image.format = COMPRESSED_DXT1_RGB; + if (ddsHeader.ddspf.flags == 0x04) image.format = COMPRESSED_DXT1_RGB; else image.format = COMPRESSED_DXT1_RGBA; } break; case FOURCC_DXT3: image.format = COMPRESSED_DXT3_RGBA; break; @@ -1719,7 +1745,7 @@ static Image LoadPKM(const char *fileName) unsigned short height; // Texture height (big-endian) (origHeight rounded to multiple of 4) unsigned short origWidth; // Original width (big-endian) unsigned short origHeight; // Original height (big-endian) - } pkmHeader; + } PKMHeader; // Formats list // version 10: format: 0=ETC1_RGB, [1=ETC1_RGBA, 2=ETC1_RGB_MIP, 3=ETC1_RGBA_MIP] (not used) @@ -1744,32 +1770,32 @@ static Image LoadPKM(const char *fileName) } else { - pkmHeader header; + PKMHeader pkmHeader; // Get the image header - fread(&header, sizeof(pkmHeader), 1, pkmFile); + fread(&pkmHeader, sizeof(PKMHeader), 1, pkmFile); - if (strncmp(header.id, "PKM ", 4) != 0) + if (strncmp(pkmHeader.id, "PKM ", 4) != 0) { TraceLog(WARNING, "[%s] PKM file does not seem to be a valid image", fileName); } else { // NOTE: format, width and height come as big-endian, data must be swapped to little-endian - header.format = ((header.format & 0x00FF) << 8) | ((header.format & 0xFF00) >> 8); - header.width = ((header.width & 0x00FF) << 8) | ((header.width & 0xFF00) >> 8); - header.height = ((header.height & 0x00FF) << 8) | ((header.height & 0xFF00) >> 8); + pkmHeader.format = ((pkmHeader.format & 0x00FF) << 8) | ((pkmHeader.format & 0xFF00) >> 8); + pkmHeader.width = ((pkmHeader.width & 0x00FF) << 8) | ((pkmHeader.width & 0xFF00) >> 8); + pkmHeader.height = ((pkmHeader.height & 0x00FF) << 8) | ((pkmHeader.height & 0xFF00) >> 8); - TraceLog(DEBUG, "PKM (ETC) image width: %i", header.width); - TraceLog(DEBUG, "PKM (ETC) image height: %i", header.height); - TraceLog(DEBUG, "PKM (ETC) image format: %i", header.format); + TraceLog(DEBUG, "PKM (ETC) image width: %i", pkmHeader.width); + TraceLog(DEBUG, "PKM (ETC) image height: %i", pkmHeader.height); + TraceLog(DEBUG, "PKM (ETC) image format: %i", pkmHeader.format); - image.width = header.width; - image.height = header.height; + image.width = pkmHeader.width; + image.height = pkmHeader.height; image.mipmaps = 1; int bpp = 4; - if (header.format == 3) bpp = 8; + if (pkmHeader.format == 3) bpp = 8; int size = image.width*image.height*bpp/8; // Total data size in bytes @@ -1777,9 +1803,9 @@ static Image LoadPKM(const char *fileName) fread(image.data, 1, size, pkmFile); - if (header.format == 0) image.format = COMPRESSED_ETC1_RGB; - else if (header.format == 1) image.format = COMPRESSED_ETC2_RGB; - else if (header.format == 3) image.format = COMPRESSED_ETC2_EAC_RGBA; + if (pkmHeader.format == 0) image.format = COMPRESSED_ETC1_RGB; + else if (pkmHeader.format == 1) image.format = COMPRESSED_ETC2_RGB; + else if (pkmHeader.format == 3) image.format = COMPRESSED_ETC2_EAC_RGBA; } fclose(pkmFile); // Close file pointer @@ -1817,7 +1843,7 @@ static Image LoadKTX(const char *fileName) unsigned int faces; // Cubemap faces, for no-cubemap = 1 unsigned int mipmapLevels; // Non-mipmapped textures = 1 unsigned int keyValueDataSize; // Used to encode any arbitrary data... - } ktxHeader; + } KTXHeader; // NOTE: Before start of every mipmap data block, we have: unsigned int dataSize @@ -1836,31 +1862,31 @@ static Image LoadKTX(const char *fileName) } else { - ktxHeader header; + KTXHeader ktxHeader; // Get the image header - fread(&header, sizeof(ktxHeader), 1, ktxFile); + fread(&ktxHeader, sizeof(KTXHeader), 1, ktxFile); - if ((header.id[1] != 'K') || (header.id[2] != 'T') || (header.id[3] != 'X') || - (header.id[4] != ' ') || (header.id[5] != '1') || (header.id[6] != '1')) + if ((ktxHeader.id[1] != 'K') || (ktxHeader.id[2] != 'T') || (ktxHeader.id[3] != 'X') || + (ktxHeader.id[4] != ' ') || (ktxHeader.id[5] != '1') || (ktxHeader.id[6] != '1')) { TraceLog(WARNING, "[%s] KTX file does not seem to be a valid file", fileName); } else { - image.width = header.width; - image.height = header.height; - image.mipmaps = header.mipmapLevels; + image.width = ktxHeader.width; + image.height = ktxHeader.height; + image.mipmaps = ktxHeader.mipmapLevels; - TraceLog(DEBUG, "KTX (ETC) image width: %i", header.width); - TraceLog(DEBUG, "KTX (ETC) image height: %i", header.height); - TraceLog(DEBUG, "KTX (ETC) image format: 0x%x", header.glInternalFormat); + TraceLog(DEBUG, "KTX (ETC) image width: %i", ktxHeader.width); + TraceLog(DEBUG, "KTX (ETC) image height: %i", ktxHeader.height); + TraceLog(DEBUG, "KTX (ETC) image format: 0x%x", ktxHeader.glInternalFormat); unsigned char unused; - if (header.keyValueDataSize > 0) + if (ktxHeader.keyValueDataSize > 0) { - for (int i = 0; i < header.keyValueDataSize; i++) fread(&unused, 1, 1, ktxFile); + for (int i = 0; i < ktxHeader.keyValueDataSize; i++) fread(&unused, 1, 1, ktxFile); } int dataSize; @@ -1870,9 +1896,9 @@ static Image LoadKTX(const char *fileName) fread(image.data, 1, dataSize, ktxFile); - if (header.glInternalFormat == 0x8D64) image.format = COMPRESSED_ETC1_RGB; - else if (header.glInternalFormat == 0x9274) image.format = COMPRESSED_ETC2_RGB; - else if (header.glInternalFormat == 0x9278) image.format = COMPRESSED_ETC2_EAC_RGBA; + if (ktxHeader.glInternalFormat == 0x8D64) image.format = COMPRESSED_ETC1_RGB; + else if (ktxHeader.glInternalFormat == 0x9274) image.format = COMPRESSED_ETC2_RGB; + else if (ktxHeader.glInternalFormat == 0x9278) image.format = COMPRESSED_ETC2_EAC_RGBA; } fclose(ktxFile); // Close file pointer @@ -1908,7 +1934,7 @@ static Image LoadPVR(const char *fileName) unsigned int bitmaskAlpha; unsigned int pvrTag; unsigned int numSurfs; - } pvrHeaderV2; + } PVRHeaderV2; #endif // PVR file v3 Header (52 bytes) @@ -1927,7 +1953,7 @@ static Image LoadPVR(const char *fileName) unsigned int numFaces; unsigned int numMipmaps; unsigned int metaDataSize; - } pvrHeaderV3; + } PVRHeaderV3; #if 0 // Not used... // Metadata (usually 15 bytes) @@ -1936,7 +1962,7 @@ static Image LoadPVR(const char *fileName) unsigned int key; unsigned int dataSize; // Not used? unsigned char *data; // Not used? - } pvrMetadata; + } PVRMetadata; #endif Image image; @@ -1963,44 +1989,49 @@ static Image LoadPVR(const char *fileName) // Load different PVR data formats if (pvrVersion == 0x50) { - pvrHeaderV3 header; + PVRHeaderV3 pvrHeader; // Get PVR image header - fread(&header, sizeof(pvrHeaderV3), 1, pvrFile); + fread(&pvrHeader, sizeof(PVRHeaderV3), 1, pvrFile); - if ((header.id[0] != 'P') || (header.id[1] != 'V') || (header.id[2] != 'R') || (header.id[3] != 3)) + if ((pvrHeader.id[0] != 'P') || (pvrHeader.id[1] != 'V') || (pvrHeader.id[2] != 'R') || (pvrHeader.id[3] != 3)) { TraceLog(WARNING, "[%s] PVR file does not seem to be a valid image", fileName); } else { - image.width = header.width; - image.height = header.height; - image.mipmaps = header.numMipmaps; + image.width = pvrHeader.width; + image.height = pvrHeader.height; + image.mipmaps = pvrHeader.numMipmaps; // Check data format - if (((header.channels[0] == 'l') && (header.channels[1] == 0)) && (header.channelDepth[0] == 8)) image.format = UNCOMPRESSED_GRAYSCALE; - else if (((header.channels[0] == 'l') && (header.channels[1] == 'a')) && ((header.channelDepth[0] == 8) && (header.channelDepth[1] == 8))) image.format = UNCOMPRESSED_GRAY_ALPHA; - else if ((header.channels[0] == 'r') && (header.channels[1] == 'g') && (header.channels[2] == 'b')) + if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8)) + image.format = UNCOMPRESSED_GRAYSCALE; + else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8))) + image.format = UNCOMPRESSED_GRAY_ALPHA; + else if ((pvrHeader.channels[0] == 'r') && (pvrHeader.channels[1] == 'g') && (pvrHeader.channels[2] == 'b')) { - if (header.channels[3] == 'a') + if (pvrHeader.channels[3] == 'a') { - if ((header.channelDepth[0] == 5) && (header.channelDepth[1] == 5) && (header.channelDepth[2] == 5) && (header.channelDepth[3] == 1)) image.format = UNCOMPRESSED_R5G5B5A1; - else if ((header.channelDepth[0] == 4) && (header.channelDepth[1] == 4) && (header.channelDepth[2] == 4) && (header.channelDepth[3] == 4)) image.format = UNCOMPRESSED_R4G4B4A4; - else if ((header.channelDepth[0] == 8) && (header.channelDepth[1] == 8) && (header.channelDepth[2] == 8) && (header.channelDepth[3] == 8)) image.format = UNCOMPRESSED_R8G8B8A8; + if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1)) + image.format = UNCOMPRESSED_R5G5B5A1; + else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4)) + image.format = UNCOMPRESSED_R4G4B4A4; + else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8)) + image.format = UNCOMPRESSED_R8G8B8A8; } - else if (header.channels[3] == 0) + else if (pvrHeader.channels[3] == 0) { - if ((header.channelDepth[0] == 5) && (header.channelDepth[1] == 6) && (header.channelDepth[2] == 5)) image.format = UNCOMPRESSED_R5G6B5; - else if ((header.channelDepth[0] == 8) && (header.channelDepth[1] == 8) && (header.channelDepth[2] == 8)) image.format = UNCOMPRESSED_R8G8B8; + if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 6) && (pvrHeader.channelDepth[2] == 5)) image.format = UNCOMPRESSED_R5G6B5; + else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8)) image.format = UNCOMPRESSED_R8G8B8; } } - else if (header.channels[0] == 2) image.format = COMPRESSED_PVRT_RGB; - else if (header.channels[0] == 3) image.format = COMPRESSED_PVRT_RGBA; + else if (pvrHeader.channels[0] == 2) image.format = COMPRESSED_PVRT_RGB; + else if (pvrHeader.channels[0] == 3) image.format = COMPRESSED_PVRT_RGBA; // Skip meta data header unsigned char unused = 0; - for (int i = 0; i < header.metaDataSize; i++) fread(&unused, sizeof(unsigned char), 1, pvrFile); + for (int i = 0; i < pvrHeader.metaDataSize; i++) fread(&unused, sizeof(unsigned char), 1, pvrFile); // Calculate data size (depends on format) int bpp = 0; @@ -2054,7 +2085,7 @@ static Image LoadASTC(const char *fileName) unsigned char width[3]; // Image width in pixels (24bit value) unsigned char height[3]; // Image height in pixels (24bit value) unsigned char lenght[3]; // Image Z-size (1 for 2D images) - } astcHeader; + } ASTCHeader; Image image; @@ -2072,30 +2103,30 @@ static Image LoadASTC(const char *fileName) } else { - astcHeader header; + ASTCHeader astcHeader; // Get ASTC image header - fread(&header, sizeof(astcHeader), 1, astcFile); + fread(&astcHeader, sizeof(ASTCHeader), 1, astcFile); - if ((header.id[3] != 0x5c) || (header.id[2] != 0xa1) || (header.id[1] != 0xab) || (header.id[0] != 0x13)) + if ((astcHeader.id[3] != 0x5c) || (astcHeader.id[2] != 0xa1) || (astcHeader.id[1] != 0xab) || (astcHeader.id[0] != 0x13)) { TraceLog(WARNING, "[%s] ASTC file does not seem to be a valid image", fileName); } else { // NOTE: Assuming Little Endian (could it be wrong?) - image.width = 0x00000000 | ((int)header.width[2] << 16) | ((int)header.width[1] << 8) | ((int)header.width[0]); - image.height = 0x00000000 | ((int)header.height[2] << 16) | ((int)header.height[1] << 8) | ((int)header.height[0]); + image.width = 0x00000000 | ((int)astcHeader.width[2] << 16) | ((int)astcHeader.width[1] << 8) | ((int)astcHeader.width[0]); + image.height = 0x00000000 | ((int)astcHeader.height[2] << 16) | ((int)astcHeader.height[1] << 8) | ((int)astcHeader.height[0]); // NOTE: ASTC format only contains one mipmap level image.mipmaps = 1; TraceLog(DEBUG, "ASTC image width: %i", image.width); TraceLog(DEBUG, "ASTC image height: %i", image.height); - TraceLog(DEBUG, "ASTC image blocks: %ix%i", header.blockX, header.blockY); + TraceLog(DEBUG, "ASTC image blocks: %ix%i", astcHeader.blockX, astcHeader.blockY); // NOTE: Each block is always stored in 128bit so we can calculate the bpp - int bpp = 128/(header.blockX*header.blockY); + int bpp = 128/(astcHeader.blockX*astcHeader.blockY); // NOTE: Currently we only support 2 blocks configurations: 4x4 and 8x8 if ((bpp == 8) || (bpp == 2)) -- cgit v1.2.3 From 202f45415c98df2201202ba8edb10b6496cbeb62 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 27 Dec 2016 17:42:22 +0100 Subject: rRES raylib resources custom file format support First version of custom raylib resources file format -IN DEVELOPMENT- --- src/raylib.h | 20 +++ src/rres.h | 444 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 464 insertions(+) create mode 100644 src/rres.h (limited to 'src') diff --git a/src/raylib.h b/src/raylib.h index 6fd960dc..e2e4ee13 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -602,6 +602,26 @@ typedef enum { HMD_FOVE_VR, } VrDevice; +// rRES data returned when reading a resource, it contains all required data for user (24 byte) +typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) +} RRESData; + +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT +} RRESDataType; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif diff --git a/src/rres.h b/src/rres.h new file mode 100644 index 00000000..dcf7be3f --- /dev/null +++ b/src/rres.h @@ -0,0 +1,444 @@ +/********************************************************************************************** +* +* rres - raylib Resource custom format management functions +* +* Basic functions to load/save rRES resource files +* +* External libs: +* tinfl - DEFLATE decompression functions +* +* Module Configuration Flags: +* +* #define RREM_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* +* +* Copyright (c) 2016-2017 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RRES_H +#define RRES_H + +#if !defined(RRES_STANDALONE) + #include "raylib.h" +#endif + +//#define RRES_STATIC +#ifdef RRES_STATIC + #define RRESDEF static // Functions just visible to module including this file +#else + #ifdef __cplusplus + #define RRESDEF extern "C" // Functions visible from other files (no name mangling of functions in C++) + #else + #define RRESDEF extern // Functions visible from other files + #endif +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define MAX_RESOURCES_SUPPORTED 256 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +// NOTE: Some types are required for RAYGUI_STANDALONE usage +//---------------------------------------------------------------------------------- +#if defined(RRES_STANDALONE) + // rRES data returned when reading a resource, it contains all required data for user (24 byte) + typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) + } RRESData; + + typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT + } RRESDataType; +#endif + +//---------------------------------------------------------------------------------- +// Global variables +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +RRESDEF RRESData LoadResource(const char *rresFileName); +RRESDEF RRESData LoadResourceById(const char *rresFileName, int rresId); +RRESDEF void UnloadResource(RRESData rres); + +#endif // RRES_H + + +/*********************************************************************************** +* +* RRES IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RRES_IMPLEMENTATION) + +#include // Required for: FILE, fopen(), fclose() + +// Check if custom malloc/free functions defined, if not, using standard ones +#if !defined(RRES_MALLOC) + #include // Required for: malloc(), free() + + #define RRES_MALLOC(size) malloc(size) + #define RRES_FREE(ptr) free(ptr) +#endif + +#include "external/tinfl.c" // Required for: tinfl_decompress_mem_to_mem() + // NOTE: DEFLATE algorythm data decompression + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// rRES file header (8 byte) +typedef struct { + char id[4]; // File identifier: rRES (4 byte) + unsigned short version; // File version and subversion (2 byte) + unsigned short count; // Number of resources in this file (2 byte) +} RRESFileHeader; + +// rRES info header, every resource includes this header (12 byte + 16 byte) +typedef struct { + unsigned short id; // Resource unique identifier (2 byte) + unsigned char dataType; // Resource data type (1 byte) + unsigned char compType; // Resource data compression type (1 byte) + unsigned int dataSize; // Resource data size (compressed or not, only DATA) (4 byte) + unsigned int uncompSize; // Resource data size (uncompressed, only DATA) (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) +} RRESInfoHeader; + +// Compression types +typedef enum { + RRES_COMP_NONE = 0, // No data compression + RRES_COMP_DEFLATE, // DEFLATE compression + RRES_COMP_LZ4, // LZ4 compression + RRES_COMP_LZMA, // LZMA compression + // brotli, zopfli, gzip // Other compression algorythms... +} RRESCompressionType; + +#if defined(RRES_STANDALONE) +typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static void *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize); + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Load resource from file (only one) +// NOTE: Returns uncompressed data with parameters, only first resource found +RRESDEF RRESData LoadResource(const char *fileName) +{ + RRESData rres = { 0 }; + + RRESFileHeader fileHeader; + RRESInfoHeader infoHeader; + + FILE *rresFile = fopen(fileName, "rb"); + + if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", fileName); + else + { + // Read rres file info header + fread(&fileHeader.id[0], sizeof(char), 1, rresFile); + fread(&fileHeader.id[1], sizeof(char), 1, rresFile); + fread(&fileHeader.id[2], sizeof(char), 1, rresFile); + fread(&fileHeader.id[3], sizeof(char), 1, rresFile); + fread(&fileHeader.version, sizeof(short), 1, rresFile); + fread(&fileHeader.count, sizeof(short), 1, rresFile); + + // Verify "rRES" identifier + if ((fileHeader.id[0] != 'r') && (fileHeader.id[1] != 'R') && (fileHeader.id[2] != 'E') && (fileHeader.id[3] != 'S')) + { + TraceLog(WARNING, "[%s] This is not a valid raylib resource file", fileName); + } + else + { + // Read first resource info and parameters + fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); + + // Register data type and parameters + rres.type = infoHeader.dataType; + rres.param1 = infoHeader.param1; + rres.param2 = infoHeader.param2; + rres.param3 = infoHeader.param3; + rres.param4 = infoHeader.param4; + + // Read resource data block + void *data = RRES_MALLOC(infoHeader.dataSize); + fread(data, infoHeader.dataSize, 1, rresFile); + + if (infoHeader.compType == RRES_COMP_DEFLATE) + { + void *uncompData = DecompressData(data, infoHeader.dataSize, infoHeader.uncompSize); + + rres.data = uncompData; + + RRES_FREE(data); + } + else rres.data = data; + + if (rres.data != NULL) TraceLog(INFO, "[%s] Resource data loaded successfully", fileName); + } + + fclose(rresFile); + } + + return rres; +} + +// Load resource from file by id +// NOTE: Returns uncompressed data with parameters, search resource by id +RRESDEF RRESData LoadResourceById(const char *fileName, int rresId) +{ + RRESData rres = { 0 }; + + RRESFileHeader fileHeader; + RRESInfoHeader infoHeader; + + FILE *rresFile = fopen(fileName, "rb"); + + if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", fileName); + else + { + // Read rres file info header + fread(&fileHeader.id[0], sizeof(char), 1, rresFile); + fread(&fileHeader.id[1], sizeof(char), 1, rresFile); + fread(&fileHeader.id[2], sizeof(char), 1, rresFile); + fread(&fileHeader.id[3], sizeof(char), 1, rresFile); + fread(&fileHeader.version, sizeof(short), 1, rresFile); + fread(&fileHeader.count, sizeof(short), 1, rresFile); + + // Verify "rRES" identifier + if ((fileHeader.id[0] != 'r') && (fileHeader.id[1] != 'R') && (fileHeader.id[2] != 'E') && (fileHeader.id[3] != 'S')) + { + TraceLog(WARNING, "[%s] This is not a valid raylib resource file", fileName); + } + else + { + for (int i = 0; i < fileHeader.count; i++) + { + // Read resource info and parameters + fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); + + if (infoHeader.id == rresId) + { + // Register data type and parameters + rres.type = infoHeader.dataType; + rres.param1 = infoHeader.param1; + rres.param2 = infoHeader.param2; + rres.param3 = infoHeader.param3; + rres.param4 = infoHeader.param4; + + // Read resource data block + void *data = RRES_MALLOC(infoHeader.dataSize); + fread(data, infoHeader.dataSize, 1, rresFile); + + if (infoHeader.compType == RRES_COMP_DEFLATE) + { + void *uncompData = DecompressData(data, infoHeader.dataSize, infoHeader.uncompSize); + + rres.data = uncompData; + + RRES_FREE(data); + } + else rres.data = data; + + if (rres.data != NULL) TraceLog(INFO, "[%s][ID %i] Resource data loaded successfully", fileName, (int)rresId); + } + else + { + // Skip required data to read next resource infoHeader + fseek(rresFile, infoHeader.dataSize, SEEK_CUR); + } + } + + if (rres.data == NULL) TraceLog(WARNING, "[%s][ID %i] Requested resource could not be found, wrong id?", fileName, (int)rresId); + } + + fclose(rresFile); + } + + return rres; +} + +RRESDEF void UnloadResource(RRESData rres) +{ + if (rres.data != NULL) free(rres.data); +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Data decompression function +// NOTE: Allocated data MUST be freed by user +static void *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize) +{ + int tempUncompSize; + void *uncompData; + + // Allocate buffer to hold decompressed data + uncompData = (mz_uint8 *)RRES_MALLOC((size_t)uncompSize); + + // Check correct memory allocation + if (uncompData == NULL) + { + TraceLog(WARNING, "Out of memory while decompressing data"); + } + else + { + // Decompress data + tempUncompSize = tinfl_decompress_mem_to_mem(uncompData, (size_t)uncompSize, data, compSize, 1); + + if (tempUncompSize == -1) + { + TraceLog(WARNING, "Data decompression failed"); + RRES_FREE(uncompData); + } + + if (uncompSize != (int)tempUncompSize) + { + TraceLog(WARNING, "Expected uncompressed size do not match, data may be corrupted"); + TraceLog(WARNING, " -- Expected uncompressed size: %i", uncompSize); + TraceLog(WARNING, " -- Returned uncompressed size: %i", tempUncompSize); + } + + TraceLog(INFO, "Data decompressed successfully from %u bytes to %u bytes", (mz_uint32)compSize, (mz_uint32)tempUncompSize); + } + + return uncompData; +} + + +// Some required functions for rres standalone module version +#if defined(RRES_STANDALONE) +// Outputs a trace log message (INFO, ERROR, WARNING) +// NOTE: If a file has been init, output log is written there +void TraceLog(int msgType, const char *text, ...) +{ + va_list args; + int traceDebugMsgs = 0; + +#ifdef DO_NOT_TRACE_DEBUG_MSGS + traceDebugMsgs = 0; +#endif + + switch (msgType) + { + case INFO: fprintf(stdout, "INFO: "); break; + case ERROR: fprintf(stdout, "ERROR: "); break; + case WARNING: fprintf(stdout, "WARNING: "); break; + case DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break; + default: break; + } + + if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs))) + { + va_start(args, text); + vfprintf(stdout, text, args); + va_end(args); + + fprintf(stdout, "\n"); + } + + if (msgType == ERROR) exit(1); // If ERROR message, exit program +} +#endif + +#endif // RAYGUI_IMPLEMENTATION + + +/* +//T LoadResource(const char *rresFileName, int resId); + +// ASSUMPTION: rRES files only contain one resource (solution to id requirement...) + +// Now, rres file check and data loading can be managed inside each function: +Image LoadImage(); // -> Texture2D +Wave LoadWave() // -> Sound, Music +const char *LoadText(); // -> Shader, Material + +// NOTE: RRESData uses void* data pointer, so we can load to image.data, wave.data, mesh.*, (unsigned char *) + +Image LoadImagePro(void *data, int width, int height, int format); +Image LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + +Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); +Mesh LoadMeshEx(rres.param1, rres.data, rres.data + offset, rres.data + offset*2, rres.data + offset*3); + +Shader LoadShaderV(const char *vsText, int vsLength); +Shader LoadShaderV(rres.data, rres.param1); + +Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); +Wave LoadWaveEx(rres.data, rres.param1, (int)rres.param2, (int)rres.param3, (int)rres.param4); + +// Max value for an unsigned short: 65535 + +// Parameters information depending on resource type (IMAGE, WAVE, MESH, TEXT) + +// Image data params +int imgWidth, imgHeight; +char colorFormat, mipmaps; + +// Wave data params +short sampleRate, bps; +char channels, reserved; + +// Mesh data params +int vertexCount, reserved; +short vertexTypesMask, vertexFormatsMask; + +// Text data params +int numChars; +char textFormat, language, charsetCode; +*/ \ No newline at end of file -- cgit v1.2.3 From 674ee2cf752aa31d688210418a4ceb349afdce38 Mon Sep 17 00:00:00 2001 From: Joel Davis Date: Sat, 31 Dec 2016 14:05:30 -0800 Subject: Fix vbo indexes for rlglUpdateMesh --- src/rlgl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/rlgl.c b/src/rlgl.c index cb1ac709..9770b647 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1950,27 +1950,27 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) } break; case 2: // Update normals (vertex normals) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.normals, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.normals); } break; case 3: // Update colors (vertex colors) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]); + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*numVertex, mesh.colors, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*numVertex, mesh.colors); } break; case 4: // Update tangents (vertex tangents) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.tangents, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.tangents); } break; case 5: // Update texcoords2 (vertex second texture coordinates) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]); + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*numVertex, mesh.texcoords2, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*numVertex, mesh.texcoords2); } break; -- cgit v1.2.3 From 037da8879a3ae61b09d8388bc2b4a2fe5359256a Mon Sep 17 00:00:00 2001 From: Joel Davis Date: Sat, 31 Dec 2016 15:06:39 -0800 Subject: Added RaycastGround and ray picking example --- examples/Makefile | 6 +++ examples/core_3d_raypick.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ src/raylib.h | 15 ++++++ src/shapes.c | 20 ++++++++ 4 files changed, 159 insertions(+) create mode 100644 examples/core_3d_raypick.c (limited to 'src') diff --git a/examples/Makefile b/examples/Makefile index 710e97c4..676529c7 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -203,6 +203,7 @@ EXAMPLES = \ core_gestures_detection \ core_3d_mode \ core_3d_picking \ + core_3d_raypick \ core_3d_camera_free \ core_3d_camera_first_person \ core_2d_camera \ @@ -320,6 +321,11 @@ core_3d_mode: core_3d_mode.c core_3d_picking: core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) +# compile [core] example - 3d ray picking +core_3d_raypick: core_3d_raypick.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + + # compile [core] example - 3d camera free core_3d_camera_free: core_3d_camera_free.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) diff --git a/examples/core_3d_raypick.c b/examples/core_3d_raypick.c new file mode 100644 index 00000000..c1c32771 --- /dev/null +++ b/examples/core_3d_raypick.c @@ -0,0 +1,118 @@ +/******************************************************************************************* +* +* raylib [core] example - Ray-Picking in 3d mode, also ground plane +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d ray picking"); + + // Define the camera to look into our 3d world + Camera camera; + camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + + Vector3 cubePosition = { 0.0f, 1.0f, 0.0f }; + Vector3 cubeSize = { 2.0f, 2.0f, 2.0f }; + Vector3 groundCursorPos = { 0 }; + + Ray ray; // Picking line ray + + bool collision = false; + + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera); // Update camera + + // if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + // { + // // NOTE: This function is NOT WORKING properly! + // ray = GetMouseRay(GetMousePosition(), camera); + + // // Check collision between ray and box + // collision = CheckCollisionRayBox(ray, + // (BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 }, + // (Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }}); + // } + + ray = GetMouseRay(GetMousePosition(), camera); + RayHitInfo hitinfo = RaycastGroundPlane( ray, 0.0 ); + + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + Begin3dMode(camera); + + if (collision) + { + DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED); + DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON); + + DrawCubeWires(cubePosition, cubeSize.x + 0.2f, cubeSize.y + 0.2f, cubeSize.z + 0.2f, GREEN); + } + else + { + DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY); + DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY); + } + + if (hitinfo.hit) { + + groundCursorPos = hitinfo.hitPosition; + groundCursorPos.y += 0.25; // Offset so the cube rests on the ground + printf("Hit: groundpos %3.2f %3.2f %3.2f\n", + groundCursorPos.x, groundCursorPos.y, groundCursorPos.z ); + DrawCubeWires( groundCursorPos, 0.5, 0.5, 0.5, RED ); + } + + DrawRay(ray, MAROON); + + DrawGrid(10, 1.0f); + + End3dMode(); + + //DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY); + + //if(collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/src/raylib.h b/src/raylib.h index e2e4ee13..f291ce85 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -97,6 +97,9 @@ #define DEG2RAD (PI/180.0f) #define RAD2DEG (180.0f/PI) +// A small number +#define EPSILON 0.000001 + // raylib Config Flags #define FLAG_FULLSCREEN_MODE 1 #define FLAG_RESIZABLE_WINDOW 2 @@ -491,6 +494,13 @@ typedef struct Ray { Vector3 direction; // Ray direction } Ray; +// Information returned from a raycast +typedef struct RayHitInfo { + bool hit; // Did the ray hit something? + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit +} RayHitInfo; + // Wave type, defines audio wave data typedef struct Wave { unsigned int sampleCount; // Number of samples @@ -910,6 +920,11 @@ RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphe Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +//------------------------------------------------------------------------------------ +// Ray Casts +//------------------------------------------------------------------------------------ +RLAPI RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ); + //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 diff --git a/src/shapes.c b/src/shapes.c index 3d3333c1..4b2de4f2 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -533,4 +533,24 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) } return retRec; +} + + +RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ) +{ + RayHitInfo result = {0}; + + if (fabs(ray.direction.y) > EPSILON) + { + float t = (ray.position.y - groundHeight) / -ray.direction.y; + if (t >= 0.0) { + Vector3 camDir = ray.direction; + VectorScale( &camDir, t ); + result.hit = true; + result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; + result.hitPosition = VectorAdd( ray.position, camDir ); + } + } + + return result; } \ No newline at end of file -- cgit v1.2.3 From d5d391faaf69027b8fecb26f30754c3bff83c311 Mon Sep 17 00:00:00 2001 From: Joel Davis Date: Mon, 2 Jan 2017 21:56:25 -0800 Subject: Added RaycastMesh function and example test case --- examples/core_3d_raypick.c | 159 +++++++--- examples/resources/model/lowpoly-tower.obj | 456 +++++++++++++++++++++++++++++ examples/resources/model/lowpoly-tower.png | Bin 0 -> 24939 bytes src/models.c | 38 +++ src/raylib.h | 3 + src/raymath.h | 26 ++ src/shapes.c | 73 ++++- 7 files changed, 708 insertions(+), 47 deletions(-) create mode 100644 examples/resources/model/lowpoly-tower.obj create mode 100644 examples/resources/model/lowpoly-tower.png (limited to 'src') diff --git a/examples/core_3d_raypick.c b/examples/core_3d_raypick.c index c1c32771..cf56b277 100644 --- a/examples/core_3d_raypick.c +++ b/examples/core_3d_raypick.c @@ -1,15 +1,21 @@ /******************************************************************************************* * -* raylib [core] example - Ray-Picking in 3d mode, also ground plane +* raylib [core] example - Ray-Picking in 3d mode, ground plane, triangle, mesh * * This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2015 Ramon Santamaria (@raysan5) +* Example contributed by Joel Davis (@joeld42) * ********************************************************************************************/ #include "raylib.h" +#include "raymath.h" + +#include +#include + int main() { @@ -22,24 +28,36 @@ int main() // Define the camera to look into our 3d world Camera camera; - camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.position = (Vector3){ 10.0f, 8.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.3f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y Vector3 cubePosition = { 0.0f, 1.0f, 0.0f }; Vector3 cubeSize = { 2.0f, 2.0f, 2.0f }; - Vector3 groundCursorPos = { 0 }; Ray ray; // Picking line ray - bool collision = false; - + Model tower = LoadModel("resources/model/lowpoly-tower.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/model/lowpoly-tower.png"); // Load model texture + tower.material.texDiffuse = texture; // Set model diffuse texture + Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position + BoundingBox towerBBox = CalculateBoundingBox( tower.mesh ); + bool hitMeshBBox; + bool hitTriangle; + + // Test triangle + Vector3 ta = (Vector3){ -25.0, 0.5, 0.0 }; + Vector3 tb = (Vector3){ -4.0, 2.5, 1.0 }; + Vector3 tc = (Vector3){ -8.0, 6.5, 0.0 }; + + Vector3 bary = {0}; + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { @@ -47,22 +65,52 @@ int main() //---------------------------------------------------------------------------------- UpdateCamera(&camera); // Update camera - // if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) - // { - // // NOTE: This function is NOT WORKING properly! - // ray = GetMouseRay(GetMousePosition(), camera); - - // // Check collision between ray and box - // collision = CheckCollisionRayBox(ray, - // (BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 }, - // (Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }}); - // } + // Display information about closest hit + RayHitInfo nearestHit; + char *hitObjectName = "None"; + nearestHit.distance = FLT_MAX; + nearestHit.hit = false; + Color cursorColor = WHITE; + + // Get ray and test against ground, triangle, and mesh ray = GetMouseRay(GetMousePosition(), camera); - RayHitInfo hitinfo = RaycastGroundPlane( ray, 0.0 ); + + RayHitInfo groundHitInfo = RaycastGroundPlane( ray, 0.0 ); + if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) { + nearestHit = groundHitInfo; + cursorColor = GREEN; + hitObjectName = "Ground"; + } + + RayHitInfo triHitInfo = RaycastTriangle( ray, ta, tb, tc ); + if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) { + nearestHit = triHitInfo; + cursorColor = PURPLE; + hitObjectName = "Triangle"; + + bary = Barycentric( nearestHit.hitPosition, ta, tb, tc ); + hitTriangle = true; + } else { + hitTriangle = false; + } + + RayHitInfo meshHitInfo; + + // check the bounding box first, before trying the full ray/mesh test + if (CheckCollisionRayBox( ray, towerBBox )) { + hitMeshBBox = true; + meshHitInfo = RaycastMesh( ray, &tower.mesh ); + if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) { + nearestHit = meshHitInfo; + cursorColor = ORANGE; + hitObjectName = "Mesh"; + } + } else { + hitMeshBBox = false; + } //---------------------------------------------------------------------------------- - // Draw //---------------------------------------------------------------------------------- BeginDrawing(); @@ -71,37 +119,66 @@ int main() Begin3dMode(camera); - if (collision) - { - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED); - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON); - - DrawCubeWires(cubePosition, cubeSize.x + 0.2f, cubeSize.y + 0.2f, cubeSize.z + 0.2f, GREEN); - } - else - { - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY); - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY); + // Draw the tower + DrawModel( tower, towerPos, 1.0, WHITE ); + + // Draw the test triangle + DrawLine3D( ta, tb, PURPLE ); + DrawLine3D( tb, tc, PURPLE ); + DrawLine3D( tc, ta, PURPLE ); + + // Draw the mesh bbox if we hit it + if (hitMeshBBox) { + DrawBoundingBox( towerBBox, LIME ); } - if (hitinfo.hit) { + // If we hit something, draw the cursor at the hit point + if (nearestHit.hit) { + DrawCube( nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor ); + DrawCubeWires( nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW ); - groundCursorPos = hitinfo.hitPosition; - groundCursorPos.y += 0.25; // Offset so the cube rests on the ground - printf("Hit: groundpos %3.2f %3.2f %3.2f\n", - groundCursorPos.x, groundCursorPos.y, groundCursorPos.z ); - DrawCubeWires( groundCursorPos, 0.5, 0.5, 0.5, RED ); + Vector3 normalEnd; + normalEnd.x = nearestHit.hitPosition.x + nearestHit.hitNormal.x; + normalEnd.y = nearestHit.hitPosition.y + nearestHit.hitNormal.y; + normalEnd.z = nearestHit.hitPosition.z + nearestHit.hitNormal.z; + DrawLine3D( nearestHit.hitPosition, normalEnd, YELLOW ); } - + DrawRay(ray, MAROON); DrawGrid(10, 1.0f); End3dMode(); - //DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY); - - //if(collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN); + // Show some debug text + char line[1024]; + sprintf( line, "Hit Object: %s\n", hitObjectName ); + DrawText( line, 10, 30, 15, BLACK ); + + if (nearestHit.hit) { + int ypos = 45; + sprintf( line, "Distance: %3.2f", nearestHit.distance ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + sprintf( line, "Hit Pos: %3.2f %3.2f %3.2f", + nearestHit.hitPosition.x, nearestHit.hitPosition.y, nearestHit.hitPosition.z ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + sprintf( line, "Hit Norm: %3.2f %3.2f %3.2f", + nearestHit.hitNormal.x, nearestHit.hitNormal.y, nearestHit.hitNormal.z ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + if (hitTriangle) { + sprintf( line, "Barycentric: %3.2f %3.2f %3.2f", + bary.x, bary.y, bary.z ); + DrawText( line, 10, ypos, 15, BLACK ); + } + } + + DrawText( "Use Mouse to Move Camera", 10, 420, 15, LIGHTGRAY ); DrawFPS(10, 10); diff --git a/examples/resources/model/lowpoly-tower.obj b/examples/resources/model/lowpoly-tower.obj new file mode 100644 index 00000000..ea03a9fc --- /dev/null +++ b/examples/resources/model/lowpoly-tower.obj @@ -0,0 +1,456 @@ +# Blender v2.78 (sub 0) OBJ File: 'lowpoly-tower.blend' +# www.blender.org +o Grid +v -4.000000 0.000000 4.000000 +v -2.327363 0.000000 4.654725 +v 0.000000 0.000000 4.654725 +v 2.327363 0.000000 4.654725 +v 4.000000 0.000000 4.000000 +v -4.654725 0.955085 2.327363 +v -2.000000 0.815050 2.000000 +v 0.000000 0.476341 2.423448 +v 2.000000 0.476341 2.000000 +v 4.654725 0.000000 2.327363 +v -4.654725 1.649076 0.000000 +v -2.423448 1.092402 0.000000 +v 2.423448 0.198579 0.000000 +v 4.654725 0.000000 0.000000 +v -4.654725 1.649076 -2.327363 +v -2.000000 1.092402 -2.000000 +v 0.000000 0.476341 -2.423448 +v 2.000000 -0.012791 -2.000000 +v 4.654725 0.000000 -2.612731 +v -4.000000 0.955085 -4.000000 +v -2.327363 0.955085 -4.654725 +v 0.000000 0.955085 -4.654725 +v 2.327363 0.000000 -4.654725 +v 4.000000 0.000000 -4.000000 +v 2.423448 0.682825 0.000000 +v 2.000000 0.565423 -2.000000 +v -4.654725 -0.020560 2.327363 +v -4.654725 0.000000 0.000000 +v -4.654725 0.000000 -2.327363 +v -4.000000 0.000000 -4.000000 +v -2.327363 0.000000 -4.654725 +v 0.000000 -0.020560 -4.654725 +v 0.000000 0.709880 -1.230535 +v -0.000000 7.395413 0.000000 +v 0.962071 0.709880 -0.767226 +v -0.533909 0.709880 1.108674 +v -1.199683 0.709880 0.273820 +v -0.962071 0.709880 -0.767226 +v 1.506076 0.859071 1.325337 +v 1.199683 0.709880 0.273820 +v 0.533909 0.709880 1.108674 +v 0.000000 1.875340 -1.177842 +v -0.000000 2.293973 -0.649884 +v -0.000000 4.365648 -0.627970 +v 0.000000 6.167194 -0.942957 +v 0.000000 6.232434 -1.708677 +v 1.335898 6.232434 -1.065343 +v 0.737233 6.167195 -0.587924 +v 0.490966 4.365648 -0.391533 +v 0.508100 2.293973 -0.405196 +v 0.920874 1.875340 -0.734372 +v -0.741367 6.232434 1.539465 +v -0.409133 6.167195 0.849574 +v -0.272466 4.365648 0.565781 +v -0.281974 2.293973 0.585526 +v -0.511047 1.875340 1.061199 +v -1.665837 6.232434 0.380217 +v -0.919314 6.167195 0.209828 +v -0.612225 4.365648 0.139736 +v -0.633590 2.293973 0.144613 +v -1.148311 1.875340 0.262095 +v -1.335898 6.232434 -1.065343 +v -0.737233 6.167195 -0.587924 +v -0.490967 4.365648 -0.391533 +v -0.508100 2.293973 -0.405196 +v -0.920874 1.875340 -0.734372 +v 1.665837 6.232434 0.380216 +v 0.919315 6.167195 0.209828 +v 0.612225 4.365648 0.139736 +v 0.633590 2.293973 0.144613 +v 1.148311 1.875340 0.262095 +v 0.741367 6.232434 1.539465 +v 0.409133 6.167195 0.849575 +v 0.272466 4.365648 0.565781 +v 0.281974 2.293973 0.585526 +v 0.511046 1.875340 1.061199 +v 0.000000 5.012550 -0.969733 +v 0.758168 5.012550 -0.604618 +v -0.420751 5.012550 0.873699 +v -0.945419 5.012550 0.215786 +v -0.758168 5.012550 -0.604618 +v 0.945419 5.012550 0.215786 +v 0.420751 5.012550 0.873699 +vt 0.0523 0.5444 +vt 0.1817 0.4284 +vt 0.1641 0.5859 +vt 0.0177 0.4451 +vt 0.1526 0.3090 +vt 0.0189 0.1737 +vt 0.0188 0.3088 +vt 0.0561 0.0762 +vt 0.1757 0.1924 +vt 0.3024 0.4534 +vt 0.3071 0.5902 +vt 0.3413 0.2459 +vt 0.2906 0.1614 +vt 0.4116 0.1801 +vt 0.2834 0.3774 +vt 0.1526 0.0362 +vt 0.2917 0.1622 +vt 0.4446 0.5865 +vt 0.4443 0.2989 +vt 0.3711 0.3021 +vt 0.4396 0.0275 +vt 0.4094 0.1829 +vt 0.4219 0.4255 +vt 0.5474 0.5381 +vt 0.5811 0.4376 +vt 0.5715 0.1505 +vt 0.5811 0.2997 +vt 0.5272 0.0533 +vt 0.2208 0.2194 +vt 0.3456 0.3610 +vt 0.2878 0.0321 +vt 0.2321 0.3392 +vt 0.4432 0.0177 +vt 0.7347 0.7934 +vt 0.7382 0.7595 +vt 0.8982 0.7768 +vt 0.6169 0.7595 +vt 0.6139 0.7879 +vt 0.4951 0.7634 +vt 0.1551 0.6832 +vt 0.2925 0.6268 +vt 0.2925 0.6832 +vt 0.7795 0.6832 +vt 0.6421 0.6268 +vt 0.7795 0.6255 +vt 0.5046 0.7241 +vt 0.6421 0.7241 +vt 0.3986 0.6268 +vt 0.3986 0.6832 +vt 0.5046 0.6268 +vt 0.0177 0.6268 +vt 0.1551 0.6255 +vt 0.8856 0.6268 +vt 0.1899 0.9579 +vt 0.1194 0.8696 +vt 0.2324 0.8696 +vt 0.1899 0.7813 +vt 0.0943 0.7595 +vt 0.0177 0.8206 +vt 0.0177 0.9186 +vt 0.0943 0.9797 +vt 0.2793 0.2349 +vt 0.2304 0.2758 +vt 0.6597 0.0177 +vt 0.6954 0.0993 +vt 0.6367 0.0768 +vt 0.7558 0.0777 +vt 0.7238 0.0440 +vt 0.8840 0.1330 +vt 0.7385 0.1141 +vt 0.9157 0.0886 +vt 0.9781 0.1232 +vt 0.9224 0.1276 +vt 0.2677 0.8141 +vt 0.3463 0.8037 +vt 0.3086 0.8339 +vt 0.6387 0.3550 +vt 0.7130 0.3801 +vt 0.6596 0.4053 +vt 0.7245 0.3245 +vt 0.6919 0.3383 +vt 0.8655 0.3566 +vt 0.7351 0.3577 +vt 0.9770 0.3365 +vt 0.9078 0.3751 +vt 0.9174 0.3282 +vt 0.2677 0.9018 +vt 0.3086 0.8821 +vt 0.6803 0.2948 +vt 0.6251 0.3035 +vt 0.7194 0.2854 +vt 0.8764 0.2832 +vt 0.9221 0.2861 +vt 0.3363 0.9565 +vt 0.3464 0.9122 +vt 0.6751 0.2482 +vt 0.6178 0.2499 +vt 0.7179 0.2431 +vt 0.9823 0.2484 +vt 0.9247 0.2452 +vt 0.3935 0.9014 +vt 0.6755 0.1996 +vt 0.6164 0.1941 +vt 0.7201 0.1992 +vt 0.8793 0.2446 +vt 0.9823 0.2060 +vt 0.9257 0.2051 +vt 0.4598 0.8580 +vt 0.4144 0.8579 +vt 0.6819 0.1498 +vt 0.6222 0.1361 +vt 0.7266 0.1555 +vt 0.8831 0.1684 +vt 0.9252 0.1659 +vt 0.4218 0.7790 +vt 0.3934 0.8145 +vt 0.3363 0.7595 +vt 0.8815 0.2060 +vt 0.8720 0.3208 +vt 0.8825 0.1012 +vt 0.9735 0.0816 +vt 0.9718 0.3817 +vt 0.9807 0.2918 +vt 0.4218 0.9370 +vt 0.9810 0.1644 +vn 0.1035 0.8806 0.4623 +vn 0.0964 0.9481 0.3030 +vn 0.0000 0.9780 0.2088 +vn 0.0659 0.9835 0.1683 +vn 0.2325 0.9320 0.2779 +vn 0.0553 0.9960 -0.0702 +vn 0.2827 0.9564 0.0728 +vn 0.1873 0.9776 -0.0961 +vn 0.2421 0.9703 0.0000 +vn 0.0921 0.9772 -0.1913 +vn -0.0277 0.9947 -0.0993 +vn 0.2308 0.9274 -0.2944 +vn 0.2771 0.9572 -0.0837 +vn 0.3724 0.9074 0.1947 +vn 0.0777 0.9770 -0.1985 +vn -0.1094 0.9539 0.2794 +vn 0.0364 0.9844 0.1721 +vn 0.1683 0.9835 0.0659 +vn 0.0674 0.9901 0.1230 +vn 0.4338 0.8823 0.1829 +vn 0.2845 0.9565 0.0649 +vn 0.0886 0.9961 0.0000 +vn 0.2000 0.9789 0.0424 +vn 0.1417 0.9830 0.1171 +vn 0.3021 0.9524 0.0412 +vn -0.0193 0.9986 -0.0493 +vn 0.0000 0.9777 0.2098 +vn 0.0005 0.9781 -0.2083 +vn 0.1879 0.9782 -0.0887 +vn 0.2249 0.0000 0.9744 +vn 0.9783 0.0000 -0.2071 +vn 0.9783 0.0000 0.2071 +vn 0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn -0.3645 0.0000 -0.9312 +vn -0.9312 0.0000 -0.3645 +vn -0.9312 0.0000 0.3645 +vn 0.2615 0.7979 -0.5431 +vn 0.5877 0.7979 -0.1341 +vn 0.4713 0.7979 0.3758 +vn -0.0000 0.7979 0.6028 +vn -0.4713 0.7979 0.3758 +vn -0.5877 0.7979 -0.1341 +vn -0.2615 0.7979 -0.5431 +vn -0.1285 0.9864 -0.1025 +vn 0.0929 0.8937 0.4389 +vn -0.4335 0.0407 -0.9002 +vn -0.2867 0.7507 -0.5952 +vn -0.4339 0.0095 -0.9009 +vn -0.4338 0.0209 -0.9008 +vn -0.0408 -0.9956 -0.0848 +vn -0.9741 0.0407 -0.2223 +vn -0.6441 0.7507 -0.1470 +vn -0.9749 0.0095 -0.2225 +vn -0.9747 0.0209 -0.2225 +vn -0.0918 -0.9956 -0.0209 +vn -0.7812 0.0407 0.6230 +vn -0.5165 0.7507 0.4119 +vn -0.7818 0.0095 0.6235 +vn -0.7817 0.0209 0.6234 +vn -0.0736 -0.9956 0.0587 +vn -0.0000 0.0407 0.9992 +vn 0.0000 0.7507 0.6607 +vn 0.0000 0.0095 1.0000 +vn -0.0000 0.0209 0.9998 +vn -0.0000 -0.9956 0.0941 +vn 0.7812 0.0407 0.6230 +vn 0.5165 0.7507 0.4119 +vn 0.7818 0.0095 0.6235 +vn 0.7817 0.0209 0.6234 +vn 0.0736 -0.9956 0.0587 +vn 0.9741 0.0407 -0.2223 +vn 0.6441 0.7507 -0.1470 +vn 0.9749 0.0095 -0.2225 +vn 0.9747 0.0209 -0.2225 +vn 0.0918 -0.9956 -0.0209 +vn 0.4335 0.0407 -0.9002 +vn 0.2867 0.7507 -0.5952 +vn 0.4339 0.0095 -0.9009 +vn 0.4338 0.0209 -0.9008 +vn 0.0408 -0.9956 -0.0848 +vn 0.3918 -0.4298 -0.8135 +vn 0.8803 -0.4298 -0.2009 +vn 0.7059 -0.4298 0.5630 +vn -0.0000 -0.4298 0.9029 +vn -0.7059 -0.4298 0.5630 +vn -0.8803 -0.4298 -0.2009 +vn -0.3918 -0.4298 -0.8135 +vn 0.0210 0.9998 -0.0048 +vn 0.0482 0.9981 -0.0385 +vn -0.0166 0.9914 -0.1301 +vn -0.0090 0.9904 -0.1379 +vn 0.2820 0.9576 0.0597 +vn -0.0000 0.9846 0.1749 +vn -0.0921 0.9772 -0.1913 +vn -0.1734 0.9794 0.1036 +s off +f 1/1/1 7/2/1 6/3/1 +f 2/4/2 8/5/2 7/2/2 +f 4/6/3 8/5/3 3/7/3 +f 5/8/4 9/9/4 4/6/4 +f 6/3/5 12/10/5 11/11/5 +f 35/12/6 25/13/6 26/14/6 +f 7/2/7 37/15/7 12/10/7 +f 10/16/8 13/17/8 9/9/8 +f 12/10/9 15/18/9 11/11/9 +f 35/12/10 17/19/10 33/20/10 +f 13/17/11 19/21/11 18/22/11 +f 16/23/12 20/24/12 15/18/12 +f 17/19/13 21/25/13 16/23/13 +f 17/19/14 23/26/14 22/27/14 +f 26/14/15 24/28/15 23/26/15 +f 1/1/16 2/4/16 7/2/16 +f 2/4/3 3/7/3 8/5/3 +f 4/6/17 9/9/17 8/5/17 +f 5/8/18 10/16/18 9/9/18 +f 6/3/19 7/2/19 12/10/19 +f 25/13/20 39/29/20 9/9/20 +f 38/30/21 12/10/21 37/15/21 +f 10/16/22 14/31/22 13/17/22 +f 12/10/23 16/23/23 15/18/23 +f 8/5/24 36/32/24 7/2/24 +f 38/30/25 17/19/25 16/23/25 +f 13/17/22 14/31/22 19/21/22 +f 16/23/26 21/25/26 20/24/26 +f 17/19/27 22/27/27 21/25/27 +f 17/19/28 26/14/28 23/26/28 +f 26/14/29 19/33/29 24/28/29 +f 26/34/30 18/35/30 19/36/30 +f 26/34/31 13/37/31 18/35/31 +f 25/38/32 9/39/32 13/37/32 +f 22/40/33 31/41/33 21/42/33 +f 6/43/34 28/44/34 27/45/34 +f 15/46/34 28/44/34 11/47/34 +f 21/42/35 30/48/35 20/49/35 +f 20/49/36 29/50/36 15/46/36 +f 22/40/33 23/51/33 32/52/33 +f 6/43/37 27/45/37 1/53/37 +f 46/54/38 34/55/38 47/56/38 +f 47/56/39 34/55/39 67/57/39 +f 67/57/40 34/55/40 72/58/40 +f 72/58/41 34/55/41 52/59/41 +f 52/59/42 34/55/42 57/60/42 +f 57/60/43 34/55/43 62/61/43 +f 62/61/44 34/55/44 46/54/44 +f 40/62/45 41/63/45 39/29/45 +f 39/29/46 8/5/46 9/9/46 +f 38/64/47 42/65/47 33/66/47 +f 65/67/48 42/65/48 66/68/48 +f 65/67/49 44/69/49 43/70/49 +f 81/71/50 45/72/50 77/73/50 +f 62/74/51 45/75/51 63/76/51 +f 37/77/52 66/78/52 38/79/52 +f 60/80/53 66/78/53 61/81/53 +f 60/80/54 64/82/54 65/83/54 +f 58/84/55 81/85/55 80/86/55 +f 57/87/56 63/76/56 58/88/56 +f 56/89/57 37/77/57 36/90/57 +f 55/91/58 61/81/58 56/89/58 +f 54/92/59 60/80/59 55/91/59 +f 79/93/60 58/84/60 80/86/60 +f 52/94/61 58/88/61 53/95/61 +f 76/96/62 36/90/62 41/97/62 +f 75/98/63 56/89/63 76/96/63 +f 75/98/64 54/92/64 55/91/64 +f 73/99/65 79/93/65 83/100/65 +f 73/101/66 52/94/66 53/95/66 +f 71/102/67 41/97/67 40/103/67 +f 70/104/68 76/96/68 71/102/68 +f 70/104/69 74/105/69 75/98/69 +f 68/106/70 83/100/70 82/107/70 +f 67/108/71 73/101/71 68/109/71 +f 51/110/72 40/103/72 35/111/72 +f 50/112/73 71/102/73 51/110/73 +f 49/113/74 70/104/74 50/112/74 +f 78/114/75 68/106/75 82/107/75 +f 47/115/76 68/109/76 48/116/76 +f 42/65/77 35/111/77 33/66/77 +f 43/70/78 51/110/78 42/65/78 +f 44/69/79 50/112/79 43/70/79 +f 45/72/80 78/114/80 77/73/80 +f 46/117/81 48/116/81 45/75/81 +f 44/69/82 78/114/82 49/113/82 +f 49/113/83 82/107/83 69/118/83 +f 82/107/84 74/105/84 69/118/84 +f 83/100/85 54/92/85 74/105/85 +f 79/93/86 59/119/86 54/92/86 +f 80/86/87 64/82/87 59/119/87 +f 64/120/88 77/73/88 44/69/88 +f 35/12/89 40/62/89 25/13/89 +f 7/2/90 36/32/90 37/15/90 +f 35/12/91 26/14/91 17/19/91 +f 25/13/92 40/62/92 39/29/92 +f 38/30/93 16/23/93 12/10/93 +f 8/5/94 41/63/94 36/32/94 +f 38/30/95 33/20/95 17/19/95 +f 26/34/31 25/38/31 13/37/31 +f 22/40/33 32/52/33 31/41/33 +f 6/43/34 11/47/34 28/44/34 +f 15/46/34 29/50/34 28/44/34 +f 21/42/35 31/41/35 30/48/35 +f 20/49/36 30/48/36 29/50/36 +f 39/29/96 41/63/96 8/5/96 +f 38/64/47 66/68/47 42/65/47 +f 65/67/48 43/70/48 42/65/48 +f 65/67/49 64/120/49 44/69/49 +f 81/71/50 63/121/50 45/72/50 +f 62/74/51 46/117/51 45/75/51 +f 37/77/52 61/81/52 66/78/52 +f 60/80/53 65/83/53 66/78/53 +f 60/80/54 59/119/54 64/82/54 +f 58/84/55 63/122/55 81/85/55 +f 57/87/56 62/74/56 63/76/56 +f 56/89/57 61/81/57 37/77/57 +f 55/91/58 60/80/58 61/81/58 +f 54/92/59 59/119/59 60/80/59 +f 79/93/60 53/123/60 58/84/60 +f 52/94/61 57/87/61 58/88/61 +f 76/96/62 56/89/62 36/90/62 +f 75/98/63 55/91/63 56/89/63 +f 75/98/64 74/105/64 54/92/64 +f 73/99/65 53/123/65 79/93/65 +f 73/101/66 72/124/66 52/94/66 +f 71/102/67 76/96/67 41/97/67 +f 70/104/68 75/98/68 76/96/68 +f 70/104/69 69/118/69 74/105/69 +f 68/106/70 73/99/70 83/100/70 +f 67/108/71 72/124/71 73/101/71 +f 51/110/72 71/102/72 40/103/72 +f 50/112/73 70/104/73 71/102/73 +f 49/113/74 69/118/74 70/104/74 +f 78/114/75 48/125/75 68/106/75 +f 47/115/76 67/108/76 68/109/76 +f 42/65/77 51/110/77 35/111/77 +f 43/70/78 50/112/78 51/110/78 +f 44/69/79 49/113/79 50/112/79 +f 45/72/80 48/125/80 78/114/80 +f 46/117/81 47/115/81 48/116/81 +f 44/69/82 77/73/82 78/114/82 +f 49/113/83 78/114/83 82/107/83 +f 82/107/84 83/100/84 74/105/84 +f 83/100/85 79/93/85 54/92/85 +f 79/93/86 80/86/86 59/119/86 +f 80/86/87 81/85/87 64/82/87 +f 64/120/88 81/71/88 77/73/88 diff --git a/examples/resources/model/lowpoly-tower.png b/examples/resources/model/lowpoly-tower.png new file mode 100644 index 00000000..7c9239e2 Binary files /dev/null and b/examples/resources/model/lowpoly-tower.png differ diff --git a/src/models.c b/src/models.c index a2043913..41e527dc 100644 --- a/src/models.c +++ b/src/models.c @@ -1918,3 +1918,41 @@ static Material LoadMTL(const char *fileName) return material; } + +RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ) +{ + RayHitInfo result = {0}; + + // If mesh doesn't have vertex data on CPU, can't test it. + if (!mesh->vertices) { + return result; + } + + // mesh->triangleCount may not be set, vertexCount is more reliable + int triangleCount = mesh->vertexCount / 3; + + // Test against all triangles in mesh + for (int i=0; i < triangleCount; i++) { + Vector3 a, b, c; + Vector3 *vertdata = (Vector3*)mesh->vertices; + if (mesh->indices) { + a = vertdata[ mesh->indices[i*3+0] ]; + b = vertdata[ mesh->indices[i*3+1] ]; + c = vertdata[ mesh->indices[i*3+2] ]; + } else { + a = vertdata[i*3+0]; + b = vertdata[i*3+1]; + c = vertdata[i*3+2]; + } + + RayHitInfo triHitInfo = RaycastTriangle( ray, a, b, c ); + if (triHitInfo.hit) { + // Save the closest hit triangle + if ((!result.hit)||(result.distance > triHitInfo.distance)) { + result = triHitInfo; + } + } + } + + return result; +} diff --git a/src/raylib.h b/src/raylib.h index f291ce85..7252ba4e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -497,6 +497,7 @@ typedef struct Ray { // Information returned from a raycast typedef struct RayHitInfo { bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit Vector3 hitPosition; // Position of nearest hit Vector3 hitNormal; // Surface normal of hit } RayHitInfo; @@ -924,6 +925,8 @@ RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Ray Casts //------------------------------------------------------------------------------------ RLAPI RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ); +RLAPI RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ); +RLAPI RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ); //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) diff --git a/src/raymath.h b/src/raymath.h index 3cd1394e..5871e350 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -130,6 +130,7 @@ RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Ve RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components +RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycentric coords for p in triangle abc //------------------------------------------------------------------------------------ // Functions Declaration to work with Matrix @@ -382,6 +383,31 @@ RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2) return result; } +// Compute barycentric coordinates (u, v, w) for +// point p with respect to triangle (a, b, c) +// Assumes P is on the plane of the triangle +RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c) +{ + + //Vector v0 = b - a, v1 = c - a, v2 = p - a; + Vector3 v0 = VectorSubtract( b, a ); + Vector3 v1 = VectorSubtract( c, a ); + Vector3 v2 = VectorSubtract( p, a ); + float d00 = VectorDotProduct(v0, v0); + float d01 = VectorDotProduct(v0, v1); + float d11 = VectorDotProduct(v1, v1); + float d20 = VectorDotProduct(v2, v0); + float d21 = VectorDotProduct(v2, v1); + float denom = d00 * d11 - d01 * d01; + + Vector3 result; + result.y = (d11 * d20 - d01 * d21) / denom; + result.z = (d00 * d21 - d01 * d20) / denom; + result.x = 1.0f - (result.z + result.y); + + return result; +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- diff --git a/src/shapes.c b/src/shapes.c index 4b2de4f2..74480c83 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -544,13 +544,74 @@ RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ) { float t = (ray.position.y - groundHeight) / -ray.direction.y; if (t >= 0.0) { - Vector3 camDir = ray.direction; - VectorScale( &camDir, t ); - result.hit = true; - result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; - result.hitPosition = VectorAdd( ray.position, camDir ); + Vector3 rayDir = ray.direction; + VectorScale( &rayDir, t ); + result.hit = true; + result.distance = t; + result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; + result.hitPosition = VectorAdd( ray.position, rayDir ); } } + return result; +} +// Adapted from: +// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm +RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ) +{ + Vector3 e1, e2; //Edge1, Edge2 + Vector3 p, q, tv; + float det, inv_det, u, v; + float t; + RayHitInfo result = {0}; + + //Find vectors for two edges sharing V1 + e1 = VectorSubtract( b, a); + e2 = VectorSubtract( c, a); + + //Begin calculating determinant - also used to calculate u parameter + p = VectorCrossProduct( ray.direction, e2); + + //if determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle + det = VectorDotProduct(e1, p); + + //NOT CULLING + if(det > -EPSILON && det < EPSILON) return result; + inv_det = 1.f / det; + + //calculate distance from V1 to ray origin + tv = VectorSubtract( ray.position, a ); + + //Calculate u parameter and test bound + u = VectorDotProduct(tv, p) * inv_det; + + //The intersection lies outside of the triangle + if(u < 0.f || u > 1.f) return result; + + //Prepare to test v parameter + q = VectorCrossProduct( tv, e1 ); + + //Calculate V parameter and test bound + v = VectorDotProduct( ray.direction, q) * inv_det; + + //The intersection lies outside of the triangle + if(v < 0.f || (u + v) > 1.f) return result; + + t = VectorDotProduct(e2, q) * inv_det; + + + if(t > EPSILON) { + // ray hit, get hit point and normal + result.hit = true; + result.distance = t; + result.hit = true; + result.hitNormal = VectorCrossProduct( e1, e2 ); + VectorNormalize( &result.hitNormal ); + Vector3 rayDir = ray.direction; + VectorScale( &rayDir, t ); + result.hitPosition = VectorAdd( ray.position, rayDir ); + } + return result; -} \ No newline at end of file +} + -- cgit v1.2.3 From 658c2806690ace34a0dae6b6ed12d0ea52d2d6e4 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 5 Jan 2017 19:33:05 +0100 Subject: Lattest PR review Function names, code formatting... --- examples/Makefile | 11 ++- examples/core_3d_raypick.c | 195 ----------------------------------------- examples/models_ray_picking.c | 197 ++++++++++++++++++++++++++++++++++++++++++ src/models.c | 167 +++++++++++++++++++++++++++-------- src/raylib.h | 21 ++--- src/raymath.h | 25 +++--- src/shapes.c | 81 ----------------- 7 files changed, 351 insertions(+), 346 deletions(-) delete mode 100644 examples/core_3d_raypick.c create mode 100644 examples/models_ray_picking.c (limited to 'src') diff --git a/examples/Makefile b/examples/Makefile index 676529c7..80437590 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -203,7 +203,6 @@ EXAMPLES = \ core_gestures_detection \ core_3d_mode \ core_3d_picking \ - core_3d_raypick \ core_3d_camera_free \ core_3d_camera_first_person \ core_2d_camera \ @@ -237,6 +236,7 @@ EXAMPLES = \ models_obj_loading \ models_heightmap \ models_cubicmap \ + models_ray_picking \ shaders_model_shader \ shaders_shapes_textures \ shaders_custom_uniform \ @@ -321,11 +321,6 @@ core_3d_mode: core_3d_mode.c core_3d_picking: core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) -# compile [core] example - 3d ray picking -core_3d_raypick: core_3d_raypick.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - - # compile [core] example - 3d camera free core_3d_camera_free: core_3d_camera_free.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) @@ -462,6 +457,10 @@ models_heightmap: models_heightmap.c models_cubicmap: models_cubicmap.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) +# compile [models] example - model ray picking +models_ray_picking: models_ray_picking.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [shaders] example - model shader shaders_model_shader: shaders_model_shader.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) diff --git a/examples/core_3d_raypick.c b/examples/core_3d_raypick.c deleted file mode 100644 index cf56b277..00000000 --- a/examples/core_3d_raypick.c +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************************* -* -* raylib [core] example - Ray-Picking in 3d mode, ground plane, triangle, mesh -* -* This example has been created using raylib 1.3 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2015 Ramon Santamaria (@raysan5) -* Example contributed by Joel Davis (@joeld42) -* -********************************************************************************************/ - -#include "raylib.h" -#include "raymath.h" - -#include -#include - - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; - - InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d ray picking"); - - // Define the camera to look into our 3d world - Camera camera; - camera.position = (Vector3){ 10.0f, 8.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 2.3f, 0.0f }; // Camera looking at point - camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) - camera.fovy = 45.0f; // Camera field-of-view Y - - Vector3 cubePosition = { 0.0f, 1.0f, 0.0f }; - Vector3 cubeSize = { 2.0f, 2.0f, 2.0f }; - - Ray ray; // Picking line ray - - Model tower = LoadModel("resources/model/lowpoly-tower.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/model/lowpoly-tower.png"); // Load model texture - tower.material.texDiffuse = texture; // Set model diffuse texture - Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position - BoundingBox towerBBox = CalculateBoundingBox( tower.mesh ); - bool hitMeshBBox; - bool hitTriangle; - - // Test triangle - Vector3 ta = (Vector3){ -25.0, 0.5, 0.0 }; - Vector3 tb = (Vector3){ -4.0, 2.5, 1.0 }; - Vector3 tc = (Vector3){ -8.0, 6.5, 0.0 }; - - Vector3 bary = {0}; - - SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - - //-------------------------------------------------------------------------------------- - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - UpdateCamera(&camera); // Update camera - - - // Display information about closest hit - RayHitInfo nearestHit; - char *hitObjectName = "None"; - nearestHit.distance = FLT_MAX; - nearestHit.hit = false; - Color cursorColor = WHITE; - - // Get ray and test against ground, triangle, and mesh - ray = GetMouseRay(GetMousePosition(), camera); - - RayHitInfo groundHitInfo = RaycastGroundPlane( ray, 0.0 ); - if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) { - nearestHit = groundHitInfo; - cursorColor = GREEN; - hitObjectName = "Ground"; - } - - RayHitInfo triHitInfo = RaycastTriangle( ray, ta, tb, tc ); - if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) { - nearestHit = triHitInfo; - cursorColor = PURPLE; - hitObjectName = "Triangle"; - - bary = Barycentric( nearestHit.hitPosition, ta, tb, tc ); - hitTriangle = true; - } else { - hitTriangle = false; - } - - RayHitInfo meshHitInfo; - - // check the bounding box first, before trying the full ray/mesh test - if (CheckCollisionRayBox( ray, towerBBox )) { - hitMeshBBox = true; - meshHitInfo = RaycastMesh( ray, &tower.mesh ); - if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) { - nearestHit = meshHitInfo; - cursorColor = ORANGE; - hitObjectName = "Mesh"; - } - } else { - hitMeshBBox = false; - } - - //---------------------------------------------------------------------------------- - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - Begin3dMode(camera); - - // Draw the tower - DrawModel( tower, towerPos, 1.0, WHITE ); - - // Draw the test triangle - DrawLine3D( ta, tb, PURPLE ); - DrawLine3D( tb, tc, PURPLE ); - DrawLine3D( tc, ta, PURPLE ); - - // Draw the mesh bbox if we hit it - if (hitMeshBBox) { - DrawBoundingBox( towerBBox, LIME ); - } - - // If we hit something, draw the cursor at the hit point - if (nearestHit.hit) { - DrawCube( nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor ); - DrawCubeWires( nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW ); - - Vector3 normalEnd; - normalEnd.x = nearestHit.hitPosition.x + nearestHit.hitNormal.x; - normalEnd.y = nearestHit.hitPosition.y + nearestHit.hitNormal.y; - normalEnd.z = nearestHit.hitPosition.z + nearestHit.hitNormal.z; - DrawLine3D( nearestHit.hitPosition, normalEnd, YELLOW ); - } - - DrawRay(ray, MAROON); - - DrawGrid(10, 1.0f); - - End3dMode(); - - // Show some debug text - char line[1024]; - sprintf( line, "Hit Object: %s\n", hitObjectName ); - DrawText( line, 10, 30, 15, BLACK ); - - if (nearestHit.hit) { - int ypos = 45; - sprintf( line, "Distance: %3.2f", nearestHit.distance ); - DrawText( line, 10, ypos, 15, BLACK ); - ypos += 15; - - sprintf( line, "Hit Pos: %3.2f %3.2f %3.2f", - nearestHit.hitPosition.x, nearestHit.hitPosition.y, nearestHit.hitPosition.z ); - DrawText( line, 10, ypos, 15, BLACK ); - ypos += 15; - - sprintf( line, "Hit Norm: %3.2f %3.2f %3.2f", - nearestHit.hitNormal.x, nearestHit.hitNormal.y, nearestHit.hitNormal.z ); - DrawText( line, 10, ypos, 15, BLACK ); - ypos += 15; - - if (hitTriangle) { - sprintf( line, "Barycentric: %3.2f %3.2f %3.2f", - bary.x, bary.y, bary.z ); - DrawText( line, 10, ypos, 15, BLACK ); - } - } - - DrawText( "Use Mouse to Move Camera", 10, 420, 15, LIGHTGRAY ); - - DrawFPS(10, 10); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} \ No newline at end of file diff --git a/examples/models_ray_picking.c b/examples/models_ray_picking.c new file mode 100644 index 00000000..c578a185 --- /dev/null +++ b/examples/models_ray_picking.c @@ -0,0 +1,197 @@ +/******************************************************************************************* +* +* raylib [models] example - Ray picking in 3d mode, ground plane, triangle, mesh +* +* This example has been created using raylib 1.7 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* Example contributed by Joel Davis (@joeld42) +* +********************************************************************************************/ + +#include "raylib.h" +#include "../src/raymath.h" + +#include +#include + + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - 3d ray picking"); + + // Define the camera to look into our 3d world + Camera camera; + camera.position = (Vector3){ 10.0f, 8.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.3f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + + Vector3 cubePosition = { 0.0f, 1.0f, 0.0f }; + Vector3 cubeSize = { 2.0f, 2.0f, 2.0f }; + + Ray ray; // Picking line ray + + Model tower = LoadModel("resources/model/lowpoly-tower.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/model/lowpoly-tower.png"); // Load model texture + tower.material.texDiffuse = texture; // Set model diffuse texture + + Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position + BoundingBox towerBBox = CalculateBoundingBox( tower.mesh ); + bool hitMeshBBox = false; + bool hitTriangle = false; + + // Test triangle + Vector3 ta = (Vector3){ -25.0, 0.5, 0.0 }; + Vector3 tb = (Vector3){ -4.0, 2.5, 1.0 }; + Vector3 tc = (Vector3){ -8.0, 6.5, 0.0 }; + + Vector3 bary = { 0.0f, 0.0f, 0.0f }; + + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera); // Update camera + + // Display information about closest hit + RayHitInfo nearestHit; + char *hitObjectName = "None"; + nearestHit.distance = FLT_MAX; + nearestHit.hit = false; + Color cursorColor = WHITE; + + // Get ray and test against ground, triangle, and mesh + ray = GetMouseRay(GetMousePosition(), camera); + + // Check ray collision aginst ground plane + RayHitInfo groundHitInfo = GetCollisionRayGround(ray, 0.0f); + + if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) + { + nearestHit = groundHitInfo; + cursorColor = GREEN; + hitObjectName = "Ground"; + } + + // Check ray collision against test triangle + RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, ta, tb, tc); + + if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) + { + nearestHit = triHitInfo; + cursorColor = PURPLE; + hitObjectName = "Triangle"; + + bary = Barycenter(nearestHit.hitPosition, ta, tb, tc); + hitTriangle = true; + } + else hitTriangle = false; + + RayHitInfo meshHitInfo; + + // Check ray collision against bounding box first, before trying the full ray-mesh test + if (CheckCollisionRayBox(ray, towerBBox)) + { + hitMeshBBox = true; + + // Check ray collision against mesh + meshHitInfo = GetCollisionRayMesh(ray, &tower.mesh); + + if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) + { + nearestHit = meshHitInfo; + cursorColor = ORANGE; + hitObjectName = "Mesh"; + } + + } hitMeshBBox = false; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + Begin3dMode(camera); + + // Draw the tower + DrawModel(tower, towerPos, 1.0, WHITE); + + // Draw the test triangle + DrawLine3D(ta, tb, PURPLE); + DrawLine3D(tb, tc, PURPLE); + DrawLine3D(tc, ta, PURPLE); + + // Draw the mesh bbox if we hit it + if (hitMeshBBox) DrawBoundingBox(towerBBox, LIME); + + // If we hit something, draw the cursor at the hit point + if (nearestHit.hit) + { + DrawCube(nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor); + DrawCubeWires(nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW); + + Vector3 normalEnd; + normalEnd.x = nearestHit.hitPosition.x + nearestHit.hitNormal.x; + normalEnd.y = nearestHit.hitPosition.y + nearestHit.hitNormal.y; + normalEnd.z = nearestHit.hitPosition.z + nearestHit.hitNormal.z; + + DrawLine3D(nearestHit.hitPosition, normalEnd, YELLOW); + } + + DrawRay(ray, MAROON); + + DrawGrid(100, 1.0f); + + End3dMode(); + + // Draw some debug GUI text + DrawText(FormatText("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK); + + if (nearestHit.hit) + { + int ypos = 70; + + DrawText(FormatText("Distance: %3.2f", nearestHit.distance), 10, ypos, 10, BLACK); + + DrawText(FormatText("Hit Pos: %3.2f %3.2f %3.2f", + nearestHit.hitPosition.x, + nearestHit.hitPosition.y, + nearestHit.hitPosition.z), 10, ypos + 15, 10, BLACK); + + DrawText(FormatText("Hit Norm: %3.2f %3.2f %3.2f", + nearestHit.hitNormal.x, + nearestHit.hitNormal.y, + nearestHit.hitNormal.z), 10, ypos + 30, 10, BLACK); + + if (hitTriangle) DrawText(FormatText("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK); + } + + DrawText("Use Mouse to Move Camera", 10, 430, 10, GRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/src/models.c b/src/models.c index 41e527dc..0673874b 100644 --- a/src/models.c +++ b/src/models.c @@ -1474,6 +1474,135 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box) return collision; } +// Get collision info between ray and mesh +RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh) +{ + RayHitInfo result = { 0 }; + + // If mesh doesn't have vertex data on CPU, can't test it. + if (!mesh->vertices) return result; + + // mesh->triangleCount may not be set, vertexCount is more reliable + int triangleCount = mesh->vertexCount/3; + + // Test against all triangles in mesh + for (int i = 0; i < triangleCount; i++) + { + Vector3 a, b, c; + Vector3 *vertdata = (Vector3 *)mesh->vertices; + + if (mesh->indices) + { + a = vertdata[mesh->indices[i*3 + 0]]; + b = vertdata[mesh->indices[i*3 + 1]]; + c = vertdata[mesh->indices[i*3 + 2]]; + } + else + { + a = vertdata[i*3 + 0]; + b = vertdata[i*3 + 1]; + c = vertdata[i*3 + 2]; + } + + RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c); + + if (triHitInfo.hit) + { + // Save the closest hit triangle + if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo; + } + } + + return result; +} + +// Get collision info between ray and triangle +// NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm +RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3) +{ + #define EPSILON 0.000001 // A small number + + Vector3 edge1, edge2; + Vector3 p, q, tv; + float det, invDet, u, v, t; + RayHitInfo result = {0}; + + // Find vectors for two edges sharing V1 + edge1 = VectorSubtract(p2, p1); + edge2 = VectorSubtract(p3, p1); + + // Begin calculating determinant - also used to calculate u parameter + p = VectorCrossProduct(ray.direction, edge2); + + // If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle + det = VectorDotProduct(edge1, p); + + // Avoid culling! + if ((det > -EPSILON) && (det < EPSILON)) return result; + + invDet = 1.0f/det; + + // Calculate distance from V1 to ray origin + tv = VectorSubtract(ray.position, p1); + + // Calculate u parameter and test bound + u = VectorDotProduct(tv, p)*invDet; + + // The intersection lies outside of the triangle + if ((u < 0.0f) || (u > 1.0f)) return result; + + // Prepare to test v parameter + q = VectorCrossProduct(tv, edge1); + + // Calculate V parameter and test bound + v = VectorDotProduct(ray.direction, q)*invDet; + + // The intersection lies outside of the triangle + if ((v < 0.0f) || ((u + v) > 1.0f)) return result; + + t = VectorDotProduct(edge2, q)*invDet; + + if (t > EPSILON) + { + // Ray hit, get hit point and normal + result.hit = true; + result.distance = t; + result.hit = true; + result.hitNormal = VectorCrossProduct(edge1, edge2); + VectorNormalize(&result.hitNormal); + Vector3 rayDir = ray.direction; + VectorScale(&rayDir, t); + result.hitPosition = VectorAdd(ray.position, rayDir); + } + + return result; +} + +// Get collision info between ray and ground plane (Y-normal plane) +RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight) +{ + #define EPSILON 0.000001 // A small number + + RayHitInfo result = { 0 }; + + if (fabsf(ray.direction.y) > EPSILON) + { + float t = (ray.position.y - groundHeight)/-ray.direction.y; + + if (t >= 0.0) + { + Vector3 rayDir = ray.direction; + VectorScale(&rayDir, t); + result.hit = true; + result.distance = t; + result.hitNormal = (Vector3){ 0.0, 1.0, 0.0 }; + result.hitPosition = VectorAdd(ray.position, rayDir); + } + } + + return result; +} + // Calculate mesh bounding box limits // NOTE: minVertex and maxVertex should be transformed by model transform matrix (position, scale, rotate) BoundingBox CalculateBoundingBox(Mesh mesh) @@ -1918,41 +2047,3 @@ static Material LoadMTL(const char *fileName) return material; } - -RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ) -{ - RayHitInfo result = {0}; - - // If mesh doesn't have vertex data on CPU, can't test it. - if (!mesh->vertices) { - return result; - } - - // mesh->triangleCount may not be set, vertexCount is more reliable - int triangleCount = mesh->vertexCount / 3; - - // Test against all triangles in mesh - for (int i=0; i < triangleCount; i++) { - Vector3 a, b, c; - Vector3 *vertdata = (Vector3*)mesh->vertices; - if (mesh->indices) { - a = vertdata[ mesh->indices[i*3+0] ]; - b = vertdata[ mesh->indices[i*3+1] ]; - c = vertdata[ mesh->indices[i*3+2] ]; - } else { - a = vertdata[i*3+0]; - b = vertdata[i*3+1]; - c = vertdata[i*3+2]; - } - - RayHitInfo triHitInfo = RaycastTriangle( ray, a, b, c ); - if (triHitInfo.hit) { - // Save the closest hit triangle - if ((!result.hit)||(result.distance > triHitInfo.distance)) { - result = triHitInfo; - } - } - } - - return result; -} diff --git a/src/raylib.h b/src/raylib.h index 7252ba4e..fa4f44e6 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -97,9 +97,6 @@ #define DEG2RAD (PI/180.0f) #define RAD2DEG (180.0f/PI) -// A small number -#define EPSILON 0.000001 - // raylib Config Flags #define FLAG_FULLSCREEN_MODE 1 #define FLAG_RESIZABLE_WINDOW 2 @@ -496,10 +493,10 @@ typedef struct Ray { // Information returned from a raycast typedef struct RayHitInfo { - bool hit; // Did the ray hit something? - float distance; // Distance to nearest hit - Vector3 hitPosition; // Position of nearest hit - Vector3 hitNormal; // Surface normal of hit + bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit } RayHitInfo; // Wave type, defines audio wave data @@ -920,13 +917,9 @@ RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphere RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box - -//------------------------------------------------------------------------------------ -// Ray Casts -//------------------------------------------------------------------------------------ -RLAPI RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ); -RLAPI RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ); -RLAPI RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ); +RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh +RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) diff --git a/src/raymath.h b/src/raymath.h index 5871e350..c073b72d 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -130,7 +130,7 @@ RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Ve RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components -RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycentric coords for p in triangle abc +RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycenter coords for p in triangle abc //------------------------------------------------------------------------------------ // Functions Declaration to work with Matrix @@ -383,26 +383,27 @@ RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2) return result; } -// Compute barycentric coordinates (u, v, w) for -// point p with respect to triangle (a, b, c) -// Assumes P is on the plane of the triangle -RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c) +// Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c) +// NOTE: Assumes P is on the plane of the triangle +RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) { - //Vector v0 = b - a, v1 = c - a, v2 = p - a; - Vector3 v0 = VectorSubtract( b, a ); - Vector3 v1 = VectorSubtract( c, a ); - Vector3 v2 = VectorSubtract( p, a ); + + Vector3 v0 = VectorSubtract(b, a); + Vector3 v1 = VectorSubtract(c, a); + Vector3 v2 = VectorSubtract(p, a); float d00 = VectorDotProduct(v0, v0); float d01 = VectorDotProduct(v0, v1); float d11 = VectorDotProduct(v1, v1); float d20 = VectorDotProduct(v2, v0); float d21 = VectorDotProduct(v2, v1); - float denom = d00 * d11 - d01 * d01; + + float denom = d00*d11 - d01*d01; Vector3 result; - result.y = (d11 * d20 - d01 * d21) / denom; - result.z = (d00 * d21 - d01 * d20) / denom; + + result.y = (d11*d20 - d01*d21)/denom; + result.z = (d00*d21 - d01*d20)/denom; result.x = 1.0f - (result.z + result.y); return result; diff --git a/src/shapes.c b/src/shapes.c index 74480c83..8c6c4be0 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -534,84 +534,3 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) return retRec; } - - -RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ) -{ - RayHitInfo result = {0}; - - if (fabs(ray.direction.y) > EPSILON) - { - float t = (ray.position.y - groundHeight) / -ray.direction.y; - if (t >= 0.0) { - Vector3 rayDir = ray.direction; - VectorScale( &rayDir, t ); - result.hit = true; - result.distance = t; - result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; - result.hitPosition = VectorAdd( ray.position, rayDir ); - } - } - return result; -} -// Adapted from: -// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm -RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ) -{ - Vector3 e1, e2; //Edge1, Edge2 - Vector3 p, q, tv; - float det, inv_det, u, v; - float t; - RayHitInfo result = {0}; - - //Find vectors for two edges sharing V1 - e1 = VectorSubtract( b, a); - e2 = VectorSubtract( c, a); - - //Begin calculating determinant - also used to calculate u parameter - p = VectorCrossProduct( ray.direction, e2); - - //if determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle - det = VectorDotProduct(e1, p); - - //NOT CULLING - if(det > -EPSILON && det < EPSILON) return result; - inv_det = 1.f / det; - - //calculate distance from V1 to ray origin - tv = VectorSubtract( ray.position, a ); - - //Calculate u parameter and test bound - u = VectorDotProduct(tv, p) * inv_det; - - //The intersection lies outside of the triangle - if(u < 0.f || u > 1.f) return result; - - //Prepare to test v parameter - q = VectorCrossProduct( tv, e1 ); - - //Calculate V parameter and test bound - v = VectorDotProduct( ray.direction, q) * inv_det; - - //The intersection lies outside of the triangle - if(v < 0.f || (u + v) > 1.f) return result; - - t = VectorDotProduct(e2, q) * inv_det; - - - if(t > EPSILON) { - // ray hit, get hit point and normal - result.hit = true; - result.distance = t; - - result.hit = true; - result.hitNormal = VectorCrossProduct( e1, e2 ); - VectorNormalize( &result.hitNormal ); - Vector3 rayDir = ray.direction; - VectorScale( &rayDir, t ); - result.hitPosition = VectorAdd( ray.position, rayDir ); - } - - return result; -} - -- cgit v1.2.3 From d4f5c4e1332c5ec3c5a1f61c3e6b8f59359ed045 Mon Sep 17 00:00:00 2001 From: "Richard R. Goodwin" Date: Thu, 5 Jan 2017 21:20:28 +0000 Subject: modified: src/core.c --- src/core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/core.c b/src/core.c index 147010f5..10b1be57 100644 --- a/src/core.c +++ b/src/core.c @@ -121,6 +121,7 @@ // Old device inputs system #define DEFAULT_KEYBOARD_DEV STDIN_FILENO // Standard input #define DEFAULT_MOUSE_DEV "/dev/input/mouse0" // Mouse input + #define DEFAULT_TOUCH_DEV "/dev/input/event4" // Touch input #define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...) // New device input events (evdev) (must be detected) -- cgit v1.2.3 From 21181f8167975d1ffc13ddd154f1731ece208fbe Mon Sep 17 00:00:00 2001 From: "Richard R. Goodwin" Date: Thu, 5 Jan 2017 21:36:40 +0000 Subject: added RPi touch interface --- release/rpi/libraylib.a | Bin 465300 -> 0 bytes src/core.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) delete mode 100644 release/rpi/libraylib.a (limited to 'src') diff --git a/release/rpi/libraylib.a b/release/rpi/libraylib.a deleted file mode 100644 index f3d41d50..00000000 Binary files a/release/rpi/libraylib.a and /dev/null differ diff --git a/src/core.c b/src/core.c index 10b1be57..fdf5d48d 100644 --- a/src/core.c +++ b/src/core.c @@ -121,7 +121,7 @@ // Old device inputs system #define DEFAULT_KEYBOARD_DEV STDIN_FILENO // Standard input #define DEFAULT_MOUSE_DEV "/dev/input/mouse0" // Mouse input - #define DEFAULT_TOUCH_DEV "/dev/input/event4" // Touch input + #define DEFAULT_TOUCH_DEV "/dev/input/event4" // Touch input virtual device (created by ts_uinput) #define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...) // New device input events (evdev) (must be detected) @@ -175,6 +175,11 @@ static int mouseStream = -1; // Mouse device file descriptor static bool mouseReady = false; // Flag to know if mouse is ready static pthread_t mouseThreadId; // Mouse reading thread id +// Touch input variables +static int touchStream = -1; // Touch device file descriptor +static bool touchReady = false; // Flag to know if touch interface is ready +static pthread_t touchThreadId; // Touch reading thread id + // Gamepad input variables static int gamepadStream[MAX_GAMEPADS] = { -1 };// Gamepad device file descriptor static pthread_t gamepadThreadId; // Gamepad reading thread id @@ -302,6 +307,8 @@ static void ProcessKeyboard(void); // Process keyboard even static void RestoreKeyboard(void); // Restore keyboard system static void InitMouse(void); // Mouse initialization (including mouse thread) static void *MouseThread(void *arg); // Mouse reading thread +static void InitTouch(void); // Touch device initialization (including touch thread) +static void *TouchThread(void *arg); // Touch device reading thread static void InitGamepad(void); // Init raw gamepad input static void *GamepadThread(void *arg); // Mouse reading thread #endif @@ -333,6 +340,7 @@ void InitWindow(int width, int height, const char *title) #if defined(PLATFORM_RPI) // Init raw input system InitMouse(); // Mouse init + InitTouch(); // Touch init InitKeyboard(); // Keyboard init InitGamepad(); // Gamepad init #endif @@ -474,6 +482,7 @@ void CloseWindow(void) windowShouldClose = true; // Added to force threads to exit when the close window is called pthread_join(mouseThreadId, NULL); + pthread_join(touchThreadId, NULL); pthread_join(gamepadThreadId, NULL); #endif @@ -2875,6 +2884,55 @@ static void *MouseThread(void *arg) return NULL; } +// Touch initialization (including touch thread) +static void InitTouch(void) +{ + if ((touchStream = open(DEFAULT_TOUCH_DEV, O_RDONLY|O_NONBLOCK)) < 0) + { + TraceLog(WARNING, "Touch device could not be opened, no touchscreen available"); + } + else + { + touchReady = true; + + int error = pthread_create(&touchThreadId, NULL, &TouchThread, NULL); + + if (error != 0) TraceLog(WARNING, "Error creating touch input event thread"); + else TraceLog(INFO, "Touch device initialized successfully"); + } +} + +// Touch reading thread. +// This reads from a Virtual Input Event /dev/input/event4 which is +// created by the ts_uinput daemon. This takes, filters and scales +// raw input from the Touchscreen (which appears in /dev/input/event3) +// based on the Calibration data referenced by tslib. +static void *TouchThread(void *arg) +{ + struct input_event ev; + + while (!windowShouldClose) + { + if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev)) + { + + // if pressure > 0 then simulate left mouse button click + if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0) currentMouseState[0] = 0; + if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0) currentMouseState[0] = 1; + // x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data + if (ev.type == EV_ABS && ev.code == 0) mousePosition.x = ev.value; + if (ev.type == EV_ABS && ev.code == 1) mousePosition.y = ev.value; + + if (mousePosition.x < 0) mousePosition.x = 0; + if (mousePosition.y < 0) mousePosition.y = 0; + + if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; + if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; + } + } + return NULL; +} + // Init gamepad system static void InitGamepad(void) { -- cgit v1.2.3 From fbda9c4180a8043d568bc791d96b0236fcb8219a Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 7 Jan 2017 18:12:59 +0100 Subject: Support rRES data loading --- src/audio.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 944d1b9d..989512c0 100644 --- a/src/audio.c +++ b/src/audio.c @@ -219,6 +219,17 @@ Wave LoadWave(const char *fileName) if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName); else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName); else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName); + else if (strcmp(GetExtension(fileName),"rres") == 0) + { + RRESData rres = LoadResource(fileName); + + // NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels + + if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4); + else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName); + + UnloadResource(rres); + } else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName); return wave; -- cgit v1.2.3 From 07a2c00e842723970ace9eb0154e838b47d3fe82 Mon Sep 17 00:00:00 2001 From: AudioMorphology Date: Sat, 14 Jan 2017 16:18:06 +0000 Subject: modified: core.c --- src/core.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index fdf5d48d..424e5725 100644 --- a/src/core.c +++ b/src/core.c @@ -2910,24 +2910,79 @@ static void InitTouch(void) static void *TouchThread(void *arg) { struct input_event ev; + GestureEvent gestureEvent; while (!windowShouldClose) { if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev)) { - // if pressure > 0 then simulate left mouse button click - if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0) currentMouseState[0] = 0; - if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0) currentMouseState[0] = 1; + if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1) + { + currentMouseState[0] = 0; + gestureEvent.touchAction = TOUCH_UP; + gestureEvent.pointCount = 1; + gestureEvent.pointerId[0] = 0; + gestureEvent.pointerId[1] = 1; + gestureEvent.position[0] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[1] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + ProcessGestureEvent(gestureEvent); + } + if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0) + { + currentMouseState[0] = 1; + gestureEvent.touchAction = TOUCH_DOWN; + gestureEvent.pointCount = 1; + gestureEvent.pointerId[0] = 0; + gestureEvent.pointerId[1] = 1; + gestureEvent.position[0] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[1] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + ProcessGestureEvent(gestureEvent); + } // x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data - if (ev.type == EV_ABS && ev.code == 0) mousePosition.x = ev.value; - if (ev.type == EV_ABS && ev.code == 1) mousePosition.y = ev.value; - - if (mousePosition.x < 0) mousePosition.x = 0; - if (mousePosition.y < 0) mousePosition.y = 0; - - if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; - if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; + if (ev.type == EV_ABS && ev.code == 0) + { + mousePosition.x = ev.value; + if (mousePosition.x < 0) mousePosition.x = 0; + if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; + gestureEvent.touchAction = TOUCH_MOVE; + gestureEvent.pointCount = 1; + gestureEvent.pointerId[0] = 0; + gestureEvent.pointerId[1] = 1; + gestureEvent.position[0] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[1] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + ProcessGestureEvent(gestureEvent); + } + if (ev.type == EV_ABS && ev.code == 1) + { + mousePosition.y = ev.value; + if (mousePosition.y < 0) mousePosition.y = 0; + if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; + gestureEvent.touchAction = TOUCH_MOVE; + gestureEvent.pointCount = 1; + gestureEvent.pointerId[0] = 0; + gestureEvent.pointerId[1] = 1; + gestureEvent.position[0] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[1] = (Vector2){ mousePosition.x, mousePosition.y }; + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + ProcessGestureEvent(gestureEvent); + } + } } return NULL; -- cgit v1.2.3 From 4a158d972d9d110fcb581bc9f6583d05a2dc2544 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 15 Jan 2017 01:09:15 +0100 Subject: Added LoadText() function Actually, renamed ReadTextFile() from rlgl and make it public --- src/raylib.h | 1 + src/rlgl.c | 76 +++++++++++++++++++++++++++++------------------------------- 2 files changed, 38 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/raylib.h b/src/raylib.h index fa4f44e6..a47d3c59 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -925,6 +925,7 @@ RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ +RLAPI char *LoadText(const char *fileName); // Load chars array from text file RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) diff --git a/src/rlgl.c b/src/rlgl.c index 9770b647..bcbca227 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -48,7 +48,7 @@ #include "rlgl.h" -#include // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()] +#include // Required for: fopen(), fclose(), fread()... [Used only on LoadText()] #include // Required for: malloc(), free(), rand() #include // Required for: strcmp(), strlen(), strtok() #include // Required for: atan2() @@ -400,8 +400,6 @@ static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); static void GetShaderLightsLocations(Shader shader); // Get shader locations for lights (up to MAX_LIGHTS) static void SetShaderLightsValues(Shader shader); // Set shader uniform values for lights - -static char *ReadTextFile(const char *fileName); // Read chars array from text file #endif #if defined(RLGL_OCULUS_SUPPORT) @@ -2423,6 +2421,40 @@ Texture2D GetDefaultTexture(void) return texture; } +// Load text data from file +// NOTE: text chars array should be freed manually +char *LoadText(const char *fileName) +{ + FILE *textFile; + char *text = NULL; + + int count = 0; + + if (fileName != NULL) + { + textFile = fopen(fileName,"rt"); + + if (textFile != NULL) + { + fseek(textFile, 0, SEEK_END); + count = ftell(textFile); + rewind(textFile); + + if (count > 0) + { + text = (char *)malloc(sizeof(char)*(count + 1)); + count = fread(text, sizeof(char), count, textFile); + text[count] = '\0'; + } + + fclose(textFile); + } + else TraceLog(WARNING, "[%s] Text file could not be opened", fileName); + } + + return text; +} + // Load shader from files and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName) { @@ -2430,8 +2462,8 @@ Shader LoadShader(char *vsFileName, char *fsFileName) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Shaders loading from external text file - char *vShaderStr = ReadTextFile(vsFileName); - char *fShaderStr = ReadTextFile(fsFileName); + char *vShaderStr = LoadText(vsFileName); + char *fShaderStr = LoadText(fsFileName); if ((vShaderStr != NULL) && (fShaderStr != NULL)) { @@ -3829,40 +3861,6 @@ static void SetShaderLightsValues(Shader shader) } } -// Read text data from file -// NOTE: text chars array should be freed manually -static char *ReadTextFile(const char *fileName) -{ - FILE *textFile; - char *text = NULL; - - int count = 0; - - if (fileName != NULL) - { - textFile = fopen(fileName,"rt"); - - if (textFile != NULL) - { - fseek(textFile, 0, SEEK_END); - count = ftell(textFile); - rewind(textFile); - - if (count > 0) - { - text = (char *)malloc(sizeof(char)*(count + 1)); - count = fread(text, sizeof(char), count, textFile); - text[count] = '\0'; - } - - fclose(textFile); - } - else TraceLog(WARNING, "[%s] Text file could not be opened", fileName); - } - - return text; -} - // Configure stereo rendering (including distortion shader) with HMD device parameters static void SetStereoConfig(VrDeviceInfo hmd) { -- cgit v1.2.3 From 61f6b0f707f408b89306ff1a6a2d825662ba8311 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 15 Jan 2017 01:10:23 +0100 Subject: Removed GetNextPOT(), review TraceLog() --- src/rlua.h | 9 ------ src/text.c | 7 +++-- src/textures.c | 12 +++++--- src/utils.c | 97 ++++++++++++++++------------------------------------------ src/utils.h | 18 ++--------- 5 files changed, 42 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/rlua.h b/src/rlua.h index 10a75e3a..e9ed2c3c 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -3232,14 +3232,6 @@ int lua_GetExtension(lua_State* L) return 1; } -int lua_GetNextPOT(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int result = GetNextPOT(arg1); - lua_pushinteger(L, result); - return 1; -} - //---------------------------------------------------------------------------------- // raylib [raymath] module functions - Vector3 math //---------------------------------------------------------------------------------- @@ -3955,7 +3947,6 @@ static luaL_Reg raylib_functions[] = { #endif REG(TraceLog) REG(GetExtension) - REG(GetNextPOT) REG(VectorAdd) REG(VectorSubtract) REG(VectorCrossProduct) diff --git a/src/text.c b/src/text.c index 74d5940b..4510b3af 100644 --- a/src/text.c +++ b/src/text.c @@ -36,7 +36,7 @@ #include // Required for: va_list, va_start(), vfprintf(), va_end() #include // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets() -#include "utils.h" // Required for: GetExtension(), GetNextPOT() +#include "utils.h" // Required for: GetExtension() // Following libs are used on LoadTTF() #define STBTT_STATIC // Define stb_truetype functions static to this module @@ -930,7 +930,10 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int // NOTE: Font texture size is predicted (being as much conservative as possible) // Predictive method consist of supposing same number of chars by line-column (sqrtf) // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests... - int textureSize = GetNextPOT(ceil((float)fontSize*3/4)*ceil(sqrtf((float)numChars))); + + // Calculate next power-of-two value + float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars)); + int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize); diff --git a/src/textures.c b/src/textures.c index 6538c316..3fa250c2 100644 --- a/src/textures.c +++ b/src/textures.c @@ -758,9 +758,10 @@ void ImageToPOT(Image *image, Color fillColor) { Color *pixels = GetImageData(*image); // Get pixels data - // Just add the required amount of pixels at the right and bottom sides of image... - int potWidth = GetNextPOT(image->width); - int potHeight = GetNextPOT(image->height); + // Calculate next power-of-two values + // NOTE: Just add the required amount of pixels at the right and bottom sides of image... + int potWidth = (int)powf(2, ceilf(logf((float)image->width)/logf(2))); + int potHeight = (int)powf(2, ceilf(logf((float)image->height)/logf(2))); // Check if POT texture generation is required (if texture is not already POT) if ((potWidth != image->width) || (potHeight != image->height)) @@ -1342,8 +1343,9 @@ void ImageColorBrightness(Image *image, int brightness) void GenTextureMipmaps(Texture2D *texture) { #if PLATFORM_WEB - int potWidth = GetNextPOT(texture->width); - int potHeight = GetNextPOT(texture->height); + // Calculate next power-of-two values + int potWidth = (int)powf(2, ceilf(logf((float)texture->width)/logf(2))); + int potHeight = (int)powf(2, ceilf(logf((float)texture->height)/logf(2))); // Check if texture is POT if ((potWidth != texture->width) || (potHeight != texture->height)) diff --git a/src/utils.c b/src/utils.c index 711ffab3..e5e05955 100644 --- a/src/utils.c +++ b/src/utils.c @@ -52,6 +52,7 @@ #define RRES_IMPLEMENTATION #include "rres.h" +//#define NO_TRACELOG // Avoid TraceLog() output (any type) #define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing //---------------------------------------------------------------------------------- @@ -74,59 +75,11 @@ static int android_close(void *cookie); //---------------------------------------------------------------------------------- // Module Functions Definition - Utilities //---------------------------------------------------------------------------------- - -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) -// Creates a BMP image file from an array of pixel data -void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize) -{ - stbi_write_bmp(fileName, width, height, compSize, imgData); -} - -// Creates a PNG image file from an array of pixel data -void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize) -{ - stbi_write_png(fileName, width, height, compSize, imgData, width*compSize); -} -#endif - -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) -// Outputs a trace log message (INFO, ERROR, WARNING) -// NOTE: If a file has been init, output log is written there +// Outputs a trace log message void TraceLog(int msgType, const char *text, ...) { - va_list args; - int traceDebugMsgs = 1; - -#ifdef DO_NOT_TRACE_DEBUG_MSGS - traceDebugMsgs = 0; -#endif - - switch(msgType) - { - case INFO: fprintf(stdout, "INFO: "); break; - case ERROR: fprintf(stdout, "ERROR: "); break; - case WARNING: fprintf(stdout, "WARNING: "); break; - case DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break; - default: break; - } - - if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs))) - { - va_start(args, text); - vfprintf(stdout, text, args); - va_end(args); - - fprintf(stdout, "\n"); - } - - if (msgType == ERROR) exit(1); // If ERROR message, exit program -} -#endif - -#if defined(PLATFORM_ANDROID) -void TraceLog(int msgType, const char *text, ...) -{ - static char buffer[100]; +#if !defined(NO_TRACELOG) + static char buffer[128]; int traceDebugMsgs = 1; #ifdef DO_NOT_TRACE_DEBUG_MSGS @@ -146,8 +99,9 @@ void TraceLog(int msgType, const char *text, ...) strcat(buffer, "\n"); va_list args; - va_start(args, buffer); + va_start(args, text); +#if defined(PLATFORM_ANDROID) switch(msgType) { case INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", buffer, args); break; @@ -156,12 +110,32 @@ void TraceLog(int msgType, const char *text, ...) case DEBUG: if (traceDebugMsgs) __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", buffer, args); break; default: break; } +#else + if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs))) vprintf(buffer, args); +#endif va_end(args); - if (msgType == ERROR) exit(1); + if (msgType == ERROR) exit(1); // If ERROR message, exit program + +#endif // NO_TRACELOG +} + +#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) +// Creates a BMP image file from an array of pixel data +void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize) +{ + stbi_write_bmp(fileName, width, height, compSize, imgData); +} + +// Creates a PNG image file from an array of pixel data +void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize) +{ + stbi_write_png(fileName, width, height, compSize, imgData, width*compSize); } +#endif +#if defined(PLATFORM_ANDROID) // Initialize asset manager from android app void InitAssetManager(AAssetManager *manager) { @@ -199,23 +173,6 @@ const char *GetExtension(const char *fileName) return (dot + 1); } -// Calculate next power-of-two value for a given num -int GetNextPOT(int num) -{ - if (num != 0) - { - num--; - num |= (num >> 1); // Or first 2 bits - num |= (num >> 2); // Or next 2 bits - num |= (num >> 4); // Or next 4 bits - num |= (num >> 8); // Or next 8 bits - num |= (num >> 16); // Or next 16 bits - num++; - } - - return num; -} - //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- diff --git a/src/utils.h b/src/utils.h index e0db51fe..3ffd025c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -43,19 +43,8 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef enum { IMAGE = 0, SOUND, MODEL, TEXT, RAW } DataType; - typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; -// One resource info header, every resource includes this header (8 byte) -typedef struct { - unsigned short id; // Resource unique identifier (2 byte) - unsigned char type; // Resource type (1 byte) - unsigned char comp; // Data Compression and Coding (1 byte) - unsigned int size; // Data size in .rres file (compressed or not, only DATA) (4 byte) - unsigned int srcSize; // Source data size (uncompressed, only DATA) -} ResInfoHeader; - #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -68,15 +57,14 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- +void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message +const char *GetExtension(const char *fileName); // Returns extension of a filename + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize); void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize); #endif -void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message -const char *GetExtension(const char *fileName); // Returns extension of a filename -int GetNextPOT(int num); // Calculate next power-of-two value for a given num - #if defined(PLATFORM_ANDROID) void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -- cgit v1.2.3 From e5a2def57f96567c23072c95afeceeb9e76f7e10 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 15 Jan 2017 01:10:34 +0100 Subject: Code formatting --- src/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 424e5725..4d662a41 100644 --- a/src/core.c +++ b/src/core.c @@ -561,14 +561,14 @@ void HideCursor() { #if defined(PLATFORM_DESKTOP) #ifdef __linux - XColor Col; - const char Nil[] = {0}; + XColor col; + const char nil[] = {0}; - Pixmap Pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), Nil, 1, 1); - Cursor Cur = XCreatePixmapCursor(glfwGetX11Display(), Pix, Pix, &Col, &Col, 0, 0); + Pixmap pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), nil, 1, 1); + Cursor cur = XCreatePixmapCursor(glfwGetX11Display(), pix, pix, &col, &col, 0, 0); - XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), Cur); - XFreeCursor(glfwGetX11Display(), Cur); + XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), cur); + XFreeCursor(glfwGetX11Display(), cur); #else glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); #endif -- cgit v1.2.3 From 53457e466477e3d3d47477d2b319035433386063 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 15 Jan 2017 01:11:38 +0100 Subject: Work on rres file format -IN PROGRESS- --- src/rres.h | 180 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 87 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/rres.h b/src/rres.h index dcf7be3f..700c9ab3 100644 --- a/src/rres.h +++ b/src/rres.h @@ -61,6 +61,7 @@ //---------------------------------------------------------------------------------- #if defined(RRES_STANDALONE) // rRES data returned when reading a resource, it contains all required data for user (24 byte) + // NOTE: Using void *data pointer, so we can load to image.data, wave.data, mesh.*, (unsigned char *) typedef struct { unsigned int type; // Resource type (4 byte) @@ -73,11 +74,14 @@ } RRESData; typedef enum { - RRES_RAW = 0, - RRES_IMAGE, - RRES_WAVE, - RRES_VERTEX, - RRES_TEXT + RRES_TYPE_RAW = 0, + RRES_TYPE_IMAGE, + RRES_TYPE_WAVE, + RRES_TYPE_VERTEX, + RRES_TYPE_TEXT, + RRES_TYPE_FONT_IMAGE, + RRES_TYPE_FONT_DATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } + RRES_TYPE_DIRECTORY } RRESDataType; #endif @@ -133,11 +137,13 @@ typedef struct { unsigned short count; // Number of resources in this file (2 byte) } RRESFileHeader; -// rRES info header, every resource includes this header (12 byte + 16 byte) +// rRES info header, every resource includes this header (16 byte + 16 byte) typedef struct { - unsigned short id; // Resource unique identifier (2 byte) + unsigned int id; // Resource unique identifier (4 byte) unsigned char dataType; // Resource data type (1 byte) unsigned char compType; // Resource data compression type (1 byte) + unsigned char cryptoType; // Resource data encryption type (1 byte) + unsigned char partsCount; // Resource data parts count, used for splitted data (1 byte) unsigned int dataSize; // Resource data size (compressed or not, only DATA) (4 byte) unsigned int uncompSize; // Resource data size (uncompressed, only DATA) (4 byte) @@ -153,11 +159,66 @@ typedef enum { RRES_COMP_DEFLATE, // DEFLATE compression RRES_COMP_LZ4, // LZ4 compression RRES_COMP_LZMA, // LZMA compression - // brotli, zopfli, gzip // Other compression algorythms... + RRES_COMP_BROTLI, // BROTLI compression + // gzip, zopfli, lzo, zstd // Other compression algorythms... } RRESCompressionType; +typedef enum { + RRES_CRYPTO_NONE = 0, // No data encryption + RRES_CRYPTO_XOR, // XOR (128 bit) encryption + RRES_CRYPTO_AES, // RIJNDAEL (128 bit) encryption (AES) + RRES_CRYPTO_TDES, // Triple DES encryption + RRES_CRYPTO_BLOWFISH, // BLOWFISH encryption + RRES_CRYPTO_XTEA, // XTEA encryption + // twofish, RC5, RC6 // Other encryption algorythm... +} RRESEncryptionType; + +typedef enum { + RRES_IM_UNCOMP_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + RRES_IM_UNCOMP_GRAY_ALPHA, // 16 bpp (2 channels) + RRES_IM_UNCOMP_R5G6B5, // 16 bpp + RRES_IM_UNCOMP_R8G8B8, // 24 bpp + RRES_IM_UNCOMP_R5G5B5A1, // 16 bpp (1 bit alpha) + RRES_IM_UNCOMP_R4G4B4A4, // 16 bpp (4 bit alpha) + RRES_IM_UNCOMP_R8G8B8A8, // 32 bpp + RRES_IM_COMP_DXT1_RGB, // 4 bpp (no alpha) + RRES_IM_COMP_DXT1_RGBA, // 4 bpp (1 bit alpha) + RRES_IM_COMP_DXT3_RGBA, // 8 bpp + RRES_IM_COMP_DXT5_RGBA, // 8 bpp + RRES_IM_COMP_ETC1_RGB, // 4 bpp + RRES_IM_COMP_ETC2_RGB, // 4 bpp + RRES_IM_COMP_ETC2_EAC_RGBA, // 8 bpp + RRES_IM_COMP_PVRT_RGB, // 4 bpp + RRES_IM_COMP_PVRT_RGBA, // 4 bpp + RRES_IM_COMP_ASTC_4x4_RGBA, // 8 bpp + RRES_IM_COMP_ASTC_8x8_RGBA // 2 bpp + //... +} RRESImageFormat; + +typedef enum { + RRES_VERT_POSITION, + RRES_VERT_TEXCOORD1, + RRES_VERT_TEXCOORD2, + RRES_VERT_TEXCOORD3, + RRES_VERT_TEXCOORD4, + RRES_VERT_NORMAL, + RRES_VERT_TANGENT, + RRES_VERT_COLOR, + RRES_VERT_INDEX, + //... +} RRESVertexType; + +typedef enum { + RRES_VERT_BYTE, + RRES_VERT_SHORT, + RRES_VERT_INT, + RRES_VERT_HFLOAT, + RRES_VERT_FLOAT, + //... +} RRESVertexFormat; + #if defined(RRES_STANDALONE) -typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; +typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType; #endif //---------------------------------------------------------------------------------- @@ -178,61 +239,11 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i // NOTE: Returns uncompressed data with parameters, only first resource found RRESDEF RRESData LoadResource(const char *fileName) { + // Force loading first resource available RRESData rres = { 0 }; - RRESFileHeader fileHeader; - RRESInfoHeader infoHeader; - - FILE *rresFile = fopen(fileName, "rb"); - - if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", fileName); - else - { - // Read rres file info header - fread(&fileHeader.id[0], sizeof(char), 1, rresFile); - fread(&fileHeader.id[1], sizeof(char), 1, rresFile); - fread(&fileHeader.id[2], sizeof(char), 1, rresFile); - fread(&fileHeader.id[3], sizeof(char), 1, rresFile); - fread(&fileHeader.version, sizeof(short), 1, rresFile); - fread(&fileHeader.count, sizeof(short), 1, rresFile); - - // Verify "rRES" identifier - if ((fileHeader.id[0] != 'r') && (fileHeader.id[1] != 'R') && (fileHeader.id[2] != 'E') && (fileHeader.id[3] != 'S')) - { - TraceLog(WARNING, "[%s] This is not a valid raylib resource file", fileName); - } - else - { - // Read first resource info and parameters - fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); - - // Register data type and parameters - rres.type = infoHeader.dataType; - rres.param1 = infoHeader.param1; - rres.param2 = infoHeader.param2; - rres.param3 = infoHeader.param3; - rres.param4 = infoHeader.param4; - - // Read resource data block - void *data = RRES_MALLOC(infoHeader.dataSize); - fread(data, infoHeader.dataSize, 1, rresFile); - - if (infoHeader.compType == RRES_COMP_DEFLATE) - { - void *uncompData = DecompressData(data, infoHeader.dataSize, infoHeader.uncompSize); - - rres.data = uncompData; - - RRES_FREE(data); - } - else rres.data = data; - - if (rres.data != NULL) TraceLog(INFO, "[%s] Resource data loaded successfully", fileName); - } - - fclose(rresFile); - } - + rres = LoadResourceById(fileName, 0); + return rres; } @@ -293,7 +304,9 @@ RRESDEF RRESData LoadResourceById(const char *fileName, int rresId) } else rres.data = data; - if (rres.data != NULL) TraceLog(INFO, "[%s][ID %i] Resource data loaded successfully", fileName, (int)rresId); + if (rres.data != NULL) TraceLog(INFO, "[%s][ID %i] Resource data loaded successfully", fileName, (int)infoHeader.id); + + if (rresId == 0) break; // Break for loop, do not check next resource } else { @@ -302,7 +315,7 @@ RRESDEF RRESData LoadResourceById(const char *fileName, int rresId) } } - if (rres.data == NULL) TraceLog(WARNING, "[%s][ID %i] Requested resource could not be found, wrong id?", fileName, (int)rresId); + if (rres.data == NULL) TraceLog(WARNING, "[%s][ID %i] Requested resource could not be found", fileName, (int)rresId); } fclose(rresFile); @@ -364,7 +377,7 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i #if defined(RRES_STANDALONE) // Outputs a trace log message (INFO, ERROR, WARNING) // NOTE: If a file has been init, output log is written there -void TraceLog(int msgType, const char *text, ...) +void TraceLog(int logType, const char *text, ...) { va_list args; int traceDebugMsgs = 0; @@ -375,14 +388,14 @@ void TraceLog(int msgType, const char *text, ...) switch (msgType) { - case INFO: fprintf(stdout, "INFO: "); break; - case ERROR: fprintf(stdout, "ERROR: "); break; - case WARNING: fprintf(stdout, "WARNING: "); break; - case DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break; + case LOG_INFO: fprintf(stdout, "INFO: "); break; + case LOG_ERROR: fprintf(stdout, "ERROR: "); break; + case LOG_WARNING: fprintf(stdout, "WARNING: "); break; + case LOG_DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break; default: break; } - if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs))) + if ((msgType != LOG_DEBUG) || ((msgType == LOG_DEBUG) && (traceDebugMsgs))) { va_start(args, text); vfprintf(stdout, text, args); @@ -397,33 +410,13 @@ void TraceLog(int msgType, const char *text, ...) #endif // RAYGUI_IMPLEMENTATION - /* -//T LoadResource(const char *rresFileName, int resId); - -// ASSUMPTION: rRES files only contain one resource (solution to id requirement...) - -// Now, rres file check and data loading can be managed inside each function: -Image LoadImage(); // -> Texture2D -Wave LoadWave() // -> Sound, Music -const char *LoadText(); // -> Shader, Material - -// NOTE: RRESData uses void* data pointer, so we can load to image.data, wave.data, mesh.*, (unsigned char *) - -Image LoadImagePro(void *data, int width, int height, int format); -Image LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); - Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); Mesh LoadMeshEx(rres.param1, rres.data, rres.data + offset, rres.data + offset*2, rres.data + offset*3); -Shader LoadShaderV(const char *vsText, int vsLength); +Shader LoadShader(const char *vsText, int vsLength); Shader LoadShaderV(rres.data, rres.param1); -Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); -Wave LoadWaveEx(rres.data, rres.param1, (int)rres.param2, (int)rres.param3, (int)rres.param4); - -// Max value for an unsigned short: 65535 - // Parameters information depending on resource type (IMAGE, WAVE, MESH, TEXT) // Image data params @@ -431,6 +424,7 @@ int imgWidth, imgHeight; char colorFormat, mipmaps; // Wave data params +int sampleCount, short sampleRate, bps; char channels, reserved; @@ -439,6 +433,6 @@ int vertexCount, reserved; short vertexTypesMask, vertexFormatsMask; // Text data params -int numChars; -char textFormat, language, charsetCode; +int charsCount; +int cultureCode; */ \ No newline at end of file -- cgit v1.2.3 From 6d6659205c04e52b88d5f22eda1722c352f548a9 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 15 Jan 2017 01:25:09 +0100 Subject: Add support for 32-bit PCM sample data --- src/audio.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 989512c0..9dedefba 100644 --- a/src/audio.c +++ b/src/audio.c @@ -21,7 +21,7 @@ * * Some design decisions: * Support only up to two channels: MONO and STEREO (for additional channels, AL_EXT_MCFORMATS) -* Support only the following sample sizes: 8bit PCM and 16bit PCM (for additional size, AL_EXT_FLOAT32) +* Support only the following sample sizes: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) * * Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions: * XM audio module support (jar_xm) @@ -98,6 +98,15 @@ // In case of music-stalls, just increase this number #define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. 16bit, Mono: 8Kb) +// Support uncompressed PCM data in 32-bit float IEEE format +// NOTE: This definition is included in "AL/alext.h", but some OpenAL implementations +// could not provide the extensions header (Android), so its defined here +#if !defined(AL_EXT_float32) + #define AL_EXT_float32 1 + #define AL_FORMAT_MONO_FLOAT32 0x10010 + #define AL_FORMAT_STEREO_FLOAT32 0x10011 +#endif + //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -284,7 +293,7 @@ Sound LoadSoundFromWave(Wave wave) { case 8: format = AL_FORMAT_MONO8; break; case 16: format = AL_FORMAT_MONO16; break; - case 32: //format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 + case 32: format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break; } } @@ -294,7 +303,7 @@ Sound LoadSoundFromWave(Wave wave) { case 8: format = AL_FORMAT_STEREO8; break; case 16: format = AL_FORMAT_STEREO16; break; - case 32: //format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 + case 32: format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break; } } @@ -863,7 +872,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un { case 8: stream.format = AL_FORMAT_MONO8; break; case 16: stream.format = AL_FORMAT_MONO16; break; - case 32: //stream.format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 + case 32: stream.format = AL_FORMAT_MONO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break; } } @@ -873,7 +882,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un { case 8: stream.format = AL_FORMAT_STEREO8; break; case 16: stream.format = AL_FORMAT_STEREO16; break; - case 32: //stream.format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 + case 32: stream.format = AL_FORMAT_STEREO_FLOAT32; break; // Requires OpenAL extension: AL_EXT_FLOAT32 default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break; } } -- cgit v1.2.3 From 46f95a730a68d50c9d369739af61e60961166721 Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 18 Jan 2017 17:04:20 +0100 Subject: Corrected bug on OGG sound loading --- src/audio.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 9dedefba..c70c9004 100644 --- a/src/audio.c +++ b/src/audio.c @@ -608,7 +608,7 @@ Music LoadMusicStream(const char *fileName) // OGG bit rate defaults to 16 bit, it's enough for compressed format music->stream = InitAudioStream(info.sample_rate, 16, info.channels); - music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg); + music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg); // Independent by channel music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_OGG; music->loop = true; // We loop by default @@ -1134,20 +1134,17 @@ static Wave LoadOGG(const char *fileName) wave.sampleRate = info.sample_rate; wave.sampleSize = 16; // 16 bit per sample (short) wave.channels = info.channels; - - int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile)*info.channels); + wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile); + float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile); - if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds); - int totalSamples = (int)(totalSeconds*info.sample_rate*info.channels); - wave.sampleCount = totalSamples; - - wave.data = (short *)malloc(totalSamplesLength*sizeof(short)); + wave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short)); - int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, (short *)wave.data, totalSamplesLength); + // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) + int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, (short *)wave.data, wave.sampleCount*wave.channels); - TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained); + TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, numSamplesOgg); TraceLog(INFO, "[%s] OGG file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); -- cgit v1.2.3 From fc7d4cef1833f216a98c13bc2c44f43e67163623 Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 18 Jan 2017 17:25:25 +0100 Subject: Stop sound source before unloading --- src/audio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index c70c9004..47a15975 100644 --- a/src/audio.c +++ b/src/audio.c @@ -353,6 +353,8 @@ void UnloadWave(Wave wave) // Unload sound void UnloadSound(Sound sound) { + alSourceStop(sound.source); + alDeleteSources(1, &sound.source); alDeleteBuffers(1, &sound.buffer); -- cgit v1.2.3 From 3b120bd7d936b5e6b730caa60709c6d73865d146 Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 18 Jan 2017 19:14:39 +0100 Subject: Some tweaks for consistency --- src/audio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 47a15975..119b057d 100644 --- a/src/audio.c +++ b/src/audio.c @@ -324,7 +324,7 @@ Sound LoadSoundFromWave(Wave wave) ALuint buffer; alGenBuffers(1, &buffer); // Generate pointer to buffer - unsigned int dataSize = wave.sampleCount*wave.sampleSize/8*wave.channels; // Size in bytes + unsigned int dataSize = wave.sampleCount*wave.channels*wave.sampleSize/8; // Size in bytes // Upload sound data to buffer alBufferData(buffer, format, wave.data, dataSize, wave.sampleRate); @@ -345,7 +345,7 @@ Sound LoadSoundFromWave(Wave wave) // Unload wave data void UnloadWave(Wave wave) { - free(wave.data); + if (wave.data != NULL) free(wave.data); TraceLog(INFO, "Unloaded wave data from RAM"); } @@ -374,7 +374,7 @@ void UpdateSound(Sound sound, const void *data, int numSamples) TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize); TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels); - unsigned int dataSize = numSamples*sampleSize/8*channels; // Size of data in bytes + unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes alSourceStop(sound.source); // Stop sound alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update -- cgit v1.2.3 From 7cd24d27061cb08f818692961beb1ecb4a74445e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 18 Jan 2017 23:27:41 +0100 Subject: Updated stb external libraries --- src/external/stb_image.h | 905 +++++++++++++++++++++++++++------------- src/external/stb_image_resize.h | 8 +- src/external/stb_image_write.h | 5 +- src/external/stb_rect_pack.h | 29 +- src/external/stb_truetype.h | 857 ++++++++++++++++++++++++++++++++++--- 5 files changed, 1458 insertions(+), 346 deletions(-) (limited to 'src') diff --git a/src/external/stb_image.h b/src/external/stb_image.h index 5572a880..4d8d0133 100644 --- a/src/external/stb_image.h +++ b/src/external/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h +/* stb_image - v2.14 - public domain image loader - http://nothings.org/stb_image.h no warranty implied; use at your own risk Do this: @@ -146,6 +146,7 @@ Latest revision history: + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 RGB-format JPEG; remove white matting in PSD; @@ -157,21 +158,6 @@ 2.07 (2015-09-13) partial animated GIF support limited 16-bit PSD support minor bugs, code cleanup, and compiler warnings - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) additional corruption checking - stbi_set_flip_vertically_on_load - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD - progressive JPEG - PGM/PPM support - STBI_MALLOC,STBI_REALLOC,STBI_FREE - STBI_NO_*, STBI_ONLY_* - GIF bugfix See end of file for full revision history. @@ -186,9 +172,9 @@ Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) - urraka@github (animated gif) Junggon Kim (PNM comments) + github:urraka (animated gif) Junggon Kim (PNM comments) Daniel Gibson (16-bit TGA) - + socks-the-fox (16-bit TGA) Optimizations & bugfixes Fabian "ryg" Giesen Arseny Kapoulkine @@ -199,13 +185,14 @@ Dave Moore Roy Eltham Hayaki Saito Phil Jordan Won Chun Luke Graham Johan Duparc Nathan Reed the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis - Janez Zemva John Bartholomew Michal Cichon svdijk@github + Janez Zemva John Bartholomew Michal Cichon github:svdijk Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson - Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github + Laurent Gomila Cort Stratton Sergio Gonzalez github:romigrou Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan - Ryamond Barbiero Paul Du Bois Engin Manap snagar@github - Michaelangel007@github Oriol Ferrer Mesia socks-the-fox - Blazej Dariusz Roszkowski + Ryamond Barbiero Paul Du Bois Engin Manap github:snagar + Michaelangel007@github Oriol Ferrer Mesia Dale Weiler github:Zelex + Philipp Wiesemann Josh Tobin github:rlyeh github:grim210@github + Blazej Dariusz Roszkowski github:sammyhw LICENSE @@ -238,10 +225,10 @@ publish, and distribute this file as you see fit. // stbi_image_free(data) // // Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *comp -- outputs # of image components in image file -// int req_comp -- if non-zero, # of image components requested in result +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result // // The return value from an image loader is an 'unsigned char *' which points // to the pixel data, or NULL on an allocation failure or if the image is @@ -389,13 +376,13 @@ publish, and distribute this file as you see fit. // -#define STBI_NO_HDR // RaySan: not required by raylib -//#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2 - #ifndef STBI_NO_STDIO #include #endif // STBI_NO_STDIO +#define STBI_NO_HDR // RaySan: not required by raylib +//#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2 + // NOTE: Added to work with raylib on Android #if defined(PLATFORM_ANDROID) #include "utils.h" // RaySan: Android fopen function map @@ -414,6 +401,7 @@ enum }; typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; #ifdef __cplusplus extern "C" { @@ -441,22 +429,42 @@ typedef struct int (*eof) (void *user); // returns nonzero if we are at end of file/data } stbi_io_callbacks; -STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); -STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *comp, int req_comp); -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *comp, int req_comp); +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO -STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); // for stbi_load_from_file, file pointer is left pointing immediately after image #endif +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif +// @TODO the other variants + +//////////////////////////////////// +// +// float-per-channel interface +// #ifndef STBI_NO_LINEAR - STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); - STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); - STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO - STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); #endif #endif @@ -574,6 +582,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #include // ptrdiff_t on osx #include #include +#include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #include // ldexp @@ -835,57 +844,70 @@ static void stbi__rewind(stbi__context *s) s->img_buffer_end = s->img_buffer_original_end; } +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + #ifndef STBI_NO_JPEG static int stbi__jpeg_test(stbi__context *s); -static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNG static int stbi__png_test(stbi__context *s); -static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_BMP static int stbi__bmp_test(stbi__context *s); -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_TGA static int stbi__tga_test(stbi__context *s); -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PSD static int stbi__psd_test(stbi__context *s); -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_HDR static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PIC static int stbi__pic_test(stbi__context *s); -static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_GIF static int stbi__gif_test(stbi__context *s); -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNM static int stbi__pnm_test(stbi__context *s); -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); #endif @@ -908,6 +930,77 @@ static void *stbi__malloc(size_t size) return STBI_MALLOC(size); } +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} + +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} + // stbi__err - error // stbi__errpf - error returning pointer to float // stbi__errpuc - error returning pointer to unsigned char @@ -943,33 +1036,38 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) stbi__vertically_flip_on_load = flag_true_if_should_flip; } -static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); #endif #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); } #endif @@ -977,35 +1075,117 @@ static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *com #ifndef STBI_NO_TGA // test tga last because it's a crappy test! if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp); + return stbi__tga_load(s,x,y,comp,req_comp, ri); #endif return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); } -static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) { - unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); + int i; + int img_len = w * h * channels; + stbi_uc *reduced; - if (stbi__vertically_flip_on_load && result != NULL) { + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 8) { + STBI_ASSERT(ri.bits_per_channel == 16); + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { int w = *x, h = *y; - int depth = req_comp ? req_comp : *comp; + int channels = req_comp ? req_comp : *comp; int row,col,z; - stbi_uc temp; + stbi_uc *image = (stbi_uc *) result; // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once for (row = 0; row < (h>>1); row++) { for (col = 0; col < w; col++) { - for (z = 0; z < depth; z++) { - temp = result[(row * w + col) * depth + z]; - result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; - result[((h - row - 1) * w + col) * depth + z] = temp; + for (z = 0; z < channels; z++) { + stbi_uc temp = image[(row * w + col) * channels + z]; + image[(row * w + col) * channels + z] = image[((h - row - 1) * w + col) * channels + z]; + image[((h - row - 1) * w + col) * channels + z] = temp; } } } } - return result; + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 16) { + STBI_ASSERT(ri.bits_per_channel == 8); + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int w = *x, h = *y; + int channels = req_comp ? req_comp : *comp; + int row,col,z; + stbi__uint16 *image = (stbi__uint16 *) result; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < channels; z++) { + stbi__uint16 temp = image[(row * w + col) * channels + z]; + image[(row * w + col) * channels + z] = image[((h - row - 1) * w + col) * channels + z]; + image[((h - row - 1) * w + col) * channels + z] = temp; + } + } + } + } + + return (stbi__uint16 *) result; } #ifndef STBI_NO_HDR @@ -1061,27 +1241,52 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req unsigned char *result; stbi__context s; stbi__start_file(&s,f); - result = stbi__load_flip(&s,x,y,comp,req_comp); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); if (result) { // need to 'unget' all the characters in the IO buffer fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); } return result; } + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + #endif //!STBI_NO_STDIO STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_mem(&s,buffer,len); - return stbi__load_flip(&s,x,y,comp,req_comp); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_flip(&s,x,y,comp,req_comp); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } #ifndef STBI_NO_LINEAR @@ -1090,13 +1295,14 @@ static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int unsigned char *data; #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); if (hdr_data) stbi__float_postprocess(hdr_data,x,y,comp,req_comp); return hdr_data; } #endif - data = stbi__load_flip(s, x, y, comp, req_comp); + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); if (data) return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); @@ -1354,7 +1560,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - good = (unsigned char *) stbi__malloc(req_comp * x * y); + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); if (good == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); @@ -1364,26 +1570,75 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r unsigned char *src = data + j * x * img_n ; unsigned char *dest = good + j * x * req_comp; - #define COMBO(a,b) ((a)*8+(b)) - #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros - switch (COMBO(img_n, req_comp)) { - CASE(1,2) dest[0]=src[0], dest[1]=255; break; - CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; - CASE(2,1) dest[0]=src[0]; break; - CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; - CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; - CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; - CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; - CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; default: STBI_ASSERT(0); } - #undef CASE + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} + +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE } STBI_FREE(data); @@ -1394,7 +1649,9 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) { int i,k,n; - float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; @@ -1414,7 +1671,9 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) { int i,k,n; - stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; @@ -2709,6 +2968,28 @@ static int stbi__process_scan_header(stbi__jpeg *z) return 1; } +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + static int stbi__process_frame_header(stbi__jpeg *z, int scan) { stbi__context *s = z->s; @@ -2746,7 +3027,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) if (scan != STBI__SCAN_load) return 1; - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); for (i=0; i < s->img_n; ++i) { if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; @@ -2758,6 +3039,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) z->img_v_max = v_max; z->img_mcu_w = h_max * 8; z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; @@ -2769,28 +3051,27 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) // the bogus oversized data from using interleaved MCUs and their // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); - - if (z->img_comp[i].raw_data == NULL) { - for(--i; i >= 0; --i) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - } - return stbi__err("outofmem", "Out of memory"); - } + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); // align blocks for idct using mmx/sse z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - z->img_comp[i].linebuf = NULL; if (z->progressive) { - z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; - z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; - z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); - } else { - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; } } @@ -3296,23 +3577,7 @@ static void stbi__setup_jpeg(stbi__jpeg *j) // clean up the temporary component buffers static void stbi__cleanup_jpeg(stbi__jpeg *j) { - int i; - for (i=0; i < j->s->img_n; ++i) { - if (j->img_comp[i].raw_data) { - STBI_FREE(j->img_comp[i].raw_data); - j->img_comp[i].raw_data = NULL; - j->img_comp[i].data = NULL; - } - if (j->img_comp[i].raw_coeff) { - STBI_FREE(j->img_comp[i].raw_coeff); - j->img_comp[i].raw_coeff = 0; - j->img_comp[i].coeff = 0; - } - if (j->img_comp[i].linebuf) { - STBI_FREE(j->img_comp[i].linebuf); - j->img_comp[i].linebuf = NULL; - } - } + stbi__free_jpeg_components(j, j->s->img_n, 0); } typedef struct @@ -3376,7 +3641,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp } // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } // now go ahead and resample @@ -3432,7 +3697,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp } } -static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { unsigned char* result; stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); @@ -3729,6 +3994,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) int hlit = stbi__zreceive(a,5) + 257; int hdist = stbi__zreceive(a,5) + 1; int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; memset(codelength_sizes, 0, sizeof(codelength_sizes)); for (i=0; i < hclen; ++i) { @@ -3738,27 +4004,29 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; n = 0; - while (n < hlit + hdist) { + while (n < ntot) { int c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); if (c < 16) lencodes[n++] = (stbi_uc) c; - else if (c == 16) { - c = stbi__zreceive(a,2)+3; - memset(lencodes+n, lencodes[n-1], c); - n += c; - } else if (c == 17) { - c = stbi__zreceive(a,3)+3; - memset(lencodes+n, 0, c); - n += c; - } else { - STBI_ASSERT(c == 18); - c = stbi__zreceive(a,7)+11; - memset(lencodes+n, 0, c); + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) + c = stbi__zreceive(a,3)+3; + else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); n += c; } } - if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; return 1; @@ -4024,7 +4292,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r int width = x; STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); @@ -4089,37 +4357,37 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r // this is a little gross, so that we don't switch per-pixel or per-component if (depth < 8 || img_n == out_n) { int nk = (width - 1)*filter_bytes; - #define CASE(f) \ + #define STBI__CASE(f) \ case f: \ for (k=0; k < nk; ++k) switch (filter) { // "none" filter turns into a memcpy here; make that explicit. case STBI__F_none: memcpy(cur, raw, nk); break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; } - #undef CASE + #undef STBI__CASE raw += nk; } else { STBI_ASSERT(img_n+1 == out_n); - #define CASE(f) \ + #define STBI__CASE(f) \ case f: \ for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ for (k=0; k < filter_bytes; ++k) switch (filter) { - CASE(STBI__F_none) cur[k] = raw[k]; break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; } - #undef CASE + #undef STBI__CASE // the loop above sets the high byte of the pixels' alpha, but for // 16 bit png files we also need the low byte set. we'll do that here. @@ -4222,13 +4490,15 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) { + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; stbi_uc *final; int p; if (!interlaced) return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); // de-interlacing - final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); for (p=0; p < 7; ++p) { int xorig[] = { 0,4,0,2,0,1,0 }; int yorig[] = { 0,0,4,0,2,0,1 }; @@ -4248,8 +4518,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3 for (i=0; i < x; ++i) { int out_y = j*yspc[p]+yorig[p]; int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, - a->out + (j*x+i)*out_n, out_n); + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); } } STBI_FREE(a->out); @@ -4317,7 +4587,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; stbi_uc *p, *temp_out, *orig = a->out; - p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); if (p == NULL) return stbi__err("outofmem", "Out of memory"); // between here and free(out) below, exitting would leak @@ -4349,26 +4619,6 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int return 1; } -static int stbi__reduce_png(stbi__png *p) -{ - int i; - int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n; - stbi_uc *reduced; - stbi__uint16 *orig = (stbi__uint16*)p->out; - - if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data - - reduced = (stbi_uc *)stbi__malloc(img_len); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling - - p->out = reduced; - STBI_FREE(orig); - - return 1; -} - static int stbi__unpremultiply_on_load = 0; static int stbi__de_iphone_flag = 0; @@ -4508,7 +4758,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); has_trans = 1; if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is } else { for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger } @@ -4595,20 +4845,22 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) } } -static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { - unsigned char *result=NULL; + void *result=NULL; if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - if (p->depth == 16) { - if (!stbi__reduce_png(p)) { - return result; - } - } + if (p->depth < 8) + ri->bits_per_channel = 8; + else + ri->bits_per_channel = p->depth; result = p->out; p->out = NULL; if (req_comp && req_comp != p->s->img_out_n) { - result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); p->s->img_out_n = req_comp; if (result == NULL) return result; } @@ -4623,11 +4875,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req return result; } -static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi__png p; p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp); + return stbi__do_png(&p, x,y,comp,req_comp, ri); } static int stbi__png_test(stbi__context *s) @@ -4815,7 +5067,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) } -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; unsigned int mr=0,mg=0,mb=0,ma=0, all_a; @@ -4823,6 +5075,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int int psize=0,i,j,width; int flip_vertically, pad, target; stbi__bmp_data info; + STBI_NOTUSED(ri); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == NULL) @@ -4851,7 +5104,11 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int else target = s->img_n; // if they want monochrome, we'll post-convert - out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); if (info.bpp < 16) { int z=0; @@ -5085,18 +5342,18 @@ errorEnd: } // read 16bit value and convert to 24bit RGB -void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) { - stbi__uint16 px = stbi__get16le(s); + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); stbi__uint16 fiveBitMask = 31; // we have 3 channels with 5bits each int r = (px >> 10) & fiveBitMask; int g = (px >> 5) & fiveBitMask; int b = px & fiveBitMask; // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (r * 255)/31; - out[1] = (g * 255)/31; - out[2] = (b * 255)/31; + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); // some people claim that the most significant bit might be used for alpha // (possibly if an alpha-bit is set in the "image descriptor byte") @@ -5104,7 +5361,7 @@ void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) // so let's treat all 15 and 16bit TGAs as RGB with no alpha. } -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { // read in the TGA header stuff int tga_offset = stbi__get8(s); @@ -5126,10 +5383,11 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int unsigned char *tga_data; unsigned char *tga_palette = NULL; int i, j; - unsigned char raw_data[4]; + unsigned char raw_data[4] = {0}; int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; + STBI_NOTUSED(ri); // do a tiny bit of precessing if ( tga_image_type >= 8 ) @@ -5151,7 +5409,10 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int *y = tga_height; if (comp) *comp = tga_comp; - tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); // skip to the data's starting position (offset usually = 0) @@ -5170,7 +5431,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int // any data to skip? (offset usually = 0) stbi__skip(s, tga_palette_start ); // load the palette - tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); if (!tga_palette) { STBI_FREE(tga_data); return stbi__errpuc("outofmem", "Out of memory"); @@ -5306,14 +5567,53 @@ static int stbi__psd_test(stbi__context *s) return r; } -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) { - int pixelCount; + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; int channelCount, compression; - int channel, i, count, len; + int channel, i; int bitdepth; int w,h; stbi_uc *out; + STBI_NOTUSED(ri); // Check identifier if (stbi__get32be(s) != 0x38425053) // "8BPS" @@ -5370,8 +5670,18 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int if (compression > 1) return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + // Create the destination image. - out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); pixelCount = w*h; @@ -5403,82 +5713,86 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int *p = (channel == 3 ? 255 : 0); } else { // Read the RLE data. - count = 0; - while (count < pixelCount) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0x0FF; - len += 2; - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); } } } } else { // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. // Read the data by channel. for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out + channel; if (channel >= channelCount) { // Fill this channel with default data. - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } else { - // Read the data. - if (bitdepth == 16) { - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } } } } } + // remove weird white matte from PSD if (channelCount >= 4) { - for (i=0; i < w*h; ++i) { - unsigned char *pixel = out + 4*i; - if (pixel[3] != 0 && pixel[3] != 255) { - // remove weird white matte from PSD - float a = pixel[3] / 255.0f; - float ra = 1.0f / a; - float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); - pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); - pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } } } } + // convert to desired output format if (req_comp && req_comp != 4) { - out = stbi__convert_format(out, 4, req_comp, w, h); + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); if (out == NULL) return out; // stbi__convert_format frees input on failure } @@ -5662,10 +5976,11 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c return result; } -static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) { stbi_uc *result; int i, x,y; + STBI_NOTUSED(ri); for (i=0; i<92; ++i) stbi__get8(s); @@ -5673,14 +5988,14 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re x = stbi__get16be(s); y = stbi__get16be(s); if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); stbi__get32be(s); //skip `ratio' stbi__get16be(s); //skip `fields' stbi__get16be(s); //skip `pad' // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc(x*y*4); + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); memset(result, 0xff, x*y*4); if (!stbi__pic_load_core(s,x,y,comp, result)) { @@ -5939,8 +6254,11 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(g->w, g->h, 4, 0)) + return stbi__errpuc("too large", "GIF too large"); + prev_out = g->out; - g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + g->out = (stbi_uc *) stbi__malloc_mad3(4, g->w, g->h, 0); if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); switch ((g->eflags & 0x1C) >> 2) { @@ -6047,11 +6365,12 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i STBI_NOTUSED(req_comp); } -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *u = 0; stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); memset(g, 0, sizeof(*g)); + STBI_NOTUSED(ri); u = stbi__gif_load_next(s, g, comp, req_comp); if (u == (stbi_uc *) s) u = 0; // end of animated gif marker @@ -6077,20 +6396,24 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) // Radiance RGBE HDR loader // originally by Nicolas Schulz #ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context *s) +static int stbi__hdr_test_core(stbi__context *s, const char *signature) { - const char *signature = "#?RADIANCE\n"; int i; for (i=0; signature[i]; ++i) if (stbi__get8(s) != signature[i]) - return 0; + return 0; + stbi__rewind(s); return 1; } static int stbi__hdr_test(stbi__context* s) { - int r = stbi__hdr_test_core(s); + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } return r; } @@ -6144,7 +6467,7 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) } } -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { char buffer[STBI__HDR_BUFLEN]; char *token; @@ -6155,10 +6478,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re int len; unsigned char count, value; int i, j, k, c1,c2, z; - + const char *headerToken; + STBI_NOTUSED(ri); // Check identifier - if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) return stbi__errpf("not HDR", "Corrupt HDR image"); // Parse header @@ -6187,8 +6512,13 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re if (comp) *comp = 3; if (req_comp == 0) req_comp = 3; + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + // Read data - hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); // Load image data // image data is stored as some number of sca @@ -6227,20 +6557,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re len <<= 8; len |= stbi__get8(s); if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } for (k = 0; k < 4; ++k) { + int nleft; i = 0; - while (i < width) { + while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { // Run value = stbi__get8(s); count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = value; } else { // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = stbi__get8(s); } @@ -6249,7 +6588,8 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re for (i=0; i < width; ++i) stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); } - STBI_FREE(scanline); + if (scanline) + STBI_FREE(scanline); } return hdr_data; @@ -6427,16 +6767,22 @@ static int stbi__pnm_test(stbi__context *s) return 1; } -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; + STBI_NOTUSED(ri); + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) return 0; + *x = s->img_x; *y = s->img_y; *comp = s->img_n; - out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); + if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); stbi__getn(s, out, s->img_n * s->img_x * s->img_y); @@ -6601,6 +6947,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) allocate large structures on the stack remove white matting for transparent PSD diff --git a/src/external/stb_image_resize.h b/src/external/stb_image_resize.h index 4cabe540..5214ad6e 100644 --- a/src/external/stb_image_resize.h +++ b/src/external/stb_image_resize.h @@ -1,4 +1,4 @@ -/* stb_image_resize - v0.91 - public domain image resizing +/* stb_image_resize - v0.92 - public domain image resizing by Jorge L Rodriguez (@VinoBS) - 2014 http://github.com/nothings/stb @@ -154,8 +154,10 @@ ADDITIONAL CONTRIBUTORS Sean Barrett: API design, optimizations + Aras Pranckevicius: bugfix REVISIONS + 0.92 (2017-01-02) fix integer overflow on large (>2GB) images 0.91 (2016-04-02) fix warnings; fix handling of subpixel regions 0.90 (2014-09-17) first released version @@ -1239,11 +1241,11 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n) int type = stbir_info->type; int colorspace = stbir_info->colorspace; int input_w = stbir_info->input_w; - int input_stride_bytes = stbir_info->input_stride_bytes; + size_t input_stride_bytes = stbir_info->input_stride_bytes; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir_edge edge_horizontal = stbir_info->edge_horizontal; stbir_edge edge_vertical = stbir_info->edge_vertical; - int in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes; + size_t in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes; const void* input_data = (char *) stbir_info->input_data + in_buffer_row_offset; int max_x = input_w + stbir_info->horizontal_filter_pixel_margin; int decode = STBIR__DECODE(type, colorspace); diff --git a/src/external/stb_image_write.h b/src/external/stb_image_write.h index 4319c0de..ae9180b0 100644 --- a/src/external/stb_image_write.h +++ b/src/external/stb_image_write.h @@ -1,4 +1,4 @@ -/* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h +/* stb_image_write - v1.03 - public domain - http://nothings.org/stb/stb_image_write.h writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk @@ -103,6 +103,7 @@ CREDITS: Jonas Karlsson Filip Wasil Thatcher Ulrich + github:poppolopoppo LICENSE @@ -475,7 +476,6 @@ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *dat // ************************************************************************************************* // Radiance RGBE HDR writer // by Baldur Karlsson -#ifndef STBI_WRITE_NO_STDIO #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) @@ -630,6 +630,7 @@ int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, i return stbi_write_hdr_core(&s, x, y, comp, (float *) data); } +#ifndef STBI_WRITE_NO_STDIO int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) { stbi__write_context s; diff --git a/src/external/stb_rect_pack.h b/src/external/stb_rect_pack.h index bd1cfc60..c75527da 100644 --- a/src/external/stb_rect_pack.h +++ b/src/external/stb_rect_pack.h @@ -1,4 +1,4 @@ -// stb_rect_pack.h - v0.08 - public domain - rectangle packing +// stb_rect_pack.h - v0.10 - public domain - rectangle packing // Sean Barrett 2014 // // Useful for e.g. packing rectangular textures into an atlas. @@ -32,6 +32,8 @@ // // Version history: // +// 0.10 (2016-10-25) remove cast-away-const to avoid warnings +// 0.09 (2016-08-27) fix compiler warnings // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort @@ -148,7 +150,7 @@ enum { STBRP_HEURISTIC_Skyline_default=0, STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, - STBRP_HEURISTIC_Skyline_BF_sortHeight, + STBRP_HEURISTIC_Skyline_BF_sortHeight }; @@ -198,9 +200,15 @@ struct stbrp_context #define STBRP_ASSERT assert #endif +#ifdef _MSC_VER +#define STBRP__NOTUSED(v) (void)(v) +#else +#define STBRP__NOTUSED(v) (void)sizeof(v) +#endif + enum { - STBRP__INIT_skyline = 1, + STBRP__INIT_skyline = 1 }; STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) @@ -273,6 +281,9 @@ static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0 stbrp_node *node = first; int x1 = x0 + width; int min_y, visited_width, waste_area; + + STBRP__NOTUSED(c); + STBRP_ASSERT(first->x <= x0); #if 0 @@ -500,8 +511,8 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i static int rect_height_compare(const void *a, const void *b) { - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; + const stbrp_rect *p = (const stbrp_rect *) a; + const stbrp_rect *q = (const stbrp_rect *) b; if (p->h > q->h) return -1; if (p->h < q->h) @@ -511,8 +522,8 @@ static int rect_height_compare(const void *a, const void *b) static int rect_width_compare(const void *a, const void *b) { - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; + const stbrp_rect *p = (const stbrp_rect *) a; + const stbrp_rect *q = (const stbrp_rect *) b; if (p->w > q->w) return -1; if (p->w < q->w) @@ -522,8 +533,8 @@ static int rect_width_compare(const void *a, const void *b) static int rect_original_order(const void *a, const void *b) { - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; + const stbrp_rect *p = (const stbrp_rect *) a; + const stbrp_rect *q = (const stbrp_rect *) b; return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); } diff --git a/src/external/stb_truetype.h b/src/external/stb_truetype.h index d360d609..92b9a875 100644 --- a/src/external/stb_truetype.h +++ b/src/external/stb_truetype.h @@ -1,5 +1,5 @@ -// stb_truetype.h - v1.11 - public domain -// authored from 2009-2015 by Sean Barrett / RAD Game Tools +// stb_truetype.h - v1.14 - public domain +// authored from 2009-2016 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: // parse files @@ -20,10 +20,12 @@ // // Mikko Mononen: compound shape support, more cmap formats // Tor Andersson: kerning, subpixel rendering +// Dougall Johnson: OpenType / Type 2 font handling // // Misc other: // Ryan Gordon // Simon Glass +// github:IntellectualKitty // // Bug/warning reports/fixes: // "Zer" on mollyrocket (with fix) @@ -51,6 +53,8 @@ // // VERSION HISTORY // +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef // 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly @@ -60,12 +64,6 @@ // fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); // fixed an assert() bug in the new rasterizer // replace assert() with STBTT_assert() in new rasterizer -// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) -// also more precise AA rasterizer, except if shapes overlap -// remove need for STBTT_sort -// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC -// 1.04 (2015-04-15) typo in example -// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes // // Full history can be found at the end of this file. // @@ -100,7 +98,8 @@ // // "Load" a font file from a memory buffer (you have to keep the buffer loaded) // stbtt_InitFont() -// stbtt_GetFontOffsetForIndex() -- use for TTC font collections +// stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections +// stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections // // Render a unicode codepoint to a bitmap // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap @@ -458,6 +457,14 @@ int main(int arg, char **argv) extern "C" { #endif +// private structure +typedef struct +{ + unsigned char *data; + int cursor; + int size; +} stbtt__buf; + ////////////////////////////////////////////////////////////////////////////// // // TEXTURE BAKING API @@ -527,7 +534,7 @@ typedef struct stbrp_rect stbrp_rect; STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); // Initializes a packing context stored in the passed-in stbtt_pack_context. // Future calls using this context will pack characters into the bitmap passed -// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// in here: a 1-channel bitmap that is width * height. stride_in_bytes is // the distance from one row to the next (or 0 to mean they are packed tightly // together). "padding" is the amount of padding to leave between each // character (normally you want '1' for bitmaps you'll use as textures with @@ -593,9 +600,9 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, stbtt_aligned_quad *q, // output: quad to draw int align_to_integer); -STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); -STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); // Calling these functions in sequence is roughly equivalent to calling // stbtt_PackFontRanges(). If you more control over the packing of multiple // fonts, or if you want to pack custom data into a font texture, take a look @@ -626,14 +633,19 @@ struct stbtt_pack_context { // // +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); +// This function will determine the number of fonts in a font file. TrueType +// collection (.ttc) files may contain multiple fonts, while TrueType font +// (.ttf) files only contain one font. The number of fonts can be used for +// indexing with the previous function where the index is between zero and one +// less than the total fonts. If an error occurs, -1 is returned. + STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); // Each .ttf/.ttc file may have more than one font. Each font has a sequential // index number starting from 0. Call this function to get the font offset for // a given index; it returns -1 if the index is out of range. A regular .ttf // file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. You can just skip -// this step if you know it's that kind of font. - +// return '0' for index 0, and -1 for all other indices. // The following structure is defined publically so you can declare one on // the stack or as a global or etc, but you should treat it as opaque. @@ -648,6 +660,13 @@ struct stbtt_fontinfo int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph + + stbtt__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict }; STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); @@ -725,7 +744,8 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in enum { STBTT_vmove=1, STBTT_vline, - STBTT_vcurve + STBTT_vcurve, + STBTT_vcubic }; #endif @@ -734,7 +754,7 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file typedef struct { - stbtt_vertex_type x,y,cx,cy; + stbtt_vertex_type x,y,cx,cy,cx1,cy1; unsigned char type,padding; } stbtt_vertex; #endif @@ -956,6 +976,152 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS #define STBTT__NOTUSED(v) (void)sizeof(v) #endif +////////////////////////////////////////////////////////////////////////// +// +// stbtt__buf helpers to parse data from file +// + +static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; +} + +static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; +} + +static void stbtt__buf_seek(stbtt__buf *b, int o) +{ + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +static void stbtt__buf_skip(stbtt__buf *b, int o) +{ + stbtt__buf_seek(b, b->cursor + o); +} + +static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) +{ + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; +} + +static stbtt__buf stbtt__new_buf(const void *p, size_t size) +{ + stbtt__buf r; + STBTT_assert(size < 0x40000000); + r.data = (stbtt_uint8*) p; + r.size = (int) size; + r.cursor = 0; + return r; +} + +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) + +static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) +{ + stbtt__buf r = stbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; +} + +static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) +{ + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if (count) { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); +} + +static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) +{ + int b0 = stbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) return b0 - 139; + else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108; + else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108; + else if (b0 == 28) return stbtt__buf_get16(b); + else if (b0 == 29) return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; +} + +static void stbtt__cff_skip_operand(stbtt__buf *b) { + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if (b0 == 30) { + stbtt__buf_skip(b, 1); + while (b->cursor < b->size) { + v = stbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } else { + stbtt__cff_int(b); + } +} + +static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) +{ + stbtt__buf_seek(b, 0); + while (b->cursor < b->size) { + int start = b->cursor, end, op; + while (stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if (op == 12) op = stbtt__buf_get8(b) | 0x100; + if (op == key) return stbtt__buf_range(b, start, end-start); + } + return stbtt__buf_range(b, 0, 0); +} + +static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) +{ + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); +} + +static int stbtt__cff_index_count(stbtt__buf *b) +{ + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); +} + +static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) +{ + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i*offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); +} + ////////////////////////////////////////////////////////////////////////// // // accessors to parse data from file @@ -968,32 +1134,22 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS #define ttCHAR(p) (* (stbtt_int8 *) (p)) #define ttFixed(p) ttLONG(p) -#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) - - #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) - #define ttSHORT(p) (* (stbtt_int16 *) (p)) - #define ttULONG(p) (* (stbtt_uint32 *) (p)) - #define ttLONG(p) (* (stbtt_int32 *) (p)) - -#else - - static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - -#endif +static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } +static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) #define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) -static int stbtt__isfont(const stbtt_uint8 *font) +static int stbtt__isfont(stbtt_uint8 *font) { // check the version number if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts return 0; } @@ -1011,7 +1167,7 @@ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, return 0; } -STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) +static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index) { // if it's just a font, there's only one valid index if (stbtt__isfont(font_collection)) @@ -1030,14 +1186,43 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, return -1; } -STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) +static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) +{ + // if it's just a font, there's only one valid font + if (stbtt__isfont(font_collection)) + return 1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + return ttLONG(font_collection+8); + } + } + return 0; +} + +static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) +{ + stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1]+subrsoff); + return stbtt__cff_get_index(&cff); +} + +static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) { - stbtt_uint8 *data = (stbtt_uint8 *) data2; stbtt_uint32 cmap, t; stbtt_int32 i,numTables; info->data = data; info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); cmap = stbtt__find_table(data, fontstart, "cmap"); // required info->loca = stbtt__find_table(data, fontstart, "loca"); // required @@ -1046,8 +1231,61 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required info->kern = stbtt__find_table(data, fontstart, "kern"); // not required - if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + + if (!cmap || !info->head || !info->hhea || !info->hmtx) return 0; + if (info->glyf) { + // required for truetype + if (!info->loca) return 0; + } else { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; + + cff = stbtt__find_table(data, fontstart, "CFF "); + if (!cff) return 0; + + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); + + // @TODO this should use size from table (not 512MB) + info->cff = stbtt__new_buf(data+cff, 512*1024*1024); + b = info->cff; + + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); + + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); + + // we only support Type 2 charstrings + if (cstype != 2) return 0; + if (charstrings == 0) return 0; + + if (fdarrayoff) { + // looks like a CID font + if (!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff); + } + + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } t = stbtt__find_table(data, fontstart, "maxp"); if (t) @@ -1198,6 +1436,8 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) { int g1,g2; + STBTT_assert(!info->cff.size); + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format @@ -1212,15 +1452,21 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) return g1==g2 ? -1 : g1; // if length is 0, return -1 } +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; + if (info->cff.size) { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } else { + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; - if (x0) *x0 = ttSHORT(info->data + g + 2); - if (y0) *y0 = ttSHORT(info->data + g + 4); - if (x1) *x1 = ttSHORT(info->data + g + 6); - if (y1) *y1 = ttSHORT(info->data + g + 8); + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + } return 1; } @@ -1232,7 +1478,10 @@ STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, i STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) { stbtt_int16 numberOfContours; - int g = stbtt__GetGlyfOffset(info, glyph_index); + int g; + if (info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + g = stbtt__GetGlyfOffset(info, glyph_index); if (g < 0) return 1; numberOfContours = ttSHORT(info->data + g); return numberOfContours == 0; @@ -1254,7 +1503,7 @@ static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_ return num_vertices; } -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { stbtt_int16 numberOfContours; stbtt_uint8 *endPtsOfContours; @@ -1480,6 +1729,416 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s return num_vertices; } +typedef struct +{ + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; + + stbtt_vertex *pvertices; + int num_vertices; +} stbtt__csctx; + +#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) +{ + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) +{ + if (c->bounds) { + stbtt__track_vertex(c, x, y); + if (type == STBTT_vcubic) { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } else { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1; + } + c->num_vertices++; +} + +static void stbtt__csctx_close_shape(stbtt__csctx *ctx) +{ + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) +{ + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) +{ + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); +} + +static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if (fmt == 0) { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } else if (fmt == 3) { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); +} + +static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define STBTT__CSERR(s) (0) + + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch (b0) { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if (in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; + + case 0x15: // rmoveto + in_header = 0; + if (sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); + break; + case 0x04: // vmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp-1]); + break; + case 0x16: // hmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-1], 0); + break; + + case 0x05: // rlineto + if (sp < 2) return STBTT__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. + + case 0x07: // vlineto + if (sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if (sp < 1) return STBTT__CSERR("hlineto stack"); + for (;;) { + if (i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: // hvcurveto + if (sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if (sp < 4) return STBTT__CSERR("vhcurveto stack"); + for (;;) { + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); + i += 4; + } + break; + + case 0x08: // rrcurveto + if (sp < 6) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x18: // rcurveline + if (sp < 8) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + case 0x19: // rlinecurve + if (sp < 8) return STBTT__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) { f = s[i]; i++; } + for (; i + 3 < sp; i += 4) { + if (b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); + f = 0.0; + } + break; + + case 0x0A: // callsubr + if (!has_subrs) { + if (info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // fallthrough + case 0x1D: // callgsubr + if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int) s[--sp]; + if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: // return + if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch (b1) { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if (sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: // flex + if (sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: // hflex1 + if (sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); + break; + + case 0x25: // flex1 + if (sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1+dx2+dx3+dx4+dx5; + dy = dy1+dy2+dy3+dy4+dy5; + if (STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return STBTT__CSERR("unimplemented"); + } + } break; + + default: + if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) + return STBTT__CSERR("reserved operator"); + + // push immediate + if (b0 == 255) { + f = (float)stbtt__buf_get32(&b) / 0x10000; + } else { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if (sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); + +#undef STBTT__CSERR +} + +static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if (x0) { + *x0 = r ? c.min_x : 0; + *y0 = r ? c.min_y : 0; + *x1 = r ? c.max_x : 0; + *y1 = r ? c.max_y : 0; + } + return r ? c.num_vertices : 0; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + if (!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) { stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); @@ -2350,6 +3009,48 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x return 1; } +static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1-x0; + float dy0 = y1-y0; + float dx1 = x2-x1; + float dy1 = y2-y1; + float dx2 = x3-x2; + float dy2 = y3-y2; + float dx = x3-x0; + float dy = y3-y0; + float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2)); + float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy); + float flatness_squared = longlen*longlen-shortlen*shortlen; + + if (n > 16) // 65536 segments on one curve better be enough! + return; + + if (flatness_squared > objspace_flatness_squared) { + float x01 = (x0+x1)/2; + float y01 = (y0+y1)/2; + float x12 = (x1+x2)/2; + float y12 = (y1+y2)/2; + float x23 = (x2+x3)/2; + float y23 = (y2+y3)/2; + + float xa = (x01+x12)/2; + float ya = (y01+y12)/2; + float xb = (x12+x23)/2; + float yb = (y12+y23)/2; + + float mx = (xa+xb)/2; + float my = (ya+yb)/2; + + stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x3,y3); + *num_points = *num_points+1; + } +} + // returns number of contours static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { @@ -2406,6 +3107,14 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, objspace_flatness_squared, 0); x = vertices[i].x, y = vertices[i].y; break; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; } } (*contour_lengths)[n] = num_points - start; @@ -2532,7 +3241,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch // // This is SUPER-CRAPPY packing to keep source code small -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) +static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) float pixel_height, // height of font in pixels unsigned char *pixels, int pw, int ph, // bitmap to be filled in int first_char, int num_chars, // characters to bake @@ -2862,7 +3571,7 @@ static float stbtt__oversample_shift(int oversample) } // rects array must be big enough to accommodate all characters in the given ranges -STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { int i,j,k; @@ -2891,7 +3600,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon } // rects array must be big enough to accommodate all characters in the given ranges -STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { int i,j,k, return_value = 1; @@ -3060,7 +3769,7 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i // // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) { stbtt_int32 i=0; @@ -3099,9 +3808,9 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 return i; } -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) { - return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); } // returns results in whatever encoding you request... but note that 2-byte encodings @@ -3157,7 +3866,7 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, return 1; } else if (matchlen < nlen && name[matchlen] == ' ') { ++matchlen; - if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) + if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) return 1; } } else { @@ -3203,7 +3912,7 @@ static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *nam return 0; } -STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) +static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) { stbtt_int32 i; for (i=0;;++i) { @@ -3214,11 +3923,53 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const } } +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, + float pixel_height, unsigned char *pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar *chardata) +{ + return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) +{ + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); +} + +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) +{ + return stbtt_GetNumberOfFonts_internal((unsigned char *) data); +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) +{ + return stbtt_InitFont_internal(info, (unsigned char *) data, offset); +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) +{ + return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags); +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + #endif // STB_TRUETYPE_IMPLEMENTATION // FULL VERSION HISTORY // +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) allow user-defined fabs() replacement // fix memory leak if fontsize=0.0 -- cgit v1.2.3 From 7586031410c7c3746025ef6c8bc6bee4b73baf1f Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Jan 2017 13:18:04 +0100 Subject: Support 32bit wav data --- src/audio.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 119b057d..74a54b04 100644 --- a/src/audio.c +++ b/src/audio.c @@ -459,7 +459,15 @@ void SetSoundPitch(Sound sound, float pitch) void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) { // Format sample rate - if (wave->sampleRate != sampleRate) wave->sampleRate = sampleRate; + // NOTE: Only supported 22050 <--> 44100 + if (wave->sampleRate != sampleRate) + { + // TODO: Resample wave data (upsampling or downsampling) + // NOTE 1: To downsample, you have to drop samples or average them. + // NOTE 2: To upsample, you have to interpolate new samples. + + wave->sampleRate = sampleRate; + } // Format sample size // NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit @@ -1078,23 +1086,23 @@ static Wave LoadWAV(const char *fileName) else { // Allocate memory for data - wave.data = (unsigned char *)malloc(sizeof(unsigned char)*wavData.subChunkSize); + wave.data = malloc(wavData.subChunkSize); // Read in the sound data into the soundData variable - fread(wave.data, wavData.subChunkSize, 1, wavFile); + fread(wave.data, 1, wavData.subChunkSize, wavFile); // Store wave parameters wave.sampleRate = wavFormat.sampleRate; wave.sampleSize = wavFormat.bitsPerSample; wave.channels = wavFormat.numChannels; - // NOTE: Only support up to 16 bit sample sizes - if (wave.sampleSize > 16) + // NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes + if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32)) { - WaveFormat(&wave, wave.sampleRate, 16, wave.channels); TraceLog(WARNING, "[%s] WAV sample size (%ibit) not supported, converted to 16bit", fileName, wave.sampleSize); + WaveFormat(&wave, wave.sampleRate, 16, wave.channels); } - + // NOTE: Only support up to 2 channels (mono, stereo) if (wave.channels > 2) { -- cgit v1.2.3 From f164ec80d6f1ca7afb7aec6a1e525cd67d401c14 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 22 Jan 2017 15:31:56 +0100 Subject: Upload wave collector - GGJ17 game --- examples/audio_sound_loading.c | 2 +- examples/resources/audio/sound.wav | Bin 0 -> 97512 bytes examples/shaders_standard_lighting.c | 4 +- games/wave_collector/Makefile | 233 ++++++++++ games/wave_collector/resources/audio/pause.wav | Bin 0 -> 25906 bytes .../wave_collector/resources/audio/sample_off.wav | Bin 0 -> 9291 bytes games/wave_collector/resources/audio/sample_on.wav | Bin 0 -> 2335 bytes games/wave_collector/resources/audio/start.wav | Bin 0 -> 14079 bytes games/wave_collector/resources/audio/wave.ogg | Bin 0 -> 1364969 bytes games/wave_collector/resources/font.fnt | 100 +++++ games/wave_collector/resources/font.png | Bin 0 -> 140998 bytes .../resources/textures/background.png | Bin 0 -> 840327 bytes .../resources/textures/background_gameplay.png | Bin 0 -> 561566 bytes .../resources/textures/background_title.png | Bin 0 -> 606904 bytes .../resources/textures/icon_synchro.png | Bin 0 -> 10015 bytes .../resources/textures/icon_warp.png | Bin 0 -> 11832 bytes games/wave_collector/resources/textures/line.png | Bin 0 -> 977 bytes .../resources/textures/logo_raylib.png | Bin 0 -> 1868 bytes games/wave_collector/resources/textures/lose.png | Bin 0 -> 79189 bytes games/wave_collector/resources/textures/player.png | Bin 0 -> 11785 bytes .../resources/textures/sample_big.png | Bin 0 -> 3006 bytes .../resources/textures/sample_mid.png | Bin 0 -> 1720 bytes .../resources/textures/sample_small.png | Bin 0 -> 1857 bytes games/wave_collector/resources/textures/title.png | Bin 0 -> 125004 bytes games/wave_collector/resources/textures/win.png | Bin 0 -> 33189 bytes games/wave_collector/screens/screen_ending.c | 111 +++++ games/wave_collector/screens/screen_gameplay.c | 490 +++++++++++++++++++++ games/wave_collector/screens/screen_logo.c | 181 ++++++++ games/wave_collector/screens/screen_title.c | 112 +++++ games/wave_collector/screens/screens.h | 87 ++++ games/wave_collector/wave_collector.c | 310 +++++++++++++ release/html5/libraylib.bc | Bin 753552 -> 788572 bytes release/html5/raylib.h | 163 ++++--- release/win32/mingw32/libraylib.a | Bin 675332 -> 695888 bytes release/win32/raylib.h | 163 ++++--- src/audio.c | 8 +- src/rlgl.h | 2 +- 37 files changed, 1836 insertions(+), 130 deletions(-) create mode 100644 examples/resources/audio/sound.wav create mode 100644 games/wave_collector/Makefile create mode 100644 games/wave_collector/resources/audio/pause.wav create mode 100644 games/wave_collector/resources/audio/sample_off.wav create mode 100644 games/wave_collector/resources/audio/sample_on.wav create mode 100644 games/wave_collector/resources/audio/start.wav create mode 100644 games/wave_collector/resources/audio/wave.ogg create mode 100644 games/wave_collector/resources/font.fnt create mode 100644 games/wave_collector/resources/font.png create mode 100644 games/wave_collector/resources/textures/background.png create mode 100644 games/wave_collector/resources/textures/background_gameplay.png create mode 100644 games/wave_collector/resources/textures/background_title.png create mode 100644 games/wave_collector/resources/textures/icon_synchro.png create mode 100644 games/wave_collector/resources/textures/icon_warp.png create mode 100644 games/wave_collector/resources/textures/line.png create mode 100644 games/wave_collector/resources/textures/logo_raylib.png create mode 100644 games/wave_collector/resources/textures/lose.png create mode 100644 games/wave_collector/resources/textures/player.png create mode 100644 games/wave_collector/resources/textures/sample_big.png create mode 100644 games/wave_collector/resources/textures/sample_mid.png create mode 100644 games/wave_collector/resources/textures/sample_small.png create mode 100644 games/wave_collector/resources/textures/title.png create mode 100644 games/wave_collector/resources/textures/win.png create mode 100644 games/wave_collector/screens/screen_ending.c create mode 100644 games/wave_collector/screens/screen_gameplay.c create mode 100644 games/wave_collector/screens/screen_logo.c create mode 100644 games/wave_collector/screens/screen_title.c create mode 100644 games/wave_collector/screens/screens.h create mode 100644 games/wave_collector/wave_collector.c (limited to 'src') diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c index f081e8ed..feb30563 100644 --- a/examples/audio_sound_loading.c +++ b/examples/audio_sound_loading.c @@ -24,7 +24,7 @@ int main() InitAudioDevice(); // Initialize audio device - Sound fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file + Sound fxWav = LoadSound("resources/audio/sound.wav"); // Load WAV audio file Sound fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file SetTargetFPS(60); diff --git a/examples/resources/audio/sound.wav b/examples/resources/audio/sound.wav new file mode 100644 index 00000000..b5d01c9b Binary files /dev/null and b/examples/resources/audio/sound.wav differ diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index e539ec47..728bdae0 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -35,7 +35,9 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Material material = LoadStandardMaterial(); + Material material;// = LoadStandardMaterial(); + + material.shader = LoadShader("resources/shaders/glsl330/standard.vs", "resources/shaders/glsl330/standard.fs"); material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture diff --git a/games/wave_collector/Makefile b/games/wave_collector/Makefile new file mode 100644 index 00000000..bac51ef1 --- /dev/null +++ b/games/wave_collector/Makefile @@ -0,0 +1,233 @@ +#************************************************************************************************** +# +# raylib - Advance Game +# +# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten) +# +# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +# +# This software is provided "as-is", without any express or implied warranty. In no event +# will the authors be held liable for any damages arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, including commercial +# applications, and to alter it and redistribute it freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not claim that you +# wrote the original software. If you use this software in a product, an acknowledgment +# in the product documentation would be appreciated but is not required. +# +# 2. Altered source versions must be plainly marked as such, and must not be misrepresented +# as being the original software. +# +# 3. This notice may not be removed or altered from any source distribution. +# +#************************************************************************************************** + +.PHONY: all clean + +# define raylib platform to compile for +# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB +# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() +PLATFORM ?= PLATFORM_DESKTOP + +# determine PLATFORM_OS in case PLATFORM_DESKTOP selected +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows + ifeq ($(OS),Windows_NT) + PLATFORM_OS=WINDOWS + LIBPATH=win32 + else + UNAMEOS:=$(shell uname) + ifeq ($(UNAMEOS),Linux) + PLATFORM_OS=LINUX + LIBPATH=linux + else + ifeq ($(UNAMEOS),Darwin) + PLATFORM_OS=OSX + LIBPATH=osx + endif + endif + endif +endif + +# define compiler: gcc for C program, define as g++ for C++ +ifeq ($(PLATFORM),PLATFORM_WEB) + # define emscripten compiler + CC = emcc +else +ifeq ($(PLATFORM_OS),OSX) + # define llvm compiler for mac + CC = clang +else + # define default gcc compiler + CC = gcc +endif +endif + +# define compiler flags: +# -O2 defines optimization level +# -Wall turns on most, but not all, compiler warnings +# -std=c99 use standard C from 1999 revision +ifeq ($(PLATFORM),PLATFORM_RPI) + CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline +else + CFLAGS = -O2 -Wall -std=c99 +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ALLOW_MEMORY_GROWTH=1 --preload-file resources --shell-file C:/raylib/raylib/templates/web_shell/shell.html + #-s ASSERTIONS=1 # to check for memory allocation errors (-O1 disables it) + #-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing + #-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) +endif + +#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes + +# define any directories containing required header files +ifeq ($(PLATFORM),PLATFORM_RPI) + INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads +endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # add standard directories for GNU/Linux + ifeq ($(PLATFORM_OS),LINUX) + INCLUDES = -I. -I../src -I/usr/local/include/raylib/ + else + INCLUDES = -I. -I../../src -IC:/raylib/raylib/src + # external libraries headers + # GLFW3 + INCLUDES += -I../../external/glfw3/include + # OpenAL Soft + INCLUDES += -I../../external/openal_soft/include + endif +endif + +# define library paths containing required libs +ifeq ($(PLATFORM),PLATFORM_RPI) + LFLAGS = -L. -L../../src -L/opt/vc/lib +endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # add standard directories for GNU/Linux + ifeq ($(PLATFORM_OS),LINUX) + LFLAGS = -L. -L../../src + else + LFLAGS = -L. -L../../src + ifeq ($(PLATFORM_OS),WINDOWS) + LFLAGS += -LC:/GitHub/raylib/src + endif + # external libraries to link with + # GLFW3 + LFLAGS += -L../../external/glfw3/lib/$(LIBPATH) + ifneq ($(PLATFORM_OS),OSX) + # OpenAL Soft + LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH) + endif + endif +endif + +ifeq ($(PLATFORM),PLATFORM_WEB) + INCLUDES = -I. -I.. + LFLAGS = -L. -L.. +endif + +# define any libraries to link into executable +# if you want to link libraries (libname.so or libname.a), use the -lname +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),LINUX) + # libraries for Debian GNU/Linux desktop compiling + # requires the following packages: + # libglfw3-dev libopenal-dev libegl1-mesa-dev + LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl -lX11 \ + -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + else + ifeq ($(PLATFORM_OS),OSX) + # libraries for OS X 10.9 desktop compiling + # requires the following packages: + # libglfw3-dev libopenal-dev libegl1-mesa-dev + LIBS = -lraylib -lglfw3 -framework OpenGL -framework OpenAl -framework Cocoa + else + # libraries for Windows desktop compiling + # NOTE: GLFW3 and OpenAL Soft libraries should be installed + LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lwinmm -lgdi32 + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + # libraries for Raspberry Pi compiling + # NOTE: OpenAL Soft library should be installed (libopenal1 package) + LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + # NOTE: Set the correct path to libraylib.bc + LIBS = libraylib.bc +endif + +# define additional parameters and flags for windows +ifeq ($(PLATFORM_OS),WINDOWS) + # resources file contains windows exe icon + # -Wl,--subsystem,windows hides the console window + WINFLAGS = C:/raylib/raylib/src/resources -Wl,-allow-multiple-definition + # -Wl,--subsystem,windows +endif + +ifeq ($(PLATFORM),PLATFORM_WEB) + EXT = .html +endif + +# define all screen object files required +SCREENS = \ + screens/screen_logo.o \ + screens/screen_title.o \ + screens/screen_gameplay.o \ + screens/screen_ending.o \ + +# typing 'make' will invoke the default target entry called 'all', +# in this case, the 'default' target entry is advance_game +default: wave_collector + +# compile template - advance_game +wave_collector: wave_collector.c $(SCREENS) + $(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + +# compile screen LOGO +screens/screen_logo.o: screens/screen_logo.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen TITLE +screens/screen_title.o: screens/screen_title.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen GAMEPLAY +screens/screen_gameplay.o: screens/screen_gameplay.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen ENDING +screens/screen_ending.o: screens/screen_ending.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# clean everything +clean: +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),OSX) + find . -type f -perm +ugo+x -delete + rm -f screens/*.o + else + ifeq ($(PLATFORM_OS),LINUX) + find . -type f -executable -delete + rm -f screens/*.o + else + del screens\*.o *.exe + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + find . -type f -executable -delete + rm -f screens/*.o +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + del screens/*.o *.html *.js +endif + @echo Cleaning done + +# instead of defining every module one by one, we can define a pattern +# this pattern below will automatically compile every module defined on $(OBJS) +#%.exe : %.c +# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) diff --git a/games/wave_collector/resources/audio/pause.wav b/games/wave_collector/resources/audio/pause.wav new file mode 100644 index 00000000..f35301ee Binary files /dev/null and b/games/wave_collector/resources/audio/pause.wav differ diff --git a/games/wave_collector/resources/audio/sample_off.wav b/games/wave_collector/resources/audio/sample_off.wav new file mode 100644 index 00000000..d2203e72 Binary files /dev/null and b/games/wave_collector/resources/audio/sample_off.wav differ diff --git a/games/wave_collector/resources/audio/sample_on.wav b/games/wave_collector/resources/audio/sample_on.wav new file mode 100644 index 00000000..38b7ca58 Binary files /dev/null and b/games/wave_collector/resources/audio/sample_on.wav differ diff --git a/games/wave_collector/resources/audio/start.wav b/games/wave_collector/resources/audio/start.wav new file mode 100644 index 00000000..66ce7ac1 Binary files /dev/null and b/games/wave_collector/resources/audio/start.wav differ diff --git a/games/wave_collector/resources/audio/wave.ogg b/games/wave_collector/resources/audio/wave.ogg new file mode 100644 index 00000000..a5b0dea4 Binary files /dev/null and b/games/wave_collector/resources/audio/wave.ogg differ diff --git a/games/wave_collector/resources/font.fnt b/games/wave_collector/resources/font.fnt new file mode 100644 index 00000000..607e5a4d --- /dev/null +++ b/games/wave_collector/resources/font.fnt @@ -0,0 +1,100 @@ +info face=font size=57 bold=0 italic=0 charset= unicode= stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=0,0 outline=0 +common lineHeight=68 base=55 scaleW=512 scaleH=1024 pages=1 packed=0 +page id=0 file="font.png" +chars count=95 +char id=32 x=2 y=57 width=0 height=0 xoffset=0 yoffset=55 xadvance=29 page=0 chnl=15 +char id=33 x=4 y=5 width=16 height=61 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15 +char id=34 x=22 y=10 width=25 height=27 xoffset=0 yoffset=8 xadvance=23 page=0 chnl=15 +char id=35 x=49 y=26 width=41 height=27 xoffset=-3 yoffset=24 xadvance=34 page=0 chnl=15 +char id=36 x=92 y=26 width=41 height=27 xoffset=-3 yoffset=24 xadvance=34 page=0 chnl=15 +char id=37 x=135 y=13 width=34 height=49 xoffset=-1 yoffset=12 xadvance=30 page=0 chnl=15 +char id=38 x=171 y=16 width=51 height=46 xoffset=-1 yoffset=14 xadvance=47 page=0 chnl=15 +char id=39 x=224 y=10 width=16 height=27 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 +char id=40 x=242 y=8 width=18 height=60 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15 +char id=41 x=262 y=8 width=18 height=60 xoffset=-1 yoffset=6 xadvance=15 page=0 chnl=15 +char id=42 x=282 y=11 width=29 height=32 xoffset=-1 yoffset=10 xadvance=25 page=0 chnl=15 +char id=43 x=313 y=25 width=29 height=29 xoffset=-2 yoffset=24 xadvance=24 page=0 chnl=15 +char id=44 x=344 y=45 width=16 height=29 xoffset=0 yoffset=44 xadvance=13 page=0 chnl=15 +char id=45 x=362 y=33 width=29 height=15 xoffset=1 yoffset=31 xadvance=28 page=0 chnl=15 +char id=46 x=393 y=45 width=16 height=17 xoffset=-1 yoffset=44 xadvance=13 page=0 chnl=15 +char id=47 x=411 y=6 width=37 height=61 xoffset=-3 yoffset=4 xadvance=30 page=0 chnl=15 +char id=48 x=450 y=14 width=43 height=49 xoffset=-1 yoffset=12 xadvance=39 page=0 chnl=15 +char id=49 x=2 y=91 width=22 height=49 xoffset=-1 yoffset=12 xadvance=19 page=0 chnl=15 +char id=50 x=26 y=91 width=42 height=49 xoffset=-1 yoffset=12 xadvance=39 page=0 chnl=15 +char id=51 x=70 y=91 width=41 height=48 xoffset=-2 yoffset=12 xadvance=35 page=0 chnl=15 +char id=52 x=113 y=91 width=40 height=48 xoffset=-2 yoffset=12 xadvance=35 page=0 chnl=15 +char id=53 x=155 y=91 width=35 height=49 xoffset=-1 yoffset=12 xadvance=31 page=0 chnl=15 +char id=54 x=192 y=91 width=48 height=48 xoffset=-2 yoffset=13 xadvance=43 page=0 chnl=15 +char id=55 x=242 y=91 width=38 height=49 xoffset=-2 yoffset=12 xadvance=33 page=0 chnl=15 +char id=56 x=282 y=91 width=49 height=49 xoffset=-2 yoffset=12 xadvance=43 page=0 chnl=15 +char id=57 x=333 y=91 width=46 height=49 xoffset=-2 yoffset=12 xadvance=41 page=0 chnl=15 +char id=58 x=381 y=102 width=16 height=37 xoffset=0 yoffset=24 xadvance=14 page=0 chnl=15 +char id=59 x=399 y=102 width=16 height=48 xoffset=0 yoffset=24 xadvance=15 page=0 chnl=15 +char id=60 x=417 y=98 width=41 height=42 xoffset=-2 yoffset=19 xadvance=37 page=0 chnl=15 +char id=61 x=460 y=104 width=29 height=30 xoffset=0 yoffset=25 xadvance=27 page=0 chnl=15 +char id=62 x=2 y=173 width=42 height=42 xoffset=-1 yoffset=19 xadvance=36 page=0 chnl=15 +char id=63 x=46 y=155 width=39 height=61 xoffset=0 yoffset=0 xadvance=35 page=0 chnl=15 +char id=64 x=87 y=167 width=58 height=53 xoffset=-1 yoffset=12 xadvance=54 page=0 chnl=15 +char id=65 x=147 y=169 width=47 height=47 xoffset=-2 yoffset=14 xadvance=41 page=0 chnl=15 +char id=66 x=196 y=169 width=47 height=46 xoffset=0 yoffset=14 xadvance=42 page=0 chnl=15 +char id=67 x=245 y=169 width=41 height=47 xoffset=-1 yoffset=14 xadvance=37 page=0 chnl=15 +char id=68 x=288 y=169 width=43 height=47 xoffset=0 yoffset=14 xadvance=39 page=0 chnl=15 +char id=69 x=333 y=169 width=43 height=46 xoffset=-2 yoffset=14 xadvance=39 page=0 chnl=15 +char id=70 x=378 y=169 width=40 height=46 xoffset=-2 yoffset=14 xadvance=35 page=0 chnl=15 +char id=71 x=420 y=169 width=41 height=46 xoffset=-2 yoffset=14 xadvance=37 page=0 chnl=15 +char id=72 x=463 y=167 width=43 height=48 xoffset=1 yoffset=12 xadvance=43 page=0 chnl=15 +char id=73 x=2 y=237 width=16 height=48 xoffset=1 yoffset=12 xadvance=15 page=0 chnl=15 +char id=74 x=20 y=239 width=25 height=46 xoffset=-2 yoffset=14 xadvance=21 page=0 chnl=15 +char id=75 x=47 y=238 width=45 height=49 xoffset=1 yoffset=14 xadvance=41 page=0 chnl=15 +char id=76 x=94 y=237 width=31 height=48 xoffset=1 yoffset=13 xadvance=28 page=0 chnl=15 +char id=77 x=127 y=239 width=51 height=46 xoffset=0 yoffset=14 xadvance=49 page=0 chnl=15 +char id=78 x=180 y=239 width=40 height=46 xoffset=0 yoffset=14 xadvance=39 page=0 chnl=15 +char id=79 x=222 y=239 width=51 height=46 xoffset=-2 yoffset=14 xadvance=45 page=0 chnl=15 +char id=80 x=275 y=239 width=44 height=46 xoffset=0 yoffset=14 xadvance=40 page=0 chnl=15 +char id=81 x=321 y=239 width=51 height=46 xoffset=-2 yoffset=14 xadvance=45 page=0 chnl=15 +char id=82 x=374 y=239 width=45 height=48 xoffset=0 yoffset=15 xadvance=41 page=0 chnl=15 +char id=83 x=421 y=238 width=34 height=48 xoffset=-2 yoffset=13 xadvance=28 page=0 chnl=15 +char id=84 x=457 y=239 width=41 height=47 xoffset=-2 yoffset=14 xadvance=36 page=0 chnl=15 +char id=85 x=2 y=306 width=46 height=46 xoffset=0 yoffset=15 xadvance=43 page=0 chnl=15 +char id=86 x=50 y=305 width=44 height=48 xoffset=-2 yoffset=13 xadvance=38 page=0 chnl=15 +char id=87 x=96 y=305 width=55 height=47 xoffset=-2 yoffset=13 xadvance=49 page=0 chnl=15 +char id=88 x=153 y=306 width=43 height=46 xoffset=-2 yoffset=14 xadvance=38 page=0 chnl=15 +char id=89 x=198 y=305 width=38 height=47 xoffset=-2 yoffset=13 xadvance=31 page=0 chnl=15 +char id=90 x=238 y=306 width=40 height=47 xoffset=-2 yoffset=14 xadvance=35 page=0 chnl=15 +char id=91 x=280 y=295 width=26 height=66 xoffset=1 yoffset=4 xadvance=24 page=0 chnl=15 +char id=92 x=308 y=293 width=37 height=61 xoffset=-4 yoffset=2 xadvance=29 page=0 chnl=15 +char id=93 x=347 y=295 width=26 height=66 xoffset=-2 yoffset=4 xadvance=22 page=0 chnl=15 +char id=94 x=375 y=294 width=28 height=17 xoffset=-1 yoffset=3 xadvance=24 page=0 chnl=15 +char id=95 x=405 y=346 width=49 height=15 xoffset=-1 yoffset=55 xadvance=45 page=0 chnl=15 +char id=96 x=456 y=295 width=20 height=17 xoffset=1 yoffset=3 xadvance=18 page=0 chnl=15 +char id=97 x=2 y=387 width=38 height=39 xoffset=-2 yoffset=22 xadvance=35 page=0 chnl=15 +char id=98 x=42 y=375 width=41 height=52 xoffset=1 yoffset=9 xadvance=38 page=0 chnl=15 +char id=99 x=85 y=387 width=38 height=39 xoffset=-2 yoffset=22 xadvance=34 page=0 chnl=15 +char id=100 x=125 y=375 width=41 height=52 xoffset=-2 yoffset=9 xadvance=38 page=0 chnl=15 +char id=101 x=168 y=387 width=38 height=39 xoffset=1 yoffset=22 xadvance=34 page=0 chnl=15 +char id=102 x=208 y=375 width=27 height=52 xoffset=1 yoffset=9 xadvance=23 page=0 chnl=15 +char id=103 x=237 y=387 width=41 height=52 xoffset=-2 yoffset=21 xadvance=38 page=0 chnl=15 +char id=104 x=280 y=375 width=37 height=51 xoffset=1 yoffset=9 xadvance=34 page=0 chnl=15 +char id=105 x=319 y=380 width=15 height=47 xoffset=2 yoffset=14 xadvance=16 page=0 chnl=15 +char id=106 x=336 y=378 width=25 height=60 xoffset=-6 yoffset=12 xadvance=18 page=0 chnl=15 +char id=107 x=363 y=375 width=40 height=51 xoffset=2 yoffset=9 xadvance=38 page=0 chnl=15 +char id=108 x=405 y=379 width=15 height=48 xoffset=1 yoffset=13 xadvance=16 page=0 chnl=15 +char id=109 x=422 y=387 width=47 height=39 xoffset=0 yoffset=22 xadvance=46 page=0 chnl=15 +char id=110 x=2 y=465 width=37 height=39 xoffset=0 yoffset=22 xadvance=34 page=0 chnl=15 +char id=111 x=41 y=465 width=41 height=40 xoffset=-1 yoffset=21 xadvance=37 page=0 chnl=15 +char id=112 x=84 y=465 width=41 height=52 xoffset=1 yoffset=22 xadvance=37 page=0 chnl=15 +char id=113 x=127 y=465 width=41 height=51 xoffset=-2 yoffset=22 xadvance=38 page=0 chnl=15 +char id=114 x=170 y=465 width=34 height=39 xoffset=1 yoffset=22 xadvance=30 page=0 chnl=15 +char id=115 x=206 y=462 width=37 height=42 xoffset=-2 yoffset=19 xadvance=31 page=0 chnl=15 +char id=116 x=245 y=453 width=36 height=52 xoffset=0 yoffset=9 xadvance=31 page=0 chnl=15 +char id=117 x=283 y=465 width=37 height=39 xoffset=0 yoffset=22 xadvance=35 page=0 chnl=15 +char id=118 x=322 y=463 width=35 height=41 xoffset=-2 yoffset=19 xadvance=28 page=0 chnl=15 +char id=119 x=359 y=463 width=51 height=41 xoffset=-2 yoffset=19 xadvance=44 page=0 chnl=15 +char id=120 x=412 y=465 width=35 height=40 xoffset=-2 yoffset=21 xadvance=29 page=0 chnl=15 +char id=121 x=449 y=465 width=37 height=52 xoffset=0 yoffset=22 xadvance=35 page=0 chnl=15 +char id=122 x=2 y=543 width=38 height=40 xoffset=-3 yoffset=21 xadvance=31 page=0 chnl=15 +char id=123 x=42 y=527 width=24 height=61 xoffset=-3 yoffset=5 xadvance=18 page=0 chnl=15 +char id=124 x=68 y=522 width=16 height=66 xoffset=1 yoffset=1 xadvance=15 page=0 chnl=15 +char id=125 x=86 y=527 width=24 height=61 xoffset=-1 yoffset=5 xadvance=18 page=0 chnl=15 +char id=126 x=112 y=526 width=32 height=16 xoffset=0 yoffset=4 xadvance=29 page=0 chnl=15 +char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=4 xadvance=29 page=0 chnl=15 \ No newline at end of file diff --git a/games/wave_collector/resources/font.png b/games/wave_collector/resources/font.png new file mode 100644 index 00000000..15287ccb Binary files /dev/null and b/games/wave_collector/resources/font.png differ diff --git a/games/wave_collector/resources/textures/background.png b/games/wave_collector/resources/textures/background.png new file mode 100644 index 00000000..f8613f82 Binary files /dev/null and b/games/wave_collector/resources/textures/background.png differ diff --git a/games/wave_collector/resources/textures/background_gameplay.png b/games/wave_collector/resources/textures/background_gameplay.png new file mode 100644 index 00000000..e4180288 Binary files /dev/null and b/games/wave_collector/resources/textures/background_gameplay.png differ diff --git a/games/wave_collector/resources/textures/background_title.png b/games/wave_collector/resources/textures/background_title.png new file mode 100644 index 00000000..01fc46d3 Binary files /dev/null and b/games/wave_collector/resources/textures/background_title.png differ diff --git a/games/wave_collector/resources/textures/icon_synchro.png b/games/wave_collector/resources/textures/icon_synchro.png new file mode 100644 index 00000000..b7172823 Binary files /dev/null and b/games/wave_collector/resources/textures/icon_synchro.png differ diff --git a/games/wave_collector/resources/textures/icon_warp.png b/games/wave_collector/resources/textures/icon_warp.png new file mode 100644 index 00000000..2a5eb7bb Binary files /dev/null and b/games/wave_collector/resources/textures/icon_warp.png differ diff --git a/games/wave_collector/resources/textures/line.png b/games/wave_collector/resources/textures/line.png new file mode 100644 index 00000000..6c338710 Binary files /dev/null and b/games/wave_collector/resources/textures/line.png differ diff --git a/games/wave_collector/resources/textures/logo_raylib.png b/games/wave_collector/resources/textures/logo_raylib.png new file mode 100644 index 00000000..99ba5437 Binary files /dev/null and b/games/wave_collector/resources/textures/logo_raylib.png differ diff --git a/games/wave_collector/resources/textures/lose.png b/games/wave_collector/resources/textures/lose.png new file mode 100644 index 00000000..f01c0284 Binary files /dev/null and b/games/wave_collector/resources/textures/lose.png differ diff --git a/games/wave_collector/resources/textures/player.png b/games/wave_collector/resources/textures/player.png new file mode 100644 index 00000000..c8913a8f Binary files /dev/null and b/games/wave_collector/resources/textures/player.png differ diff --git a/games/wave_collector/resources/textures/sample_big.png b/games/wave_collector/resources/textures/sample_big.png new file mode 100644 index 00000000..b4c4be97 Binary files /dev/null and b/games/wave_collector/resources/textures/sample_big.png differ diff --git a/games/wave_collector/resources/textures/sample_mid.png b/games/wave_collector/resources/textures/sample_mid.png new file mode 100644 index 00000000..20ec5868 Binary files /dev/null and b/games/wave_collector/resources/textures/sample_mid.png differ diff --git a/games/wave_collector/resources/textures/sample_small.png b/games/wave_collector/resources/textures/sample_small.png new file mode 100644 index 00000000..7b624f7f Binary files /dev/null and b/games/wave_collector/resources/textures/sample_small.png differ diff --git a/games/wave_collector/resources/textures/title.png b/games/wave_collector/resources/textures/title.png new file mode 100644 index 00000000..383dfdc3 Binary files /dev/null and b/games/wave_collector/resources/textures/title.png differ diff --git a/games/wave_collector/resources/textures/win.png b/games/wave_collector/resources/textures/win.png new file mode 100644 index 00000000..d7afdc25 Binary files /dev/null and b/games/wave_collector/resources/textures/win.png differ diff --git a/games/wave_collector/screens/screen_ending.c b/games/wave_collector/screens/screen_ending.c new file mode 100644 index 00000000..d246005c --- /dev/null +++ b/games/wave_collector/screens/screen_ending.c @@ -0,0 +1,111 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Ending Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Ending screen global variables +static int framesCounter; +static int finishScreen; + +static Texture2D texBackground; +static Texture2D texWin; +static Texture2D texLose; +static Texture2D texLogo; + +//---------------------------------------------------------------------------------- +// Ending Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Ending Screen Initialization logic +void InitEndingScreen(void) +{ + // TODO: Initialize ENDING screen variables here! + framesCounter = 0; + finishScreen = 0; + + texBackground = LoadTexture("resources/textures/background.png"); + texWin = LoadTexture("resources/textures/win.png"); + texLose = LoadTexture("resources/textures/lose.png"); + texLogo = LoadTexture("resources/textures/logo_raylib.png"); +} + +// Ending Screen Update logic +void UpdateEndingScreen(void) +{ + // TODO: Update ENDING screen variables here! + framesCounter++; + + // Press enter to return to TITLE screen + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + finishScreen = 1; + } +} + +// Ending Screen Draw logic +void DrawEndingScreen(void) +{ + DrawTexture(texBackground, 0, 0, WHITE); + + if (endingStatus == 1) // Win + { + DrawTexture(texWin, GetScreenWidth()/2 - texWin.width/2, 90, WHITE); + DrawTextEx(font, "congrats, you got the wave!", (Vector2){ 200, 335 }, font.size, 0, WHITE); + } + else if (endingStatus == 2) // Lose + { + DrawTexture(texLose, GetScreenWidth()/2 - texWin.width/2, 90, WHITE); + DrawTextEx(font, "it seems you lose the wave...", (Vector2){ 205, 335 }, font.size, 0, WHITE); + } + + DrawRectangle(0, GetScreenHeight() - 70, 560, 40, Fade(RAYWHITE, 0.8f)); + DrawText("(c) Developed by Ramon Santamaria (@raysan5)", 36, GetScreenHeight() - 60, 20, DARKBLUE); + + DrawText("powered by", GetScreenWidth() - 162, GetScreenHeight() - 190, 20, DARKGRAY); + DrawTexture(texLogo, GetScreenWidth() - 128 - 34, GetScreenHeight() - 128 - 36, WHITE); + + if ((framesCounter > 80) && ((framesCounter/40)%2)) DrawTextEx(font, "mouse click to return", (Vector2){ 300, 464 }, font.size, 0, SKYBLUE); +} + +// Ending Screen Unload logic +void UnloadEndingScreen(void) +{ + // TODO: Unload ENDING screen variables here! + UnloadTexture(texBackground); + UnloadTexture(texWin); + UnloadTexture(texLose); + UnloadTexture(texLogo); +} + +// Ending Screen should finish? +int FinishEndingScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_gameplay.c b/games/wave_collector/screens/screen_gameplay.c new file mode 100644 index 00000000..a3a9394a --- /dev/null +++ b/games/wave_collector/screens/screen_gameplay.c @@ -0,0 +1,490 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +#include // Required for: malloc(), free() +#include // Required for: sqrtf(), asinf() + +#define MAX_SAMPLES_SPEED 7 // Max speed for samples movement +#define MIN_SAMPLES_SPEED 3 // Min speed for samples movement +#define SAMPLES_SPACING 100 // Separation between samples in pixels +#define SAMPLES_MULTIPLIER 500 // Defines sample data scaling value (it would be adjusted to MAX_GAME_HEIGHT) +#define MAX_GAME_HEIGHT 400 // Defines max possible amplitude between samples (game area) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct Player { + Vector2 position; + Vector2 speed; + int width; + int height; + Color color; +} Player; + +typedef struct Sample { + float value; + Vector2 position; + int radius; + bool active; // Define if sample is active (can be collected) + bool collected; // Define if sample has been collected + bool renderable; // Define if sample should be rendered + Color color; +} Sample; + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Gameplay screen global variables +static int framesCounter; +static int finishScreen; +static bool pause; + +// Player variables +static Player player; +static Rectangle playerArea; // Define player movement area (and sample collection limits) + +static float warpCounter; // Time warp counter +static float synchro; // Calculates collected samples relation [0..1] + +//static int combo; +//static int maxCombo; + +static Rectangle waveRec; + +// Samples variables +static Sample *samples; // Game samples +static int totalSamples = 0; // Total game samples (proportional to waveData num samples) +static int collectedSamples; // Samples collected by player +static int currentSample; // Last sample to go through player collect area +static float samplesSpeed; // All samples move at the same speed +static float waveTime; // Total sample time in ms + +// Resources variables +static Texture2D texBackground; +static Texture2D texPlayer; +static Texture2D texSampleSmall; +static Texture2D texSampleMid; +static Texture2D texSampleBig; +static Texture2D texLine; + +//static RenderTexture2D waveTarget; + +static Sound fxSampleOn; // Collected sample sound +static Sound fxSampleOff; // Miss sample sound +static Sound fxWave; // Sound from wave sample +static Sound fxPause; // Pause sound +// Debug variables + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +//static void DrawWave(float *waveData, int sampleCount, Rectangle bounds, Color color); +//static void DrawWaveEx(float *waveData, int sampleCount, int playedSamples, Rectangle bounds, Color color); +static void DrawSamples(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color); + +//---------------------------------------------------------------------------------- +// Gameplay Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Gameplay Screen Initialization logic +void InitGameplayScreen(void) +{ + framesCounter = 0; + finishScreen = 0; + pause = false; + endingStatus = 0; + + // Textures loading + texBackground = LoadTexture("resources/textures/background_gameplay.png"); + texPlayer = LoadTexture("resources/textures/player.png"); + texSampleSmall = LoadTexture("resources/textures/sample_small.png"); + texSampleMid = LoadTexture("resources/textures/sample_mid.png"); + texSampleBig = LoadTexture("resources/textures/sample_big.png"); + texLine = LoadTexture("resources/textures/line.png"); + + waveRec = (Rectangle){ 32, 32, 1280 - 64, 105 }; + //RenderTexture2D waveTarget = LoadRenderTexture(waveRec.width, waveRec.height); + + // Sound loading + fxSampleOn = LoadSound("resources/audio/sample_on.wav"); + fxSampleOff = LoadSound("resources/audio/sample_off.wav"); + fxPause = LoadSound("resources/audio/pause.wav"); + + SetSoundVolume(fxSampleOn, 0.6f); + SetSoundVolume(fxPause, 0.5f); + + // Initialize player data + playerArea = (Rectangle){ 200, 160, 80, 400 }; + + player.width = 20; + player.height = 60; + player.speed = (Vector2){ 15, 15 }; + player.color = GOLD; + player.position = (Vector2){ playerArea.x + playerArea.width/2 - texPlayer.width/2, + playerArea.y + playerArea.height/2 - texPlayer.height/2 }; + + warpCounter = 395; + synchro = 0.2f; + + // Initialize wave and samples data + Wave wave = LoadWave("resources/audio/wave.ogg"); + float *waveData = GetWaveData(wave); + //printf("Wave total samples: %i\n", wave.sampleCount); + + // We calculate the required parameters to adjust audio time to gameplay time + // that way samples collected correspond to audio playing + // Synchonization is not perfect due to possible rounding issues (float to int) + waveTime = wave.sampleCount/wave.sampleRate; // Total sample time in seconds + float requiredSamples = (MAX_SAMPLES_SPEED*waveTime*60 - 1000)/SAMPLES_SPACING; + int samplesDivision = (int)(wave.sampleCount/requiredSamples); + + totalSamples = wave.sampleCount/samplesDivision; + + fxWave = LoadSoundFromWave(wave); + UnloadWave(wave); + + collectedSamples = 0; + + // Init samples + samples = (Sample *)malloc(totalSamples*sizeof(Sample)); + + // Normalize wave data (min vs max values) to scale properly + float minSampleValue = 0.0f; + float maxSampleValue = 0.0f; + + for (int i = 0; i < totalSamples; i++) + { + if (waveData[i*samplesDivision] < minSampleValue) minSampleValue = waveData[i*samplesDivision]; + if (waveData[i*samplesDivision] > maxSampleValue) maxSampleValue = waveData[i*samplesDivision]; + } + + float sampleScaleFactor = 1.0f/(maxSampleValue - minSampleValue); // 400 pixels maximum size + + // Initialize samples + for (int i = 0; i < totalSamples; i++) + { + samples[i].value = waveData[i*samplesDivision]*sampleScaleFactor; // Normalized value [-1.0..1.0] + samples[i].position.x = player.position.x + 1000 + i*SAMPLES_SPACING; + + samples[i].position.y = GetScreenHeight()/2 + samples[i].value*SAMPLES_MULTIPLIER; + + if (samples[i].position.y > GetScreenHeight()/2 + MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 - MAX_GAME_HEIGHT/2; + else if (samples[i].position.y < GetScreenHeight()/2 - MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 + MAX_GAME_HEIGHT/2; + + samples[i].radius = 6; + samples[i].active = true; + samples[i].collected = false; + samples[i].color = RED; + } + + samplesSpeed = MAX_SAMPLES_SPEED; + currentSample = 0; + + // We already saved the samples we needed for the game, we can free waveData + free(waveData); + + // Load and start playing music + // NOTE: Music is loaded in main code base + PlayMusicStream(music); +} + +// Gameplay Screen Update logic +void UpdateGameplayScreen(void) +{ + if (IsKeyPressed('P')) + { + PlaySound(fxPause); + pause = !pause; + + if (pause) PauseMusicStream(music); + else ResumeMusicStream(music); + } + + if (!pause) + { + framesCounter++; // Time starts counting to awake enemies + + // Player movement logic (mouse) + player.position.y = GetMousePosition().y; + + // Player movement logic (keyboard) + if (IsKeyDown(KEY_W)) player.position.y -= player.speed.y; + else if (IsKeyDown(KEY_S)) player.position.y += player.speed.y; + + // Player movement logic (gamepad) + /* + if (IsGamepadAvailable(GAMEPAD_PLAYER1)) + { + Vector2 movement = { 0.0f }; + + movement.x = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_X); + movement.y = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_Y); + + player.position.x += movement.x*0.1f; // Scale gamepad movement value + player.position.y += movement.y*0.1f; // Scale gamepad movement value + } + */ + + // Player logic: check player area limits + if (player.position.x < playerArea.x) player.position.x = playerArea.x; + else if ((player.position.x + player.width) > (playerArea.x + playerArea.width)) player.position.x = playerArea.x + playerArea.width - player.width; + + if (player.position.y < playerArea.y) player.position.y = playerArea.y; + else if ((player.position.y + player.height) > (playerArea.y + playerArea.height)) player.position.y = playerArea.y + playerArea.height - player.height; + + // Samples logic + for (int i = 0; i < totalSamples; i++) + { + // Samples movement logic + samples[i].position.x -= samplesSpeed; + + if (((samples[i].position.x + samples[i].radius) > -SAMPLES_SPACING) && + ((samples[i].position.x - samples[i].radius) < GetScreenWidth())) samples[i].renderable = true; + else samples[i].renderable = false; + + // Samples catch logic + if (!samples[i].collected && CheckCollisionCircleRec(samples[i].position, samples[i].radius, (Rectangle){ (int)player.position.x, (int)player.position.y, player.width, player.height })) + { + samples[i].collected = true; + collectedSamples++; + synchro += 0.02; + + if (synchro >= 1.0f) synchro = 1.0f; + + // Set sound pitch depending on sample position (base pitch: 1.0f) + // NOTE: waveData[i*WAVE_SAMPLES_DIV] is scaled to [0.3..1.7] + SetSoundPitch(fxSampleOn, samples[i].value*1.4f + 0.7f); + + PlaySound(fxSampleOn); + } + + if ((samples[i].position.x - samples[i].radius) < player.position.x) + { + currentSample = i; // Register last sample going out range + + if (samples[i].active) + { + samples[i].active = false; + + //PlaySound(fxSampleOff); + + if (!samples[i].collected) synchro -= 0.05f; + } + } + } + + if (IsKeyDown(KEY_SPACE) && (warpCounter > 0)) + { + warpCounter--; + if (warpCounter < 0) warpCounter = 0; + + samplesSpeed -= 0.1f; + if (samplesSpeed <= MIN_SAMPLES_SPEED) samplesSpeed = MIN_SAMPLES_SPEED; + + SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED); + } + else + { + warpCounter++; + if (warpCounter > 395) warpCounter = 395; + + samplesSpeed += 0.1f; + if (samplesSpeed >= MAX_SAMPLES_SPEED) samplesSpeed = MAX_SAMPLES_SPEED; + + SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED); + } + + // Check ending conditions + if (currentSample >= totalSamples) + { + StopMusicStream(music); + endingStatus = 1; // Win + finishScreen = 1; + } + + if (synchro <= 0.0f) + { + synchro = 0.0f; + StopMusicStream(music); + endingStatus = 2; // Loose + finishScreen = 1; + } + } +} + +// Gameplay Screen Draw logic +void DrawGameplayScreen(void) +{ + // Draw background + DrawTexture(texBackground, 0, 0, WHITE); + + // Screen elements drawing + //DrawRectangleLines(playerArea.x, playerArea.y, playerArea.width, playerArea.height, BLUE); + DrawRectangle(0, GetScreenHeight()/2 - 1, GetScreenWidth(), 2, Fade(BLUE, 0.3f)); + //DrawRectangleLines(0, GetScreenHeight()/2 - MAX_GAME_HEIGHT/2, GetScreenWidth(), MAX_GAME_HEIGHT, GRAY); + + // Draw samples + for (int i = 0; i < totalSamples - 1; i++) + { + if (samples[i].renderable) + { + Color col = samples[i].color; + + if (i < (currentSample + 1)) col = Fade(DARKGRAY, 0.5f); + else col = WHITE; + + //DrawCircleV(samples[i].position, samples[i].radius, col); + if (!samples[i].collected) + { + // TODO: Draw differnt size samples + DrawTexture(texSampleMid, samples[i].position.x - texSampleMid.width/2, samples[i].position.y - texSampleMid.height/2, col); + + } + + if (i < (currentSample + 1)) col = Fade(GRAY, 0.3f); + else col = Fade(WHITE, 0.5f); + + // Draw line between samples + //DrawLine(samples[i].position.x, samples[i].position.y, samples[i + 1].position.x, samples[i + 1].position.y, col); + + float dx = samples[i + 1].position.x - samples[i].position.x; + float dy = samples[i + 1].position.y - samples[i].position.y; + float d = sqrtf(dx*dx + dy*dy); + float angle = asinf(dy/d); + + // TODO: Draw lines using textures - IMPROVE! + //DrawTextureEx(texLine, (Vector2){ samples[i].position.x - 2, samples[i].position.y - 2 }, -RAD2DEG*angle, d/SAMPLES_SPACING, col); + + DrawTexturePro(texLine, (Rectangle){ 0, 0, texLine.width, texLine.height }, + (Rectangle){ samples[i].position.x, samples[i].position.y, (float)texLine.width*d/SAMPLES_SPACING, texLine.height }, + (Vector2){ 0, (float)texLine.height/2 }, -RAD2DEG*angle, col); + } + } + + // Draw player + //DrawRectangle((int)player.position.x, (int)player.position.y, player.width, player.height, player.color); + DrawTexture(texPlayer, player.position.x - 32, player.position.y - 24, WHITE); + + // Draw pause message + if (pause) DrawTextEx(font, "WAVE PAUSED", (Vector2){ 235, 400 }, font.size*2, 0, WHITE); + + // Draw number of samples + //DrawText(FormatText("%05i", collectedSamples), 900, 200, 40, GRAY); + //DrawText(FormatText("%05i", totalSamples), 900, 250, 40, GRAY); + DrawTextEx(font, FormatText("%05i / %05i", collectedSamples, totalSamples), (Vector2){810, 170}, font.size, -2, SKYBLUE); + + // Draw synchonicity level + DrawRectangle(99, 622, 395, 32, Fade(RAYWHITE, 0.8f)); + + if (synchro <= 0.3f) DrawRectangle(99, 622, synchro*395, 32, Fade(RED, 0.8f)); + else if (synchro <= 0.8f) DrawRectangle(99, 622, synchro*395, 32, Fade(ORANGE,0.8f)); + else if (synchro < 1.0f) DrawRectangle(99, 622, synchro*395, 32, Fade(LIME,0.8f)); + else DrawRectangle(99, 622, synchro*395, 32, Fade(GREEN, 0.9f)); + + DrawRectangleLines(99, 622, 395, 32, MAROON); + + if (synchro == 1.0f) DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.size, -2, GREEN); + else DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.size, -2, SKYBLUE); + + // Draw time warp coool-down bar + DrawRectangle(754, 622, 395, 32, Fade(RAYWHITE, 0.8f)); + DrawRectangle(754, 622, warpCounter, 32, Fade(SKYBLUE, 0.8f)); + DrawRectangleLines(754, 622, 395, 32, DARKGRAY); + //DrawText(FormatText("%02i%%", (int)(synchro*100)), 754 + 410, 628, 20, DARKGRAY); + DrawTextEx(font, FormatText("%02i%%", (int)((float)warpCounter/395.0f*100.0f)), (Vector2){754 + 390, 600}, font.size, -2, SKYBLUE); + + // Draw wave + // NOTE: Old drawing method, replaced by rendertarget + DrawSamples(samples, totalSamples, currentSample, waveRec, MAROON); + DrawRectangle(waveRec.x + (int)currentSample*1240/totalSamples, waveRec.y, 2, 99, DARKGRAY); + //DrawRectangleLines(20, 20, 1240, 140, DARKGRAY); + //DrawRectangle(20, 150, (float)currentSample/totalSamples*1240, 10, GRAY); + + // TODO: Draw wave using render target --> It FAILS! Need to review... + /* + BeginTextureMode(waveTarget); + DrawSamples(samples, totalSamples, currentSample, (Rectangle){ 0, 0, waveTarget.texture.width, waveTarget.texture.height }, MAROON); + EndTextureMode(); + + DrawTextureEx(waveTarget.texture, (Vector2){ waveRec.x, waveRec.y }, 0.0f, 1.0f, WHITE); + */ +} + +// Gameplay Screen Unload logic +void UnloadGameplayScreen(void) +{ + // Unload textures + UnloadTexture(texBackground); + UnloadTexture(texPlayer); + UnloadTexture(texSampleSmall); + UnloadTexture(texSampleMid); + UnloadTexture(texSampleBig); + UnloadTexture(texLine); + + //UnloadRenderTexture(waveTarget); + + // Unload sounds + UnloadSound(fxSampleOn); + UnloadSound(fxSampleOff); + UnloadSound(fxWave); + UnloadSound(fxPause); + + //free(samples); // Unload game samples (crashes game) +} + +// Gameplay Screen should finish? +int FinishGameplayScreen(void) +{ + return finishScreen; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Draw samples in wave form (including already played samples in a different color!) +// NOTE: For proper visualization, MSAA x4 is recommended, alternatively +// it should be rendered to a bigger texture and then scaled down with +// bilinear/trilinear texture filtering +static void DrawSamples(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color) +{ + // NOTE: We just pick a sample to draw every increment + float sampleIncrementX = (float)bounds.width/sampleCount; + + Color col = color; + + for (int i = 0; i < sampleCount - 1; i++) + { + if (i < playedSamples) col = GRAY; + else col = color; + + DrawLineV((Vector2){ (float)bounds.x + (float)i*sampleIncrementX, (float)(bounds.y + bounds.height/2) + samples[i].value*bounds.height }, + (Vector2){ (float)bounds.x + (float)(i + 1)*sampleIncrementX, (float)(bounds.y + bounds.height/2) + + samples[i + 1].value*bounds.height }, col); + } +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_logo.c b/games/wave_collector/screens/screen_logo.c new file mode 100644 index 00000000..e855752e --- /dev/null +++ b/games/wave_collector/screens/screen_logo.c @@ -0,0 +1,181 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Logo Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +#define LOGO_RECS_SIDE 16 + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Logo screen global variables +static int framesCounter; +static int finishScreen; + +static int logoPositionX; +static int logoPositionY; + +static int lettersCount; + +static int topSideRecWidth; +static int leftSideRecHeight; + +static int bottomSideRecWidth; +static int rightSideRecHeight; + +static int state; // Tracking animation states (State Machine) +static float alpha = 1.0f; // Useful for fading + +//---------------------------------------------------------------------------------- +// Logo Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Logo Screen Initialization logic +void InitLogoScreen(void) +{ + // Initialize LOGO screen variables here! + finishScreen = 0; + framesCounter = 0; + lettersCount = 0; + + logoPositionX = GetScreenWidth()/2 - 128; + logoPositionY = GetScreenHeight()/2 - 128; + + topSideRecWidth = LOGO_RECS_SIDE; + leftSideRecHeight = LOGO_RECS_SIDE; + bottomSideRecWidth = LOGO_RECS_SIDE; + rightSideRecHeight = LOGO_RECS_SIDE; + + state = 0; + alpha = 1.0f; +} + +// Logo Screen Update logic +void UpdateLogoScreen(void) +{ + // Update LOGO screen variables here! + if (state == 0) // State 0: Small box blinking + { + framesCounter++; + + if (framesCounter == 80) + { + state = 1; + framesCounter = 0; // Reset counter... will be used later... + + PlayMusicStream(music); // Start playing music... ;) + } + } + else if (state == 1) // State 1: Top and left bars growing + { + topSideRecWidth += 8; + leftSideRecHeight += 8; + + if (topSideRecWidth == 256) state = 2; + } + else if (state == 2) // State 2: Bottom and right bars growing + { + bottomSideRecWidth += 8; + rightSideRecHeight += 8; + + if (bottomSideRecWidth == 256) state = 3; + } + else if (state == 3) // State 3: Letters appearing (one by one) + { + framesCounter++; + + if (lettersCount < 10) + { + if (framesCounter/15) // Every 12 frames, one more letter! + { + lettersCount++; + framesCounter = 0; + } + } + else // When all letters have appeared, just fade out everything + { + if (framesCounter > 200) + { + alpha -= 0.02f; + + if (alpha <= 0.0f) + { + alpha = 0.0f; + finishScreen = 1; + } + } + } + } +} + +// Logo Screen Draw logic +void DrawLogoScreen(void) +{ + if (state == 0) + { + if ((framesCounter/10)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK); + } + else if (state == 1) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + } + else if (state == 2) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + + DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK); + } + else if (state == 3) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha)); + + DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)); + + DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); + + DrawText(SubText("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha)); + + if (framesCounter > 20) DrawText("powered by", logoPositionX, logoPositionY - 27, 20, Fade(DARKGRAY, alpha)); + } +} + +// Logo Screen Unload logic +void UnloadLogoScreen(void) +{ + // Unload LOGO screen variables here! +} + +// Logo Screen should finish? +int FinishLogoScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_title.c b/games/wave_collector/screens/screen_title.c new file mode 100644 index 00000000..1d33e3ba --- /dev/null +++ b/games/wave_collector/screens/screen_title.c @@ -0,0 +1,112 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Title Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Title screen global variables +static int framesCounter; +static int finishScreen; + +static Texture2D texBackground; +static Texture2D texTitle; +static Texture2D texLogo; + +static float titleAlpha = 0.0f; + +static Sound fxStart; + +//---------------------------------------------------------------------------------- +// Title Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Title Screen Initialization logic +void InitTitleScreen(void) +{ + // Initialize TITLE screen variables here! + framesCounter = 0; + finishScreen = 0; + + texBackground = LoadTexture("resources/textures/background_title.png"); + texTitle = LoadTexture("resources/textures/title.png"); + texLogo = LoadTexture("resources/textures/logo_raylib.png"); + + fxStart = LoadSound("resources/audio/start.wav"); +} + +// Title Screen Update logic +void UpdateTitleScreen(void) +{ + // Update TITLE screen variables here! + framesCounter++; + + titleAlpha += 0.005f; + + if (titleAlpha >= 1.0f) titleAlpha = 1.0f; + + // Press enter to change to ATTIC screen + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + PlaySound(fxStart); + StopMusicStream(music); + finishScreen = 1; + } +} + +// Title Screen Draw logic +void DrawTitleScreen(void) +{ + DrawTexture(texBackground, 0, 0, WHITE); + DrawTexture(texTitle, GetScreenWidth()/2 - texTitle.width/2, -25, Fade(WHITE, titleAlpha)); + + DrawRectangle(0, GetScreenHeight() - 70, 560, 40, Fade(RAYWHITE, 0.8f)); + DrawText("(c) Developed by Ramon Santamaria (@raysan5)", 36, GetScreenHeight() - 60, 20, DARKBLUE); + + DrawText("powered by", GetScreenWidth() - 162, GetScreenHeight() - 190, 20, DARKGRAY); + DrawTexture(texLogo, GetScreenWidth() - 128 - 34, GetScreenHeight() - 128 - 36, WHITE); + + if ((framesCounter > 160) && ((framesCounter/40)%2)) DrawTextEx(font, "mouse click to start", (Vector2){ 325, 500 }, font.size, 0, SKYBLUE); +} + +// Title Screen Unload logic +void UnloadTitleScreen(void) +{ + // Unload TITLE screen variables here! + UnloadTexture(texBackground); + UnloadTexture(texTitle); + UnloadTexture(texLogo); + + UnloadSound(fxStart); +} + +// Title Screen should finish? +int FinishTitleScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screens.h b/games/wave_collector/screens/screens.h new file mode 100644 index 00000000..9c9c5175 --- /dev/null +++ b/games/wave_collector/screens/screens.h @@ -0,0 +1,87 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Screens Functions Declarations (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef SCREENS_H +#define SCREENS_H + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO = 0, TITLE, GAMEPLAY, ENDING } GameScreen; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +GameScreen currentScreen; +SpriteFont font; +Music music; +int endingStatus; // 1 - Win, 2 - Lose +//char *sampleFilename; + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Logo Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitLogoScreen(void); +void UpdateLogoScreen(void); +void DrawLogoScreen(void); +void UnloadLogoScreen(void); +int FinishLogoScreen(void); + +//---------------------------------------------------------------------------------- +// Title Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitTitleScreen(void); +void UpdateTitleScreen(void); +void DrawTitleScreen(void); +void UnloadTitleScreen(void); +int FinishTitleScreen(void); + +//---------------------------------------------------------------------------------- +// Gameplay Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitGameplayScreen(void); +void UpdateGameplayScreen(void); +void DrawGameplayScreen(void); +void UnloadGameplayScreen(void); +int FinishGameplayScreen(void); + +//---------------------------------------------------------------------------------- +// Ending Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitEndingScreen(void); +void UpdateEndingScreen(void); +void DrawEndingScreen(void); +void UnloadEndingScreen(void); +int FinishEndingScreen(void); + +#ifdef __cplusplus +} +#endif + +#endif // SCREENS_H \ No newline at end of file diff --git a/games/wave_collector/wave_collector.c b/games/wave_collector/wave_collector.c new file mode 100644 index 00000000..8c271604 --- /dev/null +++ b/games/wave_collector/wave_collector.c @@ -0,0 +1,310 @@ +/******************************************************************************************* +* +* GLOBAL GAME JAM 2017 - WAVE COLLECTOR +* +* The ultimate wave particles collector is here! +* You must follow the wave and collect all the particles +* The level is actually the wave and the wave is the level! +* Be fast! Be smart! Be the best wave collector! +* +* This game has been created using raylib (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2017 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "screens/screens.h" // NOTE: Defines global variable: currentScreen + +#include + +#if defined(PLATFORM_WEB) + #include +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- +const int screenWidth = 1280; +const int screenHeight = 720; + +// Required variables to manage screen transitions (fade-in, fade-out) +float transAlpha = 0; +bool onTransition = false; +bool transFadeOut = false; +int transFromScreen = -1; +int transToScreen = -1; + +//---------------------------------------------------------------------------------- +// Local Functions Declaration +//---------------------------------------------------------------------------------- +void TransitionToScreen(int screen); +void ChangeToScreen(int screen); // No transition effect +void UpdateTransition(void); +void DrawTransition(void); + +void UpdateDrawFrame(void); // Update and Draw one frame + +//static const char *GetExtension(const char *fileName); + +//---------------------------------------------------------------------------------- +// Main entry point +//---------------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + // Initialization + //--------------------------------------------------------- + /* +#if !defined(PLATFORM_WEB) + // TODO: Add support for dropped files on the exe + sampleFilename = (char *)malloc(256); + if (argc > 1) + { + if ((strcmp(GetExtension(argv[1]), "ogg") == 0) || + (strcmp(GetExtension(argv[1]), "wav") == 0)) + { + strcpy(sampleFilename, argv[1]); + } + } +#endif + */ + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "GGJ17 - WAVE COLLECTOR"); + + // Global data loading (assets that must be available in all screens, i.e. fonts) + InitAudioDevice(); + + font = LoadSpriteFont("resources/font.fnt"); + music = LoadMusicStream("resources/audio/wave.ogg"); + + SetMusicVolume(music, 1.0f); + + // Setup and Init first screen + currentScreen = LOGO; + InitLogoScreen(); + //InitTitleScreen(); + //InitGameplayScreen(); + //InitEndingScreen(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + UpdateDrawFrame(); + } +#endif + + // De-Initialization + //-------------------------------------------------------------------------------------- + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + // Unload all global loaded data (i.e. fonts) here! + UnloadSpriteFont(font); + UnloadMusicStream(music); + + CloseAudioDevice(); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +void TransitionToScreen(int screen) +{ + onTransition = true; + transFromScreen = currentScreen; + transToScreen = screen; +} + +void ChangeToScreen(int screen) +{ + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + switch (screen) + { + case LOGO: InitLogoScreen(); break; + case TITLE: InitTitleScreen(); break; + case GAMEPLAY: InitGameplayScreen(); break; + case ENDING: InitEndingScreen(); break; + default: break; + } + + currentScreen = screen; +} + +void UpdateTransition(void) +{ + if (!transFadeOut) + { + transAlpha += 0.05f; + + if (transAlpha >= 1.0) + { + transAlpha = 1.0; + + switch (transFromScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + switch (transToScreen) + { + case LOGO: + { + InitLogoScreen(); + currentScreen = LOGO; + } break; + case TITLE: + { + InitTitleScreen(); + currentScreen = TITLE; + } break; + case GAMEPLAY: + { + InitGameplayScreen(); + currentScreen = GAMEPLAY; + } break; + case ENDING: + { + InitEndingScreen(); + currentScreen = ENDING; + } break; + default: break; + } + + transFadeOut = true; + } + } + else // Transition fade out logic + { + transAlpha -= 0.05f; + + if (transAlpha <= 0) + { + transAlpha = 0; + transFadeOut = false; + onTransition = false; + transFromScreen = -1; + transToScreen = -1; + } + } +} + +void DrawTransition(void) +{ + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, transAlpha)); +} + +// Update and draw game frame +void UpdateDrawFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + if (!onTransition) + { + switch(currentScreen) + { + case LOGO: + { + UpdateLogoScreen(); + + if (FinishLogoScreen()) TransitionToScreen(TITLE); + + } break; + case TITLE: + { + UpdateTitleScreen(); + + if (FinishTitleScreen() == 1) + { + StopMusicStream(music); + TransitionToScreen(GAMEPLAY); + } + + } break; + case GAMEPLAY: + { + UpdateGameplayScreen(); + + if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING); + //else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE); + + } break; + case ENDING: + { + UpdateEndingScreen(); + + if (FinishEndingScreen() == 1) TransitionToScreen(TITLE); + + } break; + default: break; + } + } + else + { + // Update transition (fade-in, fade-out) + UpdateTransition(); + } + + if (currentScreen != ENDING) UpdateMusicStream(music); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + switch(currentScreen) + { + case LOGO: DrawLogoScreen(); break; + case TITLE: DrawTitleScreen(); break; + case GAMEPLAY: DrawGameplayScreen(); break; + case ENDING: DrawEndingScreen(); break; + default: break; + } + + if (onTransition) DrawTransition(); + + //DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +/* +#if !defined(PLATFORM_WEB) +// Get the extension for a filename +static const char *GetExtension(const char *fileName) +{ + const char *dot = strrchr(fileName, '.'); + if (!dot || dot == fileName) return ""; + return (dot + 1); +} +#endif +*/ \ No newline at end of file diff --git a/release/html5/libraylib.bc b/release/html5/libraylib.bc index 4a7b8fa8..083a3c3d 100644 Binary files a/release/html5/libraylib.bc and b/release/html5/libraylib.bc differ diff --git a/release/html5/raylib.h b/release/html5/raylib.h index d28b07a3..a47d3c59 100644 --- a/release/html5/raylib.h +++ b/release/html5/raylib.h @@ -19,7 +19,7 @@ * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Custom color palette for fancy visuals on raywhite background * Minimal external dependencies (GLFW3, OpenGL, OpenAL) -* Complete binding for LUA [rlua] +* Complete binding for Lua [rlua] * * External libs: * GLFW3 (www.glfw.org) for window/context management and input [core] @@ -351,7 +351,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Image; // Texture2D type, bpp always RGBA (32bit) @@ -361,12 +361,12 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Texture2D; // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { - unsigned int id; // Render texture (fbo) id + unsigned int id; // OpenGL Framebuffer Object (FBO) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; @@ -491,6 +491,14 @@ typedef struct Ray { Vector3 direction; // Ray direction } Ray; +// Information returned from a raycast +typedef struct RayHitInfo { + bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit +} RayHitInfo; + // Wave type, defines audio wave data typedef struct Wave { unsigned int sampleCount; // Number of samples @@ -549,7 +557,7 @@ typedef enum { // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { +typedef enum { FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_BILINEAR, // Linear filtering FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) @@ -581,12 +589,12 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, - CAMERA_FREE, - CAMERA_ORBITAL, - CAMERA_FIRST_PERSON, - CAMERA_THIRD_PERSON +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON } CameraMode; // Head Mounted Display devices @@ -602,6 +610,26 @@ typedef enum { HMD_FOVE_VR, } VrDevice; +// rRES data returned when reading a resource, it contains all required data for user (24 byte) +typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) +} RRESData; + +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT +} RRESDataType; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -767,21 +795,19 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) +RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image @@ -794,7 +820,8 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, + float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint @@ -817,9 +844,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont -RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters @@ -855,41 +882,52 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) -RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -RLAPI void UnloadModel(Model model); // Unload 3d model from memory - -RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL) -RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM - -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file +RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data +RLAPI Model LoadModel(const char *fileName); // Load model from file +RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data +RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data +RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) +RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) + +RLAPI Material LoadMaterial(const char *fileName); // Load material from file +RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, + Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, + Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh +RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI char *LoadText(const char *fileName); // Load chars array from text file +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetStandardShader(void); // Get standard shader @@ -929,12 +967,11 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM -RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -RLAPI Sound LoadSound(const char *fileName); // Load sound to memory -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -964,7 +1001,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/release/win32/mingw32/libraylib.a b/release/win32/mingw32/libraylib.a index e0136aed..22d066aa 100644 Binary files a/release/win32/mingw32/libraylib.a and b/release/win32/mingw32/libraylib.a differ diff --git a/release/win32/raylib.h b/release/win32/raylib.h index d28b07a3..a47d3c59 100644 --- a/release/win32/raylib.h +++ b/release/win32/raylib.h @@ -19,7 +19,7 @@ * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Custom color palette for fancy visuals on raywhite background * Minimal external dependencies (GLFW3, OpenGL, OpenAL) -* Complete binding for LUA [rlua] +* Complete binding for Lua [rlua] * * External libs: * GLFW3 (www.glfw.org) for window/context management and input [core] @@ -351,7 +351,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Image; // Texture2D type, bpp always RGBA (32bit) @@ -361,12 +361,12 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Texture2D; // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { - unsigned int id; // Render texture (fbo) id + unsigned int id; // OpenGL Framebuffer Object (FBO) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; @@ -491,6 +491,14 @@ typedef struct Ray { Vector3 direction; // Ray direction } Ray; +// Information returned from a raycast +typedef struct RayHitInfo { + bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit +} RayHitInfo; + // Wave type, defines audio wave data typedef struct Wave { unsigned int sampleCount; // Number of samples @@ -549,7 +557,7 @@ typedef enum { // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { +typedef enum { FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_BILINEAR, // Linear filtering FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) @@ -581,12 +589,12 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, - CAMERA_FREE, - CAMERA_ORBITAL, - CAMERA_FIRST_PERSON, - CAMERA_THIRD_PERSON +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON } CameraMode; // Head Mounted Display devices @@ -602,6 +610,26 @@ typedef enum { HMD_FOVE_VR, } VrDevice; +// rRES data returned when reading a resource, it contains all required data for user (24 byte) +typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) +} RRESData; + +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT +} RRESDataType; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -767,21 +795,19 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) +RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image @@ -794,7 +820,8 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, + float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint @@ -817,9 +844,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont -RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters @@ -855,41 +882,52 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) -RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -RLAPI void UnloadModel(Model model); // Unload 3d model from memory - -RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL) -RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM - -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file +RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data +RLAPI Model LoadModel(const char *fileName); // Load model from file +RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data +RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data +RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) +RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) + +RLAPI Material LoadMaterial(const char *fileName); // Load material from file +RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, + Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, + Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh +RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI char *LoadText(const char *fileName); // Load chars array from text file +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetStandardShader(void); // Get standard shader @@ -929,12 +967,11 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM -RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -RLAPI Sound LoadSound(const char *fileName); // Load sound to memory -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -964,7 +1001,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/src/audio.c b/src/audio.c index 74a54b04..3b463df3 100644 --- a/src/audio.c +++ b/src/audio.c @@ -839,7 +839,13 @@ void SetMusicPitch(Music music, float pitch) { alSourcef(music->stream.source, AL_PITCH, pitch); } - +/* +// Set music speed +void SetMusicSpeed(Music music, float pitch) +{ + alSourcef(music->stream.source, AL_PITCH, 0.5f); +} +*/ // Get music time length (in seconds) float GetMusicTimeLength(Music music) { diff --git a/src/rlgl.h b/src/rlgl.h index b7c9df00..9cee39cc 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -97,7 +97,7 @@ // NOTE: This is the maximum amount of lines, triangles and quads per frame, be careful! #define MAX_LINES_BATCH 8192 #define MAX_TRIANGLES_BATCH 4096 - #define MAX_QUADS_BATCH 4096 + #define MAX_QUADS_BATCH 8192 #elif defined(GRAPHICS_API_OPENGL_ES2) // NOTE: Reduce memory sizes for embedded systems (RPI and HTML5) // NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care... -- cgit v1.2.3 From 825eab37e23658264361c0301e6e6a0dc7822428 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 24 Jan 2017 00:32:16 +0100 Subject: Revert unneeded change --- src/audio.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 3b463df3..74a54b04 100644 --- a/src/audio.c +++ b/src/audio.c @@ -839,13 +839,7 @@ void SetMusicPitch(Music music, float pitch) { alSourcef(music->stream.source, AL_PITCH, pitch); } -/* -// Set music speed -void SetMusicSpeed(Music music, float pitch) -{ - alSourcef(music->stream.source, AL_PITCH, 0.5f); -} -*/ + // Get music time length (in seconds) float GetMusicTimeLength(Music music) { -- cgit v1.2.3 From d8edcafe5a28a1b480acfa07714726ffe5b1a2bb Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 25 Jan 2017 11:38:15 +0100 Subject: Wait for events when window is minimized... ...instead of keep polling --- src/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 4d662a41..2917d839 100644 --- a/src/core.c +++ b/src/core.c @@ -494,7 +494,7 @@ bool WindowShouldClose(void) { #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) // While window minimized, stop loop execution - while (windowMinimized) glfwPollEvents(); + while (windowMinimized) glfwWaitEvents(); return (glfwWindowShouldClose(window)); #endif -- cgit v1.2.3 From 3c3a9318ffe34312bc6c08c10a68bae90ac20080 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Thu, 26 Jan 2017 20:58:00 +0100 Subject: Integrate Android build into Makefile --- src/Makefile | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 2e263189..fff3d436 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,7 +32,7 @@ .PHONY: all clean install unistall # define raylib platform to compile for -# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB +# possible platforms: PLATFORM_DESKTOP PLATFORM_ANDROID PLATFORM_RPI PLATFORM_WEB PLATFORM ?= PLATFORM_DESKTOP # define YES if you want shared/dynamic version of library instead of static (default) @@ -69,7 +69,24 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif +ifeq ($(PLATFORM),PLATFORM_ANDROID) + # path to Android NDK + ANDROID_NDK = $(ANDROID_NDK_HOME) + + # possible Android architectures: ARM ARM64 + ANDROID_ARCH ?= ARM + + # define YES to use clang instead of gcc + ANDROID_LLVM ?= NO + + # standalone Android toolchain install dir + ANDROID_TOOLCHAIN = $(CURDIR)/toolchain +endif + # define raylib graphics api depending on selected platform +ifeq ($(PLATFORM),PLATFORM_ANDROID) + GRAPHICS = GRAPHICS_API_OPENGL_ES2 +endif ifeq ($(PLATFORM),PLATFORM_RPI) # define raylib graphics api to use (on RPI, OpenGL ES 2.0 must be used) GRAPHICS = GRAPHICS_API_OPENGL_ES2 @@ -86,12 +103,41 @@ endif # NOTE: makefiles targets require tab indentation # define compiler: gcc for C program, define as g++ for C++ + +# default gcc compiler +CC = gcc + +ifeq ($(PLATFORM),PLATFORM_ANDROID) + ifeq ($(ANDROID_ARCH),ARM) + ifeq ($(ANDROID_LLVM),YES) + CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang + else + CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-gcc + endif + endif + ifeq ($(ANDROID_ARCH),ARM64) + ifeq ($(ANDROID_LLVM),YES) + CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang + else + CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-gcc + endif + endif +endif + ifeq ($(PLATFORM),PLATFORM_WEB) # emscripten compiler CC = emcc -else - # default gcc compiler - CC = gcc +endif + +AR = ar + +ifeq ($(PLATFORM),PLATFORM_ANDROID) + ifeq ($(ANDROID_ARCH),ARM) + AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar + endif + ifeq ($(ANDROID_ARCH),ARM64) + AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar + endif endif # define compiler flags: @@ -128,6 +174,15 @@ ifeq ($(PLATFORM),PLATFORM_RPI) INCLUDES = -I. -Iexternal -I/opt/vc/include \ -I/opt/vc/include/interface/vmcs_host/linux \ -I/opt/vc/include/interface/vcos/pthreads +endif +ifeq ($(PLATFORM),PLATFORM_ANDROID) +# STB libraries and others + INCLUDES = -I. -Iexternal +# OpenAL Soft library + INCLUDES += -Iexternal/openal_soft/include +# Android includes + INCLUDES += -I$(ANDROID_TOOLCHAIN)/sysroot/usr/include + INCLUDES += -I$(ANDROID_NDK)/sources/android/native_app_glue else # STB libraries and others INCLUDES = -I. -Iexternal @@ -149,6 +204,14 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) OUTPUT_PATH = ../release/osx endif endif +ifeq ($(PLATFORM),PLATFORM_ANDROID) + ifeq ($(ANDROID_ARCH),ARM) + OUTPUT_PATH = ../release/android/armeabi-v7a + endif + ifeq ($(ANDROID_ARCH),ARM64) + OUTPUT_PATH = ../release/android/arm64-v8a + endif +endif ifeq ($(PLATFORM),PLATFORM_WEB) OUTPUT_PATH = ../release/html5 endif @@ -164,7 +227,18 @@ OBJS += external/stb_vorbis.o # typing 'make' will invoke the default target entry called 'all', # in this case, the 'default' target entry is raylib -all: raylib +all: toolchain raylib + +# make standalone Android toolchain +toolchain: +ifeq ($(PLATFORM),PLATFORM_ANDROID) + ifeq ($(ANDROID_ARCH),ARM) + $(ANDROID_NDK)/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=arm-linux-androideabi-4.9 --use-llvm --install-dir=$(ANDROID_TOOLCHAIN) + endif + ifeq ($(ANDROID_ARCH),ARM64) + $(ANDROID_NDK)/build/tools/make-standalone-toolchain.sh --platform=android-21 --toolchain=aarch64-linux-androideabi-4.9 --use-llvm --install-dir=$(ANDROID_TOOLCHAIN) + endif +endif # compile raylib library raylib: $(OBJS) @@ -184,9 +258,13 @@ else $(CC) -shared -o $(OUTPUT_PATH)/raylib.dll $(OBJS) $(SHAREDLIBS) -Wl,--out-implib,$(OUTPUT_PATH)/libraylibdll.a @echo "raylib dynamic library (raylib.dll) and import library (libraylibdll.a) generated!" endif + ifeq ($(PLATFORM),PLATFORM_ANDROID) + $(CC) -shared -o $(OUTPUT_PATH)/libraylib.so $(OBJS) + @echo "raylib shared library (libraylib.so) generated!" + endif else - # compile raylib static library for desktop platforms. - ar rcs $(OUTPUT_PATH)/libraylib.a $(OBJS) + # compile raylib static library. + $(AR) rcs $(OUTPUT_PATH)/libraylib.a $(OBJS) @echo "libraylib.a generated (static library)!" ifeq ($(SHARED_OPENAL),NO) @echo "expected OpenAL Soft static library linking" @@ -283,5 +361,8 @@ ifeq ($(PLATFORM_OS),WINDOWS) del *.o $(OUTPUT_PATH)/libraylib.a $(OUTPUT_PATH)/libraylib.bc $(OUTPUT_PATH)/libraylib.so external/stb_vorbis.o else rm -f *.o $(OUTPUT_PATH)/libraylib.a $(OUTPUT_PATH)/libraylib.bc $(OUTPUT_PATH)/libraylib.so external/stb_vorbis.o +endif +ifeq ($(PLATFORM),PLATFORM_ANDROID) + rm -rf $(ANDROID_TOOLCHAIN) endif @echo "removed all generated files!" -- cgit v1.2.3 From a1527f56202c4967da80770c7f7609b7906f3977 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Thu, 26 Jan 2017 21:49:18 +0100 Subject: Fix RPi build and add missing directories --- src/Makefile | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index fff3d436..4c2278f5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -83,6 +83,10 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID) ANDROID_TOOLCHAIN = $(CURDIR)/toolchain endif +ifeq ($(PLATFORM),PLATFORM_RPI) + CROSS_COMPILE ?= NO +endif + # define raylib graphics api depending on selected platform ifeq ($(PLATFORM),PLATFORM_ANDROID) GRAPHICS = GRAPHICS_API_OPENGL_ES2 @@ -124,6 +128,13 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID) endif endif +ifeq ($(PLATFORM),PLATFORM_RPI) + ifeq ($(CROSS_COMPILE),YES) + # rpi compiler + CC = armv6j-hardfloat-linux-gnueabi-gcc + endif +endif + ifeq ($(PLATFORM),PLATFORM_WEB) # emscripten compiler CC = emcc @@ -170,11 +181,6 @@ endif #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes # define any directories containing required header files -ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDES = -I. -Iexternal -I/opt/vc/include \ - -I/opt/vc/include/interface/vmcs_host/linux \ - -I/opt/vc/include/interface/vcos/pthreads -endif ifeq ($(PLATFORM),PLATFORM_ANDROID) # STB libraries and others INCLUDES = -I. -Iexternal @@ -191,6 +197,16 @@ else # OpenAL Soft library INCLUDES += -Iexternal/openal_soft/include endif +ifeq ($(PLATFORM),PLATFORM_RPI) +# STB libraries and others + INCLUDES = -I. -Iexternal +# RPi libraries + INCLUDES += -I/opt/vc/include + INCLUDES += -I/opt/vc/include/interface/vmcs_host/linux + INCLUDES += -I/opt/vc/include/interface/vcos/pthreads +# OpenAL Soft library + INCLUDES += -Iexternal/openal_soft/include +endif # define output directory for compiled library ifeq ($(PLATFORM),PLATFORM_DESKTOP) -- cgit v1.2.3 From 37a64df7b9944d1d24872f07a7e713884b33432e Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 27 Jan 2017 23:03:08 +0100 Subject: Move lighting system out of raylib Lighting is implemented as a raylib example now --- examples/shaders_standard_lighting.c | 366 ++++++++++++++++++++++++++++++++++- src/models.c | 48 ----- src/raylib.h | 26 --- src/rlgl.c | 275 +------------------------- src/shader_standard.h | 173 ----------------- 5 files changed, 366 insertions(+), 522 deletions(-) delete mode 100644 src/shader_standard.h (limited to 'src') diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index 728bdae0..16cd7ff6 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -9,15 +9,79 @@ * on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders * raylib comes with shaders ready for both versions, check raylib/shaders install folder * -* This example has been created using raylib 1.3 (www.raylib.com) +* This example has been created using raylib 1.7 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2016 Ramon Santamaria (@raysan5) +* Copyright (c) 2016-2017 Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" +#include // Required for: NULL +#include // Required for: strcpy() +#include // Required for: vector math + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define MAX_LIGHTS 8 // Max lights supported by standard shader + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Light type +typedef struct LightData { + unsigned int id; // Light unique id + bool enabled; // Light enabled + int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT + + Vector3 position; // Light position + Vector3 target; // Light direction: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float radius; // Light attenuation radius light intensity reduced with distance (world distance) + + Color diffuse; // Light diffuse color + float intensity; // Light intensity level + + float coneAngle; // Light cone max angle: LIGHT_SPOT +} LightData, *Light; + +// Light types +typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static Light lights[MAX_LIGHTS]; // Lights pool +static int lightsCount = 0; // Enabled lights counter +static int lightsLocs[MAX_LIGHTS][8]; // Lights location points in shader: 8 possible points per light: + // enabled, type, position, target, radius, diffuse, intensity, coneAngle + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +static Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool +static void DestroyLight(Light light); // Destroy a light and take it out of the list +static void DrawLight(Light light); // Draw light in 3D world + +static void GetShaderLightsLocations(Shader shader); // Get shader locations for lights (up to MAX_LIGHTS) +static void SetShaderLightsValues(Shader shader); // Set shader uniform values for lights + +// Vector3 math functions +static float VectorLength(const Vector3 v); // Calculate vector lenght +static void VectorNormalize(Vector3 *v); // Normalize provided vector +static Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors + + +//https://www.gamedev.net/topic/655969-speed-gluniform-vs-uniform-buffer-objects/ +//https://www.reddit.com/r/opengl/comments/4ri20g/is_gluniform_more_expensive_than_glprogramuniform/ +//http://cg.alexandra.dk/?p=3778 - AZDO +//https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/BestPracticesforShaders/BestPracticesforShaders.html + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ int main() { // Initialization @@ -39,6 +103,9 @@ int main() material.shader = LoadShader("resources/shaders/glsl330/standard.vs", "resources/shaders/glsl330/standard.fs"); + // Try to get lights location points (if available) + GetShaderLightsLocations(material.shader); + material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture material.texSpecular = LoadTexture("resources/model/dwarf_specular.png"); // Load model specular texture @@ -64,6 +131,12 @@ int main() pointLight->intensity = 2.0f; pointLight->diffuse = (Color){100, 100, 255, 255}; pointLight->radius = 3.0f; + + // Set shader lights values for enabled lights + // NOTE: If values are not changed in real time, they can be set at initialization!!! + SetShaderLightsValues(material.shader); + + //SetShaderActive(0); // Setup orbital camera SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode @@ -115,8 +188,295 @@ int main() DestroyLight(dirLight); DestroyLight(spotLight); + // Unload lights + if (lightsCount > 0) + { + for (int i = 0; i < lightsCount; i++) free(lights[i]); + lightsCount = 0; + } + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} + +//-------------------------------------------------------------------------------------------- +// Module Functions Definitions +//-------------------------------------------------------------------------------------------- + +// Create a new light, initialize it and add to pool +Light CreateLight(int type, Vector3 position, Color diffuse) +{ + Light light = NULL; + + if (lightsCount < MAX_LIGHTS) + { + // Allocate dynamic memory + light = (Light)malloc(sizeof(LightData)); + + // Initialize light values with generic values + light->id = lightsCount; + light->type = type; + light->enabled = true; + + light->position = position; + light->target = (Vector3){ 0.0f, 0.0f, 0.0f }; + light->intensity = 1.0f; + light->diffuse = diffuse; + + // Add new light to the array + lights[lightsCount] = light; + + // Increase enabled lights count + lightsCount++; + } + else + { + // NOTE: Returning latest created light to avoid crashes + light = lights[lightsCount]; + } + + return light; +} + +// Destroy a light and take it out of the list +void DestroyLight(Light light) +{ + if (light != NULL) + { + int lightId = light->id; + + // Free dynamic memory allocation + free(lights[lightId]); + + // Remove *obj from the pointers array + for (int i = lightId; i < lightsCount; i++) + { + // Resort all the following pointers of the array + if ((i + 1) < lightsCount) + { + lights[i] = lights[i + 1]; + lights[i]->id = lights[i + 1]->id; + } + } + + // Decrease enabled physic objects count + lightsCount--; + } +} + +// Draw light in 3D world +void DrawLight(Light light) +{ + switch (light->type) + { + case LIGHT_POINT: + { + DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); + + DrawCircle3D(light->position, light->radius, (Vector3){ 0, 0, 0 }, 0.0f, (light->enabled ? light->diffuse : GRAY)); + DrawCircle3D(light->position, light->radius, (Vector3){ 1, 0, 0 }, 90.0f, (light->enabled ? light->diffuse : GRAY)); + DrawCircle3D(light->position, light->radius, (Vector3){ 0, 1, 0 },90.0f, (light->enabled ? light->diffuse : GRAY)); + } break; + case LIGHT_DIRECTIONAL: + { + DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); + + DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); + DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); + } break; + case LIGHT_SPOT: + { + DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); + + Vector3 dir = VectorSubtract(light->target, light->position); + VectorNormalize(&dir); + + DrawCircle3D(light->position, 0.5f, dir, 0.0f, (light->enabled ? light->diffuse : GRAY)); + + //DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : GRAY)); + DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); + } break; + default: break; + } +} + +// Get shader locations for lights (up to MAX_LIGHTS) +static void GetShaderLightsLocations(Shader shader) +{ + char locName[32] = "lights[x].\0"; + char locNameUpdated[64]; + + for (int i = 0; i < MAX_LIGHTS; i++) + { + locName[7] = '0' + i; + + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "enabled\0"); + lightsLocs[i][0] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "type\0"); + lightsLocs[i][1] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "position\0"); + lightsLocs[i][2] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "direction\0"); + lightsLocs[i][3] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "radius\0"); + lightsLocs[i][4] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "diffuse\0"); + lightsLocs[i][5] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "intensity\0"); + lightsLocs[i][6] = GetShaderLocation(shader, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "coneAngle\0"); + lightsLocs[i][7] = GetShaderLocation(shader, locNameUpdated); + } +} + +// Set shader uniform values for lights +// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0 +// TODO: Replace glUniform1i(), glUniform1f(), glUniform3f(), glUniform4f(): +//SetShaderValue(Shader shader, int uniformLoc, float *value, int size) +//SetShaderValuei(Shader shader, int uniformLoc, int *value, int size) +static void SetShaderLightsValues(Shader shader) +{ + int tempInt[8] = { 0 }; + float tempFloat[8] = { 0.0f }; + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (i < lightsCount) + { + tempInt[0] = lights[i]->enabled; + SetShaderValuei(shader, lightsLocs[i][0], tempInt, 1); //glUniform1i(lightsLocs[i][0], lights[i]->enabled); + + tempInt[0] = lights[i]->type; + SetShaderValuei(shader, lightsLocs[i][1], tempInt, 1); //glUniform1i(lightsLocs[i][1], lights[i]->type); + + tempFloat[0] = (float)lights[i]->diffuse.r/255.0f; + tempFloat[1] = (float)lights[i]->diffuse.g/255.0f; + tempFloat[2] = (float)lights[i]->diffuse.b/255.0f; + tempFloat[3] = (float)lights[i]->diffuse.a/255.0f; + SetShaderValue(shader, lightsLocs[i][5], tempFloat, 4); + //glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255); + + tempFloat[0] = lights[i]->intensity; + SetShaderValue(shader, lightsLocs[i][6], tempFloat, 1); + + switch (lights[i]->type) + { + case LIGHT_POINT: + { + tempFloat[0] = lights[i]->position.x; + tempFloat[1] = lights[i]->position.y; + tempFloat[2] = lights[i]->position.z; + SetShaderValue(shader, lightsLocs[i][2], tempFloat, 3); + + tempFloat[0] = lights[i]->radius; + SetShaderValue(shader, lightsLocs[i][4], tempFloat, 1); + + //glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + //glUniform1f(lightsLocs[i][4], lights[i]->radius); + } break; + case LIGHT_DIRECTIONAL: + { + Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); + VectorNormalize(&direction); + + tempFloat[0] = direction.x; + tempFloat[1] = direction.y; + tempFloat[2] = direction.z; + SetShaderValue(shader, lightsLocs[i][3], tempFloat, 3); + + //glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); + } break; + case LIGHT_SPOT: + { + tempFloat[0] = lights[i]->position.x; + tempFloat[1] = lights[i]->position.y; + tempFloat[2] = lights[i]->position.z; + SetShaderValue(shader, lightsLocs[i][2], tempFloat, 3); + + //glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + + Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); + VectorNormalize(&direction); + + tempFloat[0] = direction.x; + tempFloat[1] = direction.y; + tempFloat[2] = direction.z; + SetShaderValue(shader, lightsLocs[i][3], tempFloat, 3); + //glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); + + tempFloat[0] = lights[i]->coneAngle; + SetShaderValue(shader, lightsLocs[i][7], tempFloat, 1); + //glUniform1f(lightsLocs[i][7], lights[i]->coneAngle); + } break; + default: break; + } + } + else + { + tempInt[0] = 0; + SetShaderValuei(shader, lightsLocs[i][0], tempInt, 1); //glUniform1i(lightsLocs[i][0], 0); // Light disabled + } + } +} + +// Calculate vector lenght +float VectorLength(const Vector3 v) +{ + float length; + + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + + return length; +} + +// Normalize provided vector +void VectorNormalize(Vector3 *v) +{ + float length, ilength; + + length = VectorLength(*v); + + if (length == 0.0f) length = 1.0f; + + ilength = 1.0f/length; + + v->x *= ilength; + v->y *= ilength; + v->z *= ilength; +} + +// Substract two vectors +Vector3 VectorSubtract(Vector3 v1, Vector3 v2) +{ + Vector3 result; + + result.x = v1.x - v2.x; + result.y = v1.y - v2.y; + result.z = v1.z - v2.z; + + return result; +} diff --git a/src/models.c b/src/models.c index 0673874b..23c2e6fd 100644 --- a/src/models.c +++ b/src/models.c @@ -574,43 +574,6 @@ void DrawGizmo(Vector3 position) rlPopMatrix(); } - -// Draw light in 3D world -void DrawLight(Light light) -{ - switch (light->type) - { - case LIGHT_POINT: - { - DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); - - DrawCircle3D(light->position, light->radius, (Vector3){ 0, 0, 0 }, 0.0f, (light->enabled ? light->diffuse : GRAY)); - DrawCircle3D(light->position, light->radius, (Vector3){ 1, 0, 0 }, 90.0f, (light->enabled ? light->diffuse : GRAY)); - DrawCircle3D(light->position, light->radius, (Vector3){ 0, 1, 0 },90.0f, (light->enabled ? light->diffuse : GRAY)); - } break; - case LIGHT_DIRECTIONAL: - { - DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); - - DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); - DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); - } break; - case LIGHT_SPOT: - { - DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); - - Vector3 dir = VectorSubtract(light->target, light->position); - VectorNormalize(&dir); - - DrawCircle3D(light->position, 0.5f, dir, 0.0f, (light->enabled ? light->diffuse : GRAY)); - - //DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : GRAY)); - DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); - } break; - default: break; - } -} - // Load mesh from file Mesh LoadMesh(const char *fileName) { @@ -751,17 +714,6 @@ Material LoadDefaultMaterial(void) return material; } -// Load standard material (uses material attributes and lighting shader) -// NOTE: Standard shader supports multiple maps and lights -Material LoadStandardMaterial(void) -{ - Material material = LoadDefaultMaterial(); - - material.shader = GetStandardShader(); - - return material; -} - // Unload material from memory void UnloadMaterial(Material material) { diff --git a/src/raylib.h b/src/raylib.h index a47d3c59..f8f17eec 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -12,7 +12,6 @@ * Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF) * Multiple textures support, including compressed formats and mipmaps generation * Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps -* Materials (diffuse, normal, specular) and Lighting (point, directional, spot) support * Powerful math module for Vector, Matrix and Quaternion operations: [raymath] * Audio loading and playing with streaming support and mixing channels [audio] * VR stereo rendering support with configurable HMD device parameters @@ -466,25 +465,6 @@ typedef struct Model { Material material; // Shader and textures data } Model; -// Light type -typedef struct LightData { - unsigned int id; // Light unique id - bool enabled; // Light enabled - int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - - Vector3 position; // Light position - Vector3 target; // Light direction: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) - float radius; // Light attenuation radius light intensity reduced with distance (world distance) - - Color diffuse; // Light diffuse color - float intensity; // Light intensity level - - float coneAngle; // Light cone max angle: LIGHT_SPOT -} LightData, *Light; - -// Light types -typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType; - // Ray type (useful for raycast) typedef struct Ray { Vector3 position; // Ray position (origin) @@ -876,7 +856,6 @@ RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) RLAPI void DrawGizmo(Vector3 position); // Draw simple gizmo -RLAPI void DrawLight(Light light); // Draw light in 3D world //DrawTorus(), DrawTeapot() could be useful? //------------------------------------------------------------------------------------ @@ -894,7 +873,6 @@ RLAPI void UnloadModel(Model model); RLAPI Material LoadMaterial(const char *fileName); // Load material from file RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) @@ -930,7 +908,6 @@ RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Loa RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader -RLAPI Shader GetStandardShader(void); // Get standard shader RLAPI Texture2D GetDefaultTexture(void); // Get default texture RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location @@ -946,9 +923,6 @@ RLAPI void EndShaderMode(void); // End RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) -RLAPI Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool -RLAPI void DestroyLight(Light light); // Destroy a light and take it out of the list - //------------------------------------------------------------------------------------ // VR experience Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 diff --git a/src/rlgl.c b/src/rlgl.c index bcbca227..8ec867eb 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -22,7 +22,6 @@ * GRAPHICS_API_OPENGL_ES2 - Use OpenGL ES 2.0 backend * * RLGL_STANDALONE - Use rlgl as standalone library (no raylib dependency) -* RLGL_NO_STANDARD_SHADER - Avoid standard shader (shader_standard.h) inclusion * RLGL_NO_DISTORTION_SHADER - Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion * RLGL_OCULUS_SUPPORT - Enable Oculus Rift CV1 functionality * @@ -92,10 +91,6 @@ #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif -#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_STANDARD_SHADER) - #include "shader_standard.h" // Standard shader to be embedded -#endif - #if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_DISTORTION_SHADER) #include "shader_distortion.h" // Distortion shader to be embedded #endif @@ -118,8 +113,6 @@ #define MAX_DRAWS_BY_TEXTURE 256 // Draws are organized by texture changes #define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations) // NOTE: Every vertex are 3 floats (12 bytes) - -#define MAX_LIGHTS 8 // Max lights supported by standard shader #ifndef GL_SHADING_LANGUAGE_VERSION #define GL_SHADING_LANGUAGE_VERSION 0x8B8C @@ -305,10 +298,7 @@ static bool useTempBuffer = false; // Shader Programs static Shader defaultShader; // Basic shader, support vertex color and diffuse texture -static Shader standardShader; // Shader with support for lighting and materials - // NOTE: Lazy initialization when GetStandardShader() static Shader currentShader; // Shader to be used on rendering (by default, defaultShader) -static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded // Extension supported flag: VAO static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) @@ -368,12 +358,6 @@ static unsigned int whiteTexture; static int screenWidth; // Default framebuffer width static int screenHeight; // Default framebuffer height -// Lighting data -static Light lights[MAX_LIGHTS]; // Lights pool -static int lightsCount = 0; // Enabled lights counter -static int lightsLocs[MAX_LIGHTS][8]; // Lights location points in shader: 8 possible points per light: - // enabled, type, position, target, radius, diffuse, intensity, coneAngle - //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- @@ -382,10 +366,8 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr); // Load custom shader strings and return program id static Shader LoadDefaultShader(void); // Load default shader (just vertex positioning and texture coloring) -static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting) static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms) static void UnloadDefaultShader(void); // Unload default shader -static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data @@ -397,9 +379,6 @@ static void SetStereoConfig(VrDeviceInfo info); // Set internal projection and modelview matrix depending on eyes tracking data static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); - -static void GetShaderLightsLocations(Shader shader); // Get shader locations for lights (up to MAX_LIGHTS) -static void SetShaderLightsValues(Shader shader); // Set shader uniform values for lights #endif #if defined(RLGL_OCULUS_SUPPORT) @@ -1328,19 +1307,11 @@ void rlglClose(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) UnloadDefaultShader(); - UnloadStandardShader(); UnloadDefaultBuffers(); // Delete default white texture glDeleteTextures(1, &whiteTexture); TraceLog(INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", whiteTexture); - - // Unload lights - if (lightsCount > 0) - { - for (int i = 0; i < lightsCount; i++) free(lights[i]); - lightsCount = 0; - } free(draws); #endif @@ -2003,8 +1974,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.normals != NULL) glNormalPointer(GL_FLOAT, 0, mesh.normals); // Pointer to normals array if (mesh.colors != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors); // Pointer to colors array - // TODO: Support OpenGL 1.1 lighting system - rlPushMatrix(); rlMultMatrixf(MatrixToFloat(transform)); rlColor4ub(material.colDiffuse.r, material.colDiffuse.g, material.colDiffuse.b, material.colDiffuse.a); @@ -2070,10 +2039,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Check if glossiness is located in shader and upload value int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness"); if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness); - - // Set shader lights values for enabled lights - // NOTE: Lights array location points are obtained on shader loading (if available) - if (lightsCount > 0) SetShaderLightsValues(material.shader); } // Set shader textures (diffuse, normal, specular) @@ -2528,25 +2493,6 @@ Shader GetDefaultShader(void) #endif } -// Get default shader -// NOTE: Inits global variable standardShader -Shader GetStandardShader(void) -{ - Shader shader = { 0 }; - -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (standardShaderLoaded) shader = standardShader; - else - { - // Lazy initialization of standard shader - standardShader = LoadStandardShader(); - shader = standardShader; - } -#endif - - return shader; -} - // Get shader uniform location int GetShaderLocation(Shader shader, const char *uniformName) { @@ -2571,7 +2517,7 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) else if (size == 4) glUniform4fv(uniformLoc, 1, value); // Shader uniform type: vec4 else TraceLog(WARNING, "Shader value float array size not supported"); - glUseProgram(0); + //glUseProgram(0); // Avoid reseting current shader program, in case other uniforms are set #endif } @@ -2587,7 +2533,7 @@ void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size) else if (size == 4) glUniform4iv(uniformLoc, 1, value); // Shader uniform type: ivec4 else TraceLog(WARNING, "Shader value int array size not supported"); - glUseProgram(0); + //glUseProgram(0); #endif } @@ -2599,7 +2545,7 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat) glUniformMatrix4fv(uniformLoc, 1, false, MatrixToFloat(mat)); - glUseProgram(0); + //glUseProgram(0); #endif } @@ -2645,73 +2591,6 @@ void EndBlendMode(void) BeginBlendMode(BLEND_ALPHA); } -// Create a new light, initialize it and add to pool -Light CreateLight(int type, Vector3 position, Color diffuse) -{ - Light light = NULL; - - if (lightsCount < MAX_LIGHTS) - { - // Allocate dynamic memory - light = (Light)malloc(sizeof(LightData)); - - // Initialize light values with generic values - light->id = lightsCount; - light->type = type; - light->enabled = true; - - light->position = position; - light->target = (Vector3){ 0.0f, 0.0f, 0.0f }; - light->intensity = 1.0f; - light->diffuse = diffuse; - - // Add new light to the array - lights[lightsCount] = light; - - // Increase enabled lights count - lightsCount++; - } - else - { - TraceLog(WARNING, "Too many lights, only supported up to %i lights", MAX_LIGHTS); - - // NOTE: Returning latest created light to avoid crashes - light = lights[lightsCount]; - } - -#if defined(GRAPHICS_API_OPENGL_11) - TraceLog(WARNING, "Lighting currently not supported on OpenGL 1.1"); -#endif - - return light; -} - -// Destroy a light and take it out of the list -void DestroyLight(Light light) -{ - if (light != NULL) - { - int lightId = light->id; - - // Free dynamic memory allocation - free(lights[lightId]); - - // Remove *obj from the pointers array - for (int i = lightId; i < lightsCount; i++) - { - // Resort all the following pointers of the array - if ((i + 1) < lightsCount) - { - lights[i] = lights[i + 1]; - lights[i]->id = lights[i + 1]->id; - } - } - - // Decrease enabled physic objects count - lightsCount--; - } -} - // Init VR device (or simulator) // NOTE: If device is not available, it fallbacks to default device (simulator) // NOTE: It modifies the global variable: VrDeviceInfo hmd @@ -3209,39 +3088,6 @@ static Shader LoadDefaultShader(void) return shader; } -// Load standard shader -// NOTE: This shader supports: -// - Up to 3 different maps: diffuse, normal, specular -// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness -// - Up to 8 lights: Point, Directional or Spot -static Shader LoadStandardShader(void) -{ - Shader shader; - -#if !defined(RLGL_NO_STANDARD_SHADER) - // Load standard shader (embeded in standard_shader.h) - shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr); - - if (shader.id != 0) - { - LoadDefaultShaderLocations(&shader); - TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); - - standardShaderLoaded = true; - } - else - { - TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded, using default shader", shader.id); - shader = GetDefaultShader(); - } -#else - shader = GetDefaultShader(); - TraceLog(WARNING, "[SHDR ID %i] Standard shader not available, using default shader", shader.id); -#endif - - return shader; -} - // Get location handlers to for shader attributes and uniforms // NOTE: If any location is not found, loc point becomes -1 static void LoadDefaultShaderLocations(Shader *shader) @@ -3275,9 +3121,6 @@ static void LoadDefaultShaderLocations(Shader *shader) shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2"); // TODO: Try to find all expected/recognized shader locations (predefined names, must be documented) - - // Try to get lights location points (if available) - GetShaderLightsLocations(*shader); } // Unload default shader @@ -3292,20 +3135,6 @@ static void UnloadDefaultShader(void) glDeleteProgram(defaultShader.id); } -// Unload standard shader -static void UnloadStandardShader(void) -{ - glUseProgram(0); -#if !defined(RLGL_NO_STANDARD_SHADER) - //glDetachShader(defaultShader, vertexShader); - //glDetachShader(defaultShader, fragmentShader); - //glDeleteShader(vertexShader); // Already deleted on shader compilation - //glDeleteShader(fragmentShader); // Already deleted on shader compilation - glDeleteProgram(standardShader.id); -#endif -} - - // Load default internal buffers (lines, triangles, quads) static void LoadDefaultBuffers(void) { @@ -3763,104 +3592,6 @@ static void UnloadDefaultBuffers(void) free(quads.indices); } -// Get shader locations for lights (up to MAX_LIGHTS) -static void GetShaderLightsLocations(Shader shader) -{ - char locName[32] = "lights[x].\0"; - char locNameUpdated[64]; - - for (int i = 0; i < MAX_LIGHTS; i++) - { - locName[7] = '0' + i; - - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "enabled\0"); - lightsLocs[i][0] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "type\0"); - lightsLocs[i][1] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "position\0"); - lightsLocs[i][2] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "direction\0"); - lightsLocs[i][3] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "radius\0"); - lightsLocs[i][4] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "diffuse\0"); - lightsLocs[i][5] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "intensity\0"); - lightsLocs[i][6] = glGetUniformLocation(shader.id, locNameUpdated); - - locNameUpdated[0] = '\0'; - strcpy(locNameUpdated, locName); - strcat(locNameUpdated, "coneAngle\0"); - lightsLocs[i][7] = glGetUniformLocation(shader.id, locNameUpdated); - } -} - -// Set shader uniform values for lights -// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0 -static void SetShaderLightsValues(Shader shader) -{ - for (int i = 0; i < MAX_LIGHTS; i++) - { - if (i < lightsCount) - { - glUniform1i(lightsLocs[i][0], lights[i]->enabled); - - glUniform1i(lightsLocs[i][1], lights[i]->type); - glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255); - glUniform1f(lightsLocs[i][6], lights[i]->intensity); - - switch (lights[i]->type) - { - case LIGHT_POINT: - { - glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); - glUniform1f(lightsLocs[i][4], lights[i]->radius); - } break; - case LIGHT_DIRECTIONAL: - { - Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); - VectorNormalize(&direction); - glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); - } break; - case LIGHT_SPOT: - { - glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); - - Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); - VectorNormalize(&direction); - glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); - - glUniform1f(lightsLocs[i][7], lights[i]->coneAngle); - } break; - default: break; - } - } - else - { - glUniform1i(lightsLocs[i][0], 0); // Light disabled - } - } -} - // Configure stereo rendering (including distortion shader) with HMD device parameters static void SetStereoConfig(VrDeviceInfo hmd) { diff --git a/src/shader_standard.h b/src/shader_standard.h deleted file mode 100644 index 995c62ea..00000000 --- a/src/shader_standard.h +++ /dev/null @@ -1,173 +0,0 @@ - -// Vertex shader definition to embed, no external file required -static const char vStandardShaderStr[] = -#if defined(GRAPHICS_API_OPENGL_21) -"#version 120 \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) -"#version 100 \n" -#endif -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -"attribute vec3 vertexPosition; \n" -"attribute vec3 vertexNormal; \n" -"attribute vec2 vertexTexCoord; \n" -"attribute vec4 vertexColor; \n" -"varying vec3 fragPosition; \n" -"varying vec3 fragNormal; \n" -"varying vec2 fragTexCoord; \n" -"varying vec4 fragColor; \n" -#elif defined(GRAPHICS_API_OPENGL_33) -"#version 330 \n" -"in vec3 vertexPosition; \n" -"in vec3 vertexNormal; \n" -"in vec2 vertexTexCoord; \n" -"in vec4 vertexColor; \n" -"out vec3 fragPosition; \n" -"out vec3 fragNormal; \n" -"out vec2 fragTexCoord; \n" -"out vec4 fragColor; \n" -#endif -"uniform mat4 mvpMatrix; \n" -"void main() \n" -"{ \n" -" fragPosition = vertexPosition; \n" -" fragNormal = vertexNormal; \n" -" fragTexCoord = vertexTexCoord; \n" -" fragColor = vertexColor; \n" -" gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n" -"} \n"; - -// Fragment shader definition to embed, no external file required -static const char fStandardShaderStr[] = -#if defined(GRAPHICS_API_OPENGL_21) -"#version 120 \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) -"#version 100 \n" -"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) -#endif -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -"varying vec3 fragPosition; \n" -"varying vec3 fragNormal; \n" -"varying vec2 fragTexCoord; \n" -"varying vec4 fragColor; \n" -#elif defined(GRAPHICS_API_OPENGL_33) -"#version 330 \n" -"in vec3 fragPosition; \n" -"in vec3 fragNormal; \n" -"in vec2 fragTexCoord; \n" -"in vec4 fragColor; \n" -"out vec4 finalColor; \n" -#endif -"uniform sampler2D texture0; \n" -"uniform sampler2D texture1; \n" -"uniform sampler2D texture2; \n" -"uniform vec4 colAmbient; \n" -"uniform vec4 colDiffuse; \n" -"uniform vec4 colSpecular; \n" -"uniform float glossiness; \n" -"uniform int useNormal; \n" -"uniform int useSpecular; \n" -"uniform mat4 modelMatrix; \n" -"uniform vec3 viewDir; \n" -"struct Light { \n" -" int enabled; \n" -" int type; \n" -" vec3 position; \n" -" vec3 direction; \n" -" vec4 diffuse; \n" -" float intensity; \n" -" float radius; \n" -" float coneAngle; }; \n" -"const int maxLights = 8; \n" -"uniform Light lights[maxLights]; \n" -"\n" -"vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) \n" -"{\n" -" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n" -" vec3 surfaceToLight = l.position - surfacePos;\n" -" float brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0);\n" -" float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;\n" -" float spec = 0.0;\n" -" if (diff > 0.0)\n" -" {\n" -" vec3 h = normalize(-l.direction + v);\n" -" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" -" }\n" -" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n" -"}\n" -"\n" -"vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)\n" -"{\n" -" vec3 lightDir = normalize(-l.direction);\n" -" float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;\n" -" float spec = 0.0;\n" -" if (diff > 0.0)\n" -" {\n" -" vec3 h = normalize(lightDir + v);\n" -" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" -" }\n" -" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n" -"}\n" -"\n" -"vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)\n" -"{\n" -" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0));\n" -" vec3 lightToSurface = normalize(surfacePos - l.position);\n" -" vec3 lightDir = normalize(-l.direction);\n" -" float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;\n" -" float attenuation = clamp(float(dot(n, lightToSurface)), 0.0, 1.0);\n" -" attenuation = dot(lightToSurface, -lightDir);\n" -" float lightToSurfaceAngle = degrees(acos(attenuation));\n" -" if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;\n" -" float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;\n" -" float diffAttenuation = diff*attenuation;\n" -" float spec = 0.0;\n" -" if (diffAttenuation > 0.0)\n" -" {\n" -" vec3 h = normalize(lightDir + v);\n" -" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" -" }\n" -" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n" -"}\n" -"\n" -"void main()\n" -"{\n" -" mat3 normalMatrix = mat3(modelMatrix);\n" -" vec3 normal = normalize(normalMatrix*fragNormal);\n" -" vec3 n = normalize(normal);\n" -" vec3 v = normalize(viewDir);\n" -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -" vec4 texelColor = texture2D(texture0, fragTexCoord);\n" -#elif defined(GRAPHICS_API_OPENGL_33) -" vec4 texelColor = texture(texture0, fragTexCoord);\n" -#endif -" vec3 lighting = colAmbient.rgb;\n" -" if (useNormal == 1)\n" -" {\n" -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -" n *= texture2D(texture1, fragTexCoord).rgb;\n" -#elif defined(GRAPHICS_API_OPENGL_33) -" n *= texture(texture1, fragTexCoord).rgb;\n" -#endif -" n = normalize(n);\n" -" }\n" -" float spec = 1.0;\n" -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -" if (useSpecular == 1) spec = texture2D(texture2, fragTexCoord).r;\n" -#elif defined(GRAPHICS_API_OPENGL_33) -" if (useSpecular == 1) spec = texture(texture2, fragTexCoord).r;\n" -#endif -" for (int i = 0; i < maxLights; i++)\n" -" {\n" -" if (lights[i].enabled == 1)\n" -" {\n" -" if(lights[i].type == 0) lighting += CalcPointLight(lights[i], n, v, spec);\n" -" else if(lights[i].type == 1) lighting += CalcDirectionalLight(lights[i], n, v, spec);\n" -" else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);\n" -" }\n" -" }\n" -#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -" gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" -#elif defined(GRAPHICS_API_OPENGL_33) -" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" -#endif -"}\n"; -- cgit v1.2.3 From b681e8c2775bbb467c0f0607afd9840fda25c563 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 28 Jan 2017 00:56:45 +0100 Subject: Implemented Wait() Now program is halted (OS signal call) for required amount of time every frame, so CPU usage drops to zero, instead of using a busy wait loop. --- src/core.c | 66 ++++++++++++++++++++++++++++++++++++++++++++---------------- src/raylib.h | 4 ++-- src/text.c | 21 ++----------------- 3 files changed, 53 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 2917d839..8b97314d 100644 --- a/src/core.c +++ b/src/core.c @@ -67,9 +67,13 @@ #include // Required for: strcmp() //#include // Macros for reporting and retrieving error conditions through error codes +#if defined __linux || defined(PLATFORM_WEB) + #include // Required for: timespec, nanosleep(), select() - POSIX +#endif + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) - //#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3 - #include // GLFW3 library: Windows, OpenGL context and Input management + //#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3 + #include // GLFW3 library: Windows, OpenGL context and Input management #ifdef __linux #define GLFW_EXPOSE_NATIVE_X11 // Linux specific definitions for getting @@ -243,7 +247,7 @@ static int dropFilesCount = 0; // Count stored strings static double currentTime, previousTime; // Used to track timmings static double updateTime, drawTime; // Time measures for update and draw -static double frameTime; // Time measure for one frame +static double frameTime = 0.0; // Time measure for one frame static double targetTime = 0.0; // Desired time for one frame, if 0 not applied static char configFlags = 0; // Configuration flags (bit based) @@ -264,6 +268,7 @@ static void InitGraphicsDevice(int width, int height); // Initialize graphics d static void SetupFramebufferSize(int displayWidth, int displayHeight); static void InitTimer(void); // Initialize timer static double GetTime(void); // Returns time since InitTimer() was run +static void Wait(int ms); // Wait for some milliseconds (stop program execution) static bool GetKeyStatus(int key); // Returns if a key has been pressed static bool GetMouseButtonStatus(int button); // Returns if a mouse button has been pressed static void PollInputEvents(void); // Register user events @@ -313,6 +318,11 @@ static void InitGamepad(void); // Init raw gamepad inpu static void *GamepadThread(void *arg); // Mouse reading thread #endif +#if defined(_WIN32) + // NOTE: We include Sleep() function signature here to avoid windows.h inclusion + void __stdcall Sleep(unsigned long msTimeout); // Required for Delay() +#endif + //---------------------------------------------------------------------------------- // Module Functions Definition - Window and OpenGL Context Functions //---------------------------------------------------------------------------------- @@ -638,15 +648,16 @@ void EndDrawing(void) frameTime = updateTime + drawTime; - double extraTime = 0.0; - - while (frameTime < targetTime) + // Wait for some milliseconds... + if (frameTime < targetTime) { - // Implement a delay + Wait((int)((targetTime - frameTime)*1000)); + currentTime = GetTime(); - extraTime = currentTime - previousTime; + double extraTime = currentTime - previousTime; previousTime = currentTime; - frameTime += extraTime; + + frameTime = updateTime + drawTime + extraTime; } } @@ -780,20 +791,16 @@ void SetTargetFPS(int fps) } // Returns current FPS -float GetFPS(void) +int GetFPS(void) { - return (float)(1.0/frameTime); + return (int)floorf(1.0f/GetFrameTime()); } // Returns time in seconds for one frame float GetFrameTime(void) { - // As we are operate quite a lot with frameTime, - // it could be no stable, so we round it before passing it around - // NOTE: There are still problems with high framerates (>500fps) - double roundedFrameTime = round(frameTime*10000)/10000.0; - - return (float)roundedFrameTime; // Time in seconds to run a frame + // NOTE: We round value to milliseconds + return (roundf(frameTime*1000.0)/1000.0f); } // Converts Color to float array and normalizes @@ -1931,6 +1938,31 @@ static double GetTime(void) #endif } +// Wait for some milliseconds (stop program execution) +static void Wait(int ms) +{ +#if defined _WIN32 + Sleep(ms); +#elif defined __linux || defined(PLATFORM_WEB) + struct timespec req = { 0 }; + time_t sec = (int)(ms/1000); + ms -= (sec*1000); + req.tv_sec=sec; + req.tv_nsec=ms*1000000L; + + // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. + while (nanosleep(&req,&req) == -1) continue; +//#elif defined __APPLE__ + // TODO: +#else + double prevTime = GetTime(); + double nextTime = 0.0; + + // Busy wait loop + while ((nextTime - prevTime) < (double)ms/1000.0) nextTime = GetTime(); +#endif +} + // Get one key state static bool GetKeyStatus(int key) { diff --git a/src/raylib.h b/src/raylib.h index f8f17eec..97130253 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -659,8 +659,8 @@ RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) -RLAPI float GetFPS(void); // Returns current FPS -RLAPI float GetFrameTime(void); // Returns time in seconds for one frame +RLAPI int GetFPS(void); // Returns current FPS (rounded value) +RLAPI float GetFrameTime(void); // Returns time in seconds for one frame (rounded value) RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color diff --git a/src/text.c b/src/text.c index 4510b3af..4e163668 100644 --- a/src/text.c +++ b/src/text.c @@ -504,25 +504,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i // NOTE: Uses default font void DrawFPS(int posX, int posY) { - // NOTE: We are rendering fps every second for better viewing on high framerates - // TODO: Not working properly on ANDROID and RPI (for high framerates) - - static float fps = 0.0f; - static int counter = 0; - static int refreshRate = 20; - - if (counter < refreshRate) - { - counter++; - } - else - { - fps = GetFPS(); - refreshRate = (int)fps; - counter = 0; - } - - DrawText(FormatText("%2.0f FPS", fps), posX, posY, 20, LIME); + // NOTE: We have rounding errors every frame, so it oscillates a lot + DrawText(FormatText("%2i FPS", GetFPS()), posX, posY, 20, LIME); } //---------------------------------------------------------------------------------- -- cgit v1.2.3 From c85dfd4bc65099924b3ffa4402c24b73b40d35f6 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 28 Jan 2017 23:02:30 +0100 Subject: Remove unecessary spaces... --- src/audio.c | 98 ++++++------ src/core.c | 100 ++++++------ src/models.c | 66 ++++---- src/raylib.h | 26 +-- src/rlgl.c | 488 ++++++++++++++++++++++++++++----------------------------- src/text.c | 60 +++---- src/textures.c | 52 +++--- 7 files changed, 445 insertions(+), 445 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 74a54b04..22da74be 100644 --- a/src/audio.c +++ b/src/audio.c @@ -231,9 +231,9 @@ Wave LoadWave(const char *fileName) else if (strcmp(GetExtension(fileName),"rres") == 0) { RRESData rres = LoadResource(fileName); - + // NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels - + if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4); else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName); @@ -248,18 +248,18 @@ Wave LoadWave(const char *fileName) Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels) { Wave wave; - + wave.data = data; wave.sampleCount = sampleCount; wave.sampleRate = sampleRate; wave.sampleSize = sampleSize; wave.channels = channels; - + // NOTE: Copy wave data to work with, user is responsible of input data to free Wave cwave = WaveCopy(wave); - + WaveFormat(&cwave, sampleRate, sampleSize, channels); - + return cwave; } @@ -268,9 +268,9 @@ Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int Sound LoadSound(const char *fileName) { Wave wave = LoadWave(fileName); - + Sound sound = LoadSoundFromWave(wave); - + UnloadWave(wave); // Sound is loaded, we can unload wave return sound; @@ -354,7 +354,7 @@ void UnloadWave(Wave wave) void UnloadSound(Sound sound) { alSourceStop(sound.source); - + alDeleteSources(1, &sound.source); alDeleteBuffers(1, &sound.buffer); @@ -369,13 +369,13 @@ void UpdateSound(Sound sound, const void *data, int numSamples) alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format - + TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate); TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize); TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels); unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes - + alSourceStop(sound.source); // Stop sound alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update //alDeleteBuffers(1, &sound.buffer); // Delete current buffer data @@ -463,18 +463,18 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) if (wave->sampleRate != sampleRate) { // TODO: Resample wave data (upsampling or downsampling) - // NOTE 1: To downsample, you have to drop samples or average them. + // NOTE 1: To downsample, you have to drop samples or average them. // NOTE 2: To upsample, you have to interpolate new samples. - + wave->sampleRate = sampleRate; } - + // Format sample size // NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit if (wave->sampleSize != sampleSize) { void *data = malloc(wave->sampleCount*wave->channels*sampleSize/8); - + for (int i = 0; i < wave->sampleCount; i++) { for (int j = 0; j < wave->channels; j++) @@ -484,30 +484,30 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) if (wave->sampleSize == 16) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float)(((short *)wave->data)[wave->channels*i + j])/32767.0f)*256); else if (wave->sampleSize == 32) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float *)wave->data)[wave->channels*i + j]*127.0f + 127); } - else if (sampleSize == 16) + else if (sampleSize == 16) { if (wave->sampleSize == 8) ((short *)data)[wave->channels*i + j] = (short)(((float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f)*32767); else if (wave->sampleSize == 32) ((short *)data)[wave->channels*i + j] = (short)((((float *)wave->data)[wave->channels*i + j])*32767); } - else if (sampleSize == 32) + else if (sampleSize == 32) { if (wave->sampleSize == 8) ((float *)data)[wave->channels*i + j] = (float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f; else if (wave->sampleSize == 16) ((float *)data)[wave->channels*i + j] = (float)(((short *)wave->data)[wave->channels*i + j])/32767.0f; } } } - + wave->sampleSize = sampleSize; free(wave->data); wave->data = data; } - + // Format channels (interlaced mode) // NOTE: Only supported mono <--> stereo if (wave->channels != channels) { void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8); - + if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information) { for (int i = 0; i < wave->sampleCount; i++) @@ -529,7 +529,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) else if (wave->sampleSize == 32) ((float *)data)[i] = (((float *)wave->data)[j] + ((float *)wave->data)[j + 1])/2.0f; } } - + // TODO: Add/remove additional interlaced channels wave->channels = channels; @@ -563,15 +563,15 @@ Wave WaveCopy(Wave wave) // NOTE: Security check in case of out-of-range void WaveCrop(Wave *wave, int initSample, int finalSample) { - if ((initSample >= 0) && (initSample < finalSample) && + if ((initSample >= 0) && (initSample < finalSample) && (finalSample > 0) && (finalSample < wave->sampleCount)) { int sampleCount = finalSample - initSample; - + void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8); - + memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8); - + free(wave->data); wave->data = data; } @@ -583,7 +583,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample) float *GetWaveData(Wave wave) { float *samples = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float)); - + for (int i = 0; i < wave.sampleCount; i++) { for (int j = 0; j < wave.channels; j++) @@ -593,7 +593,7 @@ float *GetWaveData(Wave wave) else if (wave.sampleSize == 32) samples[wave.channels*i + j] = ((float *)wave.data)[wave.channels*i + j]; } } - + return samples; } @@ -632,7 +632,7 @@ Music LoadMusicStream(const char *fileName) else if (strcmp(GetExtension(fileName), "flac") == 0) { music->ctxFlac = drflac_open_file(fileName); - + if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName); else { @@ -641,7 +641,7 @@ Music LoadMusicStream(const char *fileName) music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_FLAC; music->loop = true; // We loop by default - + TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate); TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample); @@ -728,7 +728,7 @@ void ResumeMusicStream(Music music) void StopMusicStream(Music music) { alSourceStop(music->stream.source); - + switch (music->ctxType) { case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break; @@ -736,7 +736,7 @@ void StopMusicStream(Music music) case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break; default: break; } - + music->samplesLeft = music->totalSamples; } @@ -745,14 +745,14 @@ void UpdateMusicStream(Music music) { ALenum state; ALint processed = 0; - + alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); // Get music stream state alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers if (processed > 0) { bool active = true; - + // NOTE: Using dynamic allocation because it could require more than 16KB void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1); @@ -764,7 +764,7 @@ void UpdateMusicStream(Music music) { if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; else numSamples = music->samplesLeft; - + // TODO: Really don't like ctxType thingy... switch (music->ctxType) { @@ -784,7 +784,7 @@ void UpdateMusicStream(Music music) case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break; default: break; } - + UpdateAudioStream(music->stream, pcm, numSamples); music->samplesLeft -= numSamples; @@ -794,12 +794,12 @@ void UpdateMusicStream(Music music) break; } } - + // This error is registered when UpdateAudioStream() fails if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data..."); // Reset audio stream for looping - if (!active) + if (!active) { StopMusicStream(music); // Stop music (and reset) if (music->loop) PlayMusicStream(music); // Play again @@ -810,7 +810,7 @@ void UpdateMusicStream(Music music) // just make sure to play again on window restore if (state != AL_PLAYING) PlayMusicStream(music); } - + free(pcm); } } @@ -866,7 +866,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un stream.sampleRate = sampleRate; stream.sampleSize = sampleSize; - + // Only mono and stereo channels are supported, more channels require AL_EXT_MCFORMATS extension if ((channels > 0) && (channels < 3)) stream.channels = channels; else @@ -910,12 +910,12 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un // Initialize buffer with zeros by default // NOTE: Using dynamic allocation because it requires more than 16KB void *pcm = calloc(AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, 1); - + for (int i = 0; i < MAX_STREAM_BUFFERS; i++) { alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, stream.sampleRate); } - + free(pcm); alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers); @@ -1095,7 +1095,7 @@ static Wave LoadWAV(const char *fileName) wave.sampleRate = wavFormat.sampleRate; wave.sampleSize = wavFormat.bitsPerSample; wave.channels = wavFormat.numChannels; - + // NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32)) { @@ -1104,16 +1104,16 @@ static Wave LoadWAV(const char *fileName) } // NOTE: Only support up to 2 channels (mono, stereo) - if (wave.channels > 2) + if (wave.channels > 2) { WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); TraceLog(WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); } - + // NOTE: subChunkSize comes in bytes, we need to translate it to number of samples wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels; - TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); + TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); } } } @@ -1145,7 +1145,7 @@ static Wave LoadOGG(const char *fileName) wave.sampleSize = 16; // 16 bit per sample (short) wave.channels = info.channels; wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile); - + float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile); if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds); @@ -1173,16 +1173,16 @@ static Wave LoadFLAC(const char *fileName) // Decode an entire FLAC file in one go uint64_t totalSampleCount; wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); - + wave.sampleCount = (int)totalSampleCount/wave.channels; wave.sampleSize = 16; - + // NOTE: Only support up to 2 channels (mono, stereo) if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels); if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName); else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); - + return wave; } diff --git a/src/core.c b/src/core.c index 8b97314d..ea363fce 100644 --- a/src/core.c +++ b/src/core.c @@ -9,7 +9,7 @@ * External libs: * GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX) * raymath - 3D math functionality (Vector3, Matrix, Quaternion) -* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person) +* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person) * gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) * * Module Configuration Flags: @@ -103,7 +103,7 @@ #include // Linux: KDSKBMODE, K_MEDIUMRAM constants definition #include // Linux: Keycodes constants definition (KEY_A, ...) #include // Linux: Joystick support library - + #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions @@ -488,9 +488,9 @@ void CloseWindow(void) // Wait for mouse and gamepad threads to finish before closing // NOTE: Those threads should already have finished at this point // because they are controlled by windowShouldClose variable - + windowShouldClose = true; // Added to force threads to exit when the close window is called - + pthread_join(mouseThreadId, NULL); pthread_join(touchThreadId, NULL); pthread_join(gamepadThreadId, NULL); @@ -649,14 +649,14 @@ void EndDrawing(void) frameTime = updateTime + drawTime; // Wait for some milliseconds... - if (frameTime < targetTime) + if (frameTime < targetTime) { Wait((int)((targetTime - frameTime)*1000)); - + currentTime = GetTime(); double extraTime = currentTime - previousTime; previousTime = currentTime; - + frameTime = updateTime + drawTime + extraTime; } } @@ -1147,7 +1147,7 @@ bool IsKeyDown(int key) bool IsKeyReleased(int key) { bool released = false; - + if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true; else released = false; @@ -1182,7 +1182,7 @@ void SetExitKey(int key) bool IsGamepadAvailable(int gamepad) { bool result = false; - + #if !defined(PLATFORM_ANDROID) if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true; #endif @@ -1196,7 +1196,7 @@ bool IsGamepadName(int gamepad, const char *name) bool result = false; #if !defined(PLATFORM_ANDROID) - const char *gamepadName = NULL; + const char *gamepadName = NULL; if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad); if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0); @@ -1235,7 +1235,7 @@ int GetGamepadAxisCount(int gamepad) float GetGamepadAxisMovement(int gamepad, int axis) { float value = 0; - + #if !defined(PLATFORM_ANDROID) if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis]; #endif @@ -1249,8 +1249,8 @@ bool IsGamepadButtonPressed(int gamepad, int button) bool pressed = false; #if !defined(PLATFORM_ANDROID) - if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && + if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && + (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && (currentGamepadState[gamepad][button] == 1)) pressed = true; #endif @@ -1274,10 +1274,10 @@ bool IsGamepadButtonDown(int gamepad, int button) bool IsGamepadButtonReleased(int gamepad, int button) { bool released = false; - + #if !defined(PLATFORM_ANDROID) - if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && + if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && + (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && (currentGamepadState[gamepad][button] == 0)) released = true; #endif @@ -1290,7 +1290,7 @@ bool IsGamepadButtonUp(int gamepad, int button) bool result = false; #if !defined(PLATFORM_ANDROID) - if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && + if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && (currentGamepadState[gamepad][button] == 0)) result = true; #endif @@ -1503,7 +1503,7 @@ static void InitGraphicsDevice(int width, int height) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window } else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable - + //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) @@ -1941,7 +1941,7 @@ static double GetTime(void) // Wait for some milliseconds (stop program execution) static void Wait(int ms) { -#if defined _WIN32 +#if defined _WIN32 Sleep(ms); #elif defined __linux || defined(PLATFORM_WEB) struct timespec req = { 0 }; @@ -1949,7 +1949,7 @@ static void Wait(int ms) ms -= (sec*1000); req.tv_sec=sec; req.tv_nsec=ms*1000000L; - + // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. while (nanosleep(&req,&req) == -1) continue; //#elif defined __APPLE__ @@ -1999,10 +1999,10 @@ static void PollInputEvents(void) // NOTE: Gestures update must be called every frame to reset gestures correctly // because ProcessGestureEvent() is just called on an event, not every frame UpdateGestures(); - + // Reset last key pressed registered lastKeyPressed = -1; - + #if !defined(PLATFORM_RPI) // Reset last gamepad button/axis registered state lastGamepadButtonPressed = -1; @@ -2018,7 +2018,7 @@ static void PollInputEvents(void) mousePosition.x = (float)mouseX; mousePosition.y = (float)mouseY; - + // Keyboard input polling (automatically managed by GLFW3 through callback) // Register previous keys states @@ -2039,7 +2039,7 @@ static void PollInputEvents(void) if (glfwJoystickPresent(i)) gamepadReady[i] = true; else gamepadReady[i] = false; } - + // Register gamepads buttons events for (int i = 0; i < MAX_GAMEPADS; i++) { @@ -2047,14 +2047,14 @@ static void PollInputEvents(void) { // Register previous gamepad states for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k]; - + // Get current gamepad state // NOTE: There is no callback available, so we get it manually const unsigned char *buttons; int buttonsCount; buttons = glfwGetJoystickButtons(i, &buttonsCount); - + for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++) { if (buttons[k] == GLFW_PRESS) @@ -2064,18 +2064,18 @@ static void PollInputEvents(void) } else currentGamepadState[i][k] = 0; } - + // Get current axis state const float *axes; int axisCount = 0; axes = glfwGetJoystickAxes(i, &axisCount); - + for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++) { gamepadAxisState[i][k] = axes[k]; } - + gamepadAxisCount = axisCount; } } @@ -2088,16 +2088,16 @@ static void PollInputEvents(void) #if defined(PLATFORM_WEB) // Get number of gamepads connected int numGamepads = emscripten_get_num_gamepads(); - + for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++) { // Register previous gamepad button states for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k]; - + EmscriptenGamepadEvent gamepadState; - + int result = emscripten_get_gamepad_status(i, &gamepadState); - + if (result == EMSCRIPTEN_RESULT_SUCCESS) { // Register buttons data for every connected gamepad @@ -2109,16 +2109,16 @@ static void PollInputEvents(void) lastGamepadButtonPressed = j; } else currentGamepadState[i][j] = 0; - + //printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); } - + // Register axis data for every connected gamepad for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++) { gamepadAxisState[i][j] = gamepadState.axis[j]; } - + gamepadAxisCount = gamepadState.numAxes; } } @@ -2665,16 +2665,16 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE { /* printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n", - eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state", + eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state", gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); - + for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]); for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); */ - + if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true; else gamepadReady[gamepadEvent->index] = false; - + // TODO: Test gamepadEvent->index return 0; @@ -2935,7 +2935,7 @@ static void InitTouch(void) } // Touch reading thread. -// This reads from a Virtual Input Event /dev/input/event4 which is +// This reads from a Virtual Input Event /dev/input/event4 which is // created by the ts_uinput daemon. This takes, filters and scales // raw input from the Touchscreen (which appears in /dev/input/event3) // based on the Calibration data referenced by tslib. @@ -2949,7 +2949,7 @@ static void *TouchThread(void *arg) if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev)) { // if pressure > 0 then simulate left mouse button click - if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1) + if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1) { currentMouseState[0] = 0; gestureEvent.touchAction = TOUCH_UP; @@ -2963,10 +2963,10 @@ static void *TouchThread(void *arg) gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].y /= (float)GetScreenHeight(); ProcessGestureEvent(gestureEvent); - } - if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0) + } + if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0) { - currentMouseState[0] = 1; + currentMouseState[0] = 1; gestureEvent.touchAction = TOUCH_DOWN; gestureEvent.pointCount = 1; gestureEvent.pointerId[0] = 0; @@ -2978,9 +2978,9 @@ static void *TouchThread(void *arg) gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].y /= (float)GetScreenHeight(); ProcessGestureEvent(gestureEvent); - } + } // x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data - if (ev.type == EV_ABS && ev.code == 0) + if (ev.type == EV_ABS && ev.code == 0) { mousePosition.x = ev.value; if (mousePosition.x < 0) mousePosition.x = 0; @@ -2997,7 +2997,7 @@ static void *TouchThread(void *arg) gestureEvent.position[1].y /= (float)GetScreenHeight(); ProcessGestureEvent(gestureEvent); } - if (ev.type == EV_ABS && ev.code == 1) + if (ev.type == EV_ABS && ev.code == 1) { mousePosition.y = ev.value; if (mousePosition.y < 0) mousePosition.y = 0; @@ -3014,7 +3014,7 @@ static void *TouchThread(void *arg) gestureEvent.position[1].y /= (float)GetScreenHeight(); ProcessGestureEvent(gestureEvent); } - + } } return NULL; @@ -3084,7 +3084,7 @@ static void *GamepadThread(void *arg) { // 1 - button pressed, 0 - button released currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value; - + if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number; else lastGamepadButtonPressed = -1; } diff --git a/src/models.c b/src/models.c index 23c2e6fd..43821691 100644 --- a/src/models.c +++ b/src/models.c @@ -584,7 +584,7 @@ Mesh LoadMesh(const char *fileName) if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded"); else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) - + // TODO: Initialize default mesh data in case loading fails, maybe a cube? return mesh; @@ -607,7 +607,7 @@ Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color mesh.indices = NULL; rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) - + return mesh; } @@ -668,7 +668,7 @@ Model LoadCubicmap(Image cubicmap) return model; } - + // Unload mesh from memory (RAM and/or VRAM) void UnloadMesh(Mesh *mesh) { @@ -1438,34 +1438,34 @@ RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh) int triangleCount = mesh->vertexCount/3; // Test against all triangles in mesh - for (int i = 0; i < triangleCount; i++) + for (int i = 0; i < triangleCount; i++) { Vector3 a, b, c; Vector3 *vertdata = (Vector3 *)mesh->vertices; - - if (mesh->indices) + + if (mesh->indices) { a = vertdata[mesh->indices[i*3 + 0]]; b = vertdata[mesh->indices[i*3 + 1]]; - c = vertdata[mesh->indices[i*3 + 2]]; - } - else - { + c = vertdata[mesh->indices[i*3 + 2]]; + } + else + { a = vertdata[i*3 + 0]; b = vertdata[i*3 + 1]; c = vertdata[i*3 + 2]; } RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c); - - if (triHitInfo.hit) + + if (triHitInfo.hit) { // Save the closest hit triangle if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo; } } - return result; + return result; } // Get collision info between ray and triangle @@ -1478,44 +1478,44 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3) Vector3 p, q, tv; float det, invDet, u, v, t; RayHitInfo result = {0}; - + // Find vectors for two edges sharing V1 edge1 = VectorSubtract(p2, p1); edge2 = VectorSubtract(p3, p1); - + // Begin calculating determinant - also used to calculate u parameter p = VectorCrossProduct(ray.direction, edge2); - + // If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle det = VectorDotProduct(edge1, p); - + // Avoid culling! if ((det > -EPSILON) && (det < EPSILON)) return result; - + invDet = 1.0f/det; - + // Calculate distance from V1 to ray origin tv = VectorSubtract(ray.position, p1); - + // Calculate u parameter and test bound u = VectorDotProduct(tv, p)*invDet; - + // The intersection lies outside of the triangle if ((u < 0.0f) || (u > 1.0f)) return result; - + // Prepare to test v parameter q = VectorCrossProduct(tv, edge1); - + // Calculate V parameter and test bound v = VectorDotProduct(ray.direction, q)*invDet; - + // The intersection lies outside of the triangle if ((v < 0.0f) || ((u + v) > 1.0f)) return result; - + t = VectorDotProduct(edge2, q)*invDet; - - if (t > EPSILON) - { + + if (t > EPSILON) + { // Ray hit, get hit point and normal result.hit = true; result.distance = t; @@ -1523,10 +1523,10 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3) result.hitNormal = VectorCrossProduct(edge1, edge2); VectorNormalize(&result.hitNormal); Vector3 rayDir = ray.direction; - VectorScale(&rayDir, t); + VectorScale(&rayDir, t); result.hitPosition = VectorAdd(ray.position, rayDir); } - + return result; } @@ -1540,8 +1540,8 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight) if (fabsf(ray.direction.y) > EPSILON) { float t = (ray.position.y - groundHeight)/-ray.direction.y; - - if (t >= 0.0) + + if (t >= 0.0) { Vector3 rayDir = ray.direction; VectorScale(&rayDir, t); @@ -1551,7 +1551,7 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight) result.hitPosition = VectorAdd(ray.position, rayDir); } } - + return result; } diff --git a/src/raylib.h b/src/raylib.h index 97130253..c1c9ebae 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -593,21 +593,21 @@ typedef enum { // rRES data returned when reading a resource, it contains all required data for user (24 byte) typedef struct { unsigned int type; // Resource type (4 byte) - + unsigned int param1; // Resouce parameter 1 (4 byte) unsigned int param2; // Resouce parameter 2 (4 byte) unsigned int param3; // Resouce parameter 3 (4 byte) unsigned int param4; // Resouce parameter 4 (4 byte) - + void *data; // Resource data pointer (4 byte) } RRESData; -typedef enum { - RRES_RAW = 0, - RRES_IMAGE, - RRES_WAVE, - RRES_VERTEX, - RRES_TEXT +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT } RRESDataType; #ifdef __cplusplus @@ -800,7 +800,7 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally @@ -876,15 +876,15 @@ RLAPI Material LoadDefaultMaterial(void); RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits @@ -892,7 +892,7 @@ RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh diff --git a/src/rlgl.c b/src/rlgl.c index 8ec867eb..6c4e5927 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2,10 +2,10 @@ * * rlgl - raylib OpenGL abstraction layer * -* rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to -* selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0). +* rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to +* selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0). * -* When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal +* When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal * VBO buffers (and VAOs if available). It requires calling 3 functions: * rlglInit() - Initialize internal buffers and auxiliar resources * rlglDraw() - Process internal buffers and send required draw calls @@ -57,7 +57,7 @@ #endif #if defined(GRAPHICS_API_OPENGL_11) - #ifdef __APPLE__ + #ifdef __APPLE__ #include // OpenGL 1.1 library for OSX #else #include // OpenGL 1.1 library @@ -69,7 +69,7 @@ #endif #if defined(GRAPHICS_API_OPENGL_33) - #ifdef __APPLE__ + #ifdef __APPLE__ #include // OpenGL 3 library for OSX #else #define GLAD_IMPLEMENTATION @@ -168,7 +168,7 @@ #if defined(GRAPHICS_API_OPENGL_ES2) #define glClearDepth glClearDepthf - #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER + #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER #endif @@ -695,7 +695,7 @@ void rlEnd(void) } break; default: break; } - + // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, // as well as depth buffer bit-depth (16bit or 24bit or 32bit) // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) @@ -880,7 +880,7 @@ void rlDisableTexture(void) glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); #else - // NOTE: If quads batch limit is reached, + // NOTE: If quads batch limit is reached, // we force a draw call and next batch starts if (quads.vCounter/4 >= MAX_QUADS_BATCH) rlglDraw(); #endif @@ -982,7 +982,7 @@ void rlDeleteRenderTextures(RenderTexture2D target) if (target.id != 0) glDeleteFramebuffers(1, &target.id); if (target.texture.id != 0) glDeleteTextures(1, &target.texture.id); if (target.depth.id != 0) glDeleteTextures(1, &target.depth.id); - + TraceLog(INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id); #endif } @@ -999,7 +999,7 @@ void rlDeleteShader(unsigned int id) void rlDeleteVertexArrays(unsigned int id) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (vaoSupported) + if (vaoSupported) { if (id != 0) glDeleteVertexArrays(1, &id); TraceLog(INFO, "[VAO ID %i] Unloaded model data from VRAM (GPU)", id); @@ -1061,7 +1061,7 @@ void rlglInit(int width, int height) { // Check OpenGL information and capabilities //------------------------------------------------------------------------------ - + // Print current OpenGL and GLSL version TraceLog(INFO, "GPU: Vendor: %s", glGetString(GL_VENDOR)); TraceLog(INFO, "GPU: Renderer: %s", glGetString(GL_RENDERER)); @@ -1072,14 +1072,14 @@ void rlglInit(int width, int height) //int maxTexSize; //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); //TraceLog(INFO, "GL_MAX_TEXTURE_SIZE: %i", maxTexSize); - + //GL_MAX_TEXTURE_IMAGE_UNITS //GL_MAX_VIEWPORT_DIMS //int numAuxBuffers; //glGetIntegerv(GL_AUX_BUFFERS, &numAuxBuffers); //TraceLog(INFO, "GL_AUX_BUFFERS: %i", numAuxBuffers); - + //GLint numComp = 0; //GLint format[32] = { 0 }; //glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp); @@ -1087,7 +1087,7 @@ void rlglInit(int width, int height) //for (int i = 0; i < numComp; i++) TraceLog(INFO, "Supported compressed format: 0x%x", format[i]); // NOTE: We don't need that much data on screen... right now... - + #if defined(GRAPHICS_API_OPENGL_11) //TraceLog(INFO, "OpenGL 1.1 (or driver default) profile initialized"); #endif @@ -1095,7 +1095,7 @@ void rlglInit(int width, int height) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Get supported extensions list GLint numExt = 0; - + #if defined(GRAPHICS_API_OPENGL_33) // NOTE: On OpenGL 3.3 VAO and NPOT are supported by default @@ -1105,18 +1105,18 @@ void rlglInit(int width, int height) // We get a list of available extensions and we check for some of them (compressed textures) // NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that) glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); - + #ifdef _MSC_VER const char **extList = malloc(sizeof(const char *)*numExt); #else const char *extList[numExt]; #endif - + for (int i = 0; i < numExt; i++) extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i); - + #elif defined(GRAPHICS_API_OPENGL_ES2) char *extensions = (char *)glGetString(GL_EXTENSIONS); // One big const string - + // NOTE: We have to duplicate string because glGetString() returns a const value // If not duplicated, it fails in some systems (Raspberry Pi) // Equivalent to function: char *strdup(const char *str) @@ -1125,12 +1125,12 @@ void rlglInit(int width, int height) void *newstr = malloc(len); if (newstr == NULL) extensionsDup = NULL; extensionsDup = (char *)memcpy(newstr, extensions, len); - + // NOTE: String could be splitted using strtok() function (string.h) // NOTE: strtok() modifies the received string, it can not be const - + char *extList[512]; // Allocate 512 strings pointers (2 KB) - + extList[numExt] = strtok(extensionsDup, " "); while (extList[numExt] != NULL) @@ -1138,9 +1138,9 @@ void rlglInit(int width, int height) numExt++; extList[numExt] = strtok(NULL, " "); } - + free(extensionsDup); // Duplicated string must be deallocated - + numExt -= 1; #endif @@ -1158,25 +1158,25 @@ void rlglInit(int width, int height) if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0) { vaoSupported = true; - - // The extension is supported by our hardware and driver, try to get related functions pointers + + // The extension is supported by our hardware and driver, try to get related functions pointers // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted } - + // Check NPOT textures support // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true; #endif - + // DDS texture compression support if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) || (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) || - (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) texCompDXTSupported = true; - + (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) texCompDXTSupported = true; + // ETC1 texture compression support if ((strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) || (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_etc1") == 0)) texCompETC1Supported = true; @@ -1189,26 +1189,26 @@ void rlglInit(int width, int height) // ASTC texture compression support if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true; - + // Anisotropic texture filter support if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0) { texAnisotropicFilterSupported = true; - glGetFloatv(0x84FF, &maxAnisotropicLevel); // GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT + glGetFloatv(0x84FF, &maxAnisotropicLevel); // GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT } - + // Clamp mirror wrap mode supported if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) texClampMirrorSupported = true; } - + #ifdef _MSC_VER free(extList); #endif - + #if defined(GRAPHICS_API_OPENGL_ES2) if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully"); else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported"); - + if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported"); else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)"); #endif @@ -1218,13 +1218,13 @@ void rlglInit(int width, int height) if (texCompETC2Supported) TraceLog(INFO, "[EXTENSION] ETC2/EAC compressed textures supported"); if (texCompPVRTSupported) TraceLog(INFO, "[EXTENSION] PVRT compressed textures supported"); if (texCompASTCSupported) TraceLog(INFO, "[EXTENSION] ASTC compressed textures supported"); - + if (texAnisotropicFilterSupported) TraceLog(INFO, "[EXTENSION] Anisotropic textures filtering supported (max: %.0fX)", maxAnisotropicLevel); if (texClampMirrorSupported) TraceLog(INFO, "[EXTENSION] Clamp mirror wrap texture mode supported"); // Initialize buffers, default shaders and default textures //---------------------------------------------------------- - + // Init default white texture unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) @@ -1238,7 +1238,7 @@ void rlglInit(int width, int height) currentShader = defaultShader; // Init default vertex arrays buffers (lines, triangles, quads) - LoadDefaultBuffers(); + LoadDefaultBuffers(); // Init temp vertex buffer, used when transformation required (translate, rotate, scale) tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE); @@ -1257,7 +1257,7 @@ void rlglInit(int width, int height) drawsCounter = 1; draws[drawsCounter - 1].textureId = whiteTexture; currentDrawMode = RL_TRIANGLES; // Set default draw mode - + // Init internal matrix stack (emulating OpenGL 1.1) for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity(); @@ -1286,7 +1286,7 @@ void rlglInit(int width, int height) #if defined(GRAPHICS_API_OPENGL_11) // Init state: Color hints (deprecated in OpenGL 3.0+) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) #endif @@ -1294,7 +1294,7 @@ void rlglInit(int width, int height) glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) glClearDepth(1.0f); // Set clear depth value (default) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) - + // Store screen size into global variables screenWidth = width; screenHeight = height; @@ -1308,7 +1308,7 @@ void rlglClose(void) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) UnloadDefaultShader(); UnloadDefaultBuffers(); - + // Delete default white texture glDeleteTextures(1, &whiteTexture); TraceLog(INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", whiteTexture); @@ -1326,7 +1326,7 @@ void rlglDraw(void) // NOTE: Default buffers upload and draw UpdateDefaultBuffers(); - + if (vrEnabled && vrRendering) DrawDefaultBuffers(2); else DrawDefaultBuffers(1); #endif @@ -1342,7 +1342,7 @@ void rlglLoadExtensions(void *loader) if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); #endif - + #if defined(GRAPHICS_API_OPENGL_21) #ifndef __APPLE__ if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported"); @@ -1363,17 +1363,17 @@ void rlglLoadExtensions(void *loader) Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) { Vector3 result = { 0.0f, 0.0f, 0.0f }; - + // Calculate unproject matrix (multiply projection matrix and view matrix) and invert it Matrix matProjView = MatrixMultiply(proj, view); MatrixInvert(&matProjView); - + // Create quaternion from source point Quaternion quat = { source.x, source.y, source.z, 1.0f }; - + // Multiply quat point by unproject matrix QuaternionTransform(&quat, matProjView); - + // Normalized world points in vectors result.x = quat.x/quat.w; result.y = quat.y/quat.w; @@ -1388,41 +1388,41 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding GLuint id = 0; - + // Check texture format support by OpenGL 1.1 (compressed textures not supported) -#if defined(GRAPHICS_API_OPENGL_11) +#if defined(GRAPHICS_API_OPENGL_11) if (textureFormat >= 8) { TraceLog(WARNING, "OpenGL 1.1 does not support GPU compressed texture formats"); return id; } #endif - + if ((!texCompDXTSupported) && ((textureFormat == COMPRESSED_DXT1_RGB) || (textureFormat == COMPRESSED_DXT1_RGBA) || (textureFormat == COMPRESSED_DXT3_RGBA) || (textureFormat == COMPRESSED_DXT5_RGBA))) { TraceLog(WARNING, "DXT compressed texture format not supported"); return id; } -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if ((!texCompETC1Supported) && (textureFormat == COMPRESSED_ETC1_RGB)) { TraceLog(WARNING, "ETC1 compressed texture format not supported"); return id; } - + if ((!texCompETC2Supported) && ((textureFormat == COMPRESSED_ETC2_RGB) || (textureFormat == COMPRESSED_ETC2_EAC_RGBA))) { TraceLog(WARNING, "ETC2 compressed texture format not supported"); return id; } - + if ((!texCompPVRTSupported) && ((textureFormat == COMPRESSED_PVRT_RGB) || (textureFormat == COMPRESSED_PVRT_RGBA))) { TraceLog(WARNING, "PVRT compressed texture format not supported"); return id; } - + if ((!texCompASTCSupported) && ((textureFormat == COMPRESSED_ASTC_4x4_RGBA) || (textureFormat == COMPRESSED_ASTC_8x8_RGBA))) { TraceLog(WARNING, "ASTC compressed texture format not supported"); @@ -1450,24 +1450,24 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma // GL_RGBA4 GL_RGBA GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_4_4_4_4 // GL_RGBA8 GL_RGBA GL_UNSIGNED_BYTE // GL_RGB8 GL_RGB GL_UNSIGNED_BYTE - + switch (textureFormat) { case UNCOMPRESSED_GRAYSCALE: { glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)data); - + // With swizzleMask we define how a one channel texture will be mapped to RGBA // Required GL >= 3.3 or EXT_texture_swizzle/ARB_texture_swizzle GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - + TraceLog(INFO, "[TEX ID %i] Grayscale texture loaded and swizzled", id); } break; case UNCOMPRESSED_GRAY_ALPHA: { glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, width, height, 0, GL_RG, GL_UNSIGNED_BYTE, (unsigned char *)data); - + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } break; @@ -1541,7 +1541,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma // Magnification and minification filters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Alternative: GL_LINEAR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR - + #if defined(GRAPHICS_API_OPENGL_33) if (mipmapCount > 1) { @@ -1551,7 +1551,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma #endif // At this point we have the texture loaded in GPU and texture parameters configured - + // NOTE: If mipmaps were not in data, they are not generated automatically // Unbind current texture @@ -1567,15 +1567,15 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma RenderTexture2D rlglLoadRenderTexture(int width, int height) { RenderTexture2D target; - + target.id = 0; - + target.texture.id = 0; target.texture.width = width; target.texture.height = height; target.texture.format = UNCOMPRESSED_R8G8B8A8; target.texture.mipmaps = 1; - + target.depth.id = 0; target.depth.width = width; target.depth.height = height; @@ -1592,13 +1592,13 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); - + #if defined(GRAPHICS_API_OPENGL_33) #define USE_DEPTH_TEXTURE #else #define USE_DEPTH_RENDERBUFFER #endif - + #if defined(USE_DEPTH_RENDERBUFFER) // Create the renderbuffer that will serve as the depth attachment for the framebuffer. glGenRenderbuffers(1, &target.depth.id); @@ -1634,7 +1634,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) if (status != GL_FRAMEBUFFER_COMPLETE) { TraceLog(WARNING, "Framebuffer object could not be created..."); - + switch (status) { case GL_FRAMEBUFFER_UNSUPPORTED: TraceLog(WARNING, "Framebuffer is unsupported"); break; @@ -1645,17 +1645,17 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TraceLog(WARNING, "Framebuffer incomplete missing attachment"); break; default: break; } - + glDeleteTextures(1, &target.texture.id); glDeleteTextures(1, &target.depth.id); glDeleteFramebuffers(1, &target.id); } else TraceLog(INFO, "[FBO ID %i] Framebuffer object created successfully", target.id); - + glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif - return target; + return target; } // Update already loaded texture in GPU with new data @@ -1695,11 +1695,11 @@ void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void rlglGenerateMipmaps(Texture2D *texture) { glBindTexture(GL_TEXTURE_2D, texture->id); - + // Check if texture is power-of-two (POT) bool texIsPOT = false; - - if (((texture->width > 0) && ((texture->width & (texture->width - 1)) == 0)) && + + if (((texture->width > 0) && ((texture->width & (texture->width - 1)) == 0)) && ((texture->height > 0) && ((texture->height & (texture->height - 1)) == 0))) texIsPOT = true; if ((texIsPOT) || (npotSupported)) @@ -1707,7 +1707,7 @@ void rlglGenerateMipmaps(Texture2D *texture) #if defined(GRAPHICS_API_OPENGL_11) // Compute required mipmaps void *data = rlglReadTexturePixels(*texture); - + // NOTE: data size is reallocated to fit mipmaps data // NOTE: CPU mipmap generation only supports RGBA 32bit data int mipmapCount = GenerateMipmaps(data, texture->width, texture->height); @@ -1729,12 +1729,12 @@ void rlglGenerateMipmaps(Texture2D *texture) mipWidth /= 2; mipHeight /= 2; } - + TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", texture->id); - + // NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data free(data); - + texture->mipmaps = mipmapCount + 1; #endif @@ -1745,10 +1745,10 @@ void rlglGenerateMipmaps(Texture2D *texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps - + #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) - + texture->mipmaps = 1 + (int)floor(log(MAX(texture->width, texture->height))/log(2)); #endif } @@ -1768,7 +1768,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) mesh->vboId[4] = 0; // Vertex tangents VBO mesh->vboId[5] = 0; // Vertex texcoords2 VBO mesh->vboId[6] = 0; // Vertex indices VBO - + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) int drawHint = GL_STATIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW; @@ -1783,8 +1783,8 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glBindVertexArray(vaoId); } - // NOTE: Attributes must be uploaded considering default locations points - + // NOTE: Attributes must be uploaded considering default locations points + // Enable vertex attributes: position (shader-location = 0) glGenBuffers(1, &vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, vboId[0]); @@ -1814,7 +1814,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glVertexAttrib3f(2, 1.0f, 1.0f, 1.0f); glDisableVertexAttribArray(2); } - + // Default color vertex attribute (shader-location = 3) if (mesh->colors != NULL) { @@ -1830,7 +1830,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glVertexAttrib4f(3, 1.0f, 1.0f, 1.0f, 1.0f); glDisableVertexAttribArray(3); } - + // Default tangent vertex attribute (shader-location = 4) if (mesh->tangents != NULL) { @@ -1846,7 +1846,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glVertexAttrib3f(4, 0.0f, 0.0f, 0.0f); glDisableVertexAttribArray(4); } - + // Default texcoord2 vertex attribute (shader-location = 5) if (mesh->texcoords2 != NULL) { @@ -1862,7 +1862,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glVertexAttrib2f(5, 0.0f, 0.0f); glDisableVertexAttribArray(5); } - + if (mesh->indices != NULL) { glGenBuffers(1, &vboId[6]); @@ -1900,7 +1900,7 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Activate mesh VAO if (vaoSupported) glBindVertexArray(mesh.vaoId); - + switch (buffer) { case 0: // Update vertices (vertex position) @@ -1908,28 +1908,28 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.vertices, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.vertices); - + } break; case 1: // Update texcoords (vertex texture coordinates) { glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*numVertex, mesh.texcoords, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*numVertex, mesh.texcoords); - + } break; case 2: // Update normals (vertex normals) { glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.normals, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.normals); - + } break; case 3: // Update colors (vertex colors) { glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*numVertex, mesh.colors, GL_DYNAMIC_DRAW); else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*numVertex, mesh.colors); - + } break; case 4: // Update tangents (vertex tangents) { @@ -1945,7 +1945,7 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) } break; default: break; } - + // Unbind the current VAO if (vaoSupported) glBindVertexArray(0); @@ -1973,11 +1973,11 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords); // Pointer to texture coords array if (mesh.normals != NULL) glNormalPointer(GL_FLOAT, 0, mesh.normals); // Pointer to normals array if (mesh.colors != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors); // Pointer to colors array - + rlPushMatrix(); rlMultMatrixf(MatrixToFloat(transform)); rlColor4ub(material.colDiffuse.r, material.colDiffuse.g, material.colDiffuse.b, material.colDiffuse.a); - + if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, mesh.indices); else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); rlPopMatrix(); @@ -1996,13 +1996,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (vrEnabled) eyesCount = 2; glUseProgram(material.shader.id); - + // Upload to shader material.colDiffuse glUniform4f(material.shader.colDiffuseLoc, (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255); - + // Upload to shader material.colAmbient (if available) if (material.shader.colAmbientLoc != -1) glUniform4f(material.shader.colAmbientLoc, (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); - + // Upload to shader material.colSpecular (if available) if (material.shader.colSpecularLoc != -1) glUniform4f(material.shader.colSpecularLoc, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255); @@ -2010,7 +2010,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) Matrix matProjection = projection; // Projection matrix (perspective) - + // Calculate model-view matrix combining matModel and matView Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates @@ -2026,7 +2026,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) Matrix transInvTransform = transform; MatrixTranspose(&transInvTransform); MatrixInvert(&transInvTransform); - + // Send model transformations matrix to shader glUniformMatrix4fv(modelMatrixLoc, 1, false, MatrixToFloat(transInvTransform)); } @@ -2039,7 +2039,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Check if glossiness is located in shader and upload value int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness"); if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness); - } + } // Set shader textures (diffuse, normal, specular) glActiveTexture(GL_TEXTURE0); @@ -2050,22 +2050,22 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) { // Upload to shader specular map flag glUniform1i(glGetUniformLocation(material.shader.id, "useNormal"), 1); - + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, material.texNormal.id); glUniform1i(material.shader.mapTexture1Loc, 1); // Normal texture fits in active texture unit 1 } - + if ((material.texSpecular.id != 0) && (material.shader.mapTexture2Loc != -1)) { // Upload to shader specular map flag glUniform1i(glGetUniformLocation(material.shader.id, "useSpecular"), 1); - + glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, material.texSpecular.id); glUniform1i(material.shader.mapTexture2Loc, 2); // Specular texture fits in active texture unit 2 } - + if (vaoSupported) { glBindVertexArray(mesh.vaoId); @@ -2089,7 +2089,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glVertexAttribPointer(material.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); glEnableVertexAttribArray(material.shader.normalLoc); } - + // Bind mesh VBO data: vertex colors (shader-location = 3, if available) if (material.shader.colorLoc != -1) { @@ -2107,7 +2107,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glDisableVertexAttribArray(material.shader.colorLoc); } } - + // Bind mesh VBO data: vertex tangents (shader-location = 4, if available) if (material.shader.tangentLoc != -1) { @@ -2115,7 +2115,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0); glEnableVertexAttribArray(material.shader.tangentLoc); } - + // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available) if (material.shader.texcoord2Loc != -1) { @@ -2123,7 +2123,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0); glEnableVertexAttribArray(material.shader.texcoord2Loc); } - + if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); } @@ -2142,13 +2142,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); } - + if (material.texNormal.id != 0) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); } - + if (material.texSpecular.id != 0) { glActiveTexture(GL_TEXTURE2); @@ -2166,7 +2166,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) } glUseProgram(0); // Unbind shader program - + // Restore projection/modelview matrices projection = matProjection; modelview = matView; @@ -2212,7 +2212,7 @@ unsigned char *rlglReadScreenPixels(int width, int height) { // Flip line imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; - + // Set alpha component value to 255 (no trasparent image retrieval) // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255; @@ -2230,10 +2230,10 @@ unsigned char *rlglReadScreenPixels(int width, int height) void *rlglReadTexturePixels(Texture2D texture) { void *pixels = NULL; - + #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) glBindTexture(GL_TEXTURE_2D, texture.id); - + // NOTE: Using texture.id, we can retrieve some texture info (but not on OpenGL ES 2.0) /* int width, height, format; @@ -2242,11 +2242,11 @@ void *rlglReadTexturePixels(Texture2D texture) glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); // Other texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE */ - + int glFormat = 0, glType = 0; unsigned int size = texture.width*texture.height; - + // NOTE: GL_LUMINANCE and GL_LUMINANCE_ALPHA are removed since OpenGL 3.1 // Must be replaced by GL_RED and GL_RG on Core OpenGL 3.3 @@ -2255,8 +2255,8 @@ void *rlglReadTexturePixels(Texture2D texture) #if defined(GRAPHICS_API_OPENGL_11) case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; break; // 8 bit per pixel (no alpha) case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; break; // 16 bpp (2 channels) -#elif defined(GRAPHICS_API_OPENGL_33) - case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_RED; glType = GL_UNSIGNED_BYTE; break; +#elif defined(GRAPHICS_API_OPENGL_33) + case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_RED; glType = GL_UNSIGNED_BYTE; break; case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_RG; glType = GL_UNSIGNED_BYTE; break; #endif case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; break; // 16 bpp @@ -2266,15 +2266,15 @@ void *rlglReadTexturePixels(Texture2D texture) case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; break; // 32 bpp default: TraceLog(WARNING, "Texture data retrieval, format not suported"); break; } - + // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. - // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. - // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) + // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. + // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) glPixelStorei(GL_PACK_ALIGNMENT, 1); glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); - + glBindTexture(GL_TEXTURE_2D, 0); #endif @@ -2285,7 +2285,7 @@ void *rlglReadTexturePixels(Texture2D texture) // NOTE: Two possible Options: // 1 - Bind texture to color fbo attachment and glReadPixels() // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() - + #define GET_TEXTURE_FBO_OPTION_1 // It works #if defined(GET_TEXTURE_FBO_OPTION_1) @@ -2295,48 +2295,48 @@ void *rlglReadTexturePixels(Texture2D texture) // Attach our texture to FBO -> Texture must be RGB // NOTE: Previoust attached texture is automatically detached glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0); - + pixels = (unsigned char *)malloc(texture.width*texture.height*4*sizeof(unsigned char)); - + // NOTE: Despite FBO color texture is RGB, we read data as RGBA... reading as RGB doesn't work... o__O glReadPixels(0, 0, texture.width, texture.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - + // Re-attach internal FBO color texture before deleting it glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo.texture.id, 0); - + glBindFramebuffer(GL_FRAMEBUFFER, 0); - + #elif defined(GET_TEXTURE_FBO_OPTION_2) // Render texture to fbo glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); - + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, width, height); //glMatrixMode(GL_PROJECTION); //glLoadIdentity(); - rlOrtho(0.0, width, height, 0.0, 0.0, 1.0); + rlOrtho(0.0, width, height, 0.0, 0.0, 1.0); //glMatrixMode(GL_MODELVIEW); //glLoadIdentity(); //glDisable(GL_TEXTURE_2D); //glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); - + Model quad; //quad.mesh = GenMeshQuad(width, height); quad.transform = MatrixIdentity(); quad.shader = defaultShader; - + DrawModel(quad, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, WHITE); - + pixels = (unsigned char *)malloc(texture.width*texture.height*3*sizeof(unsigned char)); - + glReadPixels(0, 0, texture.width, texture.height, GL_RGB, GL_UNSIGNED_BYTE, pixels); // Bind framebuffer 0, which means render to back buffer glBindFramebuffer(GL_FRAMEBUFFER, 0); - + UnloadModel(quad); #endif // GET_TEXTURE_FBO_OPTION @@ -2361,7 +2361,7 @@ void rlglRecordDraw(void) draws[drawsCounter].projection = projection; draws[drawsCounter].modelview = modelview; draws[drawsCounter].vertexCount = currentState.vertexCount; - + drawsCounter++; #endif } @@ -2376,13 +2376,13 @@ void rlglRecordDraw(void) Texture2D GetDefaultTexture(void) { Texture2D texture; - + texture.id = whiteTexture; texture.width = 1; texture.height = 1; texture.mipmaps = 1; texture.format = UNCOMPRESSED_R8G8B8A8; - + return texture; } @@ -2429,24 +2429,24 @@ Shader LoadShader(char *vsFileName, char *fsFileName) // Shaders loading from external text file char *vShaderStr = LoadText(vsFileName); char *fShaderStr = LoadText(fsFileName); - + if ((vShaderStr != NULL) && (fShaderStr != NULL)) { shader.id = LoadShaderProgram(vShaderStr, fShaderStr); // After shader loading, we try to load default location names if (shader.id != 0) LoadDefaultShaderLocations(&shader); - + // Shader strings must be freed free(vShaderStr); free(fShaderStr); } - + if (shader.id == 0) { TraceLog(WARNING, "Custom shader could not be loaded"); shader = defaultShader; - } + } #endif return shader; @@ -2497,9 +2497,9 @@ Shader GetDefaultShader(void) int GetShaderLocation(Shader shader, const char *uniformName) { int location = -1; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) location = glGetUniformLocation(shader.id, uniformName); - + if (location == -1) TraceLog(DEBUG, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName); #endif return location; @@ -2516,7 +2516,7 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) else if (size == 3) glUniform3fv(uniformLoc, 1, value); // Shader uniform type: vec3 else if (size == 4) glUniform4fv(uniformLoc, 1, value); // Shader uniform type: vec4 else TraceLog(WARNING, "Shader value float array size not supported"); - + //glUseProgram(0); // Avoid reseting current shader program, in case other uniforms are set #endif } @@ -2532,7 +2532,7 @@ void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size) else if (size == 3) glUniform3iv(uniformLoc, 1, value); // Shader uniform type: ivec3 else if (size == 4) glUniform4iv(uniformLoc, 1, value); // Shader uniform type: ivec4 else TraceLog(WARNING, "Shader value int array size not supported"); - + //glUseProgram(0); #endif } @@ -2544,7 +2544,7 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat) glUseProgram(shader.id); glUniformMatrix4fv(uniformLoc, 1, false, MatrixToFloat(mat)); - + //glUseProgram(0); #endif } @@ -2572,7 +2572,7 @@ void BeginBlendMode(int mode) if ((blendMode != mode) && (mode < 3)) { rlglDraw(); - + switch (mode) { case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; @@ -2580,7 +2580,7 @@ void BeginBlendMode(int mode) case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break; default: break; } - + blendMode = mode; } } @@ -2646,9 +2646,9 @@ void InitVrDevice(int vrDevice) { // Oculus Rift CV1 parameters // NOTE: CV1 represents a complete HMD redesign compared to previous versions, - // new Fresnel-hybrid-asymmetric lenses have been added and, consequently, - // previous parameters (DK2) and distortion shader (DK2) doesn't work any more. - // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering + // new Fresnel-hybrid-asymmetric lenses have been added and, consequently, + // previous parameters (DK2) and distortion shader (DK2) doesn't work any more. + // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering // but result is not the same obtained with Oculus PC SDK. hmd.hResolution = 2160; // HMD horizontal resolution in pixels hmd.vResolution = 1200; // HMD vertical resolution in pixels @@ -2667,17 +2667,17 @@ void InitVrDevice(int vrDevice) hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 } - + // Initialize framebuffer and textures for stereo rendering // NOTE: screen size should match HMD aspect ratio vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); - + // Load distortion shader (initialized by default with Oculus Rift CV1 parameters) vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr); if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader); SetStereoConfig(hmd); - + vrSimulator = true; vrEnabled = true; } @@ -2722,9 +2722,9 @@ void ToggleVrMode(void) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if (vrDeviceReady || vrSimulator) vrEnabled = !vrEnabled; else vrEnabled = false; - + if (!vrEnabled) - { + { // Reset viewport and default projection-modelview matrices rlViewport(0, 0, screenWidth, screenHeight); projection = MatrixOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f); @@ -2759,15 +2759,15 @@ void BeginVrDrawing(void) rlEnableRenderTexture(vrConfig.stereoFbo.id); } - // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) + // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then: // - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB // - Do NOT enable GL_FRAMEBUFFER_SRGB //glEnable(GL_FRAMEBUFFER_SRGB); - + //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) - + vrRendering = true; #endif } @@ -2786,12 +2786,12 @@ void EndVrDrawing(void) { // Unbind current framebuffer rlDisableRenderTexture(); - + rlClearScreenBuffers(); // Clear current framebuffer // Set viewport to default framebuffer size (screen size) rlViewport(0, 0, screenWidth, screenHeight); - + // Let rlgl reconfigure internal matrices rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix rlLoadIdentity(); // Reset internal projection matrix @@ -2799,7 +2799,7 @@ void EndVrDrawing(void) rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix rlLoadIdentity(); // Reset internal modelview matrix - // Draw RenderTexture (stereoFbo) using distortion shader + // Draw RenderTexture (stereoFbo) using distortion shader currentShader = vrConfig.distortionShader; rlEnableTexture(vrConfig.stereoFbo.texture.id); @@ -2836,7 +2836,7 @@ void EndVrDrawing(void) } rlDisableDepthTest(); - + vrRendering = false; #endif } @@ -2867,7 +2867,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in for (int level = 0; level < mipmapCount && (width || height); level++) { unsigned int size = 0; - + size = ((width + 3)/4)*((height + 3)/4)*blockSize; glCompressedTexImage2D(GL_TEXTURE_2D, level, compressedFormat, width, height, 0, size, data + offset); @@ -2923,7 +2923,7 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glGetShaderInfoLog(vertexShader, maxLength, &length, log); TraceLog(INFO, "%s", log); - + #ifdef _MSC_VER free(log); #endif @@ -2962,7 +2962,7 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); - + // NOTE: Default attribute shader locations must be binded before linking glBindAttribLocation(program, 0, DEFAULT_ATTRIB_POSITION_NAME); glBindAttribLocation(program, 1, DEFAULT_ATTRIB_TEXCOORD_NAME); @@ -2970,11 +2970,11 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glBindAttribLocation(program, 3, DEFAULT_ATTRIB_COLOR_NAME); glBindAttribLocation(program, 4, DEFAULT_ATTRIB_TANGENT_NAME); glBindAttribLocation(program, 5, DEFAULT_ATTRIB_TEXCOORD2_NAME); - + // NOTE: If some attrib name is no found on the shader, it locations becomes -1 - + glLinkProgram(program); - + // NOTE: All uniform variables are intitialised to 0 when a program links glGetProgramiv(program, GL_LINK_STATUS, &success); @@ -2996,7 +2996,7 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glGetProgramInfoLog(program, maxLength, &length, log); TraceLog(INFO, "%s", log); - + #ifdef _MSC_VER free(log); #endif @@ -3099,7 +3099,7 @@ static void LoadDefaultShaderLocations(Shader *shader) // vertex color location = 3 // vertex tangent location = 4 // vertex texcoord2 location = 5 - + // Get handles to GLSL input attibute locations shader->vertexLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME); shader->texcoordLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD_NAME); @@ -3115,15 +3115,15 @@ static void LoadDefaultShaderLocations(Shader *shader) shader->colDiffuseLoc = glGetUniformLocation(shader->id, "colDiffuse"); shader->colAmbientLoc = glGetUniformLocation(shader->id, "colAmbient"); shader->colSpecularLoc = glGetUniformLocation(shader->id, "colSpecular"); - + shader->mapTexture0Loc = glGetUniformLocation(shader->id, "texture0"); shader->mapTexture1Loc = glGetUniformLocation(shader->id, "texture1"); shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2"); - + // TODO: Try to find all expected/recognized shader locations (predefined names, must be documented) } -// Unload default shader +// Unload default shader static void UnloadDefaultShader(void) { glUseProgram(0); @@ -3140,7 +3140,7 @@ static void LoadDefaultBuffers(void) { // [CPU] Allocate and initialize float array buffers to store vertex data (lines, triangles, quads) //-------------------------------------------------------------------------------------------- - + // Lines - Initialize arrays (vertex position and color data) lines.vertices = (float *)malloc(sizeof(float)*3*2*MAX_LINES_BATCH); // 3 float by vertex, 2 vertex by line lines.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*2*MAX_LINES_BATCH); // 4 float by color, 2 colors by line @@ -3202,11 +3202,11 @@ static void LoadDefaultBuffers(void) TraceLog(INFO, "[CPU] Default buffers initialized successfully (lines, triangles, quads)"); //-------------------------------------------------------------------------------------------- - + // [GPU] Upload vertex data and initialize VAOs/VBOs (lines, triangles, quads) // NOTE: Default buffers are linked to use currentShader (defaultShader) //-------------------------------------------------------------------------------------------- - + // Upload and link lines vertex buffers if (vaoSupported) { @@ -3215,7 +3215,7 @@ static void LoadDefaultBuffers(void) glBindVertexArray(lines.vaoId); } - // Lines - Vertex buffers binding and attributes enable + // Lines - Vertex buffers binding and attributes enable // Vertex position buffer (shader-location = 0) glGenBuffers(2, &lines.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); @@ -3241,7 +3241,7 @@ static void LoadDefaultBuffers(void) glBindVertexArray(triangles.vaoId); } - // Triangles - Vertex buffers binding and attributes enable + // Triangles - Vertex buffers binding and attributes enable // Vertex position buffer (shader-location = 0) glGenBuffers(1, &triangles.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); @@ -3267,7 +3267,7 @@ static void LoadDefaultBuffers(void) glBindVertexArray(quads.vaoId); } - // Quads - Vertex buffers binding and attributes enable + // Quads - Vertex buffers binding and attributes enable // Vertex position buffer (shader-location = 0) glGenBuffers(1, &quads.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); @@ -3383,7 +3383,7 @@ static void DrawDefaultBuffers(int eyesCount) { Matrix matProjection = projection; Matrix matModelView = modelview; - + for (int eye = 0; eye < eyesCount; eye++) { if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView); @@ -3392,17 +3392,17 @@ static void DrawDefaultBuffers(int eyesCount) if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) { glUseProgram(currentShader.id); - + // Create modelview-projection matrix Matrix matMVP = MatrixMultiply(modelview, projection); glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); glUniform4f(currentShader.colDiffuseLoc, 1.0f, 1.0f, 1.0f, 1.0f); glUniform1i(currentShader.mapTexture0Loc, 0); - + // NOTE: Additional map textures not considered for default buffers drawing } - + // Draw lines buffers if (lines.vCounter > 0) { @@ -3486,7 +3486,7 @@ static void DrawDefaultBuffers(int eyesCount) glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glEnableVertexAttribArray(currentShader.colorLoc); - + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); } @@ -3526,7 +3526,7 @@ static void DrawDefaultBuffers(int eyesCount) glUseProgram(0); // Unbind shader program } - + // Reset draws counter drawsCounter = 1; draws[0].textureId = whiteTexture; @@ -3540,10 +3540,10 @@ static void DrawDefaultBuffers(int eyesCount) quads.vCounter = 0; quads.tcCounter = 0; quads.cCounter = 0; - + // Reset depth for next draw currentDepth = -1.0f; - + // Restore projection/modelview matrices projection = matProjection; modelview = matModelView; @@ -3604,34 +3604,34 @@ static void SetStereoConfig(VrDeviceInfo hmd) float rightLensCenter[2] = { 0.75f - lensShift, 0.5f }; float leftScreenCenter[2] = { 0.25f, 0.5f }; float rightScreenCenter[2] = { 0.75f, 0.5f }; - + // Compute distortion scale parameters // NOTE: To get lens max radius, lensShift must be normalized to [-1..1] float lensRadius = fabsf(-1.0f - 4.0f*lensShift); float lensRadiusSq = lensRadius*lensRadius; - float distortionScale = hmd.distortionK[0] + - hmd.distortionK[1]*lensRadiusSq + - hmd.distortionK[2]*lensRadiusSq*lensRadiusSq + + float distortionScale = hmd.distortionK[0] + + hmd.distortionK[1]*lensRadiusSq + + hmd.distortionK[2]*lensRadiusSq*lensRadiusSq + hmd.distortionK[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq; - + TraceLog(DEBUG, "VR: Distortion Scale: %f", distortionScale); - + float normScreenWidth = 0.5f; float normScreenHeight = 1.0f; float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect }; float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale }; - + TraceLog(DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]); TraceLog(DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]); TraceLog(DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]); TraceLog(DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]); - + // Update distortion shader with lens and distortion-scale parameters SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftScreenCenter"), leftScreenCenter, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightScreenCenter"), rightScreenCenter, 2); - + SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scale"), scale, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.distortionK, 4); @@ -3641,24 +3641,24 @@ static void SetStereoConfig(VrDeviceInfo hmd) // ...but with lens distortion it is increased (see Oculus SDK Documentation) //float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance)*RAD2DEG; // Really need distortionScale? float fovy = 2.0f*(float)atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance)*RAD2DEG; - + // Compute camera projection matrices float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1] Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0); vrConfig.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f)); vrConfig.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f)); - + // NOTE: Projection matrices must be transposed due to raymath convention MatrixTranspose(&vrConfig.eyesProjection[0]); MatrixTranspose(&vrConfig.eyesProjection[1]); - + // Compute camera transformation matrices - // NOTE: Camera movement might seem more natural if we model the head. - // Our axis of rotation is the base of our head, so we might want to add + // NOTE: Camera movement might seem more natural if we model the head. + // Our axis of rotation is the base of our head, so we might want to add // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. vrConfig.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f); vrConfig.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f); - + // Compute eyes Viewports //vrConfig.eyesViewport[0] = (Rectangle){ 0, 0, hmd.hResolution/2, hmd.vResolution }; //vrConfig.eyesViewport[1] = (Rectangle){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution }; @@ -3675,17 +3675,17 @@ static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) #if defined(RLGL_OCULUS_SUPPORT) if (vrDeviceReady) { - rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, + rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); - Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, layer.eyeLayer.RenderPose[eye].Orientation.w }; QuaternionInvert(&eyeRenderPose); Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, -layer.eyeLayer.RenderPose[eye].Position.z); Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement @@ -3701,7 +3701,7 @@ static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) // Apply view offset to modelview matrix eyeModelView = MatrixMultiply(matModelView, vrConfig.eyesViewOffset[eye]); - + eyeProjection = vrConfig.eyesProjection[eye]; } @@ -3845,7 +3845,7 @@ OCULUSAPI bool InitOculusDevice(void) bool oculusReady = false; ovrResult result = ovr_Initialize(NULL); - + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); else { @@ -3865,24 +3865,24 @@ OCULUSAPI bool InitOculusDevice(void) TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) - + // Initialize Oculus Buffers - layer = InitOculusLayer(session); + layer = InitOculusLayer(session); buffer = LoadOculusBuffer(session, layer.width, layer.height); mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); - + // Recenter OVR tracking origin ovr_RecenterTrackingOrigin(session); - + oculusReady = true; vrEnabled = true; } } - + return oculusReady; } @@ -3903,18 +3903,18 @@ OCULUSAPI void UpdateOculusTracking(Camera *camera) ovrPosef eyePoses[2]; ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - + layer.eyeLayer.RenderPose[0] = eyePoses[0]; layer.eyeLayer.RenderPose[1] = eyePoses[1]; - + // TODO: Update external camera with eyePoses data (position, orientation) // NOTE: We can simplify to simple camera if we consider IPD and HMD device configuration again later // it will be useful for the user to draw, lets say, billboards oriented to camera - + // Get session status information ovrSessionStatus sessionStatus; ovr_GetSessionStatus(session, &sessionStatus); - + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); //if (sessionStatus.HmdPresent) // HMD is present. @@ -3928,7 +3928,7 @@ OCULUSAPI void BeginOculusDrawing(void) { GLuint currentTexId; int currentIndex; - + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); @@ -3943,9 +3943,9 @@ OCULUSAPI void EndOculusDrawing(void) // Unbind current framebuffer (Oculus buffer) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - + ovr_CommitTextureSwapChain(session, buffer.textureChain); - + ovrLayerHeader *layers = &layer.eyeLayer.Header; ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); @@ -3959,7 +3959,7 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) OculusBuffer buffer; buffer.width = width; buffer.height = height; - + // Create OVR texture chain ovrTextureSwapChainDesc desc = {}; desc.Type = ovrTexture_2D; @@ -3972,12 +3972,12 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) desc.StaticImage = ovrFalse; ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); - + if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); int textureCount = 0; ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); - + if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); for (int i = 0; i < textureCount; ++i) @@ -3990,9 +3990,9 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } - + glBindTexture(GL_TEXTURE_2D, 0); - + /* // Setup framebuffer object (using depth texture) glGenFramebuffers(1, &buffer.fboId); @@ -4004,7 +4004,7 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); */ - + // Setup framebuffer object (using depth renderbuffer) glGenFramebuffers(1, &buffer.fboId); glGenRenderbuffers(1, &buffer.depthId); @@ -4037,13 +4037,13 @@ static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) OculusMirror mirror; mirror.width = width; mirror.height = height; - + ovrMirrorTextureDesc mirrorDesc; memset(&mirrorDesc, 0, sizeof(mirrorDesc)); mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; mirrorDesc.Width = mirror.width; mirrorDesc.Height = mirror.height; - + if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); glGenFramebuffers(1, &mirror.fboId); @@ -4062,9 +4062,9 @@ static void UnloadOculusMirror(ovrSession session, OculusMirror mirror) static void BlitOculusMirror(ovrSession session, OculusMirror mirror) { GLuint mirrorTextureId; - + ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId); - + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); #if defined(GRAPHICS_API_OPENGL_33) @@ -4078,7 +4078,7 @@ static void BlitOculusMirror(ovrSession session, OculusMirror mirror) static OculusLayer InitOculusLayer(ovrSession session) { OculusLayer layer = { 0 }; - + layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov)); @@ -4086,7 +4086,7 @@ static OculusLayer InitOculusLayer(ovrSession session) layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; ovrEyeRenderDesc eyeRenderDescs[2]; - + for (int eye = 0; eye < 2; eye++) { eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]); @@ -4095,7 +4095,7 @@ static OculusLayer InitOculusLayer(ovrSession session) layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset; layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov; - + ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f); layer.eyeLayer.Viewport[eye].Size = eyeSize; layer.eyeLayer.Viewport[eye].Pos.x = layer.width; @@ -4104,7 +4104,7 @@ static OculusLayer InitOculusLayer(ovrSession session) layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h); layer.width += eyeSize.w; } - + return layer; } @@ -4112,7 +4112,7 @@ static OculusLayer InitOculusLayer(ovrSession session) static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) { Matrix rmat; - + rmat.m0 = ovrmat.M[0][0]; rmat.m1 = ovrmat.M[1][0]; rmat.m2 = ovrmat.M[2][0]; @@ -4129,9 +4129,9 @@ static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) rmat.m13 = ovrmat.M[1][3]; rmat.m14 = ovrmat.M[2][3]; rmat.m15 = ovrmat.M[3][3]; - + MatrixTranspose(&rmat); - + return rmat; } #endif @@ -4162,7 +4162,7 @@ void TraceLog(int msgType, const char *text, ...) } // Converts Matrix to float array -// NOTE: Returned vector is a transposed version of the Matrix struct, +// NOTE: Returned vector is a transposed version of the Matrix struct, // it should be this way because, despite raymath use OpenGL column-major convention, // Matrix struct memory alignment and variables naming are not coherent float *MatrixToFloat(Matrix mat) diff --git a/src/text.c b/src/text.c index 4e163668..e3d22fbd 100644 --- a/src/text.c +++ b/src/text.c @@ -286,17 +286,17 @@ SpriteFont LoadSpriteFont(const char *fileName) SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars) { SpriteFont spriteFont = { 0 }; - - if (strcmp(GetExtension(fileName),"ttf") == 0) + + if (strcmp(GetExtension(fileName),"ttf") == 0) { if ((fontChars == NULL) || (numChars == 0)) { int totalChars = 95; // Default charset [32..126] - + int *defaultFontChars = (int *)malloc(totalChars*sizeof(int)); - + for (int i = 0; i < totalChars; i++) defaultFontChars[i] = i + 32; // Default first character: SPACE[32] - + spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars); } else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars); @@ -353,10 +353,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float int textOffsetX = 0; // Offset between characters int textOffsetY = 0; // Required for line break! float scaleFactor; - + unsigned char letter; // Current character int index; // Index position in sprite font - + scaleFactor = fontSize/spriteFont.size; // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly @@ -388,10 +388,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float } else index = GetCharIndex(spriteFont, (int)text[i]); - DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index], + DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index], (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor, position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor, - spriteFont.charRecs[index].width*scaleFactor, + spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing); @@ -476,7 +476,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (text[i] != '\n') { int index = GetCharIndex(spriteFont, (int)text[i]); - + if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index]; else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x); } @@ -517,7 +517,7 @@ static int GetCharIndex(SpriteFont font, int letter) #define UNORDERED_CHARSET #if defined(UNORDERED_CHARSET) int index = 0; - + for (int i = 0; i < font.numChars; i++) { if (font.charValues[i] == letter) @@ -526,7 +526,7 @@ static int GetCharIndex(SpriteFont font, int letter) break; } } - + return index; #else return (letter - 32); @@ -607,14 +607,14 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) } TraceLog(DEBUG, "SpriteFont data parsed correctly from image"); - - // NOTE: We need to remove key color borders from image to avoid weird + + // NOTE: We need to remove key color borders from image to avoid weird // artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK; // Create a new image with the processed color data (key color replaced by BLANK) Image fontClear = LoadImageEx(pixels, image.width, image.height); - + free(pixels); // Free pixels array memory // Create spritefont with all data parsed from image @@ -622,7 +622,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture spriteFont.numChars = index; - + UnloadImage(fontClear); // Unload processed image once converted to texture // We got tempCharValues and tempCharsRecs populated with chars data @@ -643,7 +643,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) } spriteFont.size = spriteFont.charRecs[0].height; - + TraceLog(INFO, "Image file loaded correctly as SpriteFont"); return spriteFont; @@ -853,13 +853,13 @@ static SpriteFont LoadBMFont(const char *fileName) strncat(texPath, texFileName, strlen(texFileName)); TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath); - + Image imFont = LoadImage(texPath); - - if (imFont.format == UNCOMPRESSED_GRAYSCALE) + + if (imFont.format == UNCOMPRESSED_GRAYSCALE) { Image imCopy = ImageCopy(imFont); - + for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff; // WHITE pixel ImageAlphaMask(&imCopy, imFont); @@ -867,7 +867,7 @@ static SpriteFont LoadBMFont(const char *fileName) UnloadImage(imCopy); } else font.texture = LoadTextureFromImage(imFont); - + font.size = fontSize; font.numChars = numChars; font.charValues = (int *)malloc(numChars*sizeof(int)); @@ -876,7 +876,7 @@ static SpriteFont LoadBMFont(const char *fileName) font.charAdvanceX = (int *)malloc(numChars*sizeof(int)); UnloadImage(imFont); - + free(texPath); int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; @@ -913,11 +913,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int // NOTE: Font texture size is predicted (being as much conservative as possible) // Predictive method consist of supposing same number of chars by line-column (sqrtf) // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests... - + // Calculate next power-of-two value float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars)); int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT - + TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize); unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25); @@ -935,7 +935,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int } fread(ttfBuffer, 1, 1 << 25, ttfFile); - + if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character"); // NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image... @@ -945,7 +945,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int //if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result); if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font"); - + free(ttfBuffer); // Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA @@ -966,11 +966,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int image.mipmaps = 1; image.format = UNCOMPRESSED_GRAY_ALPHA; image.data = dataGrayAlpha; - + font.texture = LoadTextureFromImage(image); - + //SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2); - + UnloadImage(image); // Unloads dataGrayAlpha font.size = fontSize; diff --git a/src/textures.c b/src/textures.c index 3fa250c2..9d865aa1 100644 --- a/src/textures.c +++ b/src/textures.c @@ -144,9 +144,9 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"rres") == 0) { RRESData rres = LoadResource(fileName); - + // NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps - + if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName); @@ -197,9 +197,9 @@ Image LoadImagePro(void *data, int width, int height, int format) srcImage.height = height; srcImage.mipmaps = 1; srcImage.format = format; - + Image dstImage = ImageCopy(srcImage); - + return dstImage; } @@ -244,7 +244,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int if (bytes < size) { TraceLog(WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName); - + if (image.data != NULL) free(image.data); } else @@ -615,12 +615,12 @@ void ImageAlphaMask(Image *image, Image alphaMask) // Force mask to be Grayscale Image mask = ImageCopy(alphaMask); if (mask.format != UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE); - + // In case image is only grayscale, we just add alpha channel if (image->format == UNCOMPRESSED_GRAYSCALE) { ImageFormat(image, UNCOMPRESSED_GRAY_ALPHA); - + // Apply alpha mask to alpha channel for (int i = 0, k = 1; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 2) { @@ -955,7 +955,7 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight) void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) { bool cropRequired = false; - + // Security checks to avoid size and rectangle issues (out of bounds) // Check that srcRec is inside src image if (srcRec.x < 0) srcRec.x = 0; @@ -973,15 +973,15 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height); cropRequired = true; } - + Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle - + // Check that dstRec is inside dst image // TODO: Allow negative position within destination with cropping if (dstRec.x < 0) dstRec.x = 0; if (dstRec.y < 0) dstRec.y = 0; - + // Scale source image in case destination rec size is different than source rec size if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height)) { @@ -1001,20 +1001,20 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height); cropRequired = true; } - + if (cropRequired) { // Crop destination rectangle if out of bounds Rectangle crop = { 0, 0, dstRec.width, dstRec.height }; ImageCrop(&srcCopy, crop); } - + // Get image data as Color pixels array to work with it Color *dstPixels = GetImageData(*dst); Color *srcPixels = GetImageData(srcCopy); UnloadImage(srcCopy); // Source copy not required any more... - + Color srcCol, dstCol; // Blit pixels, copy source image into destination @@ -1026,13 +1026,13 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) // Alpha blending implementation dstCol = dstPixels[j*dst->width + i]; srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)]; - + dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r; dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g; dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b; - + dstPixels[j*dst->width + i] = dstCol; - + // TODO: Support other blending options } } @@ -1369,7 +1369,7 @@ void SetTextureFilter(Texture2D texture, int filterMode) { // RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps) rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST); - + // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); } @@ -1387,7 +1387,7 @@ void SetTextureFilter(Texture2D texture, int filterMode) // RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps) // Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps) rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST); - + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); } @@ -1404,14 +1404,14 @@ void SetTextureFilter(Texture2D texture, int filterMode) { // RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps) rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR); - + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); } else { TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id); - + // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); @@ -2007,19 +2007,19 @@ static Image LoadPVR(const char *fileName) image.mipmaps = pvrHeader.numMipmaps; // Check data format - if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8)) + if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8)) image.format = UNCOMPRESSED_GRAYSCALE; - else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8))) + else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8))) image.format = UNCOMPRESSED_GRAY_ALPHA; else if ((pvrHeader.channels[0] == 'r') && (pvrHeader.channels[1] == 'g') && (pvrHeader.channels[2] == 'b')) { if (pvrHeader.channels[3] == 'a') { - if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1)) + if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1)) image.format = UNCOMPRESSED_R5G5B5A1; - else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4)) + else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4)) image.format = UNCOMPRESSED_R4G4B4A4; - else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8)) + else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8)) image.format = UNCOMPRESSED_R8G8B8A8; } else if (pvrHeader.channels[3] == 0) -- cgit v1.2.3 From 30bb24aa6e80fe8ecc9eddc4efd008ecc89b60f4 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 29 Jan 2017 22:29:54 +0100 Subject: Updated Gestures enum --- src/gestures.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gestures.h b/src/gestures.h index 19b09269..f4dcb133 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -65,17 +65,17 @@ // Gestures type // NOTE: It could be used as flags to enable only some gestures typedef enum { - GESTURE_NONE = 1, - GESTURE_TAP = 2, - GESTURE_DOUBLETAP = 4, - GESTURE_HOLD = 8, - GESTURE_DRAG = 16, - GESTURE_SWIPE_RIGHT = 32, - GESTURE_SWIPE_LEFT = 64, - GESTURE_SWIPE_UP = 128, - GESTURE_SWIPE_DOWN = 256, - GESTURE_PINCH_IN = 512, - GESTURE_PINCH_OUT = 1024 + GESTURE_NONE = 0, + GESTURE_TAP = 1, + GESTURE_DOUBLETAP = 2, + GESTURE_HOLD = 4, + GESTURE_DRAG = 8, + GESTURE_SWIPE_RIGHT = 16, + GESTURE_SWIPE_LEFT = 32, + GESTURE_SWIPE_UP = 64, + GESTURE_SWIPE_DOWN = 128, + GESTURE_PINCH_IN = 256, + GESTURE_PINCH_OUT = 512 } Gestures; #endif -- cgit v1.2.3 From 495108a2e9a911c88c090f2ddd82391130701031 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 29 Jan 2017 23:08:19 +0100 Subject: Updated raylib version to 1.7 Preparing for next version... still some work left... :P --- src/core.c | 4 ++-- src/raylib.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index ea363fce..4ce32a05 100644 --- a/src/core.c +++ b/src/core.c @@ -330,7 +330,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread // Initialize Window and Graphics Context (OpenGL) void InitWindow(int width, int height, const char *title) { - TraceLog(INFO, "Initializing raylib (v1.6.0)"); + TraceLog(INFO, "Initializing raylib (v1.7.0)"); // Store window title (could be useful...) windowTitle = title; @@ -387,7 +387,7 @@ void InitWindow(int width, int height, const char *title) // Android activity initialization void InitWindow(int width, int height, void *state) { - TraceLog(INFO, "Initializing raylib (v1.6.0)"); + TraceLog(INFO, "Initializing raylib (v1.7.0)"); app_dummy(); diff --git a/src/raylib.h b/src/raylib.h index c1c9ebae..3c84ee72 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* raylib 1.6.0 (www.raylib.com) +* raylib 1.7.0 (www.raylib.com) * * A simple and easy-to-use library to learn videogames programming * -- cgit v1.2.3 From a08117155da1a0a439239ad8801a58b85f528014 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 1 Feb 2017 00:28:28 +0100 Subject: Init memory for screenshot to zero --- src/rlgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/rlgl.c b/src/rlgl.c index 6c4e5927..ce17adc3 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2198,7 +2198,7 @@ void rlglUnloadMesh(Mesh *mesh) // Read screen pixel data (color buffer) unsigned char *rlglReadScreenPixels(int width, int height) { - unsigned char *screenData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); + unsigned char *screenData = (unsigned char *)calloc(width*height*4, sizeof(unsigned char)); // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); -- cgit v1.2.3 From 1a879ba08efe1877c26a76bfabd43f282d2b2a97 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Feb 2017 02:59:39 +0100 Subject: Refactor SpriteFont struct Now it uses CharInfo data, this way, it's better aligned with the future RRES file format data layout for sprite font characters. --- examples/text_bmfont_ttf.c | 8 +- examples/text_bmfont_unordered.c | 6 +- examples/text_font_select.c | 6 +- examples/text_rbmf_fonts.c | 6 +- examples/text_sprite_fonts.c | 18 +-- examples/text_ttf_loading.c | 2 +- src/raylib.h | 20 ++-- src/rlua.h | 8 +- src/text.c | 230 +++++++++++++++++++++------------------ src/textures.c | 4 +- 10 files changed, 164 insertions(+), 144 deletions(-) (limited to 'src') diff --git a/examples/text_bmfont_ttf.c b/examples/text_bmfont_ttf.c index caece548..4d060915 100644 --- a/examples/text_bmfont_ttf.c +++ b/examples/text_bmfont_ttf.c @@ -29,8 +29,8 @@ int main() Vector2 fontPosition; - fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.size, 0).x/2; - fontPosition.y = screenHeight/2 - fontBm.size/2 - 80; + fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.baseSize, 0).x/2; + fontPosition.y = screenHeight/2 - fontBm.baseSize/2 - 80; SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -49,8 +49,8 @@ int main() ClearBackground(RAYWHITE); - DrawTextEx(fontBm, msgBm, fontPosition, fontBm.size, 0, MAROON); - DrawTextEx(fontTtf, msgTtf, (Vector2){ 75.0f, 240.0f }, fontTtf.size*0.8f, 2, LIME); + DrawTextEx(fontBm, msgBm, fontPosition, fontBm.baseSize, 0, MAROON); + DrawTextEx(fontTtf, msgTtf, (Vector2){ 75.0f, 240.0f }, fontTtf.baseSize*0.8f, 2, LIME); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/text_bmfont_unordered.c b/examples/text_bmfont_unordered.c index b29c5f8b..6fec3256 100644 --- a/examples/text_bmfont_unordered.c +++ b/examples/text_bmfont_unordered.c @@ -45,10 +45,10 @@ int main() ClearBackground(RAYWHITE); DrawText("Font name: PixAntiqua", 40, 50, 20, GRAY); - DrawText(FormatText("Font base size: %i", font.size), 40, 80, 20, GRAY); - DrawText(FormatText("Font chars number: %i", font.numChars), 40, 110, 20, GRAY); + DrawText(FormatText("Font base size: %i", font.baseSize), 40, 80, 20, GRAY); + DrawText(FormatText("Font chars number: %i", font.charsCount), 40, 110, 20, GRAY); - DrawTextEx(font, msg, (Vector2){ 40, 180 }, font.size, 0, MAROON); + DrawTextEx(font, msg, (Vector2){ 40, 180 }, font.baseSize, 0, MAROON); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/text_font_select.c b/examples/text_font_select.c index fe586db8..5891bef7 100644 --- a/examples/text_font_select.c +++ b/examples/text_font_select.c @@ -41,7 +41,7 @@ int main() const char text[50] = "THIS is THE FONT you SELECTED!"; // Main text - Vector2 textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1); + Vector2 textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].baseSize*3, 1); Vector2 mousePoint; @@ -118,7 +118,7 @@ int main() } // Text measurement for better positioning on screen - textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1); + textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].baseSize*3, 1); //---------------------------------------------------------------------------------- // Draw @@ -140,7 +140,7 @@ int main() DrawText("NEXT", 700, positionY + 13, 20, btnNextOutColor); DrawTextEx(fonts[currentFont], text, (Vector2){ screenWidth/2 - textSize.x/2, - 260 + (70 - textSize.y)/2 }, fonts[currentFont].size*3, + 260 + (70 - textSize.y)/2 }, fonts[currentFont].baseSize*3, 1, colors[currentFont]); EndDrawing(); diff --git a/examples/text_rbmf_fonts.c b/examples/text_rbmf_fonts.c index b4bd851b..cd5da1fe 100644 --- a/examples/text_rbmf_fonts.c +++ b/examples/text_rbmf_fonts.c @@ -50,8 +50,8 @@ int main() for (int i = 0; i < 8; i++) { - positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], fonts[i].size*2, spacings[i]).x/2; - positions[i].y = 60 + fonts[i].size + 50*i; + positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], fonts[i].baseSize*2, spacings[i]).x/2; + positions[i].y = 60 + fonts[i].baseSize + 50*i; } Color colors[8] = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD }; @@ -76,7 +76,7 @@ int main() for (int i = 0; i < 8; i++) { - DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].size*2, spacings[i], colors[i]); + DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].baseSize*2, spacings[i], colors[i]); } EndDrawing(); diff --git a/examples/text_sprite_fonts.c b/examples/text_sprite_fonts.c index c73eda85..bded266e 100644 --- a/examples/text_sprite_fonts.c +++ b/examples/text_sprite_fonts.c @@ -31,14 +31,14 @@ int main() Vector2 fontPosition1, fontPosition2, fontPosition3; - fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, font1.size, -3).x/2; - fontPosition1.y = screenHeight/2 - font1.size/2 - 80; + fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, font1.baseSize, -3).x/2; + fontPosition1.y = screenHeight/2 - font1.baseSize/2 - 80; - fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, font2.size, -2).x/2; - fontPosition2.y = screenHeight/2 - font2.size/2 - 10; + fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, font2.baseSize, -2).x/2; + fontPosition2.y = screenHeight/2 - font2.baseSize/2 - 10; - fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, font3.size, 2).x/2; - fontPosition3.y = screenHeight/2 - font3.size/2 + 50; + fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, font3.baseSize, 2).x/2; + fontPosition3.y = screenHeight/2 - font3.baseSize/2 + 50; //-------------------------------------------------------------------------------------- @@ -56,9 +56,9 @@ int main() ClearBackground(RAYWHITE); - DrawTextEx(font1, msg1, fontPosition1, font1.size, -3, WHITE); - DrawTextEx(font2, msg2, fontPosition2, font2.size, -2, WHITE); - DrawTextEx(font3, msg3, fontPosition3, font3.size, 2, WHITE); + DrawTextEx(font1, msg1, fontPosition1, font1.baseSize, -3, WHITE); + DrawTextEx(font2, msg2, fontPosition2, font2.baseSize, -2, WHITE); + DrawTextEx(font3, msg3, fontPosition3, font3.baseSize, 2, WHITE); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/text_ttf_loading.c b/examples/text_ttf_loading.c index 918209dd..10025c2f 100644 --- a/examples/text_ttf_loading.c +++ b/examples/text_ttf_loading.c @@ -31,7 +31,7 @@ int main() // NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR GenTextureMipmaps(&font.texture); - float fontSize = font.size; + float fontSize = font.baseSize; Vector2 fontPosition = { 40, screenHeight/2 + 50 }; Vector2 textSize; diff --git a/src/raylib.h b/src/raylib.h index 3c84ee72..f5b908db 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -370,15 +370,21 @@ typedef struct RenderTexture2D { Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; +// SpriteFont character info +typedef struct CharInfo { + int value; // Character value (Unicode) + Rectangle rec; // Character rectangle in sprite font + int offsetX; // Character offset X when drawing + int offsetY; // Character offset Y when drawing + int advanceX; // Character advance position X +} CharInfo; + // SpriteFont type, includes texture and charSet array data typedef struct SpriteFont { Texture2D texture; // Font texture - int size; // Base size (default chars height) - int numChars; // Number of characters - int *charValues; // Characters values array - Rectangle *charRecs; // Characters rectangles within the texture - Vector2 *charOffsets; // Characters offsets (on drawing) - int *charAdvanceX; // Characters x advance (on drawing) + int baseSize; // Base size (default chars height) + int charsCount; // Number of characters + CharInfo *chars; // Characters info data } SpriteFont; // Camera type, defines a camera position/orientation in 3d space @@ -825,7 +831,7 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from TTF font file with generation parameters RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) diff --git a/src/rlua.h b/src/rlua.h index e9ed2c3c..80dede41 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -16,7 +16,7 @@ * * The following types: * Image, Texture2D, RenderTexture2D, SpriteFont -* are immutable, and you can only read their non-pointer arguments (e.g. sprfnt.size). +* are immutable, and you can only read their non-pointer arguments (e.g. sprfnt.baseSize). * * All other object types are opaque, that is, you cannot access or * change their fields directly. @@ -293,8 +293,8 @@ static int LuaIndexSpriteFont(lua_State* L) lua_pushinteger(L, img.size); else if (!strcmp(key, "texture")) LuaPush_Texture2D(L, img.texture); - else if (!strcmp(key, "numChars")) - lua_pushinteger(L, img.numChars); + else if (!strcmp(key, "charsCount")) + lua_pushinteger(L, img.charsCount); else return 0; return 1; @@ -2203,7 +2203,7 @@ int lua_LoadSpriteFontTTF(lua_State* L) int arg2 = LuaGetArgument_int(L, 2); int arg3 = LuaGetArgument_int(L, 3); int arg4 = LuaGetArgument_int(L, 4); - //LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); + //LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); SpriteFont result = LoadSpriteFontTTF(arg1, arg2, arg3, &arg4); LuaPush_SpriteFont(L, result); return 1; diff --git a/src/text.c b/src/text.c index e3d22fbd..af07bb69 100644 --- a/src/text.c +++ b/src/text.c @@ -79,7 +79,7 @@ static int GetCharIndex(SpriteFont font, int letter); static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style) static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font) static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) -static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load spritefont from TTF data +static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data extern void LoadDefaultFont(void); extern void UnloadDefaultFont(void); @@ -92,7 +92,7 @@ extern void LoadDefaultFont(void) // NOTE: Using UTF8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement // http://www.utf8-chartable.de/unicode-utf8-table.pl - defaultFont.numChars = 224; // Number of chars included in our default font + defaultFont.charsCount = 224; // Number of chars included in our default font // Default font is directly defined here (data generated from a sprite font image) // This way, we reconstruct SpriteFont without creating large global variables @@ -189,29 +189,27 @@ extern void LoadDefaultFont(void) defaultFont.texture = LoadTextureFromImage(image); UnloadImage(image); - // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars + // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, charsCount //------------------------------------------------------------------------------ - defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int)); - defaultFont.charRecs = (Rectangle *)malloc(defaultFont.numChars*sizeof(Rectangle)); // Allocate space for our character rectangle data - // This memory should be freed at end! --> Done on CloseWindow() - - defaultFont.charOffsets = (Vector2 *)malloc(defaultFont.numChars*sizeof(Vector2)); - defaultFont.charAdvanceX = (int *)malloc(defaultFont.numChars*sizeof(int)); + + // Allocate space for our characters info data + // NOTE: This memory should be freed at end! --> CloseWindow() + defaultFont.chars = (CharInfo *)malloc(defaultFont.charsCount*sizeof(CharInfo)); int currentLine = 0; int currentPosX = charsDivisor; int testPosX = charsDivisor; - for (int i = 0; i < defaultFont.numChars; i++) + for (int i = 0; i < defaultFont.charsCount; i++) { - defaultFont.charValues[i] = 32 + i; // First char is 32 + defaultFont.chars[i].value = 32 + i; // First char is 32 - defaultFont.charRecs[i].x = currentPosX; - defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor); - defaultFont.charRecs[i].width = charsWidth[i]; - defaultFont.charRecs[i].height = charsHeight; + defaultFont.chars[i].rec.x = currentPosX; + defaultFont.chars[i].rec.y = charsDivisor + currentLine*(charsHeight + charsDivisor); + defaultFont.chars[i].rec.width = charsWidth[i]; + defaultFont.chars[i].rec.height = charsHeight; - testPosX += (defaultFont.charRecs[i].width + charsDivisor); + testPosX += (defaultFont.chars[i].rec.width + charsDivisor); if (testPosX >= defaultFont.texture.width) { @@ -219,17 +217,18 @@ extern void LoadDefaultFont(void) currentPosX = 2*charsDivisor + charsWidth[i]; testPosX = currentPosX; - defaultFont.charRecs[i].x = charsDivisor; - defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor); + defaultFont.chars[i].rec.x = charsDivisor; + defaultFont.chars[i].rec.y = charsDivisor + currentLine*(charsHeight + charsDivisor); } else currentPosX = testPosX; // NOTE: On default font character offsets and xAdvance are not required - defaultFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; - defaultFont.charAdvanceX[i] = 0; + defaultFont.chars[i].offsetX = 0; + defaultFont.chars[i].offsetY = 0; + defaultFont.chars[i].advanceX = 0; } - defaultFont.size = defaultFont.charRecs[0].height; + defaultFont.baseSize = defaultFont.chars[0].rec.height; TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id); } @@ -237,10 +236,7 @@ extern void LoadDefaultFont(void) extern void UnloadDefaultFont(void) { UnloadTexture(defaultFont.texture); - free(defaultFont.charValues); - free(defaultFont.charRecs); - free(defaultFont.charOffsets); - free(defaultFont.charAdvanceX); + free(defaultFont.chars); } // Get the default font, useful to be used with extended parameters @@ -260,9 +256,35 @@ SpriteFont LoadSpriteFont(const char *fileName) SpriteFont spriteFont = { 0 }; // Check file extension - if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName); + if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName); // TODO: DELETE... SOON... else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadSpriteFontTTF(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL); else if (strcmp(GetExtension(fileName),"fnt") == 0) spriteFont = LoadBMFont(fileName); + else if (strcmp(GetExtension(fileName),"rres") == 0) + { + // TODO: Read multiple resource blocks from file (RRES_FONT_IMAGE, RRES_FONT_CHARDATA) + RRESData rres = LoadResource(fileName); + + // Load sprite font texture + if (rres.type == RRES_FONT_IMAGE) + { + // NOTE: Parameters for RRES_FONT_IMAGE type are: width, height, format, mipmaps + Image image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + spriteFont.texture = LoadTextureFromImage(image); + UnloadImage(image); + } + + // Load sprite characters data + if (rres.type == RRES_FONT_CHARDATA) + { + // NOTE: Parameters for RRES_FONT_CHARDATA type are: fontSize, charsCount + spriteFont.baseSize = rres.param1; + spriteFont.charsCount = rres.param2; + spriteFont.chars = rres.data; + } + + // TODO: Do not free rres.data memory (chars info data!) + UnloadResource(rres); + } else { Image image = LoadImage(fileName); @@ -283,13 +305,13 @@ SpriteFont LoadSpriteFont(const char *fileName) // Load SpriteFont from TTF font file with generation parameters // NOTE: You can pass an array with desired characters, those characters should be available in the font // if array is NULL, default char set is selected 32..126 -SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars) +SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars) { SpriteFont spriteFont = { 0 }; if (strcmp(GetExtension(fileName),"ttf") == 0) { - if ((fontChars == NULL) || (numChars == 0)) + if ((fontChars == NULL) || (charsCount == 0)) { int totalChars = 95; // Default charset [32..126] @@ -299,7 +321,7 @@ SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, i spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars); } - else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars); + else spriteFont = LoadTTF(fileName, fontSize, charsCount, fontChars); } if (spriteFont.texture.id == 0) @@ -318,10 +340,7 @@ void UnloadSpriteFont(SpriteFont spriteFont) if (spriteFont.texture.id != defaultFont.texture.id) { UnloadTexture(spriteFont.texture); - free(spriteFont.charValues); - free(spriteFont.charRecs); - free(spriteFont.charOffsets); - free(spriteFont.charAdvanceX); + free(spriteFont.chars); TraceLog(DEBUG, "Unloaded sprite font data"); } @@ -357,7 +376,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float unsigned char letter; // Current character int index; // Index position in sprite font - scaleFactor = fontSize/spriteFont.size; + scaleFactor = fontSize/spriteFont.baseSize; // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) @@ -367,7 +386,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines - textOffsetY += (int)((spriteFont.size + spriteFont.size/2)*scaleFactor); + textOffsetY += (int)((spriteFont.baseSize + spriteFont.baseSize/2)*scaleFactor); textOffsetX = 0; } else @@ -388,14 +407,14 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float } else index = GetCharIndex(spriteFont, (int)text[i]); - DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index], - (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor, - position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor, - spriteFont.charRecs[index].width*scaleFactor, - spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); + DrawTexturePro(spriteFont.texture, spriteFont.chars[index].rec, + (Rectangle){ position.x + textOffsetX + spriteFont.chars[index].offsetX*scaleFactor, + position.y + textOffsetY + spriteFont.chars[index].offsetY*scaleFactor, + spriteFont.chars[index].rec.width*scaleFactor, + spriteFont.chars[index].rec.height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); - if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing); - else textOffsetX += (int)(spriteFont.charAdvanceX[index]*scaleFactor + spacing); + if (spriteFont.chars[index].advanceX == 0) textOffsetX += (int)(spriteFont.chars[index].rec.width*scaleFactor + spacing); + else textOffsetX += (int)(spriteFont.chars[index].advanceX*scaleFactor + spacing); } } } @@ -466,8 +485,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i float textWidth = 0; float tempTextWidth = 0; // Used to count longer text line width - float textHeight = (float)spriteFont.size; - float scaleFactor = fontSize/(float)spriteFont.size; + float textHeight = (float)spriteFont.baseSize; + float scaleFactor = fontSize/(float)spriteFont.baseSize; for (int i = 0; i < len; i++) { @@ -477,15 +496,15 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i { int index = GetCharIndex(spriteFont, (int)text[i]); - if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index]; - else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x); + if (spriteFont.chars[index].advanceX != 0) textWidth += spriteFont.chars[index].advanceX; + else textWidth += (spriteFont.chars[index].rec.width + spriteFont.chars[index].offsetX); } else { if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; - textHeight += ((float)spriteFont.size*1.5f); // NOTE: Fixed line spacing of 1.5 lines + textHeight += ((float)spriteFont.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; @@ -518,9 +537,9 @@ static int GetCharIndex(SpriteFont font, int letter) #if defined(UNORDERED_CHARSET) int index = 0; - for (int i = 0; i < font.numChars; i++) + for (int i = 0; i < font.charsCount; i++) { - if (font.charValues[i] == letter) + if (font.chars[i].value == letter) { index = i; break; @@ -621,28 +640,26 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) SpriteFont spriteFont = { 0 }; spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture - spriteFont.numChars = index; + spriteFont.charsCount = index; UnloadImage(fontClear); // Unload processed image once converted to texture // We got tempCharValues and tempCharsRecs populated with chars data // Now we move temp data to sized charValues and charRecs arrays - spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle)); - spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); - spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2)); - spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int)); + spriteFont.chars = (CharInfo *)malloc(spriteFont.charsCount*sizeof(CharInfo)); - for (int i = 0; i < spriteFont.numChars; i++) + for (int i = 0; i < spriteFont.charsCount; i++) { - spriteFont.charValues[i] = tempCharValues[i]; - spriteFont.charRecs[i] = tempCharRecs[i]; + spriteFont.chars[i].value = tempCharValues[i]; + spriteFont.chars[i].rec = tempCharRecs[i]; // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) - spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; - spriteFont.charAdvanceX[i] = 0; + spriteFont.chars[i].offsetX = 0; + spriteFont.chars[i].offsetY = 0; + spriteFont.chars[i].advanceX = 0; } - spriteFont.size = spriteFont.charRecs[0].height; + spriteFont.baseSize = spriteFont.chars[0].rec.height; TraceLog(INFO, "Image file loaded correctly as SpriteFont"); @@ -672,6 +689,8 @@ static SpriteFont LoadRBMF(const char *fileName) SpriteFont spriteFont = { 0 }; + // REMOVE SOON!!! +/* rbmfInfoHeader rbmfHeader; unsigned int *rbmfFileData = NULL; unsigned char *rbmfCharWidthData = NULL; @@ -737,29 +756,27 @@ static SpriteFont LoadRBMF(const char *fileName) //TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName); // Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars - spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); - spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle)); - spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2)); - spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int)); + spriteFont.chars = (CharInfo *)malloc(spriteFont.charsCount*sizeof(CharInfo)); int currentLine = 0; int currentPosX = charsDivisor; int testPosX = charsDivisor; - for (int i = 0; i < spriteFont.numChars; i++) + for (int i = 0; i < spriteFont.charsCount; i++) { - spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i; + spriteFont.chars[i].value = (int)rbmfHeader.firstChar + i; - spriteFont.charRecs[i].x = currentPosX; - spriteFont.charRecs[i].y = charsDivisor + currentLine*((int)rbmfHeader.charHeight + charsDivisor); - spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i]; - spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight; + spriteFont.chars[i].rec.x = currentPosX; + spriteFont.chars[i].rec.y = charsDivisor + currentLine*((int)rbmfHeader.charHeight + charsDivisor); + spriteFont.chars[i].rec.width = (int)rbmfCharWidthData[i]; + spriteFont.chars[i].rec.height = (int)rbmfHeader.charHeight; // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) - spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; - spriteFont.charAdvanceX[i] = 0; + spriteFont.chars[i].offsetX = 0; + spriteFont.chars[i].offsetY = 0; + spriteFont.chars[i].advanceX = 0; - testPosX += (spriteFont.charRecs[i].width + charsDivisor); + testPosX += (spriteFont.chars[i].rec.width + charsDivisor); if (testPosX > spriteFont.texture.width) { @@ -767,13 +784,13 @@ static SpriteFont LoadRBMF(const char *fileName) currentPosX = 2*charsDivisor + (int)rbmfCharWidthData[i]; testPosX = currentPosX; - spriteFont.charRecs[i].x = charsDivisor; - spriteFont.charRecs[i].y = charsDivisor + currentLine*(rbmfHeader.charHeight + charsDivisor); + spriteFont.chars[i].rec.x = charsDivisor; + spriteFont.chars[i].rec.y = charsDivisor + currentLine*(rbmfHeader.charHeight + charsDivisor); } else currentPosX = testPosX; } - spriteFont.size = spriteFont.charRecs[0].height; + spriteFont.baseSize = spriteFont.charRecs[0].height; TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName); } @@ -782,6 +799,7 @@ static SpriteFont LoadRBMF(const char *fileName) free(rbmfFileData); // Now we can free loaded data from RAM memory free(rbmfCharWidthData); +*/ return spriteFont; } @@ -800,7 +818,7 @@ static SpriteFont LoadBMFont(const char *fileName) int fontSize = 0; int texWidth, texHeight; char texFileName[128]; - int numChars = 0; + int charsCount = 0; int base; // Useless data @@ -834,9 +852,9 @@ static SpriteFont LoadBMFont(const char *fileName) fgets(buffer, MAX_BUFFER_SIZE, fntFile); searchPoint = strstr(buffer, "count"); - sscanf(searchPoint, "count=%i", &numChars); + sscanf(searchPoint, "count=%i", &charsCount); - TraceLog(DEBUG, "[%s] Font num chars: %i", fileName, numChars); + TraceLog(DEBUG, "[%s] Font num chars: %i", fileName, charsCount); // Compose correct path using route of .fnt file (fileName) and texFileName char *texPath = NULL; @@ -868,12 +886,9 @@ static SpriteFont LoadBMFont(const char *fileName) } else font.texture = LoadTextureFromImage(imFont); - font.size = fontSize; - font.numChars = numChars; - font.charValues = (int *)malloc(numChars*sizeof(int)); - font.charRecs = (Rectangle *)malloc(numChars*sizeof(Rectangle)); - font.charOffsets = (Vector2 *)malloc(numChars*sizeof(Vector2)); - font.charAdvanceX = (int *)malloc(numChars*sizeof(int)); + font.baseSize = fontSize; + font.charsCount = charsCount; + font.chars = (CharInfo *)malloc(charsCount*sizeof(CharInfo)); UnloadImage(imFont); @@ -881,17 +896,18 @@ static SpriteFont LoadBMFont(const char *fileName) int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; - for (int i = 0; i < numChars; i++) + for (int i = 0; i < charsCount; i++) { fgets(buffer, MAX_BUFFER_SIZE, fntFile); sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i", &charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX); // Save data properly in sprite font - font.charValues[i] = charId; - font.charRecs[i] = (Rectangle){ charX, charY, charWidth, charHeight }; - font.charOffsets[i] = (Vector2){ (float)charOffsetX, (float)charOffsetY }; - font.charAdvanceX[i] = charAdvanceX; + font.chars[i].value = charId; + font.chars[i].rec = (Rectangle){ charX, charY, charWidth, charHeight }; + font.chars[i].offsetX = charOffsetX; + font.chars[i].offsetY = charOffsetY; + font.chars[i].advanceX = charAdvanceX; } fclose(fntFile); @@ -908,21 +924,21 @@ static SpriteFont LoadBMFont(const char *fileName) // Generate a sprite font from TTF file data (font size required) // TODO: Review texture packing method and generation (use oversampling) -static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int *fontChars) +static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars) { // NOTE: Font texture size is predicted (being as much conservative as possible) // Predictive method consist of supposing same number of chars by line-column (sqrtf) // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests... // Calculate next power-of-two value - float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars)); + float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)charsCount)); int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize); unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25); unsigned char *dataBitmap = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)); // One channel bitmap returned! - stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*numChars); + stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*charsCount); SpriteFont font = { 0 }; @@ -941,7 +957,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int // NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image... // TODO: Replace this function by a proper packing method and support random chars order, // we already receive a list (fontChars) with the ordered expected characters - int result = stbtt_BakeFontBitmap(ttfBuffer, 0, fontSize, dataBitmap, textureSize, textureSize, fontChars[0], numChars, charData); + int result = stbtt_BakeFontBitmap(ttfBuffer, 0, fontSize, dataBitmap, textureSize, textureSize, fontChars[0], charsCount, charData); //if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result); if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font"); @@ -973,24 +989,22 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int UnloadImage(image); // Unloads dataGrayAlpha - font.size = fontSize; - font.numChars = numChars; - font.charValues = (int *)malloc(font.numChars*sizeof(int)); - font.charRecs = (Rectangle *)malloc(font.numChars*sizeof(Rectangle)); - font.charOffsets = (Vector2 *)malloc(font.numChars*sizeof(Vector2)); - font.charAdvanceX = (int *)malloc(font.numChars*sizeof(int)); + font.baseSize = fontSize; + font.charsCount = charsCount; + font.chars = (CharInfo *)malloc(font.charsCount*sizeof(CharInfo)); - for (int i = 0; i < font.numChars; i++) + for (int i = 0; i < font.charsCount; i++) { - font.charValues[i] = fontChars[i]; + font.chars[i].value = fontChars[i]; - font.charRecs[i].x = (int)charData[i].x0; - font.charRecs[i].y = (int)charData[i].y0; - font.charRecs[i].width = (int)charData[i].x1 - (int)charData[i].x0; - font.charRecs[i].height = (int)charData[i].y1 - (int)charData[i].y0; + font.chars[i].rec.x = (int)charData[i].x0; + font.chars[i].rec.y = (int)charData[i].y0; + font.chars[i].rec.width = (int)charData[i].x1 - (int)charData[i].x0; + font.chars[i].rec.height = (int)charData[i].y1 - (int)charData[i].y0; - font.charOffsets[i] = (Vector2){ charData[i].xoff, charData[i].yoff }; - font.charAdvanceX[i] = (int)charData[i].xadvance; + font.chars[i].offsetX = charData[i].xoff; + font.chars[i].offsetY = charData[i].yoff; + font.chars[i].advanceX = (int)charData[i].xadvance; } free(charData); diff --git a/src/textures.c b/src/textures.c index 9d865aa1..ce978b6c 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1064,7 +1064,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing int length = strlen(text); int posX = 0; - Vector2 imSize = MeasureTextEx(font, text, font.size, spacing); + Vector2 imSize = MeasureTextEx(font, text, font.baseSize, spacing); // NOTE: GetTextureData() not available in OpenGL ES Image imFont = GetTextureData(font.texture); @@ -1080,7 +1080,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing for (int i = 0; i < length; i++) { - Rectangle letterRec = font.charRecs[(int)text[i] - 32]; + Rectangle letterRec = font.chars[(int)text[i] - 32].rec; for (int y = letterRec.y; y < (letterRec.y + letterRec.height); y++) { -- cgit v1.2.3 From c4bd214cf07c68476c4ce972766c24ee54a982f6 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Feb 2017 03:00:35 +0100 Subject: Added function SetWindowIcon() Only DESKTOP platforms (Windows, Linus, OSX) --- src/core.c | 21 ++++++++++++++++++++- src/raylib.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 4ce32a05..04dd0540 100644 --- a/src/core.c +++ b/src/core.c @@ -524,7 +524,7 @@ bool IsWindowMinimized(void) #endif } -// Fullscreen toggle +// Fullscreen toggle (only PLATFORM_DESKTOP) void ToggleFullscreen(void) { #if defined(PLATFORM_DESKTOP) @@ -540,6 +540,25 @@ void ToggleFullscreen(void) #endif } +// Set icon for window (only PLATFORM_DESKTOP) +void SetWindowIcon(Image image) +{ +#if defined(PLATFORM_DESKTOP) + ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); + + GLFWimage icon[1]; + + icon[0].width = image.width; + icon[0].height = image.height; + icon[0].pixels = (unsigned char *)image.data; + + // NOTE: We only support one image icon + glfwSetWindowIcon(window, 1, icon); + + // TODO: Support multi-image icons --> image.mipmaps +#endif +} + // Get current screen width int GetScreenWidth(void) { diff --git a/src/raylib.h b/src/raylib.h index f5b908db..5a1304fc 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -638,6 +638,7 @@ RLAPI void CloseWindow(void); // Close Windo RLAPI bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed RLAPI bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus) RLAPI void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP) +RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP) RLAPI int GetScreenWidth(void); // Get current screen width RLAPI int GetScreenHeight(void); // Get current screen height -- cgit v1.2.3 From 7bf6a712ccb4abe059bcbb739664ac1cadcf0b22 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Feb 2017 03:15:43 +0100 Subject: Remove rlua from raylib main repo Moved to own repo at https://github.com/raysan5/raylib-lua --- examples/audio_module_playing.lua | 101 - examples/audio_music_stream.lua | 66 - examples/audio_raw_stream.lua | 97 - examples/audio_sound_loading.lua | 59 - examples/core_2d_camera.lua | 130 - examples/core_3d_camera_first_person.lua | 84 - examples/core_3d_camera_free.lua | 72 - examples/core_3d_mode.lua | 64 - examples/core_3d_picking.lua | 96 - examples/core_basic_window.lua | 44 - examples/core_color_select.lua | 82 - examples/core_drop_files.lua | 66 - examples/core_gestures_detection.lua | 102 - examples/core_input_gamepad.lua | 163 - examples/core_input_keys.lua | 51 - examples/core_input_mouse.lua | 54 - examples/core_mouse_wheel.lua | 50 - examples/core_oculus_rift.lua | 73 - examples/core_random_values.lua | 56 - examples/core_storage_values.lua | 74 - examples/core_world_screen.lua | 66 - examples/models_billboard.lua | 62 - examples/models_box_collisions.lua | 115 - examples/models_cubicmap.lua | 77 - examples/models_geometric_shapes.lua | 67 - examples/models_heightmap.lua | 72 - examples/models_obj_loading.lua | 67 - examples/rlua_execute_file.c | 93 - examples/shaders_custom_uniform.lua | 113 - examples/shaders_model_shader.lua | 83 - examples/shaders_postprocessing.lua | 99 - examples/shaders_shapes_textures.lua | 101 - examples/shaders_standard_lighting.lua | 112 - examples/shapes_basic_shapes.lua | 64 - examples/shapes_colors_palette.lua | 89 - examples/shapes_logo_raylib.lua | 48 - examples/shapes_logo_raylib_anim.lua | 127 - examples/text_bmfont_ttf.lua | 59 - examples/text_bmfont_unordered.lua | 57 - examples/text_font_select.lua | 143 - examples/text_format_text.lua | 54 - examples/text_rbmf_fonts.lua | 87 - examples/text_sprite_fonts.lua | 72 - examples/text_ttf_loading.lua | 118 - examples/text_writing_anim.lua | 52 - examples/textures_formats_loading.lua | 217 -- examples/textures_image_drawing.lua | 70 - examples/textures_image_loading.lua | 55 - examples/textures_image_processing.lua | 134 - examples/textures_logo_raylib.lua | 49 - examples/textures_particles_trail_blending.lua | 113 - examples/textures_raw_data.lua | 83 - examples/textures_rectangle.lua | 69 - examples/textures_srcrec_dstrec.lua | 71 - examples/textures_to_image.lua | 60 - src/rlua.h | 4333 ------------------------ 56 files changed, 8935 deletions(-) delete mode 100644 examples/audio_module_playing.lua delete mode 100644 examples/audio_music_stream.lua delete mode 100644 examples/audio_raw_stream.lua delete mode 100644 examples/audio_sound_loading.lua delete mode 100644 examples/core_2d_camera.lua delete mode 100644 examples/core_3d_camera_first_person.lua delete mode 100644 examples/core_3d_camera_free.lua delete mode 100644 examples/core_3d_mode.lua delete mode 100644 examples/core_3d_picking.lua delete mode 100644 examples/core_basic_window.lua delete mode 100644 examples/core_color_select.lua delete mode 100644 examples/core_drop_files.lua delete mode 100644 examples/core_gestures_detection.lua delete mode 100644 examples/core_input_gamepad.lua delete mode 100644 examples/core_input_keys.lua delete mode 100644 examples/core_input_mouse.lua delete mode 100644 examples/core_mouse_wheel.lua delete mode 100644 examples/core_oculus_rift.lua delete mode 100644 examples/core_random_values.lua delete mode 100644 examples/core_storage_values.lua delete mode 100644 examples/core_world_screen.lua delete mode 100644 examples/models_billboard.lua delete mode 100644 examples/models_box_collisions.lua delete mode 100644 examples/models_cubicmap.lua delete mode 100644 examples/models_geometric_shapes.lua delete mode 100644 examples/models_heightmap.lua delete mode 100644 examples/models_obj_loading.lua delete mode 100644 examples/rlua_execute_file.c delete mode 100644 examples/shaders_custom_uniform.lua delete mode 100644 examples/shaders_model_shader.lua delete mode 100644 examples/shaders_postprocessing.lua delete mode 100644 examples/shaders_shapes_textures.lua delete mode 100644 examples/shaders_standard_lighting.lua delete mode 100644 examples/shapes_basic_shapes.lua delete mode 100644 examples/shapes_colors_palette.lua delete mode 100644 examples/shapes_logo_raylib.lua delete mode 100644 examples/shapes_logo_raylib_anim.lua delete mode 100644 examples/text_bmfont_ttf.lua delete mode 100644 examples/text_bmfont_unordered.lua delete mode 100644 examples/text_font_select.lua delete mode 100644 examples/text_format_text.lua delete mode 100644 examples/text_rbmf_fonts.lua delete mode 100644 examples/text_sprite_fonts.lua delete mode 100644 examples/text_ttf_loading.lua delete mode 100644 examples/text_writing_anim.lua delete mode 100644 examples/textures_formats_loading.lua delete mode 100644 examples/textures_image_drawing.lua delete mode 100644 examples/textures_image_loading.lua delete mode 100644 examples/textures_image_processing.lua delete mode 100644 examples/textures_logo_raylib.lua delete mode 100644 examples/textures_particles_trail_blending.lua delete mode 100644 examples/textures_raw_data.lua delete mode 100644 examples/textures_rectangle.lua delete mode 100644 examples/textures_srcrec_dstrec.lua delete mode 100644 examples/textures_to_image.lua delete mode 100644 src/rlua.h (limited to 'src') diff --git a/examples/audio_module_playing.lua b/examples/audio_module_playing.lua deleted file mode 100644 index 7c675424..00000000 --- a/examples/audio_module_playing.lua +++ /dev/null @@ -1,101 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [audio] example - Module playing (streaming) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -MAX_CIRCLES = 64 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)") - -InitAudioDevice() -- Initialize audio device - -local colors = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, - YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE } - --- Creates ome circles for visual effect -local circles = {} - -for i = MAX_CIRCLES, 1, -1 do - circles[i] = {} - circles[i].alpha = 0.0 - circles[i].radius = GetRandomValue(10, 40) - circles[i].position = Vector2(0, 0) - circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius) - circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius) - circles[i].speed = GetRandomValue(1, 100)/20000.0 - circles[i].color = colors[GetRandomValue(1, 14)] -end - -local xm = LoadMusicStream("resources/audio/mini1111.xm") - -PlayMusicStream(xm) - -local timePlayed = 0.0 - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - for i = MAX_CIRCLES, 1, -1 do - circles[i].alpha = circles[i].alpha + circles[i].speed - circles[i].radius = circles[i].radius + circles[i].speed*10.0 - - if (circles[i].alpha > 1.0) then circles[i].speed = circles[i].speed*-1 end - - if (circles[i].alpha <= 0.0) then - circles[i].alpha = 0.0 - circles[i].radius = GetRandomValue(10, 40) - circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius) - circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius) - circles[i].color = colors[GetRandomValue(1, 14)] - circles[i].speed = GetRandomValue(1, 100)/20000.0 - end - end - - -- Get timePlayed scaled to bar dimensions - timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2 - - UpdateMusicStream(xm) -- Update music buffer with new stream data - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - for i = MAX_CIRCLES, 1, -1 do - DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha)) - end - - -- Draw time bar - DrawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, LIGHTGRAY) - DrawRectangle(20, screenHeight - 20 - 12, timePlayed//1, 12, MAROON) - DrawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, WHITE) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadMusicStream(xm) -- Unload music stream buffers from RAM - -CloseAudioDevice() -- Close audio device (music streaming is automatically stopped) - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- diff --git a/examples/audio_music_stream.lua b/examples/audio_music_stream.lua deleted file mode 100644 index 33cf335f..00000000 --- a/examples/audio_music_stream.lua +++ /dev/null @@ -1,66 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [audio] example - Music playing (streaming) --- --- NOTE: This example requires OpenAL Soft library installed --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)") - -InitAudioDevice() -- Initialize audio device - -local music = LoadMusicStream("resources/audio/guitar_noodling.ogg") - -PlayMusicStream(music) - -local framesCounter = 0 -local timePlayed = 0.0 - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - framesCounter = framesCounter + 1 - - timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4 -- We scale by 4 to fit 400 pixels - - UpdateMusicStream(music) -- Update music buffer with new stream data - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("MUSIC SHOULD BE PLAYING!", 255, 200, 20, LIGHTGRAY) - - DrawRectangle(200, 250, 400, 12, LIGHTGRAY) - DrawRectangle(200, 250, timePlayed//1, 12, MAROON) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadMusicStream(music) -- Unload music stream buffers from RAM - -CloseAudioDevice() -- Close audio device (music streaming is automatically stopped) - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/audio_raw_stream.lua b/examples/audio_raw_stream.lua deleted file mode 100644 index 070984f9..00000000 --- a/examples/audio_raw_stream.lua +++ /dev/null @@ -1,97 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [audio] example - Raw audio streaming --- --- NOTE: This example requires OpenAL Soft library installed --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -MAX_SAMPLES = 20000 -DEG2RAD = math.pi/180.0 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming") - -InitAudioDevice() -- Initialize audio device - --- Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono) -local stream = InitAudioStream(22050, 32, 1) - --- Fill audio stream with some samples (sine wave) -local data = {} - -for i = 1, MAX_SAMPLES do - data[i] = math.sin(((2*math.pi*i)/2)*DEG2RAD) -end - --- NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop --- for that reason, there is a clip everytime audio stream is looped - -PlayAudioStream(stream) - -local totalSamples = MAX_SAMPLES -local samplesLeft = totalSamples - -local position = Vector2(0, 0) - -SetTargetFPS(30) -- Set our game to run at 30 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - - -- Refill audio stream if required - if (IsAudioBufferProcessed(stream)) then - local numSamples = 0 - - if (samplesLeft >= 4096) then numSamples = 4096 - else numSamples = samplesLeft end - - UpdateAudioStream(stream, data + (totalSamples - samplesLeft), numSamples) - - samplesLeft = samplesLeft - numSamples - - -- Reset samples feeding (loop audio) - if (samplesLeft <= 0) then samplesLeft = totalSamples end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, LIGHTGRAY) - - -- NOTE: Draw a part of the sine wave (only screen width) - for i = 1, GetScreenWidth() do - position.x = (i - 1) - position.y = 250 + 50*data[i] - - DrawPixelV(position, RED) - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseAudioStream(stream) -- Close raw audio stream and delete buffers from RAM - -CloseAudioDevice() -- Close audio device (music streaming is automatically stopped) - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/audio_sound_loading.lua b/examples/audio_sound_loading.lua deleted file mode 100644 index 7107eea4..00000000 --- a/examples/audio_sound_loading.lua +++ /dev/null @@ -1,59 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [audio] example - Sound loading and playing --- --- NOTE: This example requires OpenAL Soft library installed --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing") - -InitAudioDevice() -- Initialize audio device - -local fxWav = LoadSound("resources/audio/weird.wav") -- Load WAV audio file -local fxOgg = LoadSound("resources/audio/tanatana.ogg") -- Load OGG audio file - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyPressed(KEY.SPACE)) then PlaySound(fxWav) end -- Play WAV sound - if (IsKeyPressed(KEY.ENTER)) then PlaySound(fxOgg) end -- Play OGG sound - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY) - - DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadSound(fxWav) -- Unload sound data -UnloadSound(fxOgg) -- Unload sound data - -CloseAudioDevice() -- Close audio device - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_2d_camera.lua b/examples/core_2d_camera.lua deleted file mode 100644 index 95302c26..00000000 --- a/examples/core_2d_camera.lua +++ /dev/null @@ -1,130 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - 2d camera --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -MAX_BUILDINGS = 100 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera") - -local player = Rectangle(400, 280, 40, 40) -local buildings = {} -local buildColors = {} - -local spacing = 0; - -for i = 1, MAX_BUILDINGS do - buildings[i] = Rectangle(0, 0, 0, 0) - buildings[i].width = GetRandomValue(50, 200) - buildings[i].height = GetRandomValue(100, 800) - buildings[i].y = screenHeight - 130 - buildings[i].height - buildings[i].x = -6000 + spacing - - spacing = spacing + buildings[i].width - - buildColors[i] = Color(GetRandomValue(200, 240), GetRandomValue(200, 240), GetRandomValue(200, 250), 255) -end - -local camera = Camera2D(Vector2(0, 0), Vector2(0, 0), 0.0, 1.0) - -camera.target = Vector2(player.x + 20, player.y + 20) -camera.offset = Vector2(0, 0) -camera.rotation = 0.0 -camera.zoom = 1.0 - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyDown(KEY.RIGHT)) then - player.x = player.x + 2 -- Player movement - camera.offset.x = camera.offset.x - 2 -- Camera displacement with player movement - elseif (IsKeyDown(KEY.LEFT)) then - player.x = player.x - 2 -- Player movement - camera.offset.x = camera.offset.x + 2 -- Camera displacement with player movement - end - - -- Camera target follows player - camera.target = Vector2(player.x + 20, player.y + 20) - - -- Camera rotation controls - if (IsKeyDown(KEY.A)) then camera.rotation = camera.rotation - 1 - elseif (IsKeyDown(KEY.S)) then camera.rotation = camera.rotation + 1 - end - - -- Limit camera rotation to 80 degrees (-40 to 40) - if (camera.rotation > 40) then camera.rotation = 40 - elseif (camera.rotation < -40) then camera.rotation = -40 - end - - -- Camera zoom controls - camera.zoom = camera.zoom + (GetMouseWheelMove()*0.05) - - if (camera.zoom > 3.0) then camera.zoom = 3.0 - elseif (camera.zoom < 0.1) then camera.zoom = 0.1 - end - - -- Camera reset (zoom and rotation) - if (IsKeyPressed(KEY.R)) then - camera.zoom = 1.0 - camera.rotation = 0.0 - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin2dMode(camera) - - DrawRectangle(-6000, 320, 13000, 8000, DARKGRAY) - - for i = 1, MAX_BUILDINGS, 1 do DrawRectangleRec(buildings[i], buildColors[i]) end - - DrawRectangleRec(player, RED) - - DrawRectangle(camera.target.x, -500, 1, screenHeight*4, GREEN) - DrawRectangle(-500, camera.target.y, screenWidth*4, 1, GREEN) - - End2dMode() - - DrawText("SCREEN AREA", 640, 10, 20, RED) - - DrawRectangle(0, 0, screenWidth, 5, RED) - DrawRectangle(0, 5, 5, screenHeight - 10, RED) - DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED) - DrawRectangle(0, screenHeight - 5, screenWidth, 5, RED) - - DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5)) - DrawRectangleLines( 10, 10, 250, 113, BLUE) - - DrawText("Free 2d camera controls:", 20, 20, 10, BLACK) - DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY) - DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY) - DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY) - DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY) - - EndDrawing(); - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- diff --git a/examples/core_3d_camera_first_person.lua b/examples/core_3d_camera_first_person.lua deleted file mode 100644 index 22ccdc5c..00000000 --- a/examples/core_3d_camera_first_person.lua +++ /dev/null @@ -1,84 +0,0 @@ --------------------------------------------------------------------------------------------- --- --- raylib [core] example - 3d camera first person --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- --------------------------------------------------------------------------------------------- - -MAX_COLUMNS = 20 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person") - --- Define the camera to look into our 3d world (position, target, up vector) -local camera = Camera(Vector3(4.0, 2.0, 4.0), Vector3(0.0, 1.8, 0.0), Vector3(0.0, 1.0, 0.0), 60.0) - --- Generates some random columns -local heights = {} -local positions = {} -local colors = {} - -for i = 1, MAX_COLUMNS do - heights[i] = GetRandomValue(1, 12) - positions[i] = Vector3(GetRandomValue(-15, 15), heights[i]/2, GetRandomValue(-15, 15)) - colors[i] = Color(GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255) -end - -local playerPosition = Vector3(4.0, 2.0, 4.0) -- Define player position - -SetCameraMode(camera, CameraMode.FIRST_PERSON) -- Set a first person camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawPlane(Vector3(0.0, 0.0, 0.0), Vector2(32.0, 32.0), LIGHTGRAY) -- Draw ground - DrawCube(Vector3(-16.0, 2.5, 0.0), 1.0, 5.0, 32.0, BLUE) -- Draw a blue wall - DrawCube(Vector3(16.0, 2.5, 0.0), 1.0, 5.0, 32.0, LIME) -- Draw a green wall - DrawCube(Vector3(0.0, 2.5, 16.0), 32.0, 5.0, 1.0, GOLD) -- Draw a yellow wall - - -- Draw some cubes around - for i = 1, MAX_COLUMNS do - DrawCube(positions[i], 2.0, heights[i], 2.0, colors[i]) - DrawCubeWires(positions[i], 2.0, heights[i], 2.0, MAROON) - end - - End3dMode() - - DrawRectangle( 10, 10, 220, 70, Fade(SKYBLUE, 0.5)) - DrawRectangleLines( 10, 10, 220, 70, BLUE) - - DrawText("First person camera default controls:", 20, 20, 10, BLACK) - DrawText("- Move with keys: W, A, S, D", 40, 40, 10, DARKGRAY) - DrawText("- Mouse move to look around", 40, 60, 10, DARKGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_3d_camera_free.lua b/examples/core_3d_camera_free.lua deleted file mode 100644 index 57fa7a12..00000000 --- a/examples/core_3d_camera_free.lua +++ /dev/null @@ -1,72 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Initialize 3d camera free --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- --------------------------------------------------------------------------------------------- - --- Initialization ----------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free") - --- Define the camera to look into our 3d world -local camera = {} -camera.position = Vector3(10.0, 10.0, 10.0) -- Camera position -camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point -camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target) -camera.fovy = 45.0 -- Camera field-of-view Y - -local cubePosition = Vector3(0.0, 0.0, 0.0) - -SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawCube(cubePosition, 2.0, 2.0, 2.0, RED) - DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON) - - DrawGrid(10, 1.0) - - End3dMode() - - DrawRectangle( 10, 10, 320, 133, Fade(SKYBLUE, 0.5)) - DrawRectangleLines( 10, 10, 320, 133, BLUE) - - DrawText("Free camera default controls:", 20, 20, 10, BLACK) - DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, DARKGRAY) - DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, DARKGRAY) - DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, DARKGRAY) - DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, DARKGRAY) - DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, DARKGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_3d_mode.lua b/examples/core_3d_mode.lua deleted file mode 100644 index c0f7a038..00000000 --- a/examples/core_3d_mode.lua +++ /dev/null @@ -1,64 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Initialize 3d mode --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d mode") - --- Define the camera to look into our 3d world -local camera = {} -camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position -camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point -camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target) -camera.fovy = 45.0 -- Camera field-of-view Y - -local cubePosition = Vector3(0.0, 0.0, 0.0) - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) -- ERROR: Lua Error: attempt to index a number value (?) - - DrawCube(cubePosition, 2.0, 2.0, 2.0, RED) - DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON) - - DrawGrid(10, 1.0) - - End3dMode() - - DrawText("Welcome to the third dimension!", 10, 40, 20, DARKGRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_3d_picking.lua b/examples/core_3d_picking.lua deleted file mode 100644 index 230f5756..00000000 --- a/examples/core_3d_picking.lua +++ /dev/null @@ -1,96 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Picking in 3d mode --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking") - --- Define the camera to look into our 3d world -local camera = {} -camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position -camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point -camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target) -camera.fovy = 45.0 -- Camera field-of-view Y - -local cubePosition = Vector3(0.0, 1.0, 0.0) -local cubeSize = Vector3(2.0, 2.0, 2.0) - -local ray = Ray(Vector3(0, 0, 0), Vector3(0, 0, 0)) -- Picking line ray - -local collision = false - -SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - - if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then - -- NOTE: This function is NOT WORKING properly! - ray = GetMouseRay(GetMousePosition(), camera) - - -- Check collision between ray and box - collision = CheckCollisionRayBox(ray, - BoundingBox(Vector3(cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2), - Vector3(cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2))) - - --print("collision check:", collision) - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - if (collision) then - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED) - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON) - - DrawCubeWires(cubePosition, cubeSize.x + 0.2, cubeSize.y + 0.2, cubeSize.z + 0.2, GREEN) - else - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY) - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY) - end - - DrawRay(ray, MAROON) - - DrawGrid(10, 1.0) - - End3dMode() - - DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY) - - if (collision) then - DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30))/2, screenHeight*0.1, 30, GREEN) - end - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_basic_window.lua b/examples/core_basic_window.lua deleted file mode 100644 index ea3337a1..00000000 --- a/examples/core_basic_window.lua +++ /dev/null @@ -1,44 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Basic window --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window") - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_color_select.lua b/examples/core_color_select.lua deleted file mode 100644 index 2d9c7a96..00000000 --- a/examples/core_color_select.lua +++ /dev/null @@ -1,82 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Color selection by mouse (collision detection) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -NUM_RECTANGLES = 21 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - color selection (collision detection)") - -local colors = { DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN, - GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW, - GREEN, SKYBLUE, PURPLE, BEIGE } - -local colorsRecs = {} -- Rectangles array -local selected = {} - --- Fills colorsRecs data (for every rectangle) -for i = 1, NUM_RECTANGLES do - colorsRecs[i] = Rectangle(0, 0, 0, 0) - colorsRecs[i].x = 20 + 100*((i-1)%7) + 10*((i-1)%7) - colorsRecs[i].y = 60 + 100*((i-1)//7) + 10*((i-1)//7) -- Using floor division: // - colorsRecs[i].width = 100 - colorsRecs[i].height = 100 - selected[i] = false -end - -local mousePoint = Vector2(0, 0) - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - mousePoint = GetMousePosition() - - for i = 1, NUM_RECTANGLES do -- Iterate along all the rectangles - if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) then - colors[i].a = 120 - if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then selected[i] = not selected[i] end - else colors[i].a = 255 end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - for i = 1, NUM_RECTANGLES do -- Draw all rectangles - DrawRectangleRec(colorsRecs[i], colors[i]) - - -- Draw four rectangles around selected rectangle - if (selected[i]) then - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 100, 10, RAYWHITE) -- Square top rectangle - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 10, 100, RAYWHITE) -- Square left rectangle - DrawRectangle(colorsRecs[i].x + 90, colorsRecs[i].y, 10, 100, RAYWHITE) -- Square right rectangle - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y + 90, 100, 10, RAYWHITE) -- Square bottom rectangle - end - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_drop_files.lua b/examples/core_drop_files.lua deleted file mode 100644 index 1d27e618..00000000 --- a/examples/core_drop_files.lua +++ /dev/null @@ -1,66 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Windows drop files --- --- This example only works on platforms that support drag & drop (Windows, Linux, OSX) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - drop files") - -local count = 0 -local droppedFiles = {} - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsFileDropped()) then - droppedFiles = GetDroppedFiles() - count = #droppedFiles - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - if (count == 0) then DrawText("Drop your files to this window!", 100, 40, 20, DARKGRAY) - else - DrawText("Dropped files:", 100, 40, 20, DARKGRAY) - - for i = 0, count-1 do - if (i%2 == 0) then DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.5)) - else DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.3)) end - - DrawText(droppedFiles[i+1], 120, 100 + 40*i, 10, GRAY) - end - - DrawText("Drop new files...", 100, 110 + 40*count, 20, DARKGRAY) - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -ClearDroppedFiles() -- Clear internal buffers - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_gestures_detection.lua b/examples/core_gestures_detection.lua deleted file mode 100644 index 9316b990..00000000 --- a/examples/core_gestures_detection.lua +++ /dev/null @@ -1,102 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Gestures Detection --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -MAX_GESTURE_STRINGS = 20 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection") - -local touchPosition = Vector2(0, 0) -local touchArea = Rectangle(220, 10, screenWidth - 230, screenHeight - 20) - -local gesturesCount = 0 -local gestureStrings = {} - -for i = 1, MAX_GESTURE_STRINGS do gestureStrings[i] = "" end - -local currentGesture = Gestures.NONE -local lastGesture = Gestures.NONE - ---SetGesturesEnabled(0b0000000000001001) -- Enable only some gestures to be detected - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - lastGesture = currentGesture - currentGesture = GetGestureDetected() - touchPosition = GetTouchPosition(0) - - if (CheckCollisionPointRec(touchPosition, touchArea) and (currentGesture ~= Gestures.NONE)) then - if (currentGesture ~= lastGesture) then - -- Store gesture string - if (currentGesture == Gestures.TAP) then gestureStrings[gesturesCount] = "GESTURE TAP" - elseif (currentGesture == Gestures.DOUBLETAP) then gestureStrings[gesturesCount] = "GESTURE DOUBLETAP" - elseif (currentGesture == Gestures.HOLD) then gestureStrings[gesturesCount] = "GESTURE HOLD" - elseif (currentGesture == Gestures.DRAG) then gestureStrings[gesturesCount] = "GESTURE DRAG" - elseif (currentGesture == Gestures.SWIPE_RIGHT) then gestureStrings[gesturesCount] = "GESTURE SWIPE RIGHT" - elseif (currentGesture == Gestures.SWIPE_LEFT) then gestureStrings[gesturesCount] = "GESTURE SWIPE LEFT" - elseif (currentGesture == Gestures.SWIPE_UP) then gestureStrings[gesturesCount] = "GESTURE SWIPE UP" - elseif (currentGesture == Gestures.SWIPE_DOWN) then gestureStrings[gesturesCount] = "GESTURE SWIPE DOWN" - elseif (currentGesture == Gestures.PINCH_IN) then gestureStrings[gesturesCount] = "GESTURE PINCH IN" - elseif (currentGesture == Gestures.PINCH_OUT) then gestureStrings[gesturesCount] = "GESTURE PINCH OUT" - end - - gesturesCount = gesturesCount + 1 - - -- Reset gestures strings - if (gesturesCount >= MAX_GESTURE_STRINGS) then - for i = 1, MAX_GESTURE_STRINGS do gestureStrings[i] = "\0" end - gesturesCount = 0 - end - end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawRectangleRec(touchArea, GRAY) - DrawRectangle(225, 15, screenWidth - 240, screenHeight - 30, RAYWHITE) - - DrawText("GESTURES TEST AREA", screenWidth - 270, screenHeight - 40, 20, Fade(GRAY, 0.5)) - - for i = 1, gesturesCount do - if ((i - 1)%2 == 0) then DrawRectangle(10, 30 + 20*(i - 1), 200, 20, Fade(LIGHTGRAY, 0.5)) - else DrawRectangle(10, 30 + 20*(i - 1), 200, 20, Fade(LIGHTGRAY, 0.3)) end - - if (i < gesturesCount) then DrawText(gestureStrings[i], 35, 36 + 20*(i - 1), 10, DARKGRAY) - else DrawText(gestureStrings[i], 35, 36 + 20*(i - 1), 10, MAROON) end - end - - DrawRectangleLines(10, 29, 200, screenHeight - 50, GRAY) - DrawText("DETECTED GESTURES", 50, 15, 10, GRAY) - - if (currentGesture ~= GESTURE_NONE) then DrawCircleV(touchPosition, 30, MAROON) end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_input_gamepad.lua b/examples/core_input_gamepad.lua deleted file mode 100644 index ade3f00f..00000000 --- a/examples/core_input_gamepad.lua +++ /dev/null @@ -1,163 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Gamepad input --- --- NOTE: This example requires a Gamepad connected to the system --- raylib is configured to work with Xbox 360 gamepad, check raylib.h for buttons configuration --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input") - -local texPs3Pad = LoadTexture("resources/ps3.png") -local texXboxPad = LoadTexture("resources/xbox.png") - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- ... - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - if (IsGamepadAvailable(GAMEPAD.PLAYER1)) then - DrawText(string.format("GP1: %s", GetGamepadName(GAMEPAD.PLAYER1)), 10, 10, 10, BLACK) - - if (IsGamepadName(GAMEPAD.PLAYER1, "Xbox 360 Controller")) then - DrawTexture(texXboxPad, 0, 0, DARKGRAY) - - -- Draw buttons: xbox home - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_HOME)) then DrawCircle(394, 89, 19, RED) end - - -- Draw buttons: basic - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_START)) then DrawCircle(436, 150, 9, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_SELECT)) then DrawCircle(352, 150, 9, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_X)) then DrawCircle(501, 151, 15, BLUE) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_A)) then DrawCircle(536, 187, 15, LIME) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_B)) then DrawCircle(572, 151, 15, MAROON) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_Y)) then DrawCircle(536, 115, 15, GOLD) end - - -- Draw buttons: d-pad - DrawRectangle(317, 202, 19, 71, BLACK) - DrawRectangle(293, 228, 69, 19, BLACK) - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_UP)) then DrawRectangle(317, 202, 19, 26, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_DOWN)) then DrawRectangle(317, 202 + 45, 19, 26, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_LEFT)) then DrawRectangle(292, 228, 25, 19, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_RIGHT)) then DrawRectangle(292 + 44, 228, 26, 19, RED) end - - -- Draw buttons: left-right back - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_LB)) then DrawCircle(259, 61, 20, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.XBOX_BUTTON_RB)) then DrawCircle(536, 61, 20, RED) end - - -- Draw axis: left joystick - DrawCircle(259, 152, 39, BLACK) - DrawCircle(259, 152, 34, LIGHTGRAY) - DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_X)*20), - 152 - (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_Y)*20), 25, BLACK) - - -- Draw axis: right joystick - DrawCircle(461, 237, 38, BLACK) - DrawCircle(461, 237, 33, LIGHTGRAY) - DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RIGHT_X)*20), - 237 - (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RIGHT_Y)*20), 25, BLACK) - - -- Draw axis: left-right triggers - DrawRectangle(170, 30, 15, 70, GRAY) - DrawRectangle(604, 30, 15, 70, GRAY) - DrawRectangle(170, 30, 15, (((1.0 + GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LT))/2.0)*70), RED) - DrawRectangle(604, 30, 15, (((1.0 + GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RT))/2.0)*70), RED) - - --DrawText(FormatText("Xbox axis LT: %02.02f", GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LT)), 10, 40, 10, BLACK) - --DrawText(FormatText("Xbox axis RT: %02.02f", GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_RT)), 10, 60, 10, BLACK) - elseif (IsGamepadName(GAMEPAD.PLAYER1, "PLAYSTATION(R)3 Controller")) then - DrawTexture(texPs3Pad, 0, 0, DARKGRAY) - - -- Draw buttons: ps - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_PS)) then DrawCircle(396, 222, 13, RED) end - - -- Draw buttons: basic - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_SELECT)) then DrawRectangle(328, 170, 32, 13, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_START)) then DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_TRIANGLE)) then DrawCircle(557, 144, 13, LIME) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_CIRCLE)) then DrawCircle(586, 173, 13, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_CROSS)) then DrawCircle(557, 203, 13, VIOLET) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_SQUARE)) then DrawCircle(527, 173, 13, PINK) end - - -- Draw buttons: d-pad - DrawRectangle(225, 132, 24, 84, BLACK) - DrawRectangle(195, 161, 84, 25, BLACK) - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_UP)) then DrawRectangle(225, 132, 24, 29, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_DOWN)) then DrawRectangle(225, 132 + 54, 24, 30, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_LEFT)) then DrawRectangle(195, 161, 30, 25, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_RIGHT)) then DrawRectangle(195 + 54, 161, 30, 25, RED) end - - -- Draw buttons: left-right back buttons - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_L1)) then DrawCircle(239, 82, 20, RED) end - if (IsGamepadButtonDown(GAMEPAD.PLAYER1, GAMEPAD.PS3_BUTTON_R1)) then DrawCircle(557, 82, 20, RED) end - - -- Draw axis: left joystick - DrawCircle(319, 255, 35, BLACK) - DrawCircle(319, 255, 31, LIGHTGRAY) - DrawCircle(319 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_LEFT_X)*20), - 255 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_LEFT_Y)*20), 25, BLACK) - - -- Draw axis: right joystick - DrawCircle(475, 255, 35, BLACK) - DrawCircle(475, 255, 31, LIGHTGRAY) - DrawCircle(475 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_RIGHT_X)*20), - 255 + (GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_RIGHT_Y)*20), 25, BLACK) - - -- Draw axis: left-right triggers - DrawRectangle(169, 48, 15, 70, GRAY) - DrawRectangle(611, 48, 15, 70, GRAY) - DrawRectangle(169, 48, 15, (((1.0 - GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_L2))/2.0)*70), RED) - DrawRectangle(611, 48, 15, (((1.0 - GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.PS3_AXIS_R2))/2.0)*70), RED) - else - DrawText("- GENERIC GAMEPAD -", 280, 180, 20, GRAY) - - -- TODO: Draw generic gamepad - end - - DrawText(string.format("DETECTED AXIS [%i]:", GetGamepadAxisCount(GAMEPAD.PLAYER1)), 10, 50, 10, MAROON) - - for i = 1, GetGamepadAxisCount(GAMEPAD.PLAYER1) do -- Iterate along all the rectangles - DrawText(string.format("AXIS %i: %.02f", i, GetGamepadAxisMovement(GAMEPAD.PLAYER1, i)), 20, 70 + 20*i, 10, DARKGRAY) - end - - if (GetGamepadButtonPressed() ~= -1) then DrawText(string.format("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED) - else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY) end - else - DrawText("GP1: NOT DETECTED", 10, 10, 10, GRAY) - - DrawTexture(texXboxPad, 0, 0, LIGHTGRAY) - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texPs3Pad) -- Unload gamepad texture -UnloadTexture(texXboxPad) -- Unload gamepad texture - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_input_keys.lua b/examples/core_input_keys.lua deleted file mode 100644 index 523b7317..00000000 --- a/examples/core_input_keys.lua +++ /dev/null @@ -1,51 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Keyboard input --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window") - -local ballPosition = Vector2(screenWidth/2, screenHeight/2) - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyDown(KEY.RIGHT)) then ballPosition.x = ballPosition.x + 0.8 end - if (IsKeyDown(KEY.LEFT)) then ballPosition.x = ballPosition.x - 0.8 end - if (IsKeyDown(KEY.UP)) then ballPosition.y = ballPosition.y - 0.8 end - if (IsKeyDown(KEY.DOWN)) then ballPosition.y = ballPosition.y + 0.8 end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY) - - DrawCircleV(ballPosition, 50, MAROON) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- diff --git a/examples/core_input_mouse.lua b/examples/core_input_mouse.lua deleted file mode 100644 index 35ca8e73..00000000 --- a/examples/core_input_mouse.lua +++ /dev/null @@ -1,54 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Mouse input --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input") - -local ballPosition = Vector2(-100.0, -100.0) -local ballColor = DARKBLUE - -SetTargetFPS(60) -- Set target frames-per-second ------------------------------------------------------------------------------------------ - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - ------------------------------------------------------------------------------------ - ballPosition = GetMousePosition() - - if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then ballColor = MAROON - elseif (IsMouseButtonPressed(MOUSE.MIDDLE_BUTTON)) then ballColor = LIME - elseif (IsMouseButtonPressed(MOUSE.RIGHT_BUTTON)) then ballColor = DARKBLUE - end - ------------------------------------------------------------------------------------ - - -- Draw - ------------------------------------------------------------------------------------ - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawCircleV(ballPosition, 40, ballColor) - - DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY) - - EndDrawing() - ------------------------------------------------------------------------------------ -end - --- De-Initialization ----------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_mouse_wheel.lua b/examples/core_mouse_wheel.lua deleted file mode 100644 index 92e0a160..00000000 --- a/examples/core_mouse_wheel.lua +++ /dev/null @@ -1,50 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] examples - Mouse wheel --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse wheel") - -local boxPositionY = screenHeight/2 - 40 -local scrollSpeed = 4 -- Scrolling speed in pixels - -SetTargetFPS(60) -- Set target frames-per-second ----------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - ------------------------------------------------------------------------------------ - boxPositionY = boxPositionY - (GetMouseWheelMove()*scrollSpeed) - ------------------------------------------------------------------------------------ - - -- Draw - ------------------------------------------------------------------------------------ - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, MAROON) - - DrawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, GRAY) - DrawText(string.format("Box position Y: %03i", boxPositionY), 10, 40, 20, LIGHTGRAY) - - EndDrawing() - ------------------------------------------------------------------------------------ -end - --- De-Initialization ----------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_oculus_rift.lua b/examples/core_oculus_rift.lua deleted file mode 100644 index 2626d178..00000000 --- a/examples/core_oculus_rift.lua +++ /dev/null @@ -1,73 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Oculus Rift CV1 --- --- NOTE: Example requires linkage with LibOVR --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 1080 -local screenHeight = 600 - --- NOTE: screenWidth/screenHeight should match VR device aspect ratio - -InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift") - --- NOTE: If device is not available, it fallbacks to default device (simulator) -InitVrDevice(VrDevice.OCULUS_RIFT_CV1) -- Init VR device (Oculus Rift CV1) - --- Define the camera to look into our 3d world -local camera = {} -camera.position = Vector3(5.0, 5.0, 5.0) -- Camera position -camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point -camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target) -camera.fovy = 60.0 -- Camera field-of-view Y - -local cubePosition = Vector3(0.0, 0.0, 0.0) - -SetTargetFPS(90) -- Set our game to run at 90 frames-per-second ----------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - ------------------------------------------------------------------------------------ - UpdateVrTracking() - - if (IsKeyPressed(KEY.SPACE)) then ToggleVrMode() end - ------------------------------------------------------------------------------------ - - -- Draw - ------------------------------------------------------------------------------------ - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawCube(cubePosition, 2.0, 2.0, 2.0, RED) - DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON) - - DrawGrid(10, 1.0) - - End3dMode() - - DrawFPS(10, 10) - - EndDrawing() - ------------------------------------------------------------------------------------ -end - --- De-Initialization ----------------------------------------------------------------------------------------- -CloseVrDevice() -- Close VR device - -CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_random_values.lua b/examples/core_random_values.lua deleted file mode 100644 index b80ab9e2..00000000 --- a/examples/core_random_values.lua +++ /dev/null @@ -1,56 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Generate random values --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - generate random values") - -local framesCounter = 0 -- Variable used to count frames - -local randValue = GetRandomValue(-8, 5) -- Get a random integer number between -8 and 5 (both included) - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ----------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - ------------------------------------------------------------------------------------ - framesCounter = framesCounter + 1 - - -- Every two seconds (120 frames) a new random value is generated - if (((framesCounter/120)%2) == 1) then - randValue = GetRandomValue(-8, 5) - framesCounter = 0 - end - ------------------------------------------------------------------------------------ - - -- Draw - ------------------------------------------------------------------------------------ - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("Every 2 seconds a new random value is generated:", 130, 100, 20, MAROON) - - DrawText(string.format("%i", randValue), 360, 180, 80, LIGHTGRAY) - - EndDrawing() - ------------------------------------------------------------------------------------ -end - --- De-Initialization ----------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_storage_values.lua b/examples/core_storage_values.lua deleted file mode 100644 index 878b90e4..00000000 --- a/examples/core_storage_values.lua +++ /dev/null @@ -1,74 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - Storage save/load values --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- NOTE: Storage positions must start with 0, directly related to file memory layout -STORAGE_SCORE = 0 -STORAGE_HISCORE = 1 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values") - -local score = 0 -local hiscore = 0 - -local framesCounter = 0 - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyPressed(KEY.R)) then - score = GetRandomValue(1000, 2000) - hiscore = GetRandomValue(2000, 4000) - end - - if (IsKeyPressed(KEY.ENTER)) then - StorageSaveValue(STORAGE_SCORE, score) - StorageSaveValue(STORAGE_HISCORE, hiscore) - elseif (IsKeyPressed(KEY.SPACE)) then - -- NOTE: If requested position could not be found, value 0 is returned - score = StorageLoadValue(STORAGE_SCORE) - hiscore = StorageLoadValue(STORAGE_HISCORE) - end - - framesCounter = framesCounter + 1 - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText(string.format("SCORE: %i", score), 280, 130, 40, MAROON) - DrawText(string.format("HI-SCORE: %i", hiscore), 210, 200, 50, BLACK) - - DrawText(string.format("frames: %i", framesCounter), 10, 10, 20, LIME) - - DrawText("Press R to generate random numbers", 220, 40, 20, LIGHTGRAY) - DrawText("Press ENTER to SAVE values", 250, 310, 20, LIGHTGRAY) - DrawText("Press SPACE to LOAD values", 252, 350, 20, LIGHTGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/core_world_screen.lua b/examples/core_world_screen.lua deleted file mode 100644 index 48b617dd..00000000 --- a/examples/core_world_screen.lua +++ /dev/null @@ -1,66 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [core] example - World to screen --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local cubePosition = Vector3(0.0, 0.0, 0.0) - -local cubeScreenPosition = Vector2(0, 0) - -SetCameraMode(camera, CameraMode.FREE) -- Set a free camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ----------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - ------------------------------------------------------------------------------------ - camera = UpdateCamera(camera) -- Update camera - - -- Calculate cube screen space position (with a little offset to be in top) - cubeScreenPosition = GetWorldToScreen(Vector3(cubePosition.x, cubePosition.y + 2.5, cubePosition.z), camera) - ------------------------------------------------------------------------------------ - - -- Draw - ------------------------------------------------------------------------------------ - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawCube(cubePosition, 2.0, 2.0, 2.0, RED) - DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON) - - DrawGrid(10, 1.0) - - End3dMode() - - DrawText("Enemy: 100 / 100", cubeScreenPosition.x//1 - MeasureText("Enemy: 100 / 100", 20)//2, cubeScreenPosition.y//1, 20, BLACK) - DrawText("Text is always on top of the cube", (screenWidth - MeasureText("Text is always on top of the cube", 20))//2, 25, 20, GRAY) - - EndDrawing() - ------------------------------------------------------------------------------------ -end - --- De-Initialization ----------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_billboard.lua b/examples/models_billboard.lua deleted file mode 100644 index 9d81f6ce..00000000 --- a/examples/models_billboard.lua +++ /dev/null @@ -1,62 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Drawing billboards --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(5.0, 4.0, 5.0), Vector3(0.0, 2.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local bill = LoadTexture("resources/billboard.png") -- Our texture billboard -local billPosition = Vector3(0.0, 2.0, 0.0) -- Position where draw billboard - -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawBillboard(camera, bill, billPosition, 2.0, WHITE) - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(bill) -- Unload texture - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_box_collisions.lua b/examples/models_box_collisions.lua deleted file mode 100644 index 4a3107b9..00000000 --- a/examples/models_box_collisions.lua +++ /dev/null @@ -1,115 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Detect basic 3d collisions (box vs sphere vs box) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - box collisions") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local playerPosition = Vector3(0.0, 1.0, 2.0) -local playerSize = Vector3(1.0, 2.0, 1.0) -local playerColor = GREEN - -local enemyBoxPos = Vector3(-4.0, 1.0, 0.0) -local enemyBoxSize = Vector3(2.0, 2.0, 2.0) - -local enemySpherePos = Vector3(4.0, 0.0, 0.0) -local enemySphereSize = 1.5 - -local collision = false - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - - -- Move player - if (IsKeyDown(KEY.RIGHT)) then playerPosition.x = playerPosition.x + 0.2 - elseif (IsKeyDown(KEY.LEFT)) then playerPosition.x = playerPosition.x - 0.2 - elseif (IsKeyDown(KEY.DOWN)) then playerPosition.z = playerPosition.z + 0.2 - elseif (IsKeyDown(KEY.UP)) then playerPosition.z = playerPosition.z - 0.2 end - - collision = false - - -- Check collisions player vs enemy-box - if (CheckCollisionBoxes( - BoundingBox(Vector3(playerPosition.x - playerSize.x/2, - playerPosition.y - playerSize.y/2, - playerPosition.z - playerSize.z/2), - Vector3(playerPosition.x + playerSize.x/2, - playerPosition.y + playerSize.y/2, - playerPosition.z + playerSize.z/2)), - BoundingBox(Vector3(enemyBoxPos.x - enemyBoxSize.x/2, - enemyBoxPos.y - enemyBoxSize.y/2, - enemyBoxPos.z - enemyBoxSize.z/2), - Vector3(enemyBoxPos.x + enemyBoxSize.x/2, - enemyBoxPos.y + enemyBoxSize.y/2, - enemyBoxPos.z + enemyBoxSize.z/2)))) then collision = true - end - - -- Check collisions player vs enemy-sphere - if (CheckCollisionBoxSphere( - BoundingBox(Vector3(playerPosition.x - playerSize.x/2, - playerPosition.y - playerSize.y/2, - playerPosition.z - playerSize.z/2), - Vector3(playerPosition.x + playerSize.x/2, - playerPosition.y + playerSize.y/2, - playerPosition.z + playerSize.z/2)), - enemySpherePos, enemySphereSize)) then collision = true - end - - if (collision) then playerColor = RED - else playerColor = GREEN end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - -- Draw enemy-box - DrawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, GRAY) - DrawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, DARKGRAY) - - -- Draw enemy-sphere - DrawSphere(enemySpherePos, enemySphereSize, GRAY) - DrawSphereWires(enemySpherePos, enemySphereSize, 16, 16, DARKGRAY) - - -- Draw player - DrawCubeV(playerPosition, playerSize, playerColor) - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawText("Move player with cursors to collide", 220, 40, 20, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_cubicmap.lua b/examples/models_cubicmap.lua deleted file mode 100644 index 79faafc9..00000000 --- a/examples/models_cubicmap.lua +++ /dev/null @@ -1,77 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Cubicmap loading and drawing --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(16.0, 14.0, 16.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local image = LoadImage("resources/cubicmap.png") -- Load cubicmap image (RAM) -local cubicmap = LoadTextureFromImage(image) -- Convert image to texture to display (VRAM) -local map = LoadCubicmap(image) -- Load cubicmap model (generate model from image) - --- NOTE: By default each cube is mapped to one part of texture atlas -local texture = LoadTexture("resources/cubicmap_atlas.png") -- Load map texture -map.material.texDiffuse = texture -- Set map diffuse texture - -local mapPosition = Vector3(-16.0, 0.0, -8.0) -- Set model position - -UnloadImage(image) -- Unload cubesmap image from RAM, already uploaded to VRAM - -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawModel(map, mapPosition, 1.0, WHITE) - - End3dMode() - - DrawTextureEx(cubicmap, (Vector2)(screenWidth - cubicmap.width*4 - 20, 20), 0.0, 4.0, WHITE) - DrawRectangleLines(screenWidth - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN) - - DrawText("cubicmap image used to", 658, 90, 10, GRAY) - DrawText("generate map 3d model", 658, 104, 10, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(cubicmap) -- Unload cubicmap texture -UnloadTexture(texture) -- Unload map texture -UnloadModel(map) -- Unload map model - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_geometric_shapes.lua b/examples/models_geometric_shapes.lua deleted file mode 100644 index 0ce08e9f..00000000 --- a/examples/models_geometric_shapes.lua +++ /dev/null @@ -1,67 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) -- ERROR: Lua Error: attempt to index a number value - - DrawCube(Vector3(-4.0, 0.0, 2.0), 2.0, 5.0, 2.0, RED) - DrawCubeWires(Vector3(-4.0, 0.0, 2.0), 2.0, 5.0, 2.0, GOLD) - DrawCubeWires(Vector3(-4.0, 0.0, -2.0), 3.0, 6.0, 2.0, MAROON) - - DrawSphere(Vector3(-1.0, 0.0, -2.0), 1.0, GREEN) - DrawSphereWires(Vector3(1.0, 0.0, 2.0), 2.0, 16, 16, LIME) - - DrawCylinder(Vector3(4.0, 0.0, -2.0), 1.0, 2.0, 3.0, 4, SKYBLUE) - DrawCylinderWires(Vector3(4.0, 0.0, -2.0), 1.0, 2.0, 3.0, 4, DARKBLUE) - DrawCylinderWires(Vector3(4.5, -1.0, 2.0), 1.0, 1.0, 2.0, 6, BROWN) - - DrawCylinder(Vector3(1.0, 0.0, -4.0), 0.0, 1.5, 3.0, 8, GOLD) - DrawCylinderWires(Vector3(1.0, 0.0, -4.0), 0.0, 1.5, 3.0, 8, PINK) - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_heightmap.lua b/examples/models_heightmap.lua deleted file mode 100644 index efcbfb4b..00000000 --- a/examples/models_heightmap.lua +++ /dev/null @@ -1,72 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Heightmap loading and drawing --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing") - --- Define our custom camera to look into our 3d world -local camera = Camera(Vector3(18.0, 16.0, 18.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local image = LoadImage("resources/heightmap.png") -- Load heightmap image (RAM) -local texture = LoadTextureFromImage(image) -- Convert image to texture (VRAM) -local map = LoadHeightmap(image, Vector3(16, 8, 16)) -- Load heightmap model with defined size -map.material.texDiffuse = texture -- Set map diffuse texture -local mapPosition = Vector3(-8.0, 0.0, -8.0) -- Set model position (depends on model scaling!) - -UnloadImage(image) -- Unload heightmap image from RAM, already uploaded to VRAM - -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second ----------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - -- NOTE: Model is scaled to 1/4 of its original size (128x128 units) - DrawModel(map, mapPosition, 1.0, RED) - - DrawGrid(20, 1.0) - - End3dMode() - - DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE) - DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Unload texture -UnloadModel(map) -- Unload model - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/models_obj_loading.lua b/examples/models_obj_loading.lua deleted file mode 100644 index 7e5c7c4b..00000000 --- a/examples/models_obj_loading.lua +++ /dev/null @@ -1,67 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [models] example - Load and draw a 3d model (OBJ) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model -local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture -dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture -local position = Vector3(0.0, 0.0, 0.0) -- Set model position - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- ... - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - - DrawGrid(10, 1.0) -- Draw a grid - - DrawGizmo(position) -- Draw gizmo - - End3dMode() - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Unload texture -UnloadModel(dwarf) -- Unload model - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/rlua_execute_file.c b/examples/rlua_execute_file.c deleted file mode 100644 index a91ce42f..00000000 --- a/examples/rlua_execute_file.c +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************************* -* -* raylib [rlua] example - Lua file execution -* -* NOTE: This example requires Lua library (http://luabinaries.sourceforge.net/download.html) -* -* Compile example using: -* gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon / -* -I../src -I../src/external/lua/include -L../src/external/lua/lib / -* -lraylib -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -llua53 / -* -std=c99 -Wl,-allow-multiple-definition -Wl,--subsystem,windows -* -* This example has been created using raylib 1.6 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" - -#define RLUA_IMPLEMENTATION -#include "rlua.h" - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - InitLuaDevice(); - //-------------------------------------------------------------------------------------- - - ExecuteLuaFile("core_basic_window.lua"); // OK! - // ExecuteLuaFile("core_input_keys.lua"); // OK! - // ExecuteLuaFile("core_input_mouse.lua"); // OK! - // ExecuteLuaFile("core_mouse_wheel.lua"); // OK! - // ExecuteLuaFile("core_input_gamepad.lua"); // OK! - // ExecuteLuaFile("core_random_values.lua"); // OK! - // ExecuteLuaFile("core_color_select.lua"); // OK! - // ExecuteLuaFile("core_drop_files.lua"); // OK! - // ExecuteLuaFile("core_storage_values.lua"); // OK! - // ExecuteLuaFile("core_gestures_detection.lua"); // OK! - // ExecuteLuaFile("core_3d_mode.lua"); // OK! - // ExecuteLuaFile("core_3d_picking.lua"); // OK! - // ExecuteLuaFile("core_3d_camera_free.lua"); // OK! - // ExecuteLuaFile("core_3d_camera_first_person.lua"); // OK! - // ExecuteLuaFile("core_2d_camera.lua"); // OK! - // ExecuteLuaFile("core_world_screen.lua"); // OK! - // ExecuteLuaFile("core_oculus_rift.lua"); // OK! - // ExecuteLuaFile("shapes_logo_raylib.lua"); // OK! - // ExecuteLuaFile("shapes_basic_shapes.lua"); // OK! - // ExecuteLuaFile("shapes_colors_palette.lua"); // OK! - // ExecuteLuaFile("shapes_logo_raylib_anim.lua"); // OK! NOTE: Use lua string.sub() instead of raylib SubText() - // ExecuteLuaFile("textures_logo_raylib.lua"); // OK! - // ExecuteLuaFile("textures_image_loading.lua"); // OK! - // ExecuteLuaFile("textures_rectangle.lua"); // OK! - // ExecuteLuaFile("textures_srcrec_dstrec.lua"); // OK! - // ExecuteLuaFile("textures_to_image.lua"); // OK! - // ExecuteLuaFile("textures_raw_data.lua"); // ERROR: LoadImageEx() - // ExecuteLuaFile("textures_formats_loading.lua"); // OK! - // ExecuteLuaFile("textures_particles_trail_blending.lua"); // OK! - // ExecuteLuaFile("textures_image_processing.lua"); // ERROR: GetImageData() --> UpdateTexture() - // ExecuteLuaFile("textures_image_drawing.lua"); // OK! - // ExecuteLuaFile("text_sprite_fonts.lua"); // OK! - // ExecuteLuaFile("text_bmfont_ttf.lua"); // OK! - // ExecuteLuaFile("text_rbmf_fonts.lua"); // OK! - // ExecuteLuaFile("text_format_text.lua"); // OK! NOTE: Use lua string.format() instead of raylib FormatText() - // ExecuteLuaFile("text_font_select.lua"); // OK! - // ExecuteLuaFile("text_writing_anim.lua"); // OK! - // ExecuteLuaFile("text_ttf_loading.lua"); // ISSUE: Attempt to index a SpriteFont value (local 'font') - // ExecuteLuaFile("text_bmfont_unordered.lua"); // OK! - // ExecuteLuaFile("models_geometric_shapes.lua"); // OK! - // ExecuteLuaFile("models_box_collisions.lua"); // OK! - // ExecuteLuaFile("models_billboard.lua"); // OK! - // ExecuteLuaFile("models_obj_loading.lua"); // OK! - // ExecuteLuaFile("models_heightmap.lua"); // OK! - // ExecuteLuaFile("models_cubicmap.lua"); // OK! - // ExecuteLuaFile("shaders_model_shader.lua"); // OK! - // ExecuteLuaFile("shaders_shapes_textures.lua"); // OK! - // ExecuteLuaFile("shaders_custom_uniform.lua"); // OK! - // ExecuteLuaFile("shaders_postprocessing.lua"); // OK! - // ExecuteLuaFile("shaders_standard_lighting.lua"); // OK! - // ExecuteLuaFile("audio_sound_loading.lua"); // OK! - // ExecuteLuaFile("audio_music_stream.lua"); // OK! - // ExecuteLuaFile("audio_module_playing.lua"); // OK! - // ExecuteLuaFile("audio_raw_stream.lua"); // ERROR: UpdateAudioStream() - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseLuaDevice(); // Close Lua device and free resources - //-------------------------------------------------------------------------------------- - - return 0; -} \ No newline at end of file diff --git a/examples/shaders_custom_uniform.lua b/examples/shaders_custom_uniform.lua deleted file mode 100644 index dafd3b84..00000000 --- a/examples/shaders_custom_uniform.lua +++ /dev/null @@ -1,113 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shaders] example - Apply a postprocessing shader and connect a custom uniform variable --- --- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, --- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. --- --- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example --- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders --- raylib comes with shaders ready for both versions, check raylib/shaders install folder --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available) - -InitWindow(screenWidth, screenHeight, "raylib [shaders] example - custom uniform variable") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model -local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture (diffuse map) -dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture - -local position = Vector3(0.0, 0.0, 0.0) -- Set model position - -local shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/swirl.fs") -- Load postpro shader - --- Get variable (uniform) location on the shader to connect with the program --- NOTE: If uniform variable could not be found in the shader, function returns -1 -local swirlCenterLoc = GetShaderLocation(shader, "center") - -local swirlCenter = { screenWidth/2, screenHeight/2 } - --- Create a RenderTexture2D to be used for render to texture -local target = LoadRenderTexture(screenWidth, screenHeight) - --- Setup orbital camera -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - local mousePosition = GetMousePosition() - - swirlCenter[1] = mousePosition.x - swirlCenter[2] = screenHeight - mousePosition.y - - -- Send new value to the shader to be used on drawing - SetShaderValue(shader, swirlCenterLoc, swirlCenter) - - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - BeginTextureMode(target) -- Enable drawing to texture - - Begin3dMode(camera) - - DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED) - - EndTextureMode() -- End drawing to texture (now we have a texture available for next passes) - - BeginShaderMode(shader) - - -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) - DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE) - - EndShaderMode() - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadShader(shader) -- Unload shader -UnloadTexture(texture) -- Unload texture -UnloadModel(dwarf) -- Unload model -UnloadRenderTexture(target) -- Unload render texture - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shaders_model_shader.lua b/examples/shaders_model_shader.lua deleted file mode 100644 index 38f0fd30..00000000 --- a/examples/shaders_model_shader.lua +++ /dev/null @@ -1,83 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shaders] example - Apply a shader to a 3d model --- --- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, --- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. --- --- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example --- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders --- raylib comes with shaders ready for both versions, check raylib/shaders install folder --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available) - -InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model -local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture -local shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/grayscale.fs") -- Load model shader - -dwarf.material.shader = shader -- Set shader effect to 3d model -dwarf.material.texDiffuse = texture -- Bind texture to model - -local position = Vector3(0.0, 0.0, 0.0) -- Set model position - --- Setup orbital camera -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadShader(shader) -- Unload shader -UnloadTexture(texture) -- Unload texture -UnloadModel(dwarf) -- Unload model - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shaders_postprocessing.lua b/examples/shaders_postprocessing.lua deleted file mode 100644 index 7dfac816..00000000 --- a/examples/shaders_postprocessing.lua +++ /dev/null @@ -1,99 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shaders] example - Apply a postprocessing shader to a scene --- --- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, --- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. --- --- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example --- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders --- raylib comes with shaders ready for both versions, check raylib/shaders install folder --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available) - -InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model -local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture (diffuse map) -dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture - -local position = Vector3(0.0, 0.0, 0.0) -- Set model position - -local shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/bloom.fs") -- Load postpro shader - --- Create a RenderTexture2D to be used for render to texture -local target = LoadRenderTexture(screenWidth, screenHeight) - --- Setup orbital camera -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - BeginTextureMode(target) -- Enable drawing to texture - - Begin3dMode(camera) - - DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawText("HELLO POSTPROCESSING!", 70, 190, 50, RED) - - EndTextureMode() -- End drawing to texture (now we have a texture available for next passes) - - BeginShaderMode(shader) - - -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) - DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE) - - EndShaderMode() - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadShader(shader) -- Unload shader -UnloadTexture(texture) -- Unload texture -UnloadModel(dwarf) -- Unload model -UnloadRenderTexture(target) -- Unload render texture - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shaders_shapes_textures.lua b/examples/shaders_shapes_textures.lua deleted file mode 100644 index caaeba1a..00000000 --- a/examples/shaders_shapes_textures.lua +++ /dev/null @@ -1,101 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shaders] example - Apply a shader to some shape or texture --- --- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, --- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. --- --- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example --- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders --- raylib comes with shaders ready for both versions, check raylib/shaders install folder --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shapes and texture shaders") - -local sonic = LoadTexture("resources/texture_formats/sonic.png") - --- NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version -local shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/grayscale.fs") - --- Shader usage is also different than models/postprocessing, shader is just activated when required - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - -- Start drawing with default shader - - DrawText("USING DEFAULT SHADER", 20, 40, 10, RED) - - DrawCircle(80, 120, 35, DARKBLUE) - DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE) - DrawCircleLines(80, 340, 80, DARKBLUE) - - - -- Activate our custom shader to be applied on next shapes/textures drawings - BeginShaderMode(shader) - - DrawText("USING CUSTOM SHADER", 190, 40, 10, RED) - - DrawRectangle(250 - 60, 90, 120, 60, RED) - DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD) - DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE) - - -- Activate our default shader for next drawings - EndShaderMode() - - DrawText("USING DEFAULT SHADER", 370, 40, 10, RED) - - DrawTriangle(Vector2(430, 80), - Vector2(430 - 60, 150), - Vector2(430 + 60, 150), VIOLET) - - DrawTriangleLines(Vector2(430, 160), - Vector2(430 - 20, 230), - Vector2(430 + 20, 230), DARKBLUE) - - DrawPoly(Vector2(430, 320), 6, 80, 0, BROWN) - - -- Activate our custom shader to be applied on next shapes/textures drawings - BeginShaderMode(shader) - - DrawTexture(sonic, 380, -10, WHITE) -- Using custom shader - - -- Activate our default shader for next drawings - EndShaderMode() - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadShader(shader) -- Unload shader -UnloadTexture(sonic) -- Unload texture - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shaders_standard_lighting.lua b/examples/shaders_standard_lighting.lua deleted file mode 100644 index 1d4dcfcf..00000000 --- a/examples/shaders_standard_lighting.lua +++ /dev/null @@ -1,112 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shaders] example - Standard lighting (materials and lights) --- --- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, --- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. --- --- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example --- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders --- raylib comes with shaders ready for both versions, check raylib/shaders install folder --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available) - -InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader") - --- Define the camera to look into our 3d world -local camera = Camera(Vector3(4.0, 4.0, 4.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0) - -local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model -local position = Vector3(0.0, 0.0, 0.0) -- Set model position - -local material = LoadStandardMaterial() - -material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model diffuse texture -material.texNormal = LoadTexture("resources/model/dwarf_normal.png") -- Load model normal texture -material.texSpecular = LoadTexture("resources/model/dwarf_specular.png") -- Load model specular texture -material.colDiffuse = WHITE -material.colAmbient = Color(0, 0, 10, 255) -material.colSpecular = WHITE -material.glossiness = 50.0 - -dwarf.material = material -- Apply material to model - -local spotLight = CreateLight(LightType.SPOT, Vector3(3.0, 5.0, 2.0), Color(255, 255, 255, 255)) -spotLight.target = Vector3(0.0, 0.0, 0.0) -spotLight.intensity = 2.0 -spotLight.diffuse = Color(255, 100, 100, 255) -spotLight.coneAngle = 60.0 - -local dirLight = CreateLight(LightType.DIRECTIONAL, Vector3(0.0, -3.0, -3.0), Color(255, 255, 255, 255)) -dirLight.target = Vector3(1.0, -2.0, -2.0) -dirLight.intensity = 2.0 -dirLight.diffuse = Color(100, 255, 100, 255) - -local pointLight = CreateLight(LightType.POINT, Vector3(0.0, 4.0, 5.0), Color(255, 255, 255, 255)) -pointLight.intensity = 2.0 -pointLight.diffuse = Color(100, 100, 255, 255) -pointLight.radius = 3.0 - --- Setup orbital camera -SetCameraMode(camera, CameraMode.ORBITAL) -- Set an orbital camera mode - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - camera = UpdateCamera(camera) -- Update camera - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - Begin3dMode(camera) - - DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture - - DrawLight(spotLight) -- Draw spot light - DrawLight(dirLight) -- Draw directional light - DrawLight(pointLight) -- Draw point light - - DrawGrid(10, 1.0) -- Draw a grid - - End3dMode() - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY) - - DrawFPS(10, 10) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadMaterial(material) -- Unload material and assigned textures -UnloadModel(dwarf) -- Unload model - --- Destroy all created lights -DestroyLight(pointLight) -DestroyLight(dirLight) -DestroyLight(spotLight) - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shapes_basic_shapes.lua b/examples/shapes_basic_shapes.lua deleted file mode 100644 index cc943ba3..00000000 --- a/examples/shapes_basic_shapes.lua +++ /dev/null @@ -1,64 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes drawing") - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY) - - DrawLine(18, 42, screenWidth - 18, 42, BLACK) - - DrawCircle(screenWidth/4, 120, 35, DARKBLUE) - DrawCircleGradient(screenWidth/4, 220, 60, GREEN, SKYBLUE) - DrawCircleLines(screenWidth/4, 340, 80, DARKBLUE) - - DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED) - DrawRectangleGradient(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD) - DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE) - - DrawTriangle(Vector2(screenWidth/4*3, 80), - Vector2(screenWidth/4*3 - 60, 150), - Vector2(screenWidth/4*3 + 60, 150), VIOLET) - - DrawTriangleLines(Vector2(screenWidth/4*3, 160), - Vector2(screenWidth/4*3 - 20, 230), - Vector2(screenWidth/4*3 + 20, 230), DARKBLUE) - - DrawPoly(Vector2(screenWidth/4*3, 320), 6, 80, 0, BROWN) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shapes_colors_palette.lua b/examples/shapes_colors_palette.lua deleted file mode 100644 index e884cd3e..00000000 --- a/examples/shapes_colors_palette.lua +++ /dev/null @@ -1,89 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shapes] example - Draw raylib custom color palette --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib color palette") - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("raylib color palette", 28, 42, 20, BLACK) - - DrawRectangle(26, 80, 100, 100, DARKGRAY) - DrawRectangle(26, 188, 100, 100, GRAY) - DrawRectangle(26, 296, 100, 100, LIGHTGRAY) - DrawRectangle(134, 80, 100, 100, MAROON) - DrawRectangle(134, 188, 100, 100, RED) - DrawRectangle(134, 296, 100, 100, PINK) - DrawRectangle(242, 80, 100, 100, ORANGE) - DrawRectangle(242, 188, 100, 100, GOLD) - DrawRectangle(242, 296, 100, 100, YELLOW) - DrawRectangle(350, 80, 100, 100, DARKGREEN) - DrawRectangle(350, 188, 100, 100, LIME) - DrawRectangle(350, 296, 100, 100, GREEN) - DrawRectangle(458, 80, 100, 100, DARKBLUE) - DrawRectangle(458, 188, 100, 100, BLUE) - DrawRectangle(458, 296, 100, 100, SKYBLUE) - DrawRectangle(566, 80, 100, 100, DARKPURPLE) - DrawRectangle(566, 188, 100, 100, VIOLET) - DrawRectangle(566, 296, 100, 100, PURPLE) - DrawRectangle(674, 80, 100, 100, DARKBROWN) - DrawRectangle(674, 188, 100, 100, BROWN) - DrawRectangle(674, 296, 100, 100, BEIGE) - - - DrawText("DARKGRAY", 65, 166, 10, BLACK) - DrawText("GRAY", 93, 274, 10, BLACK) - DrawText("LIGHTGRAY", 61, 382, 10, BLACK) - DrawText("MAROON", 186, 166, 10, BLACK) - DrawText("RED", 208, 274, 10, BLACK) - DrawText("PINK", 204, 382, 10, BLACK) - DrawText("ORANGE", 295, 166, 10, BLACK) - DrawText("GOLD", 310, 274, 10, BLACK) - DrawText("YELLOW", 300, 382, 10, BLACK) - DrawText("DARKGREEN", 382, 166, 10, BLACK) - DrawText("LIME", 420, 274, 10, BLACK) - DrawText("GREEN", 410, 382, 10, BLACK) - DrawText("DARKBLUE", 498, 166, 10, BLACK) - DrawText("BLUE", 526, 274, 10, BLACK) - DrawText("SKYBLUE", 505, 382, 10, BLACK) - DrawText("DARKPURPLE", 592, 166, 10, BLACK) - DrawText("VIOLET", 621, 274, 10, BLACK) - DrawText("PURPLE", 620, 382, 10, BLACK) - DrawText("DARKBROWN", 705, 166, 10, BLACK) - DrawText("BROWN", 733, 274, 10, BLACK) - DrawText("BEIGE", 737, 382, 10, BLACK) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shapes_logo_raylib.lua b/examples/shapes_logo_raylib.lua deleted file mode 100644 index 4e7f18c4..00000000 --- a/examples/shapes_logo_raylib.lua +++ /dev/null @@ -1,48 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shapes] example - Draw raylib logo using basic shapes --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo using shapes") - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawRectangle(screenWidth/2 - 128, screenHeight/2 - 128, 256, 256, BLACK) - DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, RAYWHITE) - DrawText("raylib", screenWidth/2 - 44, screenHeight/2 + 48, 50, BLACK) - - DrawText("this is NOT a texture!", 350, 370, 10, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/shapes_logo_raylib_anim.lua b/examples/shapes_logo_raylib_anim.lua deleted file mode 100644 index c6c44995..00000000 --- a/examples/shapes_logo_raylib_anim.lua +++ /dev/null @@ -1,127 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [shapes] example - raylib logo animation --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo animation") - -local logoPositionX = screenWidth/2 - 128 -local logoPositionY = screenHeight/2 - 128 - -local framesCounter = 0 -local lettersCount = 0 - -local topSideRecWidth = 16 -local leftSideRecHeight = 16 - -local bottomSideRecWidth = 16 -local rightSideRecHeight = 16 - -local state = 0 -- Tracking animation states (State Machine) -local alpha = 1.0 -- Useful for fading - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (state == 0) then -- State 0: Small box blinking - framesCounter = framesCounter + 1 - - if (framesCounter == 120) then - state = 1 - framesCounter = 0 -- Reset counter... will be used later... - end - elseif (state == 1) then -- State 1: Top and left bars growing - topSideRecWidth = topSideRecWidth + 4 - leftSideRecHeight = leftSideRecHeight + 4 - - if (topSideRecWidth == 256) then state = 2 end - elseif (state == 2) then -- State 2: Bottom and right bars growing - bottomSideRecWidth = bottomSideRecWidth + 4 - rightSideRecHeight = rightSideRecHeight + 4 - - if (bottomSideRecWidth == 256) then state = 3 end - elseif (state == 3) then -- State 3: Letters appearing (one by one) - framesCounter = framesCounter + 1 - - if (framesCounter//12 == 1) then -- Every 12 frames, one more letter! - lettersCount = lettersCount + 1 - framesCounter = 0 - end - - if (lettersCount >= 10) then -- When all letters have appeared, just fade out everything - alpha = alpha - 0.02 - - if (alpha <= 0.0) then - alpha = 0.0 - state = 4 - end - end - elseif (state == 4) then -- State 4: Reset and Replay - if (IsKeyPressed(KEY.R)) then - framesCounter = 0 - lettersCount = 0 - - topSideRecWidth = 16 - leftSideRecHeight = 16 - - bottomSideRecWidth = 16 - rightSideRecHeight = 16 - - alpha = 1.0 - state = 0 -- Return to State 0 - end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - if (state == 0) then - if ((framesCounter//15)%2 == 1) then DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK) end - elseif (state == 1) then - DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK) - DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK) - elseif (state == 2) then - DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK) - DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK) - - DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK) - DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK) - elseif (state == 3) then - DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha)) - DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha)) - - DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)) - DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)) - - DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha)) - - DrawText(string.sub("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)) - elseif (state == 4) then DrawText("[R] REPLAY", 340, 200, 20, GRAY) end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_bmfont_ttf.lua b/examples/text_bmfont_ttf.lua deleted file mode 100644 index 3b8bf004..00000000 --- a/examples/text_bmfont_ttf.lua +++ /dev/null @@ -1,59 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - BMFont and TTF SpriteFonts loading --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont and ttf sprite fonts loading") - -local msgBm = "THIS IS AN AngelCode SPRITE FONT" -local msgTtf = "THIS FONT has been GENERATED from TTF" - --- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) -local fontBm = LoadSpriteFont("resources/fonts/bmfont.fnt") -- BMFont (AngelCode) -local fontTtf = LoadSpriteFont("resources/fonts/pixantiqua.ttf") -- TTF font - -local fontPosition = Vector2(0, 0) -fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.size, 0).x/2 -fontPosition.y = screenHeight/2 - fontBm.size/2 - 80 - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update variables here... - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTextEx(fontBm, msgBm, fontPosition, fontBm.size, 0, MAROON) - DrawTextEx(fontTtf, msgTtf, Vector2(60.0, 240.0), fontTtf.size, 2, LIME) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadSpriteFont(fontBm) -- AngelCode SpriteFont unloading -UnloadSpriteFont(fontTtf) -- TTF SpriteFont unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_bmfont_unordered.lua b/examples/text_bmfont_unordered.lua deleted file mode 100644 index f324ca19..00000000 --- a/examples/text_bmfont_unordered.lua +++ /dev/null @@ -1,57 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - BMFont unordered chars loading and drawing --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont unordered loading and drawing") - --- NOTE: Using chars outside the [32..127] limits! --- NOTE: If a character is not found in the font, it just renders a space -local msg = "ASCII extended characters:\n¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ\nÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæ\nçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - --- NOTE: Loaded font has an unordered list of characters (chars in the range 32..255) -local font = LoadSpriteFont("resources/fonts/pixantiqua.fnt") -- BMFont (AngelCode) - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update variables here... - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("Font name: PixAntiqua", 40, 50, 20, GRAY) - DrawText(string.format("Font base size: %i", font.size), 40, 80, 20, GRAY) - DrawText(string.format("Font chars number: %i", font.numChars), 40, 110, 20, GRAY) - - DrawTextEx(font, msg, Vector2(40, 180), font.size, 0, MAROON) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadSpriteFont(font) -- AngelCode SpriteFont unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_font_select.lua b/examples/text_font_select.lua deleted file mode 100644 index f6cea881..00000000 --- a/examples/text_font_select.lua +++ /dev/null @@ -1,143 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - Font selector --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - font selector") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) -local fonts = {} -- SpriteFont array - -fonts[1] = LoadSpriteFont("resources/fonts/alagard.rbmf") -- SpriteFont loading -fonts[2] = LoadSpriteFont("resources/fonts/pixelplay.rbmf") -- SpriteFont loading -fonts[3] = LoadSpriteFont("resources/fonts/mecha.rbmf") -- SpriteFont loading -fonts[4] = LoadSpriteFont("resources/fonts/setback.rbmf") -- SpriteFont loading -fonts[5] = LoadSpriteFont("resources/fonts/romulus.rbmf") -- SpriteFont loading -fonts[6] = LoadSpriteFont("resources/fonts/pixantiqua.rbmf") -- SpriteFont loading -fonts[7] = LoadSpriteFont("resources/fonts/alpha_beta.rbmf") -- SpriteFont loading -fonts[8] = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf") -- SpriteFont loading - -local currentFont = 1 -- Selected font - -local colors = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD, RED } - -local fontNames = { "[1] Alagard", "[2] PixelPlay", "[3] MECHA", "[4] Setback", - "[5] Romulus", "[6] PixAntiqua", "[7] Alpha Beta", "[8] Jupiter Crash" } - -local text = "THIS is THE FONT you SELECTED!" -- Main text - -local textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1) - -local mousePoint - -local btnNextOutColor = DARKBLUE -- Button color (outside line) -local btnNextInColor = SKYBLUE -- Button color (inside) - -local framesCounter = 0 -- Useful to count frames button is 'active' = clicked - -local positionY = 180 -- Text selector and button Y position - -local btnNextRec = Rectangle(673, positionY, 109, 44) -- Button rectangle (useful for collision) - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - - -- Keyboard-based font selection (easy) - if (IsKeyPressed(KEY.RIGHT)) then - if (currentFont < 8) then currentFont = currentFont + 1 end - end - - if (IsKeyPressed(KEY.LEFT)) then - if (currentFont > 1) then currentFont = currentFont - 1 end - end - - if (IsKeyPressed(KEY.ZERO)) then currentFont = 0 - elseif (IsKeyPressed(KEY.ONE)) then currentFont = 1 - elseif (IsKeyPressed(KEY.TWO)) then currentFont = 2 - elseif (IsKeyPressed(KEY.THREE)) then currentFont = 3 - elseif (IsKeyPressed(KEY.FOUR)) then currentFont = 4 - elseif (IsKeyPressed(KEY.FIVE)) then currentFont = 5 - elseif (IsKeyPressed(KEY.SIX)) then currentFont = 6 - elseif (IsKeyPressed(KEY.SEVEN)) then currentFont = 7 - end - - -- Mouse-based font selection (NEXT button logic) - mousePoint = GetMousePosition() - - if (CheckCollisionPointRec(mousePoint, btnNextRec)) then - -- Mouse hover button logic - if (framesCounter == 0) then - btnNextOutColor = DARKPURPLE - btnNextInColor = PURPLE - end - - if (IsMouseButtonDown(MOUSE.LEFT_BUTTON)) then - framesCounter = 20 -- Frames button is 'active' - btnNextOutColor = MAROON - btnNextInColor = RED - end - else - -- Mouse not hover button - btnNextOutColor = DARKBLUE - btnNextInColor = SKYBLUE - end - - if (framesCounter > 0) then framesCounter = framesCounter - 1 end - - if (framesCounter == 1) then -- We change font on frame 1 - currentFont = currentFont + 1 - if (currentFont > 7) then currentFont = 0 end - end - - -- Text measurement for better positioning on screen - textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1) - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("font selector - use arroys, button or numbers", 160, 80, 20, DARKGRAY) - DrawLine(120, 120, 680, 120, DARKGRAY) - - DrawRectangle(18, positionY, 644, 44, DARKGRAY) - DrawRectangle(20, positionY + 2, 640, 40, LIGHTGRAY) - DrawText(fontNames[currentFont], 30, positionY + 13, 20, BLACK) - DrawText("< >", 610, positionY + 8, 30, BLACK) - - DrawRectangleRec(btnNextRec, btnNextOutColor) - DrawRectangle(675, positionY + 2, 105, 40, btnNextInColor) - DrawText("NEXT", 700, positionY + 13, 20, btnNextOutColor) - - DrawTextEx(fonts[currentFont], text, Vector2(screenWidth/2 - textSize.x/2, - 260 + (70 - textSize.y)/2), fonts[currentFont].size*3, - 1, colors[currentFont]) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -for i = 1, 8 do UnloadSpriteFont(fonts[i]) end -- SpriteFont(s) unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_format_text.lua b/examples/text_format_text.lua deleted file mode 100644 index ba121db3..00000000 --- a/examples/text_format_text.lua +++ /dev/null @@ -1,54 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - Text formatting --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - text formatting") - -local score = 100020 -local hiscore = 200450 -local lives = 5 - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText(string.format("Score: %08i", score), 200, 80, 20, RED) - - DrawText(string.format("HiScore: %08i", hiscore), 200, 120, 20, GREEN) - - DrawText(string.format("Lives: %02i", lives), 200, 160, 40, BLUE) - - DrawText(string.format("Elapsed Time: %02.02f ms", GetFrameTime()*1000), 200, 220, 20, BLACK) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_rbmf_fonts.lua b/examples/text_rbmf_fonts.lua deleted file mode 100644 index 31a733f1..00000000 --- a/examples/text_rbmf_fonts.lua +++ /dev/null @@ -1,87 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - raylib bitmap font (rbmf) loading and usage --- --- NOTE: raylib is distributed with some free to use fonts (even for commercial pourposes!) --- To view details and credits for those fonts, check raylib license file --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - rBMF fonts") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) -local fonts = {} - -fonts[1] = LoadSpriteFont("resources/fonts/alagard.rbmf") -- rBMF font loading -fonts[2] = LoadSpriteFont("resources/fonts/pixelplay.rbmf") -- rBMF font loading -fonts[3] = LoadSpriteFont("resources/fonts/mecha.rbmf") -- rBMF font loading -fonts[4] = LoadSpriteFont("resources/fonts/setback.rbmf") -- rBMF font loading -fonts[5] = LoadSpriteFont("resources/fonts/romulus.rbmf") -- rBMF font loading -fonts[6] = LoadSpriteFont("resources/fonts/pixantiqua.rbmf") -- rBMF font loading -fonts[7] = LoadSpriteFont("resources/fonts/alpha_beta.rbmf") -- rBMF font loading -fonts[8] = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf") -- rBMF font loading - -local messages = { "ALAGARD FONT designed by Hewett Tsoi", - "PIXELPLAY FONT designed by Aleksander Shevchuk", - "MECHA FONT designed by Captain Falcon", - "SETBACK FONT designed by Brian Kent (AEnigma)", - "ROMULUS FONT designed by Hewett Tsoi", - "PIXANTIQUA FONT designed by Gerhard Grossmann", - "ALPHA_BETA FONT designed by Brian Kent (AEnigma)", - "JUPITER_CRASH FONT designed by Brian Kent (AEnigma)" } - -local spacings = { 2, 4, 8, 4, 3, 4, 4, 1 } - -local positions = {} - -for i = 1, 8 do - positions[i] = Vector2(0, 0) - positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], fonts[i].size*2, spacings[i]).x/2 - positions[i].y = 60 + fonts[i].size + 45*(i - 1) -end - -local colors = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD, BLACK } - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("free fonts included with raylib", 250, 20, 20, DARKGRAY) - DrawLine(220, 50, 590, 50, DARKGRAY) - - for i = 1, 8 do - DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].size*2, spacings[i], colors[i]) - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -for i = 1, 8 do UnloadSpriteFont(fonts[i]) end -- SpriteFont unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_sprite_fonts.lua b/examples/text_sprite_fonts.lua deleted file mode 100644 index 341e2ffe..00000000 --- a/examples/text_sprite_fonts.lua +++ /dev/null @@ -1,72 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - SpriteFont loading and usage --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - sprite fonts usage") - -local msg1 = "THIS IS A custom SPRITE FONT..." -local msg2 = "...and this is ANOTHER CUSTOM font..." -local msg3 = "...and a THIRD one! GREAT! :D" - --- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) -local font1 = LoadSpriteFont("resources/fonts/custom_mecha.png") -- SpriteFont loading -local font2 = LoadSpriteFont("resources/fonts/custom_alagard.png") -- SpriteFont loading -local font3 = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png") -- SpriteFont loading - -local fontPosition1 = Vector2(0, 0) -local fontPosition2 = Vector2(0, 0) -local fontPosition3 = Vector2(0, 0) - -fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, font1.size, -3).x/2 -fontPosition1.y = screenHeight/2 - font1.size/2 - 80 - -fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, font2.size, -2).x/2 -fontPosition2.y = screenHeight/2 - font2.size/2 - 10 - -fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, font3.size, 2).x/2 -fontPosition3.y = screenHeight/2 - font3.size/2 + 50 - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update variables here... - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTextEx(font1, msg1, fontPosition1, font1.size, -3, WHITE) - DrawTextEx(font2, msg2, fontPosition2, font2.size, -2, WHITE) - DrawTextEx(font3, msg3, fontPosition3, font3.size, 2, WHITE) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadSpriteFont(font1) -- SpriteFont unloading -UnloadSpriteFont(font2) -- SpriteFont unloading -UnloadSpriteFont(font3) -- SpriteFont unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_ttf_loading.lua b/examples/text_ttf_loading.lua deleted file mode 100644 index 26443212..00000000 --- a/examples/text_ttf_loading.lua +++ /dev/null @@ -1,118 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - TTF loading and usage --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800; -local screenHeight = 450; - -InitWindow(screenWidth, screenHeight, "raylib [text] example - ttf loading") - -local msg = "TTF SpriteFont" - --- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) - --- TTF SpriteFont loading with custom generation parameters -local font = LoadSpriteFontTTF("resources/fonts/KAISG.ttf", 96, 0, 0) - --- Generate mipmap levels to use trilinear filtering --- NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR ---font.texture = GenTextureMipmaps(font.texture) -- ISSUE: attempt to index a SpriteFont value (local 'font') - -local fontSize = font.size -local fontPosition = Vector2(40, screenHeight/2 + 50) -local textSize - -SetTextureFilter(font.texture, TextureFilter.POINT) -local currentFontFilter = 0 -- Default: FILTER_POINT - -local count = 0 -local droppedFiles - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - fontSize = fontSize + GetMouseWheelMove()*4.0 - - -- Choose font texture filter method - if (IsKeyPressed(KEY.ONE)) then - SetTextureFilter(font.texture, TextureFilter.POINT) - currentFontFilter = 0 - elseif (IsKeyPressed(KEY.TWO)) then - SetTextureFilter(font.texture, TextureFilter.BILINEAR) - currentFontFilter = 1 - elseif (IsKeyPressed(KEY.THREE)) then - -- NOTE: Trilinear filter won't be noticed on 2D drawing - SetTextureFilter(font.texture, TextureFilter.TRILINEAR) - currentFontFilter = 2 - end - - textSize = MeasureTextEx(font, msg, fontSize, 0) - - if (IsKeyDown(KEY.LEFT)) then fontPosition.x = fontPosition.x - 10 - elseif (IsKeyDown(KEY.RIGHT)) then fontPosition.x = fontPosition.x + 10 - end - - -- Load a dropped TTF file dynamically (at current fontSize) - if (IsFileDropped()) then - droppedFiles = GetDroppedFiles() - count = #droppedFiles - - if (count == 1) then -- Only support one ttf file dropped - UnloadSpriteFont(font) - font = LoadSpriteFontTTF(droppedFiles[1], fontSize, 0, 0) - ClearDroppedFiles() - end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("Use mouse wheel to change font size", 20, 20, 10, GRAY) - DrawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, GRAY) - DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, GRAY) - DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, DARKGRAY) - - DrawTextEx(font, msg, fontPosition, fontSize, 0, BLACK) - - -- TODO: It seems texSize measurement is not accurate due to chars offsets... - --DrawRectangleLines(fontPosition.x, fontPosition.y, textSize.x, textSize.y, RED) - - DrawRectangle(0, screenHeight - 80, screenWidth, 80, LIGHTGRAY) - DrawText(string.format("Font size: %02.02f", fontSize), 20, screenHeight - 50, 10, DARKGRAY) - DrawText(string.format("Text size: [%02.02f, %02.02f]", textSize.x, textSize.y), 20, screenHeight - 30, 10, DARKGRAY) - DrawText("CURRENT TEXTURE FILTER:", 250, 400, 20, GRAY) - - if (currentFontFilter == 0) then DrawText("POINT", 570, 400, 20, BLACK) - elseif (currentFontFilter == 1) then DrawText("BILINEAR", 570, 400, 20, BLACK) - elseif (currentFontFilter == 2) then DrawText("TRILINEAR", 570, 400, 20, BLACK) - end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadSpriteFont(font) -- SpriteFont unloading - -ClearDroppedFiles() -- Clear internal buffers - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/text_writing_anim.lua b/examples/text_writing_anim.lua deleted file mode 100644 index f4af9f58..00000000 --- a/examples/text_writing_anim.lua +++ /dev/null @@ -1,52 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [text] example - Text Writing Animation --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim") - -local message = "This sample illustrates a text writing\nanimation effect! Check it out! )" - -local framesCounter = 0 - -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - framesCounter = framesCounter + 1 - - if (IsKeyPressed(KEY.ENTER)) then framesCounter = 0 end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText(string.sub(message, 0, framesCounter//10), 210, 160, 20, MAROON) - - DrawText("PRESS [ENTER] to RESTART!", 240, 280, 20, LIGHTGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_formats_loading.lua b/examples/textures_formats_loading.lua deleted file mode 100644 index 1ce10492..00000000 --- a/examples/textures_formats_loading.lua +++ /dev/null @@ -1,217 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - texture formats loading (compressed and uncompressed) --- --- NOTE: This example requires raylib OpenGL 3.3+ or ES2 versions for compressed textures, --- OpenGL 1.1 does not support compressed textures, only uncompressed ones. --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -NUM_TEXTURES = 24 - -PNG_R8G8B8A8 = 1 -PVR_GRAYSCALE = 2 -PVR_GRAY_ALPHA = 3 -PVR_R5G6B5 = 4 -PVR_R5G5B5A1 = 5 -PVR_R4G4B4A4 = 6 -DDS_R5G6B5 = 7 -DDS_R5G5B5A1 = 8 -DDS_R4G4B4A4 = 9 -DDS_R8G8B8A8 = 10 -DDS_DXT1_RGB = 11 -DDS_DXT1_RGBA = 12 -DDS_DXT3_RGBA = 13 -DDS_DXT5_RGBA = 14 -PKM_ETC1_RGB = 15 -PKM_ETC2_RGB = 16 -PKM_ETC2_EAC_RGBA = 17 -KTX_ETC1_RGB = 18 -KTX_ETC2_RGB = 19 -KTX_ETC2_EAC_RGBA = 20 -ASTC_4x4_LDR = 21 -ASTC_8x8_LDR = 22 -PVR_PVRT_RGB = 23 -PVR_PVRT_RGBA = 24 - -local formatText = { - "PNG_R8G8B8A8", - "PVR_GRAYSCALE", - "PVR_GRAY_ALPHA", - "PVR_R5G6B5", - "PVR_R5G5B5A1", - "PVR_R4G4B4A4", - "DDS_R5G6B5", - "DDS_R5G5B5A1", - "DDS_R4G4B4A4", - "DDS_R8G8B8A8", - "DDS_DXT1_RGB", - "DDS_DXT1_RGBA", - "DDS_DXT3_RGBA", - "DDS_DXT5_RGBA", - "PKM_ETC1_RGB", - "PKM_ETC2_RGB", - "PKM_ETC2_EAC_RGBA", - "KTX_ETC1_RGB", - "KTX_ETC2_RGB", - "KTX_ETC2_EAC_RGBA", - "ASTC_4x4_LDR", - "ASTC_8x8_LDR", - "PVR_PVRT_RGB", - "PVR_PVRT_RGBA" -} - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture formats loading") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - -local sonic = {} - -sonic[PNG_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic.png") - --- Load UNCOMPRESSED PVR texture data -sonic[PVR_GRAYSCALE] = LoadTexture("resources/texture_formats/sonic_GRAYSCALE.pvr") -sonic[PVR_GRAY_ALPHA] = LoadTexture("resources/texture_formats/sonic_L8A8.pvr") -sonic[PVR_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.pvr") -sonic[PVR_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_R5G5B5A1.pvr") -sonic[PVR_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_R4G4B4A4.pvr") - --- Load UNCOMPRESSED DDS texture data -sonic[DDS_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.dds") -sonic[DDS_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_A1R5G5B5.dds") -sonic[DDS_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_A4R4G4B4.dds") -sonic[DDS_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic_A8R8G8B8.dds") - --- Load COMPRESSED DXT DDS texture data (if supported) -sonic[DDS_DXT1_RGB] = LoadTexture("resources/texture_formats/sonic_DXT1_RGB.dds") -sonic[DDS_DXT1_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT1_RGBA.dds") -sonic[DDS_DXT3_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT3_RGBA.dds") -sonic[DDS_DXT5_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT5_RGBA.dds") - --- Load COMPRESSED ETC texture data (if supported) -sonic[PKM_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.pkm") -sonic[PKM_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.pkm") -sonic[PKM_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm") - -sonic[KTX_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.ktx") -sonic[KTX_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.ktx") -sonic[KTX_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx") - --- Load COMPRESSED ASTC texture data (if supported) -sonic[ASTC_4x4_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_4x4_ldr.astc") -sonic[ASTC_8x8_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_8x8_ldr.astc") - --- Load COMPRESSED PVR texture data (if supported) -sonic[PVR_PVRT_RGB] = LoadTexture("resources/texture_formats/sonic_PVRT_RGB.pvr") -sonic[PVR_PVRT_RGBA] = LoadTexture("resources/texture_formats/sonic_PVRT_RGBA.pvr") - -local selectedFormat = PNG_R8G8B8A8 - -local selectRecs = {} - -for i = 1, NUM_TEXTURES do - if ((i - 1) < NUM_TEXTURES//2) then selectRecs[i] = Rectangle(40, 30 + 32*(i - 1), 150, 30) - else selectRecs[i] = Rectangle(40 + 152, 30 + 32*((i - 1) - NUM_TEXTURES//2), 150, 30) end -end - --- Texture sizes in KB -local textureSizes = { - 512*512*32/8/1024, --PNG_R8G8B8A8 (32 bpp) - 512*512*8/8/1024, --PVR_GRAYSCALE (8 bpp) - 512*512*16/8/1024, --PVR_GRAY_ALPHA (16 bpp) - 512*512*16/8/1024, --PVR_R5G6B5 (16 bpp) - 512*512*16/8/1024, --PVR_R5G5B5A1 (16 bpp) - 512*512*16/8/1024, --PVR_R4G4B4A4 (16 bpp) - 512*512*16/8/1024, --DDS_R5G6B5 (16 bpp) - 512*512*16/8/1024, --DDS_R5G5B5A1 (16 bpp) - 512*512*16/8/1024, --DDS_R4G4B4A4 (16 bpp) - 512*512*32/8/1024, --DDS_R8G8B8A8 (32 bpp) - 512*512*4/8/1024, --DDS_DXT1_RGB (4 bpp) -Compressed- - 512*512*4/8/1024, --DDS_DXT1_RGBA (4 bpp) -Compressed- - 512*512*8/8/1024, --DDS_DXT3_RGBA (8 bpp) -Compressed- - 512*512*8/8/1024, --DDS_DXT5_RGBA (8 bpp) -Compressed- - 512*512*4/8/1024, --PKM_ETC1_RGB (4 bpp) -Compressed- - 512*512*4/8/1024, --PKM_ETC2_RGB (4 bpp) -Compressed- - 512*512*8/8/1024, --PKM_ETC2_EAC_RGBA (8 bpp) -Compressed- - 512*512*4/8/1024, --KTX_ETC1_RGB (4 bpp) -Compressed- - 512*512*4/8/1024, --KTX_ETC2_RGB (4 bpp) -Compressed- - 512*512*8/8/1024, --KTX_ETC2_EAC_RGBA (8 bpp) -Compressed- - 512*512*8/8/1024, --ASTC_4x4_LDR (8 bpp) -Compressed- - 512*512*2/8/1024, --ASTC_8x8_LDR (2 bpp) -Compressed- - 512*512*4/8/1024, --PVR_PVRT_RGB (4 bpp) -Compressed- - 512*512*4/8/1024, --PVR_PVRT_RGBA (4 bpp) -Compressed- -} - -SetTargetFPS(60) -- Set our game to run at 60 frames-per-second -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyPressed(KEY.DOWN)) then - selectedFormat = selectedFormat + 1 - if (selectedFormat > NUM_TEXTURES) then selectedFormat = 1 end - elseif (IsKeyPressed(KEY.UP)) then - selectedFormat = selectedFormat - 1 - if (selectedFormat < 1) then selectedFormat = NUM_TEXTURES end - elseif (IsKeyPressed(KEY.RIGHT)) then - if (selectedFormat < NUM_TEXTURES//2) then selectedFormat = selectedFormat + NUM_TEXTURES//2 end - elseif (IsKeyPressed(KEY.LEFT)) then - if (selectedFormat > NUM_TEXTURES//2) then selectedFormat = selectedFormat - NUM_TEXTURES//2 end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - - BeginDrawing() - - ClearBackground(RAYWHITE) - - -- Draw rectangles - for i = 1, NUM_TEXTURES do - if (i == selectedFormat) then - DrawRectangleRec(selectRecs[i], SKYBLUE) - DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE) - DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)//2, selectRecs[i].y + 11, 10, DARKBLUE) - else - DrawRectangleRec(selectRecs[i], LIGHTGRAY) - DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY) - DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)//2, selectRecs[i].y + 11, 10, DARKGRAY) - end - end - - -- Draw selected texture - if (sonic[selectedFormat].id ~= 0) then DrawTexture(sonic[selectedFormat], 350, -10, WHITE) - else - DrawRectangleLines(488, 165, 200, 110, DARKGRAY) - DrawText("FORMAT", 550, 180, 20, MAROON) - DrawText("NOT SUPPORTED", 500, 210, 20, MAROON) - DrawText("ON YOUR GPU", 520, 240, 20, MAROON) - end - - DrawText("Select texture format (use cursor keys):", 40, 10, 10, DARKGRAY) - DrawText("Required GPU memory size (VRAM):", 40, 427, 10, DARKGRAY) - DrawText(string.format("%4.0f KB", textureSizes[selectedFormat]), 240, 420, 20, DARKBLUE) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -for i = 1, NUM_TEXTURES do UnloadTexture(sonic[i]) end - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_image_drawing.lua b/examples/textures_image_drawing.lua deleted file mode 100644 index 0261b243..00000000 --- a/examples/textures_image_drawing.lua +++ /dev/null @@ -1,70 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Image loading and drawing on it --- --- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - -local cat = LoadImage("resources/cat.png") -- Load image in CPU memory (RAM) -cat = ImageCrop(cat, Rectangle(100, 10, 280, 380)) -- Crop an image piece -cat = ImageFlipHorizontal(cat) -- Flip cropped image horizontally -cat = ImageResize(cat, 150, 200) -- Resize flipped-cropped image - -local parrots = LoadImage("resources/parrots.png") -- Load image in CPU memory (RAM) - --- Draw one image over the other with a scaling of 1.5f -parrots = ImageDraw(parrots, cat, Rectangle(0, 0, cat.width, cat.height), Rectangle(30, 40, cat.width*1.5, cat.height*1.5)) -parrots = ImageCrop(parrots, Rectangle(0, 50, parrots.width, parrots.height - 100)) -- Crop resulting image - -UnloadImage(cat) -- Unload image from RAM - -local texture = LoadTextureFromImage(parrots) -- Image converted to texture, uploaded to GPU memory (VRAM) -UnloadImage(parrots) -- Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, WHITE) - DrawRectangleLines(screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, texture.width, texture.height, DARKGRAY) - - DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, DARKGRAY) - DrawText("Source images have been cropped, scaled, flipped and copied one over the other.", 190, 370, 10, DARKGRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_image_loading.lua b/examples/textures_image_loading.lua deleted file mode 100644 index 05dbce7f..00000000 --- a/examples/textures_image_loading.lua +++ /dev/null @@ -1,55 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Image loading and texture creation --- --- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - image loading") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - -local image = LoadImage("resources/raylib_logo.png") -- Loaded in CPU memory (RAM) -local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (VRAM) - -UnloadImage(image) -- Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE) - - DrawText("this IS a texture loaded from an image!", 300, 370, 10, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_image_processing.lua b/examples/textures_image_processing.lua deleted file mode 100644 index b7304b37..00000000 --- a/examples/textures_image_processing.lua +++ /dev/null @@ -1,134 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Image processing --- --- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - ---#include -- Required for: free() - -NUM_PROCESSES = 8 - --- enum ImageProcess -local COLOR_NONE = 1 -local COLOR_GRAYSCALE = 2 -local COLOR_TINT = 3 -local COLOR_INVERT = 4 -local COLOR_CONTRAST = 5 -local COLOR_BRIGHTNESS = 6 -local FLIP_VERTICAL = 7 -local FLIP_HORIZONTAL = 8 - -local processText = { - "NO PROCESSING", - "COLOR GRAYSCALE", - "COLOR TINT", - "COLOR INVERT", - "COLOR CONTRAST", - "COLOR BRIGHTNESS", - "FLIP VERTICAL", - "FLIP HORIZONTAL" -} - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - -local image = LoadImage("resources/parrots.png") -- Loaded in CPU memory (RAM) -image = ImageFormat(image, TextureFormat.UNCOMPRESSED_R8G8B8A8) -- Format image to RGBA 32bit (required for texture update) -local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (VRAM) - -local currentProcess = COLOR_NONE -local textureReload = false - -local selectRecs = {} - -for i = 1, NUM_PROCESSES do selectRecs[i] = Rectangle(40, 50 + 32*i, 150, 30) end - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyPressed(KEY.DOWN)) then - currentProcess = currentProcess + 1 - if (currentProcess > NUM_PROCESSES) then currentProcess = 1 end - textureReload = true - elseif (IsKeyPressed(KEY.UP)) then - currentProcess = currentProcess - 1 - if (currentProcess < 1) then currentProcess = NUM_PROCESSES end - textureReload = true - end - - if (textureReload) then - UnloadImage(image) -- Unload current image data - image = LoadImage("resources/parrots.png") -- Re-load image data - - -- NOTE: Image processing is a costly CPU process to be done every frame, - -- If image processing is required in a frame-basis, it should be done - -- with a texture and by shaders - if (currentProcess == COLOR_GRAYSCALE) then image = ImageColorGrayscale(image) - elseif (currentProcess == COLOR_TINT) then image = ImageColorTint(image, GREEN) - elseif (currentProcess == COLOR_INVERT) then image = ImageColorInvert(image) - elseif (currentProcess == COLOR_CONTRAST) then image = ImageColorContrast(image, -40) - elseif (currentProcess == COLOR_BRIGHTNESS) then image = ImageColorBrightness(image, -80) - elseif (currentProcess == FLIP_VERTICAL) then image = ImageFlipVertical(image) - elseif (currentProcess == FLIP_HORIZONTAL) then image = ImageFlipHorizontal(image) - end - - local pixels = {} - pixels = GetImageData(image) -- Get pixel data from image (RGBA 32bit) - texture = UpdateTexture(texture, pixels) -- Update texture with new image data - - textureReload = false - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawText("IMAGE PROCESSING:", 40, 30, 10, DARKGRAY) - - -- Draw rectangles - for i = 1, NUM_PROCESSES do - if (i == currentProcess) then - DrawRectangleRec(selectRecs[i], SKYBLUE) - DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE) - DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)//2, selectRecs[i].y + 11, 10, DARKBLUE) - else - DrawRectangleRec(selectRecs[i], LIGHTGRAY) - DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY) - DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)//2, selectRecs[i].y + 11, 10, DARKGRAY) - end - end - - DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE) - DrawRectangleLines(screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, texture.width, texture.height, BLACK) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Unload texture from VRAM -UnloadImage(image) -- Unload image from RAM - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_logo_raylib.lua b/examples/textures_logo_raylib.lua deleted file mode 100644 index 3abcd802..00000000 --- a/examples/textures_logo_raylib.lua +++ /dev/null @@ -1,49 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Texture loading and drawing --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) -local texture = LoadTexture("resources/raylib_logo.png") -- Texture loading -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE) - - DrawText("this IS a texture!", 360, 370, 10, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_particles_trail_blending.lua b/examples/textures_particles_trail_blending.lua deleted file mode 100644 index d2c2518e..00000000 --- a/examples/textures_particles_trail_blending.lua +++ /dev/null @@ -1,113 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib example - particles trail blending --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - -MAX_PARTICLES = 200 - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles trail blending") - --- Particles pool, reuse them! -local mouseTail = {} - --- Initialize particles -for i = 1, MAX_PARTICLES do - mouseTail[i] = {} - mouseTail[i].position = Vector2(0, 0) - mouseTail[i].color = Color(GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255) - mouseTail[i].alpha = 1.0 - mouseTail[i].size = GetRandomValue(1, 30)/20.0 - mouseTail[i].rotation = GetRandomValue(0, 360) - mouseTail[i].active = false -end - -local gravity = 3.0 - -local smoke = LoadTexture("resources/smoke.png") - -local blending = BlendMode.ALPHA - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - - -- Activate one particle every frame and Update active particles - -- NOTE: Particles initial position should be mouse position when activated - -- NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0) - -- NOTE: When a particle disappears, active = false and it can be reused. - for i = 1, MAX_PARTICLES do - if (not mouseTail[i].active) then - mouseTail[i].active = true - mouseTail[i].alpha = 1.0 - mouseTail[i].position = GetMousePosition() - break - end - end - - for i = 1, MAX_PARTICLES do - if (mouseTail[i].active) then - mouseTail[i].position.y = mouseTail[i].position.y + gravity - mouseTail[i].alpha = mouseTail[i].alpha - 0.01 - - if (mouseTail[i].alpha <= 0.0) then mouseTail[i].active = false end - - mouseTail[i].rotation = mouseTail[i].rotation + 5.0 - end - end - - if (IsKeyPressed(KEY.SPACE)) then - if (blending == BlendMode.ALPHA) then blending = BlendMode.ADDITIVE - else blending = BlendMode.ALPHA end - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(DARKGRAY) - - BeginBlendMode(blending) - - -- Draw active particles - for i = 1, MAX_PARTICLES do - if (mouseTail[i].active) then - DrawTexturePro(smoke, Rectangle(0, 0, smoke.width, smoke.height), - Rectangle(mouseTail[i].position.x, mouseTail[i].position.y, - smoke.width*mouseTail[i].size//1, smoke.height*mouseTail[i].size//1), - Vector2(smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2), - mouseTail[i].rotation, Fade(mouseTail[i].color, mouseTail[i].alpha)) end - end - - EndBlendMode() - - DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK) - - if (blending == BlendMode.ALPHA) then DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK) - else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE) end - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(smoke) - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_raw_data.lua b/examples/textures_raw_data.lua deleted file mode 100644 index 0bad1771..00000000 --- a/examples/textures_raw_data.lua +++ /dev/null @@ -1,83 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Load textures from raw data --- --- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - ---#include -- Required for malloc() and free() - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture from raw data") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - --- Load RAW image data (512x512, 32bit RGBA, no file header) -local sonicRaw = LoadImageRaw("resources/texture_formats/sonic_R8G8B8A8.raw", 512, 512, TextureFormat.UNCOMPRESSED_R8G8B8A8, 0) -local sonic = LoadTextureFromImage(sonicRaw) -- Upload CPU (RAM) image to GPU (VRAM) -UnloadImage(sonicRaw) -- Unload CPU (RAM) image data - --- Generate a checked texture by code (1024x1024 pixels) -local width = 1024 -local height = 1024 - --- Dynamic memory allocation to store pixels data (Color type) -local pixels = {} - -for y = 1, height do - for x = 1, width do - if ((((x - 1)/32+(y - 1)//32)//1)%2 == 0) then pixels[(y - 1)*height + x] = DARKBLUE - else pixels[(y - 1)*height + x] = SKYBLUE end - end -end - --- Load pixels data into an image structure and create texture -local checkedIm = LoadImageEx(pixels, width, height) -local checked = LoadTextureFromImage(checkedIm) -UnloadImage(checkedIm) -- Unload CPU (RAM) image data - --- Dynamic memory must be freed after using it ---free(pixels) -- Unload CPU (RAM) pixels data -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.3)) - DrawTexture(sonic, 330, -20, WHITE) - - DrawText("CHECKED TEXTURE ", 84, 100, 30, DARKBLUE) - DrawText("GENERATED by CODE", 72, 164, 30, DARKBLUE) - DrawText("and RAW IMAGE LOADING", 46, 226, 30, DARKBLUE) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(sonic) -- Texture unloading -UnloadTexture(checked) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_rectangle.lua b/examples/textures_rectangle.lua deleted file mode 100644 index 5f481679..00000000 --- a/examples/textures_rectangle.lua +++ /dev/null @@ -1,69 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Texture loading and drawing a part defined by a rectangle --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [texture] example - texture rectangle") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) -local guybrush = LoadTexture("resources/guybrush.png") -- Texture loading - -local position = Vector2(350.0, 240.0) -local frameRec = Rectangle(0, 0, guybrush.width/7, guybrush.height) -local currentFrame = 0 -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - if (IsKeyPressed(KEY.RIGHT)) then - currentFrame = currentFrame + 1 - - if (currentFrame > 6) then currentFrame = 0 end - - frameRec.x = currentFrame*guybrush.width/7 - end - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(guybrush, 35, 40, WHITE) - DrawRectangleLines(35, 40, guybrush.width, guybrush.height, LIME) - - DrawTextureRec(guybrush, frameRec, position, WHITE) -- Draw part of the texture - - DrawRectangleLines(35 + frameRec.x, 40 + frameRec.y, frameRec.width, frameRec.height, RED) - - DrawText("PRESS RIGHT KEY to", 540, 310, 10, GRAY) - DrawText("CHANGE DRAWING RECTANGLE", 520, 330, 10, GRAY) - - DrawText("Guybrush Ulysses Threepwood,", 100, 300, 10, GRAY) - DrawText("main character of the Monkey Island series", 80, 320, 10, GRAY) - DrawText("of computer adventure games by LucasArts.", 80, 340, 10, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(guybrush) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_srcrec_dstrec.lua b/examples/textures_srcrec_dstrec.lua deleted file mode 100644 index f94deb3e..00000000 --- a/examples/textures_srcrec_dstrec.lua +++ /dev/null @@ -1,71 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Texture source and destination rectangles --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] examples - texture source and destination rectangles") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) -local guybrush = LoadTexture("resources/guybrush.png") -- Texture loading - -local frameWidth = guybrush.width/7 -local frameHeight = guybrush.height - --- NOTE: Source rectangle (part of the texture to use for drawing) -local sourceRec = Rectangle(0, 0, frameWidth, frameHeight) - --- NOTE: Destination rectangle (screen rectangle where drawing part of texture) -local destRec = Rectangle(screenWidth/2, screenHeight/2, frameWidth*2, frameHeight*2) - --- NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size -local origin = Vector2(frameWidth, frameHeight) - -local rotation = 0 - -SetTargetFPS(60) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - rotation = rotation + 1 - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - -- NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw - -- sourceRec defines the part of the texture we use for drawing - -- destRec defines the rectangle where our texture part will fit (scaling it to fit) - -- origin defines the point of the texture used as reference for rotation and scaling - -- rotation defines the texture rotation (using origin as rotation point) - DrawTexturePro(guybrush, sourceRec, destRec, origin, rotation, WHITE) - - DrawLine(destRec.x, 0, destRec.x, screenHeight, GRAY) - DrawLine(0, destRec.y, screenWidth, destRec.y, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(guybrush) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/textures_to_image.lua b/examples/textures_to_image.lua deleted file mode 100644 index b7a2d4ed..00000000 --- a/examples/textures_to_image.lua +++ /dev/null @@ -1,60 +0,0 @@ -------------------------------------------------------------------------------------------- --- --- raylib [textures] example - Retrieve image data from texture: GetTextureData() --- --- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM) --- --- This example has been created using raylib 1.6 (www.raylib.com) --- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) --- --- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) --- -------------------------------------------------------------------------------------------- - --- Initialization -------------------------------------------------------------------------------------------- -local screenWidth = 800 -local screenHeight = 450 - -InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture to image") - --- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - -local image = LoadImage("resources/raylib_logo.png") -- Load image data into CPU memory (RAM) -local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (RAM -> VRAM) -UnloadImage(image) -- Unload image data from CPU memory (RAM) - -image = GetTextureData(texture) -- Retrieve image data from GPU memory (VRAM -> RAM) -UnloadTexture(texture) -- Unload texture from GPU memory (VRAM) - -texture = LoadTextureFromImage(image) -- Recreate texture from retrieved image data (RAM -> VRAM) -UnloadImage(image) -- Unload retrieved image data from CPU memory (RAM) -------------------------------------------------------------------------------------------- - --- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key - -- Update - --------------------------------------------------------------------------------------- - -- TODO: Update your variables here - --------------------------------------------------------------------------------------- - - -- Draw - --------------------------------------------------------------------------------------- - BeginDrawing() - - ClearBackground(RAYWHITE) - - DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE) - - DrawText("this IS a texture loaded from an image!", 300, 370, 10, GRAY) - - EndDrawing() - --------------------------------------------------------------------------------------- -end - --- De-Initialization -------------------------------------------------------------------------------------------- -UnloadTexture(texture) -- Texture unloading - -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/rlua.h b/src/rlua.h deleted file mode 100644 index 80dede41..00000000 --- a/src/rlua.h +++ /dev/null @@ -1,4333 +0,0 @@ -/********************************************************************************************** -* -* rlua - raylib Lua bindings -* -* NOTE 01: -* The following types: -* Color, Vector2, Vector3, Rectangle, Ray, Camera, Camera2D -* are treated as objects with named fields, same as in C. -* -* Lua defines utility functions for creating those objects. -* Usage: -* local cl = Color(255,255,255,255) -* local rec = Rectangle(10, 10, 100, 100) -* local ray = Ray(Vector3(20, 20, 20), Vector3(50, 50, 50)) -* local x2 = rec.x + rec.width -* -* The following types: -* Image, Texture2D, RenderTexture2D, SpriteFont -* are immutable, and you can only read their non-pointer arguments (e.g. sprfnt.baseSize). -* -* All other object types are opaque, that is, you cannot access or -* change their fields directly. -* -* Remember that ALL raylib types have REFERENCE SEMANTICS in Lua. -* There is currently no way to create a copy of an opaque object. -* -* NOTE 02: -* Some raylib functions take a pointer to an array, and the size of that array. -* The equivalent Lua functions take only an array table of the specified type UNLESS -* it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns) -* a Lua string (without the size argument, as Lua strings are sized by default). -* -* NOTE 03: -* Some raylib functions take pointers to objects to modify (e.g. ImageToPOT, etc.) -* In Lua, these functions take values and return a new changed value, instead. -* So, in C: -* ImageToPOT(&img, BLACK); -* In Lua becomes: -* img = ImageToPOT(img, BLACK) -* -* Remember that functions can return multiple values, so: -* UpdateCameraPlayer(&cam, &playerPos); -* Vector3 vec = ResolveCollisionCubicmap(img, mapPos, &playerPos, 5.0); -* becomes: -* cam, playerPos = UpdateCameraPlayer(cam, playerPos) -* vec, playerPos = ResolveCollisionCubicmap(img, mapPos, playerPos, 5) -* -* This is to preserve value semantics of raylib objects. -* -* -* This Lua binding for raylib was originally created by Ghassan Al-Mashareqa (ghassan@ghassan.pl) -* for raylib 1.3 and later on reviewed and updated to raylib 1.6 by Ramon Santamaria. -* -* Copyright (c) 2015-2016 Ghassan Al-Mashareqa and Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -#pragma once - -#include "raylib.h" - -#define RLUA_STATIC -#ifdef RLUA_STATIC - #define RLUADEF static // Functions just visible to module including this file -#else - #ifdef __cplusplus - #define RLUADEF extern "C" // Functions visible from other files (no name mangling of functions in C++) - #else - #define RLUADEF extern // Functions visible from other files - #endif -#endif - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -// ... - -//---------------------------------------------------------------------------------- -// Module Functions Declaration -//---------------------------------------------------------------------------------- -RLUADEF void InitLuaDevice(void); // Initialize Lua system -RLUADEF void ExecuteLuaCode(const char *code); // Execute raylib Lua code -RLUADEF void ExecuteLuaFile(const char *filename); // Execute raylib Lua script -RLUADEF void CloseLuaDevice(void); // De-initialize Lua system - -/*********************************************************************************** -* -* RLUA IMPLEMENTATION -* -************************************************************************************/ - -#if defined(RLUA_IMPLEMENTATION) - -#include "raylib.h" -#include "utils.h" -#include "raymath.h" - -#include -#include - -#include -#include -#include - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#define LuaPush_Image(L, img) LuaPushOpaqueTypeWithMetatable(L, img, Image) -#define LuaPush_Texture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, Texture2D) -#define LuaPush_RenderTexture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, RenderTexture2D) -#define LuaPush_SpriteFont(L, sf) LuaPushOpaqueTypeWithMetatable(L, sf, SpriteFont) -#define LuaPush_Mesh(L, vd) LuaPushOpaqueType(L, vd) -#define LuaPush_Shader(L, s) LuaPushOpaqueType(L, s) -#define LuaPush_Light(L, light) LuaPushOpaqueTypeWithMetatable(L, light, Light) -#define LuaPush_Sound(L, snd) LuaPushOpaqueType(L, snd) -#define LuaPush_Wave(L, wav) LuaPushOpaqueType(L, wav) -#define LuaPush_Music(L, mus) LuaPushOpaqueType(L, mus) -#define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud) - -#define LuaGetArgument_string luaL_checkstring -#define LuaGetArgument_ptr (void *)luaL_checkinteger -#define LuaGetArgument_int (int)luaL_checkinteger -#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger -#define LuaGetArgument_char (char)luaL_checkinteger -#define LuaGetArgument_float (float)luaL_checknumber -#define LuaGetArgument_double luaL_checknumber - -#define LuaGetArgument_Image(L, img) *(Image*)LuaGetArgumentOpaqueTypeWithMetatable(L, img, "Image") -#define LuaGetArgument_Texture2D(L, tex) *(Texture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, tex, "Texture2D") -#define LuaGetArgument_RenderTexture2D(L, rtex) *(RenderTexture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, rtex, "RenderTexture2D") -#define LuaGetArgument_SpriteFont(L, sf) *(SpriteFont*)LuaGetArgumentOpaqueTypeWithMetatable(L, sf, "SpriteFont") -#define LuaGetArgument_Mesh(L, vd) *(Mesh*)LuaGetArgumentOpaqueType(L, vd) -#define LuaGetArgument_Shader(L, s) *(Shader*)LuaGetArgumentOpaqueType(L, s) -#define LuaGetArgument_Light(L, light) *(Light*)LuaGetArgumentOpaqueType(L, light) -#define LuaGetArgument_Sound(L, snd) *(Sound*)LuaGetArgumentOpaqueType(L, snd) -#define LuaGetArgument_Wave(L, wav) *(Wave*)LuaGetArgumentOpaqueType(L, wav) -#define LuaGetArgument_Music(L, mus) *(Music*)LuaGetArgumentOpaqueType(L, mus) -#define LuaGetArgument_AudioStream(L, aud) *(AudioStream*)LuaGetArgumentOpaqueType(L, aud) - -#define LuaPushOpaqueType(L, str) LuaPushOpaque(L, &str, sizeof(str)) -#define LuaPushOpaqueTypeWithMetatable(L, str, meta) LuaPushOpaqueWithMetatable(L, &str, sizeof(str), #meta) - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -static lua_State* mainLuaState = 0; -static lua_State* L = 0; - -//---------------------------------------------------------------------------------- -// Module specific Functions Declaration -//---------------------------------------------------------------------------------- -static void LuaPush_Color(lua_State* L, Color color); -static void LuaPush_Vector2(lua_State* L, Vector2 vec); -static void LuaPush_Vector3(lua_State* L, Vector3 vec); -static void LuaPush_Quaternion(lua_State* L, Quaternion vec); -static void LuaPush_Matrix(lua_State* L, Matrix *matrix); -static void LuaPush_Rectangle(lua_State* L, Rectangle rect); -static void LuaPush_Model(lua_State* L, Model mdl); -static void LuaPush_Ray(lua_State* L, Ray ray); -static void LuaPush_Camera(lua_State* L, Camera cam); - -static Vector2 LuaGetArgument_Vector2(lua_State* L, int index); -static Vector3 LuaGetArgument_Vector3(lua_State* L, int index); -static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index); -static Color LuaGetArgument_Color(lua_State* L, int index); -static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index); -static Camera LuaGetArgument_Camera(lua_State* L, int index); -static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index); -static Ray LuaGetArgument_Ray(lua_State* L, int index); -static Matrix LuaGetArgument_Matrix(lua_State* L, int index); -static Model LuaGetArgument_Model(lua_State* L, int index); - -//---------------------------------------------------------------------------------- -// rlua Helper Functions -//---------------------------------------------------------------------------------- -static void LuaStartEnum(void) -{ - lua_newtable(L); -} - -static void LuaSetEnum(const char *name, int value) -{ - lua_pushinteger(L, value); - lua_setfield(L, -2, name); -} - -static void LuaSetEnumColor(const char *name, Color color) -{ - LuaPush_Color(L, color); - lua_setfield(L, -2, name); -} - -static void LuaEndEnum(const char *name) -{ - lua_setglobal(L, name); -} - -static void LuaPushOpaque(lua_State* L, void *ptr, size_t size) -{ - void *ud = lua_newuserdata(L, size); - memcpy(ud, ptr, size); -} - -static void LuaPushOpaqueWithMetatable(lua_State* L, void *ptr, size_t size, const char *metatable_name) -{ - void *ud = lua_newuserdata(L, size); - memcpy(ud, ptr, size); - luaL_setmetatable(L, metatable_name); -} - -static void* LuaGetArgumentOpaqueType(lua_State* L, int index) -{ - return lua_touserdata(L, index); -} - -static void* LuaGetArgumentOpaqueTypeWithMetatable(lua_State* L, int index, const char *metatable_name) -{ - return luaL_checkudata(L, index, metatable_name); -} - -//---------------------------------------------------------------------------------- -// LuaIndex* functions -//---------------------------------------------------------------------------------- -static int LuaIndexImage(lua_State* L) -{ - Image img = LuaGetArgument_Image(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "width")) - lua_pushinteger(L, img.width); - else if (!strcmp(key, "height")) - lua_pushinteger(L, img.height); - else if (!strcmp(key, "mipmaps")) - lua_pushinteger(L, img.mipmaps); - else if (!strcmp(key, "format")) - lua_pushinteger(L, img.format); - else - return 0; - return 1; -} - -static int LuaIndexTexture2D(lua_State* L) -{ - Texture2D img = LuaGetArgument_Texture2D(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "width")) - lua_pushinteger(L, img.width); - else if (!strcmp(key, "height")) - lua_pushinteger(L, img.height); - else if (!strcmp(key, "mipmaps")) - lua_pushinteger(L, img.mipmaps); - else if (!strcmp(key, "format")) - lua_pushinteger(L, img.format); - else if (!strcmp(key, "id")) - lua_pushinteger(L, img.id); - else - return 0; - return 1; -} - -static int LuaIndexRenderTexture2D(lua_State* L) -{ - RenderTexture2D img = LuaGetArgument_RenderTexture2D(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "texture")) - LuaPush_Texture2D(L, img.texture); - else if (!strcmp(key, "depth")) - LuaPush_Texture2D(L, img.depth); - else - return 0; - return 1; -} - -static int LuaIndexSpriteFont(lua_State* L) -{ - SpriteFont img = LuaGetArgument_SpriteFont(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "size")) - lua_pushinteger(L, img.size); - else if (!strcmp(key, "texture")) - LuaPush_Texture2D(L, img.texture); - else if (!strcmp(key, "charsCount")) - lua_pushinteger(L, img.charsCount); - else - return 0; - return 1; -} - -static int LuaIndexLight(lua_State* L) -{ - Light light = LuaGetArgument_Light(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "id")) - lua_pushinteger(L, light->id); - else if (!strcmp(key, "enabled")) - lua_pushboolean(L, light->enabled); - else if (!strcmp(key, "type")) - lua_pushinteger(L, light->type); - else if (!strcmp(key, "position")) - LuaPush_Vector3(L, light->position); - else if (!strcmp(key, "target")) - LuaPush_Vector3(L, light->target); - else if (!strcmp(key, "radius")) - lua_pushnumber(L, light->radius); - else if (!strcmp(key, "diffuse")) - LuaPush_Color(L, light->diffuse); - else if (!strcmp(key, "intensity")) - lua_pushnumber(L, light->intensity); - else if (!strcmp(key, "coneAngle")) - lua_pushnumber(L, light->coneAngle); - else - return 0; - return 1; -} - -static int LuaNewIndexLight(lua_State* L) -{ - Light light = LuaGetArgument_Light(L, 1); - const char *key = luaL_checkstring(L, 2); - if (!strcmp(key, "id")) - light->id = LuaGetArgument_int(L, 3); - else if (!strcmp(key, "enabled")) - light->enabled = lua_toboolean(L, 3); - else if (!strcmp(key, "type")) - light->type = LuaGetArgument_int(L, 3); - else if (!strcmp(key, "position")) - light->position = LuaGetArgument_Vector3(L, 3); - else if (!strcmp(key, "target")) - light->target = LuaGetArgument_Vector3(L, 3); - else if (!strcmp(key, "radius")) - light->radius = LuaGetArgument_float(L, 3); - else if (!strcmp(key, "diffuse")) - light->diffuse = LuaGetArgument_Color(L, 3); - else if (!strcmp(key, "intensity")) - light->intensity = LuaGetArgument_float(L, 3); - else if (!strcmp(key, "coneAngle")) - light->coneAngle = LuaGetArgument_float(L, 3); - return 0; -} - -static void LuaBuildOpaqueMetatables(void) -{ - luaL_newmetatable(L, "Image"); - lua_pushcfunction(L, &LuaIndexImage); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - luaL_newmetatable(L, "Texture2D"); - lua_pushcfunction(L, &LuaIndexTexture2D); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - luaL_newmetatable(L, "RenderTexture2D"); - lua_pushcfunction(L, &LuaIndexRenderTexture2D); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - luaL_newmetatable(L, "SpriteFont"); - lua_pushcfunction(L, &LuaIndexSpriteFont); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - luaL_newmetatable(L, "Light"); - lua_pushcfunction(L, &LuaIndexLight); - lua_setfield(L, -2, "__index"); - lua_pushcfunction(L, &LuaNewIndexLight); - lua_setfield(L, -2, "__newindex"); - lua_pop(L, 1); -} - -//---------------------------------------------------------------------------------- -// LuaGetArgument functions -//---------------------------------------------------------------------------------- - -static Vector2 LuaGetArgument_Vector2(lua_State* L, int index) -{ - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector2"); - float x = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector2"); - float y = (float)lua_tonumber(L, -1); - lua_pop(L, 2); - return (Vector2) { x, y }; -} - -static Vector3 LuaGetArgument_Vector3(lua_State* L, int index) -{ - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector3"); - float x = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector3"); - float y = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Vector3"); - float z = (float)lua_tonumber(L, -1); - lua_pop(L, 3); - return (Vector3) { x, y, z }; -} - -static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index) -{ - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Quaternion"); - float x = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Quaternion"); - float y = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Quaternion"); - float z = (float)lua_tonumber(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "w") == LUA_TNUMBER, index, "Expected Quaternion"); - float w = (float)lua_tonumber(L, -1); - lua_pop(L, 4); - return (Quaternion) { x, y, z, w }; -} - -static Color LuaGetArgument_Color(lua_State* L, int index) -{ - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "r") == LUA_TNUMBER, index, "Expected Color"); - unsigned char r = (unsigned char)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "g") == LUA_TNUMBER, index, "Expected Color"); - unsigned char g = (unsigned char)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "b") == LUA_TNUMBER, index, "Expected Color"); - unsigned char b = (unsigned char)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "a") == LUA_TNUMBER, index, "Expected Color"); - unsigned char a = (unsigned char)lua_tointeger(L, -1); - lua_pop(L, 4); - return (Color) { r, g, b, a }; -} - -static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index) -{ - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Rectangle"); - int x = (int)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Rectangle"); - int y = (int)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "width") == LUA_TNUMBER, index, "Expected Rectangle"); - int w = (int)lua_tointeger(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "height") == LUA_TNUMBER, index, "Expected Rectangle"); - int h = (int)lua_tointeger(L, -1); - lua_pop(L, 4); - return (Rectangle) { x, y, w, h }; -} - -static Camera LuaGetArgument_Camera(lua_State* L, int index) -{ - Camera result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Camera"); - result.position = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera"); - result.target = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "up") == LUA_TTABLE, index, "Expected Camera"); - result.up = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "fovy") == LUA_TNUMBER, index, "Expected Camera"); - result.fovy = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; -} - -static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index) -{ - Camera2D result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "offset") == LUA_TTABLE, index, "Expected Camera2D"); - result.offset = LuaGetArgument_Vector2(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera2D"); - result.target = LuaGetArgument_Vector2(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "rotation") == LUA_TNUMBER, index, "Expected Camera2D"); - result.rotation = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "zoom") == LUA_TNUMBER, index, "Expected Camera2D"); - result.zoom = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; -} - -static BoundingBox LuaGetArgument_BoundingBox(lua_State* L, int index) -{ - BoundingBox result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "min") == LUA_TTABLE, index, "Expected BoundingBox"); - result.min = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "max") == LUA_TTABLE, index, "Expected BoundingBox"); - result.max = LuaGetArgument_Vector3(L, -1); - lua_pop(L, 2); - return result; -} - -static Ray LuaGetArgument_Ray(lua_State* L, int index) -{ - Ray result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Ray"); - result.position = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "direction") == LUA_TTABLE, index, "Expected Ray"); - result.direction = LuaGetArgument_Vector3(L, -1); - lua_pop(L, 2); - return result; -} - -static Matrix LuaGetArgument_Matrix(lua_State* L, int index) -{ - Matrix result = { 0 }; - float* ptr = &result.m0; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - - for (int i = 0; i < 16; i++) - { - lua_geti(L, index, i+1); - ptr[i] = luaL_checknumber(L, -1); - } - lua_pop(L, 16); - return result; -} - -static Material LuaGetArgument_Material(lua_State* L, int index) -{ - Material result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "shader") == LUA_TUSERDATA, index, "Expected Material"); - result.shader = LuaGetArgument_Shader(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texDiffuse") == LUA_TUSERDATA, index, "Expected Material"); - result.texDiffuse = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texNormal") == LUA_TUSERDATA, index, "Expected Material"); - result.texNormal = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texSpecular") == LUA_TUSERDATA, index, "Expected Material"); - result.texSpecular = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colDiffuse") == LUA_TTABLE, index, "Expected Material"); - result.colDiffuse = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colAmbient") == LUA_TTABLE, index, "Expected Material"); - result.colAmbient = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colSpecular") == LUA_TTABLE, index, "Expected Material"); - result.colSpecular = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "glossiness") == LUA_TNUMBER, index, "Expected Material"); - result.glossiness = LuaGetArgument_float(L, -1); - lua_pop(L, 8); - return result; -} - -static Model LuaGetArgument_Model(lua_State* L, int index) -{ - Model result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "mesh") == LUA_TUSERDATA, index, "Expected Model"); - result.mesh = LuaGetArgument_Mesh(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "transform") == LUA_TTABLE, index, "Expected Model"); - result.transform = LuaGetArgument_Matrix(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "material") == LUA_TTABLE, index, "Expected Model"); - result.material = LuaGetArgument_Material(L, -1); - lua_pop(L, 3); - return result; -} - -//---------------------------------------------------------------------------------- -// LuaPush functions -//---------------------------------------------------------------------------------- -static void LuaPush_Color(lua_State* L, Color color) -{ - lua_createtable(L, 0, 4); - lua_pushinteger(L, color.r); - lua_setfield(L, -2, "r"); - lua_pushinteger(L, color.g); - lua_setfield(L, -2, "g"); - lua_pushinteger(L, color.b); - lua_setfield(L, -2, "b"); - lua_pushinteger(L, color.a); - lua_setfield(L, -2, "a"); -} - -static void LuaPush_Vector2(lua_State* L, Vector2 vec) -{ - lua_createtable(L, 0, 2); - lua_pushnumber(L, vec.x); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, vec.y); - lua_setfield(L, -2, "y"); -} - -static void LuaPush_Vector3(lua_State* L, Vector3 vec) -{ - lua_createtable(L, 0, 3); - lua_pushnumber(L, vec.x); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, vec.y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, vec.z); - lua_setfield(L, -2, "z"); -} - -static void LuaPush_Quaternion(lua_State* L, Quaternion vec) -{ - lua_createtable(L, 0, 4); - lua_pushnumber(L, vec.x); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, vec.y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, vec.z); - lua_setfield(L, -2, "z"); - lua_pushnumber(L, vec.w); - lua_setfield(L, -2, "w"); -} - -static void LuaPush_Matrix(lua_State* L, Matrix *matrix) -{ - int i; - lua_createtable(L, 16, 0); - float* num = (&matrix->m0); - for (i = 0; i < 16; i++) - { - lua_pushnumber(L, num[i]); - lua_rawseti(L, -2, i + 1); - } -} - -static void LuaPush_Rectangle(lua_State* L, Rectangle rect) -{ - lua_createtable(L, 0, 4); - lua_pushinteger(L, rect.x); - lua_setfield(L, -2, "x"); - lua_pushinteger(L, rect.y); - lua_setfield(L, -2, "y"); - lua_pushinteger(L, rect.width); - lua_setfield(L, -2, "width"); - lua_pushinteger(L, rect.height); - lua_setfield(L, -2, "height"); -} - -static void LuaPush_Ray(lua_State* L, Ray ray) -{ - lua_createtable(L, 0, 2); - LuaPush_Vector3(L, ray.position); - lua_setfield(L, -2, "position"); - LuaPush_Vector3(L, ray.direction); - lua_setfield(L, -2, "direction"); -} - -static void LuaPush_BoundingBox(lua_State* L, BoundingBox bb) -{ - lua_createtable(L, 0, 2); - LuaPush_Vector3(L, bb.min); - lua_setfield(L, -2, "min"); - LuaPush_Vector3(L, bb.max); - lua_setfield(L, -2, "max"); -} - -static void LuaPush_Camera(lua_State* L, Camera cam) -{ - lua_createtable(L, 0, 4); - LuaPush_Vector3(L, cam.position); - lua_setfield(L, -2, "position"); - LuaPush_Vector3(L, cam.target); - lua_setfield(L, -2, "target"); - LuaPush_Vector3(L, cam.up); - lua_setfield(L, -2, "up"); - lua_pushnumber(L, cam.fovy); - lua_setfield(L, -2, "fovy"); -} - -static void LuaPush_Camera2D(lua_State* L, Camera2D cam) -{ - lua_createtable(L, 0, 4); - LuaPush_Vector2(L, cam.offset); - lua_setfield(L, -2, "offset"); - LuaPush_Vector2(L, cam.target); - lua_setfield(L, -2, "target"); - lua_pushnumber(L, cam.rotation); - lua_setfield(L, -2, "rotation"); - lua_pushnumber(L, cam.zoom); - lua_setfield(L, -2, "zoom"); -} - -static void LuaPush_Material(lua_State* L, Material mat) -{ - lua_createtable(L, 0, 8); - LuaPush_Shader(L, mat.shader); - lua_setfield(L, -2, "shader"); - LuaPush_Texture2D(L, mat.texDiffuse); - lua_setfield(L, -2, "texDiffuse"); - LuaPush_Texture2D(L, mat.texNormal); - lua_setfield(L, -2, "texNormal"); - LuaPush_Texture2D(L, mat.texSpecular); - lua_setfield(L, -2, "texSpecular"); - LuaPush_Color(L, mat.colDiffuse); - lua_setfield(L, -2, "colDiffuse"); - LuaPush_Color(L, mat.colAmbient); - lua_setfield(L, -2, "colAmbient"); - LuaPush_Color(L, mat.colSpecular); - lua_setfield(L, -2, "colSpecular"); - lua_pushnumber(L, mat.glossiness); - lua_setfield(L, -2, "glossiness"); -} - -static void LuaPush_Model(lua_State* L, Model mdl) -{ - lua_createtable(L, 0, 4); - LuaPush_Mesh(L, mdl.mesh); - lua_setfield(L, -2, "mesh"); - LuaPush_Matrix(L, &mdl.transform); - lua_setfield(L, -2, "transform"); - LuaPush_Material(L, mdl.material); - lua_setfield(L, -2, "material"); -} - -//---------------------------------------------------------------------------------- -// raylib Lua Structure constructors -//---------------------------------------------------------------------------------- -static int lua_Color(lua_State* L) -{ - LuaPush_Color(L, (Color) { (unsigned char)luaL_checkinteger(L, 1), (unsigned char)luaL_checkinteger(L, 2), (unsigned char)luaL_checkinteger(L, 3), (unsigned char)luaL_checkinteger(L, 4) }); - return 1; -} - -static int lua_Vector2(lua_State* L) -{ - LuaPush_Vector2(L, (Vector2) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2) }); - return 1; -} - -static int lua_Vector3(lua_State* L) -{ - LuaPush_Vector3(L, (Vector3) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3) }); - return 1; -} - -static int lua_Quaternion(lua_State* L) -{ - LuaPush_Quaternion(L, (Quaternion) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3), (float)luaL_checknumber(L, 4) }); - return 1; -} - -static int lua_Rectangle(lua_State* L) -{ - LuaPush_Rectangle(L, (Rectangle) { (int)luaL_checkinteger(L, 1), (int)luaL_checkinteger(L, 2), (int)luaL_checkinteger(L, 3), (int)luaL_checkinteger(L, 4) }); - return 1; -} - -static int lua_Ray(lua_State* L) -{ - Vector2 pos = LuaGetArgument_Vector2(L, 1); - Vector2 dir = LuaGetArgument_Vector2(L, 2); - LuaPush_Ray(L, (Ray) { { pos.x, pos.y }, { dir.x, dir.y } }); - return 1; -} - -static int lua_BoundingBox(lua_State* L) -{ - Vector3 min = LuaGetArgument_Vector3(L, 1); - Vector3 max = LuaGetArgument_Vector3(L, 2); - LuaPush_BoundingBox(L, (BoundingBox) { { min.x, min.y, min.z }, { max.x, max.y, max.z } }); - return 1; -} - -static int lua_Camera(lua_State* L) -{ - Vector3 pos = LuaGetArgument_Vector3(L, 1); - Vector3 tar = LuaGetArgument_Vector3(L, 2); - Vector3 up = LuaGetArgument_Vector3(L, 3); - float fovy = LuaGetArgument_float(L, 4); - LuaPush_Camera(L, (Camera) { { pos.x, pos.y, pos.z }, { tar.x, tar.y, tar.z }, { up.x, up.y, up.z }, fovy }); - return 1; -} - -static int lua_Camera2D(lua_State* L) -{ - Vector2 off = LuaGetArgument_Vector2(L, 1); - Vector2 tar = LuaGetArgument_Vector2(L, 2); - float rot = LuaGetArgument_float(L, 3); - float zoom = LuaGetArgument_float(L, 4); - LuaPush_Camera2D(L, (Camera2D) { { off.x, off.y }, { tar.x, tar.y }, rot, zoom }); - return 1; -} - -/************************************************************************************* -* raylib Lua Functions Bindings -**************************************************************************************/ - -//------------------------------------------------------------------------------------ -// raylib [core] module functions - Window and Graphics Device -//------------------------------------------------------------------------------------ -int lua_InitWindow(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - const char * arg3 = LuaGetArgument_string(L, 3); - InitWindow(arg1, arg2, arg3); - return 0; -} - -int lua_CloseWindow(lua_State* L) -{ - CloseWindow(); - return 0; -} - -int lua_WindowShouldClose(lua_State* L) -{ - bool result = WindowShouldClose(); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsWindowMinimized(lua_State* L) -{ - bool result = IsWindowMinimized(); - lua_pushboolean(L, result); - return 1; -} - -int lua_ToggleFullscreen(lua_State* L) -{ - ToggleFullscreen(); - return 0; -} - -int lua_GetScreenWidth(lua_State* L) -{ - int result = GetScreenWidth(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetScreenHeight(lua_State* L) -{ - int result = GetScreenHeight(); - lua_pushinteger(L, result); - return 1; -} - -int lua_ShowCursor(lua_State* L) -{ - ShowCursor(); - return 0; -} - -int lua_HideCursor(lua_State* L) -{ - HideCursor(); - return 0; -} - -int lua_IsCursorHidden(lua_State* L) -{ - bool result = IsCursorHidden(); - lua_pushboolean(L, result); - return 1; -} - -int lua_EnableCursor(lua_State* L) -{ - EnableCursor(); - return 0; -} - -int lua_DisableCursor(lua_State* L) -{ - DisableCursor(); - return 0; -} - -int lua_ClearBackground(lua_State* L) -{ - Color arg1 = LuaGetArgument_Color(L, 1); - ClearBackground(arg1); - return 0; -} - -int lua_BeginDrawing(lua_State* L) -{ - BeginDrawing(); - return 0; -} - -int lua_EndDrawing(lua_State* L) -{ - EndDrawing(); - return 0; -} - -int lua_Begin2dMode(lua_State* L) -{ - Camera2D arg1 = LuaGetArgument_Camera2D(L, 1); - Begin2dMode(arg1); - return 0; -} - -int lua_End2dMode(lua_State* L) -{ - End2dMode(); - return 0; -} - -int lua_Begin3dMode(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - Begin3dMode(arg1); - return 0; -} - -int lua_End3dMode(lua_State* L) -{ - End3dMode(); - return 0; -} - -int lua_BeginTextureMode(lua_State* L) -{ - RenderTexture2D arg1 = LuaGetArgument_RenderTexture2D(L, 1); - BeginTextureMode(arg1); - return 0; -} - -int lua_EndTextureMode(lua_State* L) -{ - EndTextureMode(); - return 0; -} - -int lua_GetMouseRay(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Camera arg2 = LuaGetArgument_Camera(L, 2); - Ray result = GetMouseRay(arg1, arg2); - LuaPush_Ray(L, result); - return 1; -} - -int lua_GetWorldToScreen(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Camera arg2 = LuaGetArgument_Camera(L, 2); - Vector2 result = GetWorldToScreen(arg1, arg2); - LuaPush_Vector2(L, result); - return 1; -} - -int lua_GetCameraMatrix(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - Matrix result = GetCameraMatrix(arg1); - LuaPush_Matrix(L, &result); - return 1; -} - -#if defined(PLATFORM_WEB) - -static int LuaDrawLoopFunc; - -static void LuaDrawLoop() -{ - lua_rawgeti(L, LUA_REGISTRYINDEX, LuaDrawLoopFunc); - lua_call(L, 0, 0); -} - -int lua_SetDrawingLoop(lua_State* L) -{ - luaL_argcheck(L, lua_isfunction(L, 1), 1, "Loop function expected"); - lua_pushvalue(L, 1); - LuaDrawLoopFunc = luaL_ref(L, LUA_REGISTRYINDEX); - SetDrawingLoop(&LuaDrawLoop); - return 0; -} - -#else - -int lua_SetTargetFPS(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - SetTargetFPS(arg1); - return 0; -} -#endif - -int lua_GetFPS(lua_State* L) -{ - float result = GetFPS(); - lua_pushnumber(L, result); - return 1; -} - -int lua_GetFrameTime(lua_State* L) -{ - float result = GetFrameTime(); - lua_pushnumber(L, result); - return 1; -} - -int lua_GetColor(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - Color result = GetColor(arg1); - LuaPush_Color(L, result); - return 1; -} - -int lua_GetHexValue(lua_State* L) -{ - Color arg1 = LuaGetArgument_Color(L, 1); - int result = GetHexValue(arg1); - lua_pushinteger(L, result); - return 1; -} - -int lua_ColorToFloat(lua_State* L) -{ - Color arg1 = LuaGetArgument_Color(L, 1); - float * result = ColorToFloat(arg1); - lua_createtable(L, 4, 0); - for (int i = 0; i < 4; i++) - { - lua_pushnumber(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; -} - -int lua_VectorToFloat(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float * result = VectorToFloat(arg1); - lua_createtable(L, 3, 0); - for (int i = 0; i < 3; i++) - { - lua_pushnumber(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; -} - -int lua_MatrixToFloat(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float * result = MatrixToFloat(arg1); - lua_createtable(L, 16, 0); - for (int i = 0; i < 16; i++) - { - lua_pushnumber(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; -} - -int lua_GetRandomValue(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int result = GetRandomValue(arg1, arg2); - lua_pushinteger(L, result); - return 1; -} - -int lua_Fade(lua_State* L) -{ - Color arg1 = LuaGetArgument_Color(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Color result = Fade(arg1, arg2); - LuaPush_Color(L, result); - return 1; -} - -int lua_SetConfigFlags(lua_State* L) -{ - char arg1 = LuaGetArgument_char(L, 1); - SetConfigFlags(arg1); - return 0; -} - -int lua_ShowLogo(lua_State* L) -{ - ShowLogo(); - return 0; -} - -int lua_IsFileDropped(lua_State* L) -{ - bool result = IsFileDropped(); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetDroppedFiles(lua_State* L) -{ - int count = 0; - char ** result = GetDroppedFiles(&count); - lua_createtable(L, count, 0); - for (int i = 0; i < count; i++) - { - lua_pushstring(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - return 1; -} - -int lua_ClearDroppedFiles(lua_State* L) -{ - ClearDroppedFiles(); - return 0; -} - -int lua_StorageSaveValue(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - StorageSaveValue(arg1, arg2); - return 0; -} - -int lua_StorageLoadValue(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int result = StorageLoadValue(arg1); - lua_pushinteger(L, result); - return 1; -} - -//------------------------------------------------------------------------------------ -// raylib [core] module functions - Input Handling -//------------------------------------------------------------------------------------ -int lua_IsKeyPressed(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsKeyPressed(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsKeyDown(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsKeyDown(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsKeyReleased(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsKeyReleased(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsKeyUp(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsKeyUp(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetKeyPressed(lua_State* L) -{ - int result = GetKeyPressed(); - lua_pushinteger(L, result); - return 1; -} - -int lua_SetExitKey(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - SetExitKey(arg1); - return 0; -} - -int lua_IsGamepadAvailable(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsGamepadAvailable(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsGamepadName(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - bool result = IsGamepadName(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetGamepadName(lua_State* L) -{ - // TODO: Return gamepad name id - - int arg1 = LuaGetArgument_int(L, 1); - const char * result = GetGamepadName(arg1); - //lua_pushboolean(L, result); - return 1; -} - -int lua_IsGamepadButtonPressed(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonPressed(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsGamepadButtonDown(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonDown(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsGamepadButtonReleased(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonReleased(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsGamepadButtonUp(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonUp(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetGamepadButtonPressed(lua_State* L) -{ - int result = GetGamepadButtonPressed(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetGamepadAxisCount(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int result = GetGamepadAxisCount(arg1); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetGamepadAxisMovement(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - float result = GetGamepadAxisMovement(arg1, arg2); - lua_pushnumber(L, result); - return 1; -} - -int lua_IsMouseButtonPressed(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonPressed(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsMouseButtonDown(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonDown(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsMouseButtonReleased(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonReleased(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsMouseButtonUp(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonUp(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetMouseX(lua_State* L) -{ - int result = GetMouseX(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetMouseY(lua_State* L) -{ - int result = GetMouseY(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetMousePosition(lua_State* L) -{ - Vector2 result = GetMousePosition(); - LuaPush_Vector2(L, result); - return 1; -} - -int lua_SetMousePosition(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - SetMousePosition(arg1); - return 0; -} - -int lua_GetMouseWheelMove(lua_State* L) -{ - int result = GetMouseWheelMove(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetTouchX(lua_State* L) -{ - int result = GetTouchX(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetTouchY(lua_State* L) -{ - int result = GetTouchY(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetTouchPosition(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - Vector2 result = GetTouchPosition(arg1); - LuaPush_Vector2(L, result); - return 1; -} - - -#if defined(PLATFORM_ANDROID) -int lua_IsButtonPressed(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsButtonPressed(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsButtonDown(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsButtonDown(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsButtonReleased(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsButtonReleased(arg1); - lua_pushboolean(L, result); - return 1; -} -#endif - -//------------------------------------------------------------------------------------ -// raylib [gestures] module functions - Gestures and Touch Handling -//------------------------------------------------------------------------------------ -int lua_SetGesturesEnabled(lua_State* L) -{ - unsigned arg1 = LuaGetArgument_unsigned(L, 1); - SetGesturesEnabled(arg1); - return 0; -} - -int lua_IsGestureDetected(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - bool result = IsGestureDetected(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetTouchPointsCount(lua_State* L) -{ - int result = GetTouchPointsCount(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetGestureDetected(lua_State* L) -{ - int result = GetGestureDetected(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetGestureHoldDuration(lua_State* L) -{ - int result = GetGestureHoldDuration(); - lua_pushinteger(L, result); - return 1; -} - -int lua_GetGestureDragVector(lua_State* L) -{ - Vector2 result = GetGestureDragVector(); - LuaPush_Vector2(L, result); - return 1; -} - -int lua_GetGestureDragAngle(lua_State* L) -{ - float result = GetGestureDragAngle(); - lua_pushnumber(L, result); - return 1; -} - -int lua_GetGesturePinchVector(lua_State* L) -{ - Vector2 result = GetGesturePinchVector(); - LuaPush_Vector2(L, result); - return 1; -} - -int lua_GetGesturePinchAngle(lua_State* L) -{ - float result = GetGesturePinchAngle(); - lua_pushnumber(L, result); - return 1; -} - -//------------------------------------------------------------------------------------ -// raylib [camera] module functions - Camera System -//------------------------------------------------------------------------------------ -int lua_SetCameraMode(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - SetCameraMode(arg1, arg2); - return 0; -} - -int lua_UpdateCamera(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - UpdateCamera(&arg1); - LuaPush_Camera(L, arg1); - return 1; -} - -int lua_SetCameraPanControl(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - SetCameraPanControl(arg1); - return 0; -} - -int lua_SetCameraAltControl(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - SetCameraAltControl(arg1); - return 0; -} - -int lua_SetCameraSmoothZoomControl(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - SetCameraSmoothZoomControl(arg1); - return 0; -} - -int lua_SetCameraMoveControls(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - int arg6 = LuaGetArgument_int(L, 6); - SetCameraMoveControls(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -//------------------------------------------------------------------------------------ -// raylib [shapes] module functions - Basic Shapes Drawing -//------------------------------------------------------------------------------------ -int lua_DrawPixel(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawPixel(arg1, arg2, arg3); - return 0; -} - -int lua_DrawPixelV(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawPixelV(arg1, arg2); - return 0; -} - -int lua_DrawLine(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawLine(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawLineV(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawLineV(arg1, arg2, arg3); - return 0; -} - -int lua_DrawCircle(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawCircle(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawCircleGradient(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawCircleGradient(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawCircleV(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawCircleV(arg1, arg2, arg3); - return 0; -} - -int lua_DrawCircleLines(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawCircleLines(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawRectangle(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawRectangle(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawRectangleRec(lua_State* L) -{ - Rectangle arg1 = LuaGetArgument_Rectangle(L, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawRectangleRec(arg1, arg2); - return 0; -} - -int lua_DrawRectangleGradient(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawRectangleGradient(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawRectangleV(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawRectangleV(arg1, arg2, arg3); - return 0; -} - -int lua_DrawRectangleLines(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawRectangleLines(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawTriangle(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawTriangle(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawTriangleLines(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawTriangleLines(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawPoly(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawPoly(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -#define GET_TABLE(type, name, index) \ - type* name = 0; \ - size_t name##_size = 0; \ - { \ - size_t sz = 0; \ - luaL_checktype(L, index, LUA_TTABLE); \ - lua_pushnil(L); \ - while (lua_next(L, index)) { \ - LuaGetArgument_##type(L, -1); \ - sz++; \ - lua_pop(L, 1); \ - } \ - name = calloc(sz, sizeof(type)); \ - sz = 0; \ - lua_pushnil(L); \ - while (lua_next(L, index)) { \ - name[sz] = LuaGetArgument_##type(L, -1); \ - sz++; \ - lua_pop(L, 1); \ - } \ - lua_pop(L, 1); \ - name##_size = sz; \ - } - - -int lua_DrawPolyEx(lua_State* L) -{ - GET_TABLE(Vector2, arg1, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawPolyEx(arg1, arg1_size, arg2); - free(arg1); - return 0; -} - -int lua_DrawPolyExLines(lua_State* L) -{ - GET_TABLE(Vector2, arg1, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawPolyExLines(arg1, arg1_size, arg2); - free(arg1); - return 0; -} - -int lua_CheckCollisionRecs(lua_State* L) -{ - Rectangle arg1 = LuaGetArgument_Rectangle(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - bool result = CheckCollisionRecs(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionCircles(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - bool result = CheckCollisionCircles(arg1, arg2, arg3, arg4); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionCircleRec(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Rectangle arg3 = LuaGetArgument_Rectangle(L, 3); - bool result = CheckCollisionCircleRec(arg1, arg2, arg3); - lua_pushboolean(L, result); - return 1; -} - -int lua_GetCollisionRec(lua_State* L) -{ - Rectangle arg1 = LuaGetArgument_Rectangle(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - Rectangle result = GetCollisionRec(arg1, arg2); - LuaPush_Rectangle(L, result); - return 1; -} - -int lua_CheckCollisionPointRec(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - bool result = CheckCollisionPointRec(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionPointCircle(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - bool result = CheckCollisionPointCircle(arg1, arg2, arg3); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionPointTriangle(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - Vector2 arg4 = LuaGetArgument_Vector2(L, 4); - bool result = CheckCollisionPointTriangle(arg1, arg2, arg3, arg4); - lua_pushboolean(L, result); - return 1; -} - -//------------------------------------------------------------------------------------ -// raylib [textures] module functions - Texture Loading and Drawing -//------------------------------------------------------------------------------------ -int lua_LoadImage(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Image result = LoadImage(arg1); - LuaPush_Image(L, result); - return 1; -} - -int lua_LoadImageEx(lua_State* L) -{ - // TODO: Image LoadImageEx(Color *pixels, int width, int height); - - GET_TABLE(Color, arg1, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - Image result = LoadImageEx(arg1, arg2, arg3); // ISSUE: #3 number expected, got no value - LuaPush_Image(L, result); - free(arg1); - return 1; -} - -int lua_LoadImageRaw(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Image result = LoadImageRaw(arg1, arg2, arg3, arg4, arg5); - LuaPush_Image(L, result); - return 1; -} - -int lua_LoadImageFromRES(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Image result = LoadImageFromRES(arg1, arg2); - LuaPush_Image(L, result); - return 1; -} - -int lua_LoadTexture(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Texture2D result = LoadTexture(arg1); - LuaPush_Texture2D(L, result); - return 1; -} - -int lua_LoadTextureEx(lua_State* L) -{ - void * arg1 = (char *)LuaGetArgument_string(L, 1); // NOTE: getting argument as string? - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Texture2D result = LoadTextureEx(arg1, arg2, arg3, arg4); - LuaPush_Texture2D(L, result); - return 1; -} - -int lua_LoadTextureFromRES(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Texture2D result = LoadTextureFromRES(arg1, arg2); - LuaPush_Texture2D(L, result); - return 1; -} - -int lua_LoadTextureFromImage(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Texture2D result = LoadTextureFromImage(arg1); - LuaPush_Texture2D(L, result); - return 1; -} - -int lua_LoadRenderTexture(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - RenderTexture2D result = LoadRenderTexture(arg1, arg2); - LuaPush_RenderTexture2D(L, result); - return 1; -} - -int lua_UnloadImage(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - UnloadImage(arg1); - return 0; -} - -int lua_UnloadTexture(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - UnloadTexture(arg1); - return 0; -} - -int lua_UnloadRenderTexture(lua_State* L) -{ - RenderTexture2D arg1 = LuaGetArgument_RenderTexture2D(L, 1); - UnloadRenderTexture(arg1); - return 0; -} - -int lua_GetImageData(lua_State* L) -{ - // TODO: Color *GetImageData(Image image); - - Image arg1 = LuaGetArgument_Image(L, 1); - Color * result = GetImageData(arg1); - lua_createtable(L, arg1.width*arg1.height, 0); - for (int i = 0; i < arg1.width*arg1.height; i++) - { - LuaPush_Color(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; -} - -int lua_GetTextureData(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Image result = GetTextureData(arg1); - LuaPush_Image(L, result); - return 1; -} - -int lua_UpdateTexture(lua_State* L) -{ - // TODO: void UpdateTexture(Texture2D texture, void *pixels); - - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - void * arg2 = (char *)LuaGetArgument_string(L, 2); // NOTE: Getting (void *) as string? - UpdateTexture(arg1, arg2); // ISSUE: #2 string expected, got table -> GetImageData() returns a table! - return 0; -} - -int lua_ImageToPOT(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - ImageToPOT(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageFormat(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - ImageFormat(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageDither(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - ImageDither(&arg1, arg2, arg3, arg4, arg5); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageCopy(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Image result = ImageCopy(arg1); - LuaPush_Image(L, result); - return 1; -} - -int lua_ImageCrop(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - ImageCrop(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageResize(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - ImageResize(&arg1, arg2, arg3); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageResizeNN(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - ImageResizeNN(&arg1, arg2, arg3); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageText(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - Image result = ImageText(arg1, arg2, arg3); - LuaPush_Image(L, result); - return 1; -} - -int lua_ImageTextEx(lua_State* L) -{ - SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - Image result = ImageTextEx(arg1, arg2, arg3, arg4, arg5); - LuaPush_Image(L, result); - return 1; -} - -int lua_ImageDraw(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Image arg2 = LuaGetArgument_Image(L, 2); - Rectangle arg3 = LuaGetArgument_Rectangle(L, 3); - Rectangle arg4 = LuaGetArgument_Rectangle(L, 4); - ImageDraw(&arg1, arg2, arg3, arg4); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageDrawText(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - const char * arg3 = LuaGetArgument_string(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - ImageDrawText(&arg1, arg2, arg3, arg4, arg5); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageDrawTextEx(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - SpriteFont arg3 = LuaGetArgument_SpriteFont(L, 3); - const char * arg4 = LuaGetArgument_string(L, 4); - float arg5 = LuaGetArgument_float(L, 5); - int arg6 = LuaGetArgument_int(L, 6); - Color arg7 = LuaGetArgument_Color(L, 7); - ImageDrawTextEx(&arg1, arg2, arg3, arg4, arg5, arg6, arg7); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageFlipVertical(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - ImageFlipVertical(&arg1); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageFlipHorizontal(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - ImageFlipHorizontal(&arg1); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageColorTint(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - ImageColorTint(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageColorInvert(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - ImageColorInvert(&arg1); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageColorGrayscale(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - ImageColorGrayscale(&arg1); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageColorContrast(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - ImageColorContrast(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_ImageColorBrightness(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - ImageColorBrightness(&arg1, arg2); - LuaPush_Image(L, arg1); - return 1; -} - -int lua_GenTextureMipmaps(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - GenTextureMipmaps(&arg1); - LuaPush_Texture2D(L, arg1); - return 1; -} - -int lua_SetTextureFilter(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - SetTextureFilter(arg1, arg2); - return 0; -} - -int lua_SetTextureWrap(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - SetTextureWrap(arg1, arg2); - return 0; -} - -int lua_DrawTexture(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawTexture(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawTextureV(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawTextureV(arg1, arg2, arg3); - return 0; -} - -int lua_DrawTextureEx(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawTextureEx(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawTextureRec(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawTextureRec(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawTexturePro(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Rectangle arg2 = LuaGetArgument_Rectangle(L, 2); - Rectangle arg3 = LuaGetArgument_Rectangle(L, 3); - Vector2 arg4 = LuaGetArgument_Vector2(L, 4); - float arg5 = LuaGetArgument_float(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawTexturePro(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -//------------------------------------------------------------------------------------ -// raylib [text] module functions - Font Loading and Text Drawing -//------------------------------------------------------------------------------------ -int lua_GetDefaultFont(lua_State* L) -{ - SpriteFont result = GetDefaultFont(); - LuaPush_SpriteFont(L, result); - return 1; -} - -int lua_LoadSpriteFont(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - SpriteFont result = LoadSpriteFont(arg1); - LuaPush_SpriteFont(L, result); - return 1; -} - -int lua_LoadSpriteFontTTF(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - //LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); - SpriteFont result = LoadSpriteFontTTF(arg1, arg2, arg3, &arg4); - LuaPush_SpriteFont(L, result); - return 1; -} - -int lua_UnloadSpriteFont(lua_State* L) -{ - SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1); - UnloadSpriteFont(arg1); - return 0; -} - -int lua_DrawText(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawText(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawTextEx(lua_State* L) -{ - SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - Vector2 arg3 = LuaGetArgument_Vector2(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawTextEx(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_MeasureText(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int result = MeasureText(arg1, arg2); - lua_pushinteger(L, result); - return 1; -} - -int lua_MeasureTextEx(lua_State* L) -{ - SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Vector2 result = MeasureTextEx(arg1, arg2, arg3, arg4); - LuaPush_Vector2(L, result); - return 1; -} - -int lua_DrawFPS(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - DrawFPS(arg1, arg2); - return 0; -} - -// NOTE: FormatText() can be replaced by Lua function: string.format() -// NOTE: SubText() can be replaced by Lua function: string.sub() - -//------------------------------------------------------------------------------------ -// raylib [models] module functions - Basic 3d Shapes Drawing Functions -//------------------------------------------------------------------------------------ -int lua_DrawLine3D(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawLine3D(arg1, arg2, arg3); - return 0; -} - -int lua_DrawCircle3D(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawCircle3D(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawCube(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawCube(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawCubeV(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawCubeV(arg1, arg2, arg3); - return 0; -} - -int lua_DrawCubeWires(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawCubeWires(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawCubeTexture(lua_State* L) -{ - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - float arg5 = LuaGetArgument_float(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawCubeTexture(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawSphere(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawSphere(arg1, arg2, arg3); - return 0; -} - -int lua_DrawSphereEx(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawSphereEx(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawSphereWires(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawSphereWires(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawCylinder(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawCylinder(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawCylinderWires(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawCylinderWires(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawPlane(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - DrawPlane(arg1, arg2, arg3); - return 0; -} - -int lua_DrawRay(lua_State* L) -{ - Ray arg1 = LuaGetArgument_Ray(L, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawRay(arg1, arg2); - return 0; -} - -int lua_DrawGrid(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - DrawGrid(arg1, arg2); - return 0; -} - -int lua_DrawGizmo(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - DrawGizmo(arg1); - return 0; -} - -int lua_DrawLight(lua_State* L) -{ - Light arg1 = LuaGetArgument_Light(L, 1); - DrawLight(arg1); - return 0; -} - -//------------------------------------------------------------------------------------ -// raylib [models] module functions -//------------------------------------------------------------------------------------ -int lua_LoadModel(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Model result = LoadModel(arg1); - LuaPush_Model(L, result); - return 1; -} - -int lua_LoadModelEx(lua_State* L) -{ - Mesh arg1 = LuaGetArgument_Mesh(L, 1); - bool arg2 = LuaGetArgument_int(L, 2); - Model result = LoadModelEx(arg1, arg2); - LuaPush_Model(L, result); - return 1; -} - -int lua_LoadModelFromRES(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Model result = LoadModelFromRES(arg1, arg2); - LuaPush_Model(L, result); - return 1; -} - -int lua_LoadHeightmap(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Model result = LoadHeightmap(arg1, arg2); - LuaPush_Model(L, result); - return 1; -} - -int lua_LoadCubicmap(lua_State* L) -{ - Image arg1 = LuaGetArgument_Image(L, 1); - Model result = LoadCubicmap(arg1); - LuaPush_Model(L, result); - return 1; -} - -int lua_UnloadModel(lua_State* L) -{ - Model arg1 = LuaGetArgument_Model(L, 1); - UnloadModel(arg1); - return 0; -} - -// TODO: GenMesh*() functionality (not ready yet on raylib 1.6) - -int lua_LoadMaterial(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Material result = LoadMaterial(arg1); - LuaPush_Material(L, result); - return 1; -} - -int lua_LoadDefaultMaterial(lua_State* L) -{ - Material result = LoadDefaultMaterial(); - LuaPush_Material(L, result); - return 1; -} - -int lua_LoadStandardMaterial(lua_State* L) -{ - Material result = LoadStandardMaterial(); - LuaPush_Material(L, result); - return 1; -} - -int lua_UnloadMaterial(lua_State* L) -{ - Material arg1 = LuaGetArgument_Material(L, 1); - UnloadMaterial(arg1); - return 0; -} - -int lua_DrawModel(lua_State* L) -{ - Model arg1 = LuaGetArgument_Model(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawModel(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawModelEx(lua_State* L) -{ - Model arg1 = LuaGetArgument_Model(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Vector3 arg5 = LuaGetArgument_Vector3(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawModelEx(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawModelWires(lua_State* L) -{ - Model arg1 = LuaGetArgument_Model(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Color arg4 = LuaGetArgument_Color(L, 4); - DrawModelWires(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_DrawModelWiresEx(lua_State* L) -{ - Model arg1 = LuaGetArgument_Model(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Vector3 arg5 = LuaGetArgument_Vector3(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawModelWiresEx(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_DrawBillboard(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - Texture2D arg2 = LuaGetArgument_Texture2D(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - Color arg5 = LuaGetArgument_Color(L, 5); - DrawBillboard(arg1, arg2, arg3, arg4, arg5); - return 0; -} - -int lua_DrawBillboardRec(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - Texture2D arg2 = LuaGetArgument_Texture2D(L, 2); - Rectangle arg3 = LuaGetArgument_Rectangle(L, 3); - Vector3 arg4 = LuaGetArgument_Vector3(L, 4); - float arg5 = LuaGetArgument_float(L, 5); - Color arg6 = LuaGetArgument_Color(L, 6); - DrawBillboardRec(arg1, arg2, arg3, arg4, arg5, arg6); - return 0; -} - -int lua_CalculateBoundingBox(lua_State* L) -{ - Mesh arg1 = LuaGetArgument_Mesh(L, 1); - BoundingBox result = CalculateBoundingBox(arg1); - LuaPush_BoundingBox(L, result); - return 1; -} - -int lua_CheckCollisionSpheres(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - bool result = CheckCollisionSpheres(arg1, arg2, arg3, arg4); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionBoxes(lua_State* L) -{ - BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1); - BoundingBox arg2 = LuaGetArgument_BoundingBox(L, 2); - bool result = CheckCollisionBoxes(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionBoxSphere(lua_State* L) -{ - BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - bool result = CheckCollisionBoxSphere(arg1, arg2, arg3); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionRaySphere(lua_State* L) -{ - Ray arg1 = LuaGetArgument_Ray(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - bool result = CheckCollisionRaySphere(arg1, arg2, arg3); - lua_pushboolean(L, result); - return 1; -} - -int lua_CheckCollisionRaySphereEx(lua_State* L) -{ - Ray arg1 = LuaGetArgument_Ray(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Vector3 arg4 = LuaGetArgument_Vector3(L, 4); - bool result = CheckCollisionRaySphereEx(arg1, arg2, arg3, &arg4); - lua_pushboolean(L, result); - LuaPush_Vector3(L, arg4); - return 2; -} - -int lua_CheckCollisionRayBox(lua_State* L) -{ - Ray arg1 = LuaGetArgument_Ray(L, 1); - BoundingBox arg2 = LuaGetArgument_BoundingBox(L, 2); - bool result = CheckCollisionRayBox(arg1, arg2); - lua_pushboolean(L, result); - return 1; -} - -//------------------------------------------------------------------------------------ -// raylib [raymath] module functions - Shaders -//------------------------------------------------------------------------------------ -int lua_LoadShader(lua_State* L) -{ - char * arg1 = (char *)LuaGetArgument_string(L, 1); - char * arg2 = (char *)LuaGetArgument_string(L, 2); - Shader result = LoadShader(arg1, arg2); - LuaPush_Shader(L, result); - return 1; -} - -int lua_UnloadShader(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - UnloadShader(arg1); - return 0; -} - -int lua_GetDefaultShader(lua_State* L) -{ - Shader result = GetDefaultShader(); - LuaPush_Shader(L, result); - return 1; -} - -int lua_GetStandardShader(lua_State* L) -{ - Shader result = GetStandardShader(); - LuaPush_Shader(L, result); - return 1; -} - -int lua_GetDefaultTexture(lua_State* L) -{ - Texture2D result = GetDefaultTexture(); - LuaPush_Texture2D(L, result); - return 1; -} - -int lua_GetShaderLocation(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - int result = GetShaderLocation(arg1, arg2); - lua_pushinteger(L, result); - return 1; -} - -int lua_SetShaderValue(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - GET_TABLE(float, arg3, 3); - SetShaderValue(arg1, arg2, arg3, arg3_size); - free(arg3); - return 0; -} - -int lua_SetShaderValuei(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - GET_TABLE(int, arg3, 3); - SetShaderValuei(arg1, arg2, arg3, arg3_size); - free(arg3); - return 0; -} - -int lua_SetShaderValueMatrix(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Matrix arg3 = LuaGetArgument_Matrix(L, 3); - SetShaderValueMatrix(arg1, arg2, arg3); - return 0; -} - -int lua_SetMatrixProjection(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - SetMatrixProjection(arg1); - return 0; -} - -int lua_SetMatrixModelview(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - SetMatrixModelview(arg1); - return 0; -} - -int lua_BeginShaderMode(lua_State* L) -{ - Shader arg1 = LuaGetArgument_Shader(L, 1); - BeginShaderMode(arg1); - return 0; -} - -int lua_EndShaderMode(lua_State* L) -{ - EndShaderMode(); - return 0; -} - -int lua_BeginBlendMode(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - BeginBlendMode(arg1); - return 0; -} - -int lua_EndBlendMode(lua_State* L) -{ - EndBlendMode(); - return 0; -} - -int lua_CreateLight(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Color arg3 = LuaGetArgument_Color(L, 3); - Light result = CreateLight(arg1, arg2, arg3); - LuaPush_Light(L, result); - return 1; -} - -int lua_DestroyLight(lua_State* L) -{ - Light arg1 = LuaGetArgument_Light(L, 1); - DestroyLight(arg1); - return 0; -} - - -//------------------------------------------------------------------------------------ -// raylib [rlgl] module functions - VR experience -//------------------------------------------------------------------------------------ -int lua_InitVrDevice(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - InitVrDevice(arg1); - return 0; -} - -int lua_CloseVrDevice(lua_State* L) -{ - CloseVrDevice(); - return 0; -} - -int lua_IsVrDeviceReady(lua_State* L) -{ - bool result = IsVrDeviceReady(); - lua_pushboolean(L, result); - return 1; -} - -int lua_IsVrSimulator(lua_State* L) -{ - bool result = IsVrSimulator(); - lua_pushboolean(L, result); - return 1; -} - -int lua_UpdateVrTracking(lua_State* L) -{ - Camera arg1 = LuaGetArgument_Camera(L, 1); - UpdateVrTracking(&arg1); - LuaPush_Camera(L, arg1); - return 1; -} - -int lua_ToggleVrMode(lua_State* L) -{ - ToggleVrMode(); - return 0; -} - -//------------------------------------------------------------------------------------ -// raylib [audio] module functions - Audio Loading and Playing -//------------------------------------------------------------------------------------ -int lua_InitAudioDevice(lua_State* L) -{ - InitAudioDevice(); - return 0; -} - -int lua_CloseAudioDevice(lua_State* L) -{ - CloseAudioDevice(); - return 0; -} - -int lua_IsAudioDeviceReady(lua_State* L) -{ - bool result = IsAudioDeviceReady(); - lua_pushboolean(L, result); - return 1; -} - -int lua_LoadWave(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Wave result = LoadWave((char *)arg1); - LuaPush_Wave(L, result); - return 1; -} - -int lua_LoadWaveEx(lua_State* L) -{ - // TODO: Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); - - float * arg1 = 0; - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Wave result = LoadWaveEx(arg1, arg2, arg3, arg4, arg5); - LuaPush_Wave(L, result); - return 1; -} - -int lua_LoadSound(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Sound result = LoadSound((char*)arg1); - LuaPush_Sound(L, result); - return 1; -} - -int lua_LoadSoundFromWave(lua_State* L) -{ - Wave arg1 = LuaGetArgument_Wave(L, 1); - Sound result = LoadSoundFromWave(arg1); - LuaPush_Sound(L, result); - return 1; -} - -int lua_LoadSoundFromRES(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Sound result = LoadSoundFromRES(arg1, arg2); - LuaPush_Sound(L, result); - return 1; -} - -int lua_UpdateSound(lua_State* L) -{ - // TODO: void UpdateSound(Sound sound, void *data, int numSamples); - - Sound arg1 = LuaGetArgument_Sound(L, 1); - const char * arg2 = LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - UpdateSound(arg1, arg2, arg3); - return 0; -} - -int lua_UnloadWave(lua_State* L) -{ - Wave arg1 = LuaGetArgument_Wave(L, 1); - UnloadWave(arg1); - return 0; -} - -int lua_UnloadSound(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - UnloadSound(arg1); - return 0; -} - -int lua_PlaySound(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - PlaySound(arg1); - return 0; -} - -int lua_PauseSound(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - PauseSound(arg1); - return 0; -} - -int lua_ResumeSound(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - ResumeSound(arg1); - return 0; -} - -int lua_StopSound(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - StopSound(arg1); - return 0; -} - -int lua_IsSoundPlaying(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - bool result = IsSoundPlaying(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_SetSoundVolume(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetSoundVolume(arg1, arg2); - return 0; -} - -int lua_SetSoundPitch(lua_State* L) -{ - Sound arg1 = LuaGetArgument_Sound(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetSoundPitch(arg1, arg2); - return 0; -} - -int lua_WaveFormat(lua_State* L) -{ - Wave arg1 = LuaGetArgument_Wave(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - WaveFormat(&arg1, arg2, arg3, arg4); - return 0; -} - -int lua_WaveCopy(lua_State* L) -{ - Wave arg1 = LuaGetArgument_Wave(L, 1); - Wave result = WaveCopy(arg1); - LuaPush_Wave(L, result); - return 1; -} - -int lua_WaveCrop(lua_State* L) -{ - Wave arg1 = LuaGetArgument_Wave(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - WaveCrop(&arg1, arg2, arg3); - return 0; -} - -int lua_GetWaveData(lua_State* L) -{ - // TODO: float *GetWaveData(Wave wave); - - Wave arg1 = LuaGetArgument_Wave(L, 1); - float * result = GetWaveData(arg1); - //LuaPush_float(L, result); - //lua_pushnumber(L, result); - return 0; -} - -int lua_LoadMusicStream(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - Music result = LoadMusicStream((char *)arg1); - LuaPush_Music(L, result); - return 1; -} - -int lua_UnloadMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - UnloadMusicStream(arg1); - return 0; -} - -int lua_UpdateMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - UpdateMusicStream(arg1); - return 0; -} - -int lua_PlayMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - PlayMusicStream(arg1); - return 0; -} - -int lua_StopMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - StopMusicStream(arg1); - return 0; -} - -int lua_PauseMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - PauseMusicStream(arg1); - return 0; -} - -int lua_ResumeMusicStream(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - ResumeMusicStream(arg1); - return 0; -} - -int lua_IsMusicPlaying(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - bool result = IsMusicPlaying(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_SetMusicVolume(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetMusicVolume(arg1, arg2); - return 0; -} - -int lua_SetMusicPitch(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetMusicPitch(arg1, arg2); - return 0; -} - -int lua_GetMusicTimeLength(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - float result = GetMusicTimeLength(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_GetMusicTimePlayed(lua_State* L) -{ - Music arg1 = LuaGetArgument_Music(L, 1); - float result = GetMusicTimePlayed(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_InitAudioStream(lua_State* L) -{ - int arg1 = LuaGetArgument_int(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - AudioStream result = InitAudioStream(arg1, arg2, arg3); - LuaPush_AudioStream(L, result); - return 1; -} - -int lua_CloseAudioStream(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - CloseAudioStream(arg1); - return 0; -} - -int lua_UpdateAudioStream(lua_State* L) -{ - // TODO: void UpdateAudioStream(AudioStream stream, void *data, int numSamples); - - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - void * arg2 = (char *)LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - UpdateAudioStream(arg1, arg2, arg3); - return 0; -} - -int lua_IsAudioBufferProcessed(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - bool result = IsAudioBufferProcessed(arg1); - lua_pushboolean(L, result); - return 1; -} - -int lua_PlayAudioStream(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - PlayAudioStream(arg1); - return 0; -} - - -int lua_StopAudioStream(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - StopAudioStream(arg1); - return 0; -} - -int lua_PauseAudioStream(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - PauseAudioStream(arg1); - return 0; -} - -int lua_ResumeAudioStream(lua_State* L) -{ - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - ResumeAudioStream(arg1); - return 0; -} - -//---------------------------------------------------------------------------------- -// raylib [utils] module functions -//---------------------------------------------------------------------------------- -int lua_DecompressData(lua_State* L) -{ - unsigned char *arg1 = (unsigned char *)LuaGetArgument_string(L, 1); - unsigned arg2 = (unsigned)LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - unsigned char *result = DecompressData(arg1, arg2, arg3); - lua_pushlstring(L, (const char *)result, arg3); - return 1; -} - -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) -int lua_WriteBitmap(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - WriteBitmap(arg1, arg2, arg3, arg4); - return 0; -} - -int lua_WritePNG(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - WritePNG(arg1, arg2, arg3, arg4, arg5); - return 0; -} -#endif - -int lua_TraceLog(lua_State* L) -{ - int num_args = lua_gettop(L) - 1; - int arg1 = LuaGetArgument_int(L, 1); - - /// type, fmt, args... - - lua_rotate(L, 1, -1); /// fmt, args..., type - lua_pop(L, 1); /// fmt, args... - - lua_getglobal(L, "string"); /// fmt, args..., [string] - lua_getfield(L, 1, "format"); /// fmt, args..., [string], format() - lua_rotate(L, 1, 2); /// [string], format(), fmt, args... - lua_call(L, num_args, 1); /// [string], formatted_string - - TraceLog(arg1, "%s", luaL_checkstring(L,-1)); - return 0; -} - -int lua_GetExtension(lua_State* L) -{ - const char * arg1 = LuaGetArgument_string(L, 1); - const char* result = GetExtension(arg1); - lua_pushstring(L, result); - return 1; -} - -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Vector3 math -//---------------------------------------------------------------------------------- -int lua_VectorAdd(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorAdd(arg1, arg2); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorSubtract(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorSubtract(arg1, arg2); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorCrossProduct(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorCrossProduct(arg1, arg2); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorPerpendicular(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 result = VectorPerpendicular(arg1); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorDotProduct(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float result = VectorDotProduct(arg1, arg2); - lua_pushnumber(L, result); - return 1; -} - -int lua_VectorLength(lua_State* L) -{ - const Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float result = VectorLength(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_VectorScale(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - VectorScale(&arg1, arg2); - LuaPush_Vector3(L, arg1); - return 1; -} - -int lua_VectorNegate(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - VectorNegate(&arg1); - LuaPush_Vector3(L, arg1); - return 1; -} - -int lua_VectorNormalize(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - VectorNormalize(&arg1); - LuaPush_Vector3(L, arg1); - return 1; -} - -int lua_VectorDistance(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float result = VectorDistance(arg1, arg2); - lua_pushnumber(L, result); - return 1; -} - -int lua_VectorLerp(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Vector3 result = VectorLerp(arg1, arg2, arg3); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorReflect(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorReflect(arg1, arg2); - LuaPush_Vector3(L, result); - return 1; -} - -int lua_VectorTransform(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - VectorTransform(&arg1, arg2); - LuaPush_Vector3(L, arg1); - return 1; -} - -int lua_VectorZero(lua_State* L) -{ - Vector3 result = VectorZero(); - LuaPush_Vector3(L, result); - return 1; -} - -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Matrix math -//---------------------------------------------------------------------------------- -int lua_MatrixDeterminant(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float result = MatrixDeterminant(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_MatrixTrace(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float result = MatrixTrace(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_MatrixTranspose(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixTranspose(&arg1); - LuaPush_Matrix(L, &arg1); - return 1; -} - -int lua_MatrixInvert(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixInvert(&arg1); - LuaPush_Matrix(L, &arg1); - return 1; -} - -int lua_MatrixNormalize(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixNormalize(&arg1); - LuaPush_Matrix(L, &arg1); - return 1; -} - -int lua_MatrixIdentity(lua_State* L) -{ - Matrix result = MatrixIdentity(); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixAdd(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixAdd(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixSubstract(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixSubstract(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixTranslate(lua_State* L) -{ - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Matrix result = MatrixTranslate(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixRotate(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Matrix result = MatrixRotate(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixRotateX(lua_State* L) -{ - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateX(arg1); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixRotateY(lua_State* L) -{ - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateY(arg1); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixRotateZ(lua_State* L) -{ - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateZ(arg1); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixScale(lua_State* L) -{ - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Matrix result = MatrixScale(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixMultiply(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixMultiply(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixFrustum(lua_State* L) -{ - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - double arg5 = LuaGetArgument_double(L, 5); - double arg6 = LuaGetArgument_double(L, 6); - Matrix result = MatrixFrustum(arg1, arg2, arg3, arg4, arg5, arg6); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixPerspective(lua_State* L) -{ - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - Matrix result = MatrixPerspective(arg1, arg2, arg3, arg4); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixOrtho(lua_State* L) -{ - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - double arg5 = LuaGetArgument_double(L, 5); - double arg6 = LuaGetArgument_double(L, 6); - Matrix result = MatrixOrtho(arg1, arg2, arg3, arg4, arg5, arg6); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_MatrixLookAt(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - Matrix result = MatrixLookAt(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); - return 1; -} - -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Quaternion math -//---------------------------------------------------------------------------------- -int lua_QuaternionLength(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - float result = QuaternionLength(arg1); - lua_pushnumber(L, result); - return 1; -} - -int lua_QuaternionNormalize(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - QuaternionNormalize(&arg1); - LuaPush_Quaternion(L, arg1); - return 1; -} - -int lua_QuaternionMultiply(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Quaternion arg2 = LuaGetArgument_Quaternion(L, 2); - Quaternion result = QuaternionMultiply(arg1, arg2); - LuaPush_Quaternion(L, result); - return 1; -} - -int lua_QuaternionSlerp(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Quaternion arg2 = LuaGetArgument_Quaternion(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Quaternion result = QuaternionSlerp(arg1, arg2, arg3); - LuaPush_Quaternion(L, result); - return 1; -} - -int lua_QuaternionFromMatrix(lua_State* L) -{ - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Quaternion result = QuaternionFromMatrix(arg1); - LuaPush_Quaternion(L, result); - return 1; -} - -int lua_QuaternionToMatrix(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Matrix result = QuaternionToMatrix(arg1); - LuaPush_Matrix(L, &result); - return 1; -} - -int lua_QuaternionFromAxisAngle(lua_State* L) -{ - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Quaternion result = QuaternionFromAxisAngle(arg1, arg2); - LuaPush_Quaternion(L, result); - return 1; -} - -int lua_QuaternionToAxisAngle(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Vector3 arg2; - float arg3 = 0; - QuaternionToAxisAngle(arg1, &arg2, &arg3); - LuaPush_Vector3(L, arg2); - lua_pushnumber(L, arg3); - return 2; -} - -int lua_QuaternionTransform(lua_State* L) -{ - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - QuaternionTransform(&arg1, arg2); - LuaPush_Quaternion(L, arg1); - return 1; -} - - -//---------------------------------------------------------------------------------- -// Functions Registering -//---------------------------------------------------------------------------------- -#define REG(name) { #name, lua_##name }, - -// raylib Functions (and data types) list -static luaL_Reg raylib_functions[] = { - - // Register non-opaque data types - REG(Color) - REG(Vector2) - REG(Vector3) - //REG(Matrix) - REG(Quaternion) - REG(Rectangle) - REG(Ray) - REG(Camera) - REG(Camera2D) - REG(BoundingBox) - //REG(Material) - - // Register functions - REG(InitWindow) - REG(CloseWindow) - REG(WindowShouldClose) - REG(IsWindowMinimized) - REG(ToggleFullscreen) - REG(GetScreenWidth) - REG(GetScreenHeight) - - REG(ShowCursor) - REG(HideCursor) - REG(IsCursorHidden) - REG(EnableCursor) - REG(DisableCursor) - - REG(ClearBackground) - REG(BeginDrawing) - REG(EndDrawing) - REG(Begin2dMode) - REG(End2dMode) - REG(Begin3dMode) - REG(End3dMode) - REG(BeginTextureMode) - REG(EndTextureMode) - - REG(GetMouseRay) - REG(GetWorldToScreen) - REG(GetCameraMatrix) - -#if defined(PLATFORM_WEB) - REG(SetDrawingLoop) -#else - REG(SetTargetFPS) -#endif - REG(GetFPS) - REG(GetFrameTime) - - REG(GetColor) - REG(GetHexValue) - REG(ColorToFloat) - REG(VectorToFloat) - REG(MatrixToFloat) - REG(GetRandomValue) - REG(Fade) - REG(SetConfigFlags) - REG(ShowLogo) - - REG(IsFileDropped) - REG(GetDroppedFiles) - REG(ClearDroppedFiles) - REG(StorageSaveValue) - REG(StorageLoadValue) - - REG(IsKeyPressed) - REG(IsKeyDown) - REG(IsKeyReleased) - REG(IsKeyUp) - REG(GetKeyPressed) - REG(SetExitKey) - - REG(IsGamepadAvailable) - REG(IsGamepadName) - REG(GetGamepadName) - REG(IsGamepadButtonPressed) - REG(IsGamepadButtonDown) - REG(IsGamepadButtonReleased) - REG(IsGamepadButtonUp) - REG(GetGamepadButtonPressed) - REG(GetGamepadAxisCount) - REG(GetGamepadAxisMovement) - - REG(IsMouseButtonPressed) - REG(IsMouseButtonDown) - REG(IsMouseButtonReleased) - REG(IsMouseButtonUp) - REG(GetMouseX) - REG(GetMouseY) - REG(GetMousePosition) - REG(SetMousePosition) - REG(GetMouseWheelMove) - REG(GetTouchX) - REG(GetTouchY) - REG(GetTouchPosition) - -#if defined(PLATFORM_ANDROID) - REG(IsButtonPressed) - REG(IsButtonDown) - REG(IsButtonReleased) -#endif - - REG(SetGesturesEnabled) - REG(IsGestureDetected) - REG(GetGestureDetected) - REG(GetTouchPointsCount) - REG(GetGestureHoldDuration) - REG(GetGestureDragVector) - REG(GetGestureDragAngle) - REG(GetGesturePinchVector) - REG(GetGesturePinchAngle) - - REG(SetCameraMode) - REG(UpdateCamera) - REG(SetCameraPanControl) - REG(SetCameraAltControl) - REG(SetCameraSmoothZoomControl) - REG(SetCameraMoveControls) - - REG(DrawPixel) - REG(DrawPixelV) - REG(DrawLine) - REG(DrawLineV) - REG(DrawCircle) - REG(DrawCircleGradient) - REG(DrawCircleV) - REG(DrawCircleLines) - REG(DrawRectangle) - REG(DrawRectangleRec) - REG(DrawRectangleGradient) - REG(DrawRectangleV) - REG(DrawRectangleLines) - REG(DrawTriangle) - REG(DrawTriangleLines) - REG(DrawPoly) - REG(DrawPolyEx) - REG(DrawPolyExLines) - - REG(CheckCollisionRecs) - REG(CheckCollisionCircles) - REG(CheckCollisionCircleRec) - REG(GetCollisionRec) - REG(CheckCollisionPointRec) - REG(CheckCollisionPointCircle) - REG(CheckCollisionPointTriangle) - - REG(LoadImage) - REG(LoadImageEx) - REG(LoadImageRaw) - REG(LoadImageFromRES) - REG(LoadTexture) - REG(LoadTextureEx) - REG(LoadTextureFromRES) - REG(LoadTextureFromImage) - REG(LoadRenderTexture) - REG(UnloadImage) - REG(UnloadTexture) - REG(UnloadRenderTexture) - REG(GetImageData) - REG(GetTextureData) - REG(UpdateTexture) - REG(ImageToPOT) - REG(ImageFormat) - REG(ImageDither) - REG(ImageCopy) - REG(ImageCrop) - REG(ImageResize) - REG(ImageResizeNN) - REG(ImageText) - REG(ImageTextEx) - REG(ImageDraw) - REG(ImageDrawText) - REG(ImageDrawTextEx) - REG(ImageFlipVertical) - REG(ImageFlipHorizontal) - REG(ImageColorTint) - REG(ImageColorInvert) - REG(ImageColorGrayscale) - REG(ImageColorContrast) - REG(ImageColorBrightness) - REG(GenTextureMipmaps) - REG(SetTextureFilter) - REG(SetTextureWrap) - - REG(DrawTexture) - REG(DrawTextureV) - REG(DrawTextureEx) - REG(DrawTextureRec) - REG(DrawTexturePro) - - REG(GetDefaultFont) - REG(LoadSpriteFont) - REG(LoadSpriteFontTTF) - REG(UnloadSpriteFont) - REG(DrawText) - REG(DrawTextEx) - REG(MeasureText) - REG(MeasureTextEx) - REG(DrawFPS) - - REG(DrawLine3D) - REG(DrawCircle3D) - REG(DrawCube) - REG(DrawCubeV) - REG(DrawCubeWires) - REG(DrawCubeTexture) - REG(DrawSphere) - REG(DrawSphereEx) - REG(DrawSphereWires) - REG(DrawCylinder) - REG(DrawCylinderWires) - REG(DrawPlane) - REG(DrawRay) - REG(DrawGrid) - REG(DrawGizmo) - REG(DrawLight) - - REG(LoadModel) - REG(LoadModelEx) - REG(LoadModelFromRES) - REG(LoadHeightmap) - REG(LoadCubicmap) - REG(UnloadModel) - REG(LoadMaterial) - REG(LoadDefaultMaterial) - REG(LoadStandardMaterial) - REG(UnloadMaterial) - //REG(GenMesh*) // Not ready yet... - - REG(DrawModel) - REG(DrawModelEx) - REG(DrawModelWires) - REG(DrawModelWiresEx) - REG(DrawBillboard) - REG(DrawBillboardRec) - REG(CalculateBoundingBox) - REG(CheckCollisionSpheres) - REG(CheckCollisionBoxes) - REG(CheckCollisionBoxSphere) - REG(CheckCollisionRaySphere) - REG(CheckCollisionRaySphereEx) - REG(CheckCollisionRayBox) - - REG(LoadShader) - REG(UnloadShader) - REG(GetDefaultShader) - REG(GetStandardShader) - REG(GetDefaultTexture) - REG(GetShaderLocation) - REG(SetShaderValue) - REG(SetShaderValuei) - REG(SetShaderValueMatrix) - REG(SetMatrixProjection) - REG(SetMatrixModelview) - REG(BeginShaderMode) - REG(EndShaderMode) - REG(BeginBlendMode) - REG(EndBlendMode) - REG(CreateLight) - REG(DestroyLight) - - REG(InitVrDevice) - REG(CloseVrDevice) - REG(IsVrDeviceReady) - REG(IsVrSimulator) - REG(UpdateVrTracking) - REG(ToggleVrMode) - - REG(InitAudioDevice) - REG(CloseAudioDevice) - REG(IsAudioDeviceReady) - REG(LoadWave) - REG(LoadWaveEx) - REG(LoadSound) - REG(LoadSoundFromWave) - REG(LoadSoundFromRES) - REG(UpdateSound) - REG(UnloadWave) - REG(UnloadSound) - REG(PlaySound) - REG(PauseSound) - REG(ResumeSound) - REG(StopSound) - REG(IsSoundPlaying) - REG(SetSoundVolume) - REG(SetSoundPitch) - REG(WaveFormat) - REG(WaveCopy) - REG(WaveCrop) - REG(GetWaveData) - - REG(LoadMusicStream) - REG(UnloadMusicStream) - REG(UpdateMusicStream) - REG(PlayMusicStream) - REG(StopMusicStream) - REG(PauseMusicStream) - REG(ResumeMusicStream) - REG(IsMusicPlaying) - REG(SetMusicVolume) - REG(SetMusicPitch) - REG(GetMusicTimeLength) - REG(GetMusicTimePlayed) - - REG(InitAudioStream) - REG(UpdateAudioStream) - REG(CloseAudioStream) - REG(IsAudioBufferProcessed) - REG(PlayAudioStream) - REG(PauseAudioStream) - REG(ResumeAudioStream) - REG(StopAudioStream) - - /// Math and util - REG(DecompressData) -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) - REG(WriteBitmap) - REG(WritePNG) -#endif - REG(TraceLog) - REG(GetExtension) - REG(VectorAdd) - REG(VectorSubtract) - REG(VectorCrossProduct) - REG(VectorPerpendicular) - REG(VectorDotProduct) - REG(VectorLength) - REG(VectorScale) - REG(VectorNegate) - REG(VectorNormalize) - REG(VectorDistance) - REG(VectorLerp) - REG(VectorReflect) - REG(VectorTransform) - REG(VectorZero) - REG(MatrixDeterminant) - REG(MatrixTrace) - REG(MatrixTranspose) - REG(MatrixInvert) - REG(MatrixNormalize) - REG(MatrixIdentity) - REG(MatrixAdd) - REG(MatrixSubstract) - REG(MatrixTranslate) - REG(MatrixRotate) - REG(MatrixRotateX) - REG(MatrixRotateY) - REG(MatrixRotateZ) - REG(MatrixScale) - REG(MatrixMultiply) - REG(MatrixFrustum) - REG(MatrixPerspective) - REG(MatrixOrtho) - REG(MatrixLookAt) - REG(QuaternionLength) - REG(QuaternionNormalize) - REG(QuaternionMultiply) - REG(QuaternionSlerp) - REG(QuaternionFromMatrix) - REG(QuaternionToMatrix) - REG(QuaternionFromAxisAngle) - REG(QuaternionToAxisAngle) - REG(QuaternionTransform) - - {NULL, NULL} // sentinel: end signal -}; - -// Register raylib functionality -static void LuaRegisterRayLib(const char *opt_table) -{ - if (opt_table) lua_createtable(L, 0, sizeof(raylib_functions)/sizeof(raylib_functions[0])); - else lua_pushglobaltable(L); - - luaL_setfuncs(L, raylib_functions, 0); -} - -//---------------------------------------------------------------------------------- -// raylib Lua API -//---------------------------------------------------------------------------------- - -// Initialize Lua system -RLUADEF void InitLuaDevice(void) -{ - mainLuaState = luaL_newstate(); - L = mainLuaState; - - LuaStartEnum(); - LuaSetEnum("FULLSCREEN_MODE", 1); - LuaSetEnum("SHOW_LOGO", 2); - LuaSetEnum("SHOW_MOUSE_CURSOR", 4); - LuaSetEnum("CENTERED_MODE", 8); - LuaSetEnum("MSAA_4X_HINT", 16); - LuaSetEnum("VSYNC_HINT", 32); - LuaEndEnum("FLAG"); - - LuaStartEnum(); - LuaSetEnum("SPACE", 32); - LuaSetEnum("ESCAPE", 256); - LuaSetEnum("ENTER", 257); - LuaSetEnum("BACKSPACE", 259); - LuaSetEnum("RIGHT", 262); - LuaSetEnum("LEFT", 263); - LuaSetEnum("DOWN", 264); - LuaSetEnum("UP", 265); - LuaSetEnum("F1", 290); - LuaSetEnum("F2", 291); - LuaSetEnum("F3", 292); - LuaSetEnum("F4", 293); - LuaSetEnum("F5", 294); - LuaSetEnum("F6", 295); - LuaSetEnum("F7", 296); - LuaSetEnum("F8", 297); - LuaSetEnum("F9", 298); - LuaSetEnum("F10", 299); - LuaSetEnum("LEFT_SHIFT", 340); - LuaSetEnum("LEFT_CONTROL", 341); - LuaSetEnum("LEFT_ALT", 342); - LuaSetEnum("RIGHT_SHIFT", 344); - LuaSetEnum("RIGHT_CONTROL", 345); - LuaSetEnum("RIGHT_ALT", 346); - LuaSetEnum("ZERO", 48); - LuaSetEnum("ONE", 49); - LuaSetEnum("TWO", 50); - LuaSetEnum("THREE", 51); - LuaSetEnum("FOUR", 52); - LuaSetEnum("FIVE", 53); - LuaSetEnum("SIX", 54); - LuaSetEnum("SEVEN", 55); - LuaSetEnum("EIGHT", 56); - LuaSetEnum("NINE", 57); - LuaSetEnum("A", 65); - LuaSetEnum("B", 66); - LuaSetEnum("C", 67); - LuaSetEnum("D", 68); - LuaSetEnum("E", 69); - LuaSetEnum("F", 70); - LuaSetEnum("G", 71); - LuaSetEnum("H", 72); - LuaSetEnum("I", 73); - LuaSetEnum("J", 74); - LuaSetEnum("K", 75); - LuaSetEnum("L", 76); - LuaSetEnum("M", 77); - LuaSetEnum("N", 78); - LuaSetEnum("O", 79); - LuaSetEnum("P", 80); - LuaSetEnum("Q", 81); - LuaSetEnum("R", 82); - LuaSetEnum("S", 83); - LuaSetEnum("T", 84); - LuaSetEnum("U", 85); - LuaSetEnum("V", 86); - LuaSetEnum("W", 87); - LuaSetEnum("X", 88); - LuaSetEnum("Y", 89); - LuaSetEnum("Z", 90); - LuaEndEnum("KEY"); - - LuaStartEnum(); - LuaSetEnum("LEFT_BUTTON", 0); - LuaSetEnum("RIGHT_BUTTON", 1); - LuaSetEnum("MIDDLE_BUTTON", 2); - LuaEndEnum("MOUSE"); - - LuaStartEnum(); - LuaSetEnum("PLAYER1", 0); - LuaSetEnum("PLAYER2", 1); - LuaSetEnum("PLAYER3", 2); - LuaSetEnum("PLAYER4", 3); - - LuaSetEnum("PS3_BUTTON_TRIANGLE", 0); - LuaSetEnum("PS3_BUTTON_CIRCLE", 1); - LuaSetEnum("PS3_BUTTON_CROSS", 2); - LuaSetEnum("PS3_BUTTON_SQUARE", 3); - LuaSetEnum("PS3_BUTTON_L1", 6); - LuaSetEnum("PS3_BUTTON_R1", 7); - LuaSetEnum("PS3_BUTTON_L2", 4); - LuaSetEnum("PS3_BUTTON_R2", 5); - LuaSetEnum("PS3_BUTTON_START", 8); - LuaSetEnum("PS3_BUTTON_SELECT", 9); - LuaSetEnum("PS3_BUTTON_UP", 24); - LuaSetEnum("PS3_BUTTON_RIGHT", 25); - LuaSetEnum("PS3_BUTTON_DOWN", 26); - LuaSetEnum("PS3_BUTTON_LEFT", 27); - LuaSetEnum("PS3_BUTTON_PS", 12); - LuaSetEnum("PS3_AXIS_LEFT_X", 0); - LuaSetEnum("PS3_AXIS_LEFT_Y", 1); - LuaSetEnum("PS3_AXIS_RIGHT_X", 2); - LuaSetEnum("PS3_AXIS_RIGHT_Y", 5); - LuaSetEnum("PS3_AXIS_L2", 3); // [1..-1] (pressure-level) - LuaSetEnum("PS3_AXIS_R2", 4); // [1..-1] (pressure-level) - -// Xbox360 USB Controller Buttons - LuaSetEnum("XBOX_BUTTON_A", 0); - LuaSetEnum("XBOX_BUTTON_B", 1); - LuaSetEnum("XBOX_BUTTON_X", 2); - LuaSetEnum("XBOX_BUTTON_Y", 3); - LuaSetEnum("XBOX_BUTTON_LB", 4); - LuaSetEnum("XBOX_BUTTON_RB", 5); - LuaSetEnum("XBOX_BUTTON_SELECT", 6); - LuaSetEnum("XBOX_BUTTON_START", 7); - LuaSetEnum("XBOX_BUTTON_UP", 10); - LuaSetEnum("XBOX_BUTTON_RIGHT", 11); - LuaSetEnum("XBOX_BUTTON_DOWN", 12); - LuaSetEnum("XBOX_BUTTON_LEFT", 13); - LuaSetEnum("XBOX_BUTTON_HOME", 8); -#if defined(PLATFORM_RPI) - LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [-1..1] (up->down) - LuaSetEnum("XBOX_AXIS_RIGHT_X", 3); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 4); // [-1..1] (up->down) - LuaSetEnum("XBOX_AXIS_LT", 2); // [-1..1] (pressure-level) - LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) -#else - LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [1..-1] (up->down) - LuaSetEnum("XBOX_AXIS_RIGHT_X", 2); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 3); // [1..-1] (up->down) - LuaSetEnum("XBOX_AXIS_LT", 4); // [-1..1] (pressure-level) - LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) -#endif - LuaEndEnum("GAMEPAD"); - - lua_pushglobaltable(L); - LuaSetEnumColor("LIGHTGRAY", LIGHTGRAY); - LuaSetEnumColor("GRAY", GRAY); - LuaSetEnumColor("DARKGRAY", DARKGRAY); - LuaSetEnumColor("YELLOW", YELLOW); - LuaSetEnumColor("GOLD", GOLD); - LuaSetEnumColor("ORANGE", ORANGE); - LuaSetEnumColor("PINK", PINK); - LuaSetEnumColor("RED", RED); - LuaSetEnumColor("MAROON", MAROON); - LuaSetEnumColor("GREEN", GREEN); - LuaSetEnumColor("LIME", LIME); - LuaSetEnumColor("DARKGREEN", DARKGREEN); - LuaSetEnumColor("SKYBLUE", SKYBLUE); - LuaSetEnumColor("BLUE", BLUE); - LuaSetEnumColor("DARKBLUE", DARKBLUE); - LuaSetEnumColor("PURPLE", PURPLE); - LuaSetEnumColor("VIOLET", VIOLET); - LuaSetEnumColor("DARKPURPLE", DARKPURPLE); - LuaSetEnumColor("BEIGE", BEIGE); - LuaSetEnumColor("BROWN", BROWN); - LuaSetEnumColor("DARKBROWN", DARKBROWN); - LuaSetEnumColor("WHITE", WHITE); - LuaSetEnumColor("BLACK", BLACK); - LuaSetEnumColor("BLANK", BLANK); - LuaSetEnumColor("MAGENTA", MAGENTA); - LuaSetEnumColor("RAYWHITE", RAYWHITE); - lua_pop(L, 1); - - LuaStartEnum(); - LuaSetEnum("UNCOMPRESSED_GRAYSCALE", UNCOMPRESSED_GRAYSCALE); - LuaSetEnum("UNCOMPRESSED_GRAY_ALPHA", UNCOMPRESSED_GRAY_ALPHA); - LuaSetEnum("UNCOMPRESSED_R5G6B5", UNCOMPRESSED_R5G6B5); - LuaSetEnum("UNCOMPRESSED_R8G8B8", UNCOMPRESSED_R8G8B8); - LuaSetEnum("UNCOMPRESSED_R5G5B5A1", UNCOMPRESSED_R5G5B5A1); - LuaSetEnum("UNCOMPRESSED_R4G4B4A4", UNCOMPRESSED_R4G4B4A4); - LuaSetEnum("UNCOMPRESSED_R8G8B8A8", UNCOMPRESSED_R8G8B8A8); - LuaSetEnum("COMPRESSED_DXT1_RGB", COMPRESSED_DXT1_RGB); - LuaSetEnum("COMPRESSED_DXT1_RGBA", COMPRESSED_DXT1_RGBA); - LuaSetEnum("COMPRESSED_DXT3_RGBA", COMPRESSED_DXT3_RGBA); - LuaSetEnum("COMPRESSED_DXT5_RGBA", COMPRESSED_DXT5_RGBA); - LuaSetEnum("COMPRESSED_ETC1_RGB", COMPRESSED_ETC1_RGB); - LuaSetEnum("COMPRESSED_ETC2_RGB", COMPRESSED_ETC2_RGB); - LuaSetEnum("COMPRESSED_ETC2_EAC_RGBA", COMPRESSED_ETC2_EAC_RGBA); - LuaSetEnum("COMPRESSED_PVRT_RGB", COMPRESSED_PVRT_RGB); - LuaSetEnum("COMPRESSED_PVRT_RGBA", COMPRESSED_PVRT_RGBA); - LuaSetEnum("COMPRESSED_ASTC_4x4_RGBA", COMPRESSED_ASTC_4x4_RGBA); - LuaSetEnum("COMPRESSED_ASTC_8x8_RGBA", COMPRESSED_ASTC_8x8_RGBA); - LuaEndEnum("TextureFormat"); - - LuaStartEnum(); - LuaSetEnum("ALPHA", BLEND_ALPHA); - LuaSetEnum("ADDITIVE", BLEND_ADDITIVE); - LuaSetEnum("MULTIPLIED", BLEND_MULTIPLIED); - LuaEndEnum("BlendMode"); - - LuaStartEnum(); - LuaSetEnum("POINT", LIGHT_POINT); - LuaSetEnum("DIRECTIONAL", LIGHT_DIRECTIONAL); - LuaSetEnum("SPOT", LIGHT_SPOT); - LuaEndEnum("LightType"); - - LuaStartEnum(); - LuaSetEnum("POINT", FILTER_POINT); - LuaSetEnum("BILINEAR", FILTER_BILINEAR); - LuaSetEnum("TRILINEAR", FILTER_TRILINEAR); - LuaSetEnum("ANISOTROPIC_4X", FILTER_ANISOTROPIC_4X); - LuaSetEnum("ANISOTROPIC_8X", FILTER_ANISOTROPIC_8X); - LuaSetEnum("ANISOTROPIC_16X", FILTER_ANISOTROPIC_16X); - LuaEndEnum("TextureFilter"); - - LuaStartEnum(); - LuaSetEnum("NONE", GESTURE_NONE); - LuaSetEnum("TAP", GESTURE_TAP); - LuaSetEnum("DOUBLETAP", GESTURE_DOUBLETAP); - LuaSetEnum("HOLD", GESTURE_HOLD); - LuaSetEnum("DRAG", GESTURE_DRAG); - LuaSetEnum("SWIPE_RIGHT", GESTURE_SWIPE_RIGHT); - LuaSetEnum("SWIPE_LEFT", GESTURE_SWIPE_LEFT); - LuaSetEnum("SWIPE_UP", GESTURE_SWIPE_UP); - LuaSetEnum("SWIPE_DOWN", GESTURE_SWIPE_DOWN); - LuaSetEnum("PINCH_IN", GESTURE_PINCH_IN); - LuaSetEnum("PINCH_OUT", GESTURE_PINCH_OUT); - LuaEndEnum("Gestures"); - - LuaStartEnum(); - LuaSetEnum("CUSTOM", CAMERA_CUSTOM); - LuaSetEnum("FREE", CAMERA_FREE); - LuaSetEnum("ORBITAL", CAMERA_ORBITAL); - LuaSetEnum("FIRST_PERSON", CAMERA_FIRST_PERSON); - LuaSetEnum("THIRD_PERSON", CAMERA_THIRD_PERSON); - LuaEndEnum("CameraMode"); - - LuaStartEnum(); - LuaSetEnum("DEFAULT_DEVICE", HMD_DEFAULT_DEVICE); - LuaSetEnum("OCULUS_RIFT_DK2", HMD_OCULUS_RIFT_DK2); - LuaSetEnum("OCULUS_RIFT_CV1", HMD_OCULUS_RIFT_CV1); - LuaSetEnum("VALVE_HTC_VIVE", HMD_VALVE_HTC_VIVE); - LuaSetEnum("SAMSUNG_GEAR_VR", HMD_SAMSUNG_GEAR_VR); - LuaSetEnum("GOOGLE_CARDBOARD", HMD_GOOGLE_CARDBOARD); - LuaSetEnum("SONY_PLAYSTATION_VR", HMD_SONY_PLAYSTATION_VR); - LuaSetEnum("RAZER_OSVR", HMD_RAZER_OSVR); - LuaSetEnum("FOVE_VR", HMD_FOVE_VR); - LuaEndEnum("VrDevice"); - - lua_pushglobaltable(L); - LuaSetEnum("INFO", INFO); - LuaSetEnum("ERROR", ERROR); - LuaSetEnum("WARNING", WARNING); - LuaSetEnum("DEBUG", DEBUG); - LuaSetEnum("OTHER", OTHER); - lua_pop(L, 1); - - lua_pushboolean(L, true); -#if defined(PLATFORM_DESKTOP) - lua_setglobal(L, "PLATFORM_DESKTOP"); -#elif defined(PLATFORM_ANDROID) - lua_setglobal(L, "PLATFORM_ANDROID"); -#elif defined(PLATFORM_RPI) - lua_setglobal(L, "PLATFORM_RPI"); -#elif defined(PLATFORM_WEB) - lua_setglobal(L, "PLATFORM_WEB"); -#endif - - luaL_openlibs(L); - LuaBuildOpaqueMetatables(); - - LuaRegisterRayLib(0); -} - -// De-initialize Lua system -RLUADEF void CloseLuaDevice(void) -{ - if (mainLuaState) - { - lua_close(mainLuaState); - mainLuaState = 0; - L = 0; - } -} - -// Execute raylib Lua code -RLUADEF void ExecuteLuaCode(const char *code) -{ - if (!mainLuaState) - { - TraceLog(WARNING, "Lua device not initialized"); - return; - } - - int result = luaL_dostring(L, code); - - switch (result) - { - case LUA_OK: break; - case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); break; - case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); break; - default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); break; - } -} - -// Execute raylib Lua script -RLUADEF void ExecuteLuaFile(const char *filename) -{ - if (!mainLuaState) - { - TraceLog(WARNING, "Lua device not initialized"); - return; - } - - int result = luaL_dofile(L, filename); - - switch (result) - { - case LUA_OK: break; - case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); - case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); - default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); - } -} - -#endif // RLUA_IMPLEMENTATION -- cgit v1.2.3 From 734776b923c6cc3a9f64acab7577e604ecd9602e Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 6 Feb 2017 00:44:21 +0100 Subject: Commented code for review --- src/text.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/text.c b/src/text.c index af07bb69..206d06ff 100644 --- a/src/text.c +++ b/src/text.c @@ -265,6 +265,7 @@ SpriteFont LoadSpriteFont(const char *fileName) RRESData rres = LoadResource(fileName); // Load sprite font texture + /* if (rres.type == RRES_FONT_IMAGE) { // NOTE: Parameters for RRES_FONT_IMAGE type are: width, height, format, mipmaps @@ -281,6 +282,7 @@ SpriteFont LoadSpriteFont(const char *fileName) spriteFont.charsCount = rres.param2; spriteFont.chars = rres.data; } + */ // TODO: Do not free rres.data memory (chars info data!) UnloadResource(rres); -- cgit v1.2.3 From ac6b4d3830b1ed1a1446ecb57009456306ef008d Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 6 Feb 2017 00:44:54 +0100 Subject: Added audio function: SetMasterVolume() --- src/audio.c | 33 ++++++++++++++++++++++----------- src/raylib.h | 1 + 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 22da74be..e669eceb 100644 --- a/src/audio.c +++ b/src/audio.c @@ -177,9 +177,11 @@ void InitAudioDevice(void) TraceLog(INFO, "Audio device and context initialized successfully: %s", alcGetString(device, ALC_DEVICE_SPECIFIER)); // Listener definition (just for 2D) - alListener3f(AL_POSITION, 0, 0, 0); - alListener3f(AL_VELOCITY, 0, 0, 0); - alListener3f(AL_ORIENTATION, 0, 0, -1); + alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); + alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alListener3f(AL_ORIENTATION, 0.0f, 0.0f, -1.0f); + + alListenerf(AL_GAIN, 1.0f); } } } @@ -216,6 +218,15 @@ bool IsAudioDeviceReady(void) } } +// Set master volume (listener) +void SetMasterVolume(float volume) +{ + if (volume < 0.0f) volume = 0.0f; + else if (volume > 1.0f) volume = 1.0f; + + alListenerf(AL_GAIN, volume); +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Sounds loading and playing (.WAV) //---------------------------------------------------------------------------------- @@ -313,10 +324,10 @@ Sound LoadSoundFromWave(Wave wave) ALuint source; alGenSources(1, &source); // Generate pointer to audio source - alSourcef(source, AL_PITCH, 1); - alSourcef(source, AL_GAIN, 1); - alSource3f(source, AL_POSITION, 0, 0, 0); - alSource3f(source, AL_VELOCITY, 0, 0, 0); + alSourcef(source, AL_PITCH, 1.0f); + alSourcef(source, AL_GAIN, 1.0f); + alSource3f(source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); alSourcei(source, AL_LOOPING, AL_FALSE); // Convert loaded data to OpenAL buffer @@ -899,10 +910,10 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un // Create an audio source alGenSources(1, &stream.source); - alSourcef(stream.source, AL_PITCH, 1); - alSourcef(stream.source, AL_GAIN, 1); - alSource3f(stream.source, AL_POSITION, 0, 0, 0); - alSource3f(stream.source, AL_VELOCITY, 0, 0, 0); + alSourcef(stream.source, AL_PITCH, 1.0f); + alSourcef(stream.source, AL_GAIN, 1.0f); + alSource3f(stream.source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(stream.source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); // Create Buffers (double buffering) alGenBuffers(MAX_STREAM_BUFFERS, stream.buffers); diff --git a/src/raylib.h b/src/raylib.h index 5a1304fc..85cad6c3 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -947,6 +947,7 @@ RLAPI void ToggleVrMode(void); // Enable/Disable VR experienc RLAPI void InitAudioDevice(void); // Initialize audio device and context RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully +RLAPI void SetMasterVolume(float volume); // Set master volume (listener) RLAPI Wave LoadWave(const char *fileName); // Load wave data from file RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data -- cgit v1.2.3 From f2f05a734d4999ffdc19629c838f46914650bbd0 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 6 Feb 2017 01:03:58 +0100 Subject: Added audio function: SetMusicLoopCount() Useful to set number of repeats for a music, needs to be tested... --- src/audio.c | 27 ++++++++++++++++++++------- src/raylib.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index e669eceb..5a5b008f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -123,7 +123,7 @@ typedef struct MusicData { AudioStream stream; // Audio stream (double buffering) - bool loop; // Repeat music after finish (loop) + int loopCount; // Loops count (times music repeats), -1 means infinite loop unsigned int totalSamples; // Total number of samples unsigned int samplesLeft; // Number of samples left to end } MusicData; @@ -632,7 +632,7 @@ Music LoadMusicStream(const char *fileName) music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg); // Independent by channel music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_OGG; - music->loop = true; // We loop by default + music->loopCount = -1; // Infinite loop by default TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); @@ -651,7 +651,7 @@ Music LoadMusicStream(const char *fileName) music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount/music->ctxFlac->channels; music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_FLAC; - music->loop = true; // We loop by default + music->loopCount = -1; // Infinite loop by default TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate); @@ -665,14 +665,14 @@ Music LoadMusicStream(const char *fileName) if (!result) // XM context created successfully { - jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops + jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops // NOTE: Only stereo is supported for XM music->stream = InitAudioStream(48000, 16, 2); music->totalSamples = (unsigned int)jar_xm_get_remaining_samples(music->ctxXm); music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_MODULE_XM; - music->loop = true; + music->loopCount = -1; // Infinite loop by default TraceLog(DEBUG, "[%s] XM number of samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); @@ -689,7 +689,7 @@ Music LoadMusicStream(const char *fileName) music->totalSamples = (unsigned int)jar_mod_max_samples(&music->ctxMod); music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_MODULE_MOD; - music->loop = true; + music->loopCount = -1; // Infinite loop by default TraceLog(DEBUG, "[%s] MOD number of samples: %i", fileName, music->samplesLeft); TraceLog(DEBUG, "[%s] MOD track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); @@ -813,7 +813,13 @@ void UpdateMusicStream(Music music) if (!active) { StopMusicStream(music); // Stop music (and reset) - if (music->loop) PlayMusicStream(music); // Play again + + // Decrease loopCount to stop when required + if (music->loopCount > 0) + { + music->loopCount--; // Decrease loop count + PlayMusicStream(music); // Play again + } } else { @@ -851,6 +857,13 @@ void SetMusicPitch(Music music, float pitch) alSourcef(music->stream.source, AL_PITCH, pitch); } +// Set music loop count (loop repeats) +// NOTE: If set to -1, means infinite loop +void SetMusicLoopCount(Music music, float count); +{ + music->loopCount = count; +} + // Get music time length (in seconds) float GetMusicTimeLength(Music music) { diff --git a/src/raylib.h b/src/raylib.h index 85cad6c3..907ef1e9 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -977,6 +977,7 @@ RLAPI void ResumeMusicStream(Music music); // Resume RLAPI bool IsMusicPlaying(Music music); // Check if music is playing RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) +RLAPI void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats) RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) -- cgit v1.2.3 From 836c1636a2b5d7779c69cbb633a9ac690d54ef90 Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 8 Feb 2017 20:02:40 +0100 Subject: Remove lighting system from rlgl standalone header --- src/audio.c | 2 +- src/audio.h | 2 ++ src/rlgl.h | 22 ---------------------- 3 files changed, 3 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 5a5b008f..adbe4f4f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -859,7 +859,7 @@ void SetMusicPitch(Music music, float pitch) // Set music loop count (loop repeats) // NOTE: If set to -1, means infinite loop -void SetMusicLoopCount(Music music, float count); +void SetMusicLoopCount(Music music, float count) { music->loopCount = count; } diff --git a/src/audio.h b/src/audio.h index 6f0c235a..05ba1a1d 100644 --- a/src/audio.h +++ b/src/audio.h @@ -109,6 +109,7 @@ extern "C" { // Prevents name mangling of functions void InitAudioDevice(void); // Initialize audio device and context void CloseAudioDevice(void); // Close the audio device and context bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully +void SetMasterVolume(float volume); // Set master volume (listener) Wave LoadWave(const char *fileName); // Load wave data from file Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data @@ -138,6 +139,7 @@ void ResumeMusicStream(Music music); // Resume playin bool IsMusicPlaying(Music music); // Check if music is playing void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) +void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats) float GetMusicTimeLength(Music music); // Get music time length (in seconds) float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) diff --git a/src/rlgl.h b/src/rlgl.h index 9cee39cc..41f671e6 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -251,25 +251,6 @@ typedef unsigned char byte; float fovy; // Camera field-of-view apperture in Y (degrees) } Camera; - // Light type - typedef struct LightData { - unsigned int id; // Light unique id - bool enabled; // Light enabled - int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - - Vector3 position; // Light position - Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) - float radius; // Light attenuation radius light intensity reduced with distance (world distance) - - Color diffuse; // Light diffuse color - float intensity; // Light intensity level - - float coneAngle; // Light cone max angle: LIGHT_SPOT - } LightData, *Light; - - // Light types - typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType; - // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification @@ -415,9 +396,6 @@ void EndShaderMode(void); // End custo void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) void EndBlendMode(void); // End blending mode (reset to default: alpha blending) -Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool -void DestroyLight(Light light); // Destroy a light and take it out of the list - void TraceLog(int msgType, const char *text, ...); float *MatrixToFloat(Matrix mat); -- cgit v1.2.3 From b4988777ef60b312632602d7591ab508f0c90ab2 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 9 Feb 2017 22:19:48 +0100 Subject: [audio] Renamed variable --- src/audio.c | 29 +++++++++++++++-------------- src/audio.h | 4 ++-- src/raylib.h | 4 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index adbe4f4f..720233e0 100644 --- a/src/audio.c +++ b/src/audio.c @@ -374,7 +374,7 @@ void UnloadSound(Sound sound) // Update sound buffer with new data // NOTE: data must match sound.format -void UpdateSound(Sound sound, const void *data, int numSamples) +void UpdateSound(Sound sound, const void *data, int samplesCount) { ALint sampleRate, sampleSize, channels; alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); @@ -385,7 +385,7 @@ void UpdateSound(Sound sound, const void *data, int numSamples) TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize); TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels); - unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes + unsigned int dataSize = samplesCount*channels*sampleSize/8; // Size of data in bytes alSourceStop(sound.source); // Stop sound alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update @@ -752,6 +752,7 @@ void StopMusicStream(Music music) } // Update (re-fill) music buffers if data already processed +// TODO: Make sure buffers are ready for update... check music state void UpdateMusicStream(Music music) { ALenum state; @@ -768,13 +769,13 @@ void UpdateMusicStream(Music music) void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1); int numBuffersToProcess = processed; - int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, - // individual L or R for ogg shorts + int samplesCount = 0; // Total size of data steamed in L+R samples for xm floats, + //individual L or R for ogg shorts for (int i = 0; i < numBuffersToProcess; i++) { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; - else numSamples = music->samplesLeft; + if (music->samplesLeft >= AUDIO_BUFFER_SIZE) samplesCount = AUDIO_BUFFER_SIZE; + else samplesCount = music->samplesLeft; // TODO: Really don't like ctxType thingy... switch (music->ctxType) @@ -782,22 +783,22 @@ void UpdateMusicStream(Music music) case MUSIC_AUDIO_OGG: { // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) - int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, numSamples*music->stream.channels); + int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels); } break; case MUSIC_AUDIO_FLAC: { // NOTE: Returns the number of samples to process - unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, numSamples*music->stream.channels, (short *)pcm); + unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, samplesCount*music->stream.channels, (short *)pcm); } break; - case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, numSamples); break; - case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break; + case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break; + case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, samplesCount, 0); break; default: break; } - UpdateAudioStream(music->stream, pcm, numSamples); - music->samplesLeft -= numSamples; + UpdateAudioStream(music->stream, pcm, samplesCount); + music->samplesLeft -= samplesCount; if (music->samplesLeft <= 0) { @@ -976,7 +977,7 @@ void CloseAudioStream(AudioStream stream) // Update audio stream buffers with data // NOTE: Only updates one buffer per call -void UpdateAudioStream(AudioStream stream, const void *data, int numSamples) +void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) { ALuint buffer = 0; alSourceUnqueueBuffers(stream.source, 1, &buffer); @@ -984,7 +985,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int numSamples) // Check if any buffer was available for unqueue if (alGetError() != AL_INVALID_VALUE) { - alBufferData(buffer, stream.format, data, numSamples*stream.channels*stream.sampleSize/8, stream.sampleRate); + alBufferData(buffer, stream.format, data, samplesCount*stream.channels*stream.sampleSize/8, stream.sampleRate); alSourceQueueBuffers(stream.source, 1, &buffer); } } diff --git a/src/audio.h b/src/audio.h index 05ba1a1d..99b58e15 100644 --- a/src/audio.h +++ b/src/audio.h @@ -115,7 +115,7 @@ Wave LoadWave(const char *fileName); // Load wave dat Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data Sound LoadSound(const char *fileName); // Load sound from file Sound LoadSoundFromWave(Wave wave); // Load sound from wave data -void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data +void UpdateSound(Sound sound, const void *data, int samplesCount); // Update sound buffer with new data void UnloadWave(Wave wave); // Unload wave data void UnloadSound(Sound sound); // Unload sound void PlaySound(Sound sound); // Play a sound @@ -146,7 +146,7 @@ float GetMusicTimePlayed(Music music); // Get current m AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +void UpdateAudioStream(AudioStream stream, void *data, int samplesCount); // Update audio stream buffers with data void CloseAudioStream(AudioStream stream); // Close audio stream and free memory bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/src/raylib.h b/src/raylib.h index 907ef1e9..a5849180 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -953,7 +953,7 @@ RLAPI Wave LoadWave(const char *fileName); // Load wa RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data RLAPI Sound LoadSound(const char *fileName); // Load sound from file RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data -RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data +RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -984,7 +984,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream -- cgit v1.2.3 From afcd748fdf2d4f379f7a3be1706c1d6cd2ff504d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 11 Feb 2017 23:17:56 +0100 Subject: Reviewed fread() usage around the code --- src/audio.c | 2 +- src/core.c | 4 ++-- src/text.c | 7 +++++-- src/textures.c | 22 ++++++++++++---------- 4 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 720233e0..eb5e65d6 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1114,7 +1114,7 @@ static Wave LoadWAV(const char *fileName) wave.data = malloc(wavData.subChunkSize); // Read in the sound data into the soundData variable - fread(wave.data, 1, wavData.subChunkSize, wavFile); + fread(wave.data, wavData.subChunkSize, 1, wavFile); // Store wave parameters wave.sampleRate = wavFormat.sampleRate; diff --git a/src/core.c b/src/core.c index 04dd0540..28f73345 100644 --- a/src/core.c +++ b/src/core.c @@ -1025,14 +1025,14 @@ int StorageLoadValue(int position) { // Get file size fseek(storageFile, 0, SEEK_END); - int fileSize = ftell(storageFile); // Size in bytes + int fileSize = ftell(storageFile); // Size in bytes rewind(storageFile); if (fileSize < (position*4)) TraceLog(WARNING, "Storage position could not be found"); else { fseek(storageFile, (position*4), SEEK_SET); - fread(&value, 1, 4, storageFile); + fread(&value, 4, 1, storageFile); // Read 1 element of 4 bytes size } fclose(storageFile); diff --git a/src/text.c b/src/text.c index 206d06ff..4deae25c 100644 --- a/src/text.c +++ b/src/text.c @@ -928,6 +928,8 @@ static SpriteFont LoadBMFont(const char *fileName) // TODO: Review texture packing method and generation (use oversampling) static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars) { + #define MAX_TTF_SIZE 16 // Maximum ttf file size in MB + // NOTE: Font texture size is predicted (being as much conservative as possible) // Predictive method consist of supposing same number of chars by line-column (sqrtf) // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests... @@ -938,7 +940,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize); - unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25); + unsigned char *ttfBuffer = (unsigned char *)malloc(MAX_TTF_SIZE*1024*1024); unsigned char *dataBitmap = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)); // One channel bitmap returned! stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*charsCount); @@ -952,7 +954,8 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in return font; } - fread(ttfBuffer, 1, 1 << 25, ttfFile); + // NOTE: We try reading up to 16 MB of elements of 1 byte + fread(ttfBuffer, 1, MAX_TTF_SIZE*1024*1024, ttfFile); if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character"); diff --git a/src/textures.c b/src/textures.c index ce978b6c..5b2e4775 100644 --- a/src/textures.c +++ b/src/textures.c @@ -238,7 +238,9 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int default: TraceLog(WARNING, "Image format not suported"); break; } - int bytes = fread(image.data, size, 1, rawFile); + // NOTE: fread() returns num read elements instead of bytes, + // to get bytes we need to read (1 byte size, elements) instead of (x byte size, 1 element) + int bytes = fread(image.data, 1, size, rawFile); // Check if data has been read successfully if (bytes < size) @@ -1591,7 +1593,7 @@ static Image LoadDDS(const char *fileName) // Verify the type of file char filecode[4]; - fread(filecode, 1, 4, ddsFile); + fread(filecode, 4, 1, ddsFile); if (strncmp(filecode, "DDS ", 4) != 0) { @@ -1690,17 +1692,17 @@ static Image LoadDDS(const char *fileName) } else if (((ddsHeader.ddspf.flags == 0x04) || (ddsHeader.ddspf.flags == 0x05)) && (ddsHeader.ddspf.fourCC > 0)) // Compressed { - int bufsize; + int size; // DDS image data size // Calculate data size, including all mipmaps - if (ddsHeader.mipmapCount > 1) bufsize = ddsHeader.pitchOrLinearSize*2; - else bufsize = ddsHeader.pitchOrLinearSize; + if (ddsHeader.mipmapCount > 1) size = ddsHeader.pitchOrLinearSize*2; + else size = ddsHeader.pitchOrLinearSize; TraceLog(DEBUG, "Pitch or linear size: %i", ddsHeader.pitchOrLinearSize); - image.data = (unsigned char*)malloc(bufsize*sizeof(unsigned char)); + image.data = (unsigned char*)malloc(size*sizeof(unsigned char)); - fread(image.data, 1, bufsize, ddsFile); + fread(image.data, size, 1, ddsFile); image.mipmaps = ddsHeader.mipmapCount; @@ -1803,7 +1805,7 @@ static Image LoadPKM(const char *fileName) image.data = (unsigned char*)malloc(size*sizeof(unsigned char)); - fread(image.data, 1, size, pkmFile); + fread(image.data, size, 1, pkmFile); if (pkmHeader.format == 0) image.format = COMPRESSED_ETC1_RGB; else if (pkmHeader.format == 1) image.format = COMPRESSED_ETC2_RGB; @@ -1888,7 +1890,7 @@ static Image LoadKTX(const char *fileName) if (ktxHeader.keyValueDataSize > 0) { - for (int i = 0; i < ktxHeader.keyValueDataSize; i++) fread(&unused, 1, 1, ktxFile); + for (int i = 0; i < ktxHeader.keyValueDataSize; i++) fread(&unused, sizeof(unsigned char), 1, ktxFile); } int dataSize; @@ -1896,7 +1898,7 @@ static Image LoadKTX(const char *fileName) image.data = (unsigned char*)malloc(dataSize*sizeof(unsigned char)); - fread(image.data, 1, dataSize, ktxFile); + fread(image.data, dataSize, 1, ktxFile); if (ktxHeader.glInternalFormat == 0x8D64) image.format = COMPRESSED_ETC1_RGB; else if (ktxHeader.glInternalFormat == 0x9274) image.format = COMPRESSED_ETC2_RGB; -- cgit v1.2.3 From 05f039f85fb43f9ae4598747a4d9c6770ec5774b Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 11 Feb 2017 23:34:41 +0100 Subject: Corrected issue with OpenAL being 'keg only' on OSX Also reviewed issue with stdbool when compiling with clang --- examples/Makefile | 2 +- src/audio.c | 13 +++++++++---- src/external/jar_mod.h | 3 +-- src/raylib.h | 10 +++------- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/examples/Makefile b/examples/Makefile index 80437590..bef0fa11 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -153,7 +153,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) # libraries for OS X 10.9 desktop compiling # requires the following packages: # libglfw3-dev libopenal-dev libegl1-mesa-dev - LIBS = -lraylib -lglfw3 -framework OpenGL -framework OpenAl -framework Cocoa + LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa else # libraries for Windows desktop compiling # NOTE: GLFW3 and OpenAL Soft libraries should be installed diff --git a/src/audio.c b/src/audio.c index eb5e65d6..58699035 100644 --- a/src/audio.c +++ b/src/audio.c @@ -59,9 +59,14 @@ #include "utils.h" // Required for: fopen() Android mapping, TraceLog() #endif -#include "AL/al.h" // OpenAL basic header -#include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) -//#include "AL/alext.h" // OpenAL extensions header, required for AL_EXT_FLOAT32 and AL_EXT_MCFORMATS +#ifdef __APPLE__ + #include "OpenAL/al.h" // OpenAL basic header + #include "OpenAL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) +#else + #include "AL/al.h" // OpenAL basic header + #include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) + //#include "AL/alext.h" // OpenAL extensions header, required for AL_EXT_FLOAT32 and AL_EXT_MCFORMATS +#endif // OpenAL extension: AL_EXT_FLOAT32 - Support for 32bit float samples // OpenAL extension: AL_EXT_MCFORMATS - Support for multi-channel formats (Quad, 5.1, 6.1, 7.1) @@ -1252,4 +1257,4 @@ void TraceLog(int msgType, const char *text, ...) if (msgType == ERROR) exit(1); // If ERROR message, exit program } -#endif \ No newline at end of file +#endif diff --git a/src/external/jar_mod.h b/src/external/jar_mod.h index bee9f6ee..c17130a6 100644 --- a/src/external/jar_mod.h +++ b/src/external/jar_mod.h @@ -83,8 +83,7 @@ #include #include -#include - +//#include #ifdef __cplusplus diff --git a/src/raylib.h b/src/raylib.h index a5849180..800ab2be 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -296,13 +296,9 @@ //---------------------------------------------------------------------------------- #ifndef __cplusplus // Boolean type - #ifndef __APPLE__ - #if !defined(_STDBOOL_H) - typedef enum { false, true } bool; - #define _STDBOOL_H - #endif - #else - #include + #if !defined(_STDBOOL_H) + typedef enum { false, true } bool; + #define _STDBOOL_H #endif #endif -- cgit v1.2.3 From 4cb3e4a240d342a08a97cb4659c18c34d8dccdc8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 15 Feb 2017 10:44:59 +0100 Subject: Support resources divided in multiple parts Every part is a resource itself, they are loaded in an array --- src/rres.h | 105 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 50 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/rres.h b/src/rres.h index 700c9ab3..32f0ab6b 100644 --- a/src/rres.h +++ b/src/rres.h @@ -83,6 +83,8 @@ RRES_TYPE_FONT_DATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } RRES_TYPE_DIRECTORY } RRESDataType; + + typedef struct RRESData *RRES; #endif //---------------------------------------------------------------------------------- @@ -93,9 +95,9 @@ //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -RRESDEF RRESData LoadResource(const char *rresFileName); -RRESDEF RRESData LoadResourceById(const char *rresFileName, int rresId); -RRESDEF void UnloadResource(RRESData rres); +//RRESDEF RRESData LoadResourceData(const char *rresFileName, int rresId, int part); +RRESDEF RRES LoadResource(const char *rresFileName, int rresId); +RRESDEF void UnloadResource(RRESData *rres); #endif // RRES_H @@ -235,24 +237,12 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i // Module Functions Definition //---------------------------------------------------------------------------------- -// Load resource from file (only one) -// NOTE: Returns uncompressed data with parameters, only first resource found -RRESDEF RRESData LoadResource(const char *fileName) -{ - // Force loading first resource available - RRESData rres = { 0 }; - - rres = LoadResourceById(fileName, 0); - - return rres; -} - -// Load resource from file by id +// Load resource from file by id (could be multiple parts) // NOTE: Returns uncompressed data with parameters, search resource by id -RRESDEF RRESData LoadResourceById(const char *fileName, int rresId) +RRESDEF RRES LoadResource(const char *fileName, int rresId) { - RRESData rres = { 0 }; - + RRES rres; + RRESFileHeader fileHeader; RRESInfoHeader infoHeader; @@ -280,33 +270,42 @@ RRESDEF RRESData LoadResourceById(const char *fileName, int rresId) { // Read resource info and parameters fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); - + + rres = (RRES)malloc(sizeof(RRESData)*infoHeader.partsCount) + if (infoHeader.id == rresId) { - // Register data type and parameters - rres.type = infoHeader.dataType; - rres.param1 = infoHeader.param1; - rres.param2 = infoHeader.param2; - rres.param3 = infoHeader.param3; - rres.param4 = infoHeader.param4; - - // Read resource data block - void *data = RRES_MALLOC(infoHeader.dataSize); - fread(data, infoHeader.dataSize, 1, rresFile); - - if (infoHeader.compType == RRES_COMP_DEFLATE) + // Load all required resources parts + for (int k = 0; k < infoHeader.partsCount; k++) { - void *uncompData = DecompressData(data, infoHeader.dataSize, infoHeader.uncompSize); + // TODO: Verify again that rresId is the same in every part - rres.data = uncompData; + // Register data type and parameters + rres[k].type = infoHeader.dataType; + rres[k].param1 = infoHeader.param1; + rres[k].param2 = infoHeader.param2; + rres[k].param3 = infoHeader.param3; + rres[k].param4 = infoHeader.param4; + + // Read resource data block + void *data = RRES_MALLOC(infoHeader.dataSize); + fread(data, infoHeader.dataSize, 1, rresFile); + + if (infoHeader.compType == RRES_COMP_DEFLATE) + { + void *uncompData = DecompressData(data, infoHeader.dataSize, infoHeader.uncompSize); + + rres[k].data = uncompData; + + RRES_FREE(data); + } + else rres[k].data = data; + + if (rres[k].data != NULL) TraceLog(INFO, "[%s][ID %i] Resource data loaded successfully", fileName, (int)infoHeader.id); - RRES_FREE(data); + // Read next part + fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); } - else rres.data = data; - - if (rres.data != NULL) TraceLog(INFO, "[%s][ID %i] Resource data loaded successfully", fileName, (int)infoHeader.id); - - if (rresId == 0) break; // Break for loop, do not check next resource } else { @@ -372,7 +371,6 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i return uncompData; } - // Some required functions for rres standalone module version #if defined(RRES_STANDALONE) // Outputs a trace log message (INFO, ERROR, WARNING) @@ -417,22 +415,19 @@ Mesh LoadMeshEx(rres.param1, rres.data, rres.data + offset, rres.data + offset*2 Shader LoadShader(const char *vsText, int vsLength); Shader LoadShaderV(rres.data, rres.param1); -// Parameters information depending on resource type (IMAGE, WAVE, MESH, TEXT) +// Parameters information depending on resource type -// Image data params -int imgWidth, imgHeight; -char colorFormat, mipmaps; +// RRES_TYPE_IMAGE params: imgWidth, imgHeight, format, mipmaps; +// RRES_TYPE_WAVE params: sampleCount, sampleRate, sampleSize, channels; +// RRES_TYPE_FONT_IMAGE params: imgWidth, imgHeight, format, mipmaps; +// RRES_TYPE_FONT_DATA params: charsCount, baseSize +// RRES_TYPE_VERTEX params: vertexCount, vertexType, vertexFormat // Use masks instead? +// RRES_TYPE_TEXT params: charsCount, cultureCode +// RRES_TYPE_DIRECTORY params: fileCount, directoryCount -// Wave data params -int sampleCount, -short sampleRate, bps; -char channels, reserved; +// SpriteFont = RRES_TYPE_FONT_IMAGE chunk + RRES_TYPE_FONT_DATA chunk +// Mesh = multiple RRES_TYPE_VERTEX chunks -// Mesh data params -int vertexCount, reserved; -short vertexTypesMask, vertexFormatsMask; +Ref: RIFF file-format: http://www.johnloomis.org/cpe102/asgn/asgn1/riff.html -// Text data params -int charsCount; -int cultureCode; */ \ No newline at end of file -- cgit v1.2.3 From 177af272f0713ee42bdb32201b1fff3aa75e345f Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 16 Feb 2017 00:19:03 +0100 Subject: Added function DrawRectanglePro() --- src/shapes.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/shapes.c b/src/shapes.c index 8c6c4be0..83b80182 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -4,11 +4,17 @@ * * Basic functions to draw 2d Shapes and check collisions * -* External libs: +* DEPENDENCIES: * rlgl - raylib OpenGL abstraction layer * -* Module Configuration Flags: -* ... +* CONFIGURATION: +* +* #define SUPPORT_QUADS_ONLY +* + #define SUPPORT_TRIANGLES_ONLY +* +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -190,6 +196,29 @@ void DrawRectangleRec(Rectangle rec, Color color) DrawRectangle(rec.x, rec.y, rec.width, rec.height, color); } +void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color) +{ + rlEnableTexture(GetDefaultTexture().id); + + rlPushMatrix(); + rlTranslatef((float)rec.x, (float)rec.y, 0); + rlRotatef(rotation, 0, 0, 1); + rlTranslatef(-origin.x, -origin.y, 0); + + rlBegin(RL_QUADS); + rlColor4ub(color.r, color.g, color.b, color.a); + rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + + rlVertex2f(0.0f, 0.0f); + rlVertex2f(0.0f, (float)rec.height); + rlVertex2f((float)rec.width, (float)rec.height); + rlVertex2f((float)rec.width, 0.0f); + rlEnd(); + rlPopMatrix(); + + rlDisableTexture(); +} + // Draw a gradient-filled rectangle // NOTE: Gradient goes from bottom (color1) to top (color2) void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2) -- cgit v1.2.3 From 1c364cc5074fe8abb482ed9985705eeb249b93ae Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 16 Feb 2017 00:19:30 +0100 Subject: Review rres loading to support multiple parts --- src/rres.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/rres.h b/src/rres.h index 32f0ab6b..bed28723 100644 --- a/src/rres.h +++ b/src/rres.h @@ -62,7 +62,7 @@ #if defined(RRES_STANDALONE) // rRES data returned when reading a resource, it contains all required data for user (24 byte) // NOTE: Using void *data pointer, so we can load to image.data, wave.data, mesh.*, (unsigned char *) - typedef struct { + typedef struct RRESData { unsigned int type; // Resource type (4 byte) unsigned int param1; // Resouce parameter 1 (4 byte) @@ -73,6 +73,7 @@ void *data; // Resource data pointer (4 byte) } RRESData; + // RRESData type typedef enum { RRES_TYPE_RAW = 0, RRES_TYPE_IMAGE, @@ -84,6 +85,7 @@ RRES_TYPE_DIRECTORY } RRESDataType; + // RRES type (pointer to RRESData array) typedef struct RRESData *RRES; #endif @@ -96,8 +98,8 @@ // Module Functions Declaration //---------------------------------------------------------------------------------- //RRESDEF RRESData LoadResourceData(const char *rresFileName, int rresId, int part); -RRESDEF RRES LoadResource(const char *rresFileName, int rresId); -RRESDEF void UnloadResource(RRESData *rres); +RRESDEF RRES LoadResource(const char *fileName, int rresId); +RRESDEF void UnloadResource(RRES rres); #endif // RRES_H @@ -242,7 +244,7 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i RRESDEF RRES LoadResource(const char *fileName, int rresId) { RRES rres; - + RRESFileHeader fileHeader; RRESInfoHeader infoHeader; @@ -271,7 +273,7 @@ RRESDEF RRES LoadResource(const char *fileName, int rresId) // Read resource info and parameters fread(&infoHeader, sizeof(RRESInfoHeader), 1, rresFile); - rres = (RRES)malloc(sizeof(RRESData)*infoHeader.partsCount) + rres = (RRES)malloc(sizeof(RRESData)*infoHeader.partsCount); if (infoHeader.id == rresId) { @@ -314,7 +316,7 @@ RRESDEF RRES LoadResource(const char *fileName, int rresId) } } - if (rres.data == NULL) TraceLog(WARNING, "[%s][ID %i] Requested resource could not be found", fileName, (int)rresId); + if (rres[0].data == NULL) TraceLog(WARNING, "[%s][ID %i] Requested resource could not be found", fileName, (int)rresId); } fclose(rresFile); @@ -323,9 +325,9 @@ RRESDEF RRES LoadResource(const char *fileName, int rresId) return rres; } -RRESDEF void UnloadResource(RRESData rres) +RRESDEF void UnloadResource(RRES rres) { - if (rres.data != NULL) free(rres.data); + if (rres[0].data != NULL) free(rres[0].data); } //---------------------------------------------------------------------------------- -- cgit v1.2.3 From 05cff44d0a9af5bcb41ddd0baa6b7693f6ac116b Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 16 Feb 2017 00:50:02 +0100 Subject: Improved modules description -IN PROGRESS- Working in modules configuration flags... --- src/audio.c | 56 +++++++++++++++++++++++++++++++++++++------------------- src/audio.h | 4 +++- src/camera.h | 14 +++++++++++--- src/core.c | 55 +++++++++++++++++++++++++++++++++++++------------------ src/gestures.h | 17 +++++++++++++---- src/models.c | 13 +++++++------ src/physac.h | 15 +++++++++------ src/raylib.h | 44 +++++++++++++++++++++++++++----------------- src/raymath.h | 25 +++++++++++++------------ src/rlgl.c | 46 ++++++++++++++++++++++++++++++++++++---------- src/rres.h | 18 +++++++++++------- src/shapes.c | 11 ++++------- src/text.c | 36 +++++++++++++++++++++--------------- src/textures.c | 35 +++++++++++++++++++++++++++-------- src/utils.c | 19 +++++++++++++------ 15 files changed, 269 insertions(+), 139 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 58699035..690a41eb 100644 --- a/src/audio.c +++ b/src/audio.c @@ -3,32 +3,50 @@ * raylib.audio * * This module provides basic functionality to work with audio: -* Manage audio device (init/close) -* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD) -* Play/Stop/Pause/Resume loaded audio -* Manage mixing channels -* Manage raw audio context +* Manage audio device (init/close) +* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD) +* Play/Stop/Pause/Resume loaded audio +* Manage mixing channels +* Manage raw audio context * -* External libs: +* NOTES: +* +* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS) +* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) +* +* CONFIGURATION: +* +* #define AUDIO_STANDALONE +* If defined, the module can be used as standalone library (independently of raylib). +* Required types and functions are defined in the same module. +* +* #define SUPPORT_FILEFORMAT_WAV / SUPPORT_LOAD_WAV / ENABLE_LOAD_WAV +* #define SUPPORT_FILEFORMAT_OGG +* #define SUPPORT_FILEFORMAT_XM +* #define SUPPORT_FILEFORMAT_MOD +* #define SUPPORT_FILEFORMAT_FLAC +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define SUPPORT_RAW_AUDIO_BUFFERS +* +* DEPENDENCIES: * OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) * jar_xm - XM module file loading * jar_mod - MOD audio file loading * dr_flac - FLAC audio file loading * -* Module Configuration Flags: -* AUDIO_STANDALONE - Use this module as standalone library (independently of raylib) -* -* Some design decisions: -* Support only up to two channels: MONO and STEREO (for additional channels, AL_EXT_MCFORMATS) -* Support only the following sample sizes: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) +* CONTRIBUTORS: * * Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions: -* XM audio module support (jar_xm) -* MOD audio module support (jar_mod) -* Mixing channels support -* Raw audio context support +* XM audio module support (jar_xm) +* MOD audio module support (jar_mod) +* Mixing channels support +* Raw audio context support +* * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -246,11 +264,11 @@ Wave LoadWave(const char *fileName) else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName); else if (strcmp(GetExtension(fileName),"rres") == 0) { - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); - // NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels + // NOTE: Parameters for RRES_TYPE_WAVE are: sampleCount, sampleRate, sampleSize, channels - if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4); + if (rres[0].type == RRES_TYPE_WAVE) wave = LoadWaveEx(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3, rres[0].param4); else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName); UnloadResource(rres); diff --git a/src/audio.h b/src/audio.h index 99b58e15..01ed9f72 100644 --- a/src/audio.h +++ b/src/audio.h @@ -9,7 +9,7 @@ * Manage mixing channels * Manage raw audio context * -* External libs: +* DEPENDENCIES: * OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) * jar_xm - XM module file loading @@ -23,6 +23,8 @@ * Raw audio context support * * +* LICENSE: zlib/libpng +* * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event diff --git a/src/camera.h b/src/camera.h index cf542288..87ba1942 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,6 +2,10 @@ * * raylib Camera System - Camera Modes Setup and Control Functions * +* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables) +* +* CONFIGURATION: +* * #define CAMERA_IMPLEMENTATION * Generates the implementation of the library into the included file. * If not defined, the library is in header only mode and can be included in other headers @@ -11,10 +15,14 @@ * If defined, the library can be used as standalone as a camera system but some * functions must be redefined to manage inputs accordingly. * -* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables) +* CONTRIBUTORS: +* Marc Palau: Initial implementation (2014) +* Ramon Santamaria: Supervision, review, update and maintenance +* +* +* LICENSE: zlib/libpng * -* Initial design by Marc Palau (2014) -* Reviewed by Ramon Santamaria (2015-2016) +* Copyright (c) 2015-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/core.c b/src/core.c index 28f73345..9d40edcc 100644 --- a/src/core.c +++ b/src/core.c @@ -1,27 +1,46 @@ /********************************************************************************************** * -* raylib.core -* -* Basic functions to manage windows, OpenGL context and input on multiple platforms +* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms * * The following platforms are supported: Windows, Linux, Mac (OSX), Android, Raspberry Pi, HTML5, Oculus Rift CV1 * -* External libs: +* CONFIGURATION: +* +* #define PLATFORM_DESKTOP +* Windowing and input system configured for desktop platforms: Windows, Linux, OSX (managed by GLFW3 library) +* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for mirror rendering - View [rlgl] module to enable it +* +* #define PLATFORM_ANDROID +* Windowing and input system configured for Android device, app activity managed internally in this module. +* NOTE: OpenGL ES 2.0 is required and graphic device is managed by EGL +* +* #define PLATFORM_RPI +* Windowing and input system configured for Raspberry Pi (tested on Raspbian), graphic device is managed by EGL +* and inputs are processed is raw mode, reading from /dev/input/ +* +* #define PLATFORM_WEB +* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js +* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code. +* +* #define LOAD_DEFAULT_FONT (defined by default) +* Default font is loaded on window initialization to be available for the user to render simple text. +* NOTE: If enabled, uses external module functions to load default raylib font (module: text) +* +* #define INCLUDE_CAMERA_SYSTEM / SUPPORT_CAMERA_SYSTEM +* +* #define INCLUDE_GESTURES_SYSTEM / SUPPORT_GESTURES_SYSTEM +* +* #define SUPPORT_MOUSE_GESTURES +* Mouse gestures are directly mapped like touches and processed by gestures system. +* +* DEPENDENCIES: * GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX) * raymath - 3D math functionality (Vector3, Matrix, Quaternion) * camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person) * gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) * -* Module Configuration Flags: -* PLATFORM_DESKTOP - Windows, Linux, Mac (OSX) -* PLATFORM_ANDROID - Android (only OpenGL ES 2.0 devices), graphic device is managed by EGL and input system by Android activity. -* PLATFORM_RPI - Rapsberry Pi (tested on Raspbian), graphic device is managed by EGL and input system is coded in raw mode. -* PLATFORM_WEB - HTML5 (using emscripten compiler) -* -* RL_LOAD_DEFAULT_FONT - Use external module functions to load default raylib font (module: text) -* -* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for render mirror - View [rlgl] module to enable it * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -140,7 +159,7 @@ #define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad) #define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad) -#define RL_LOAD_DEFAULT_FONT // Load default font on window initialization (module: text) +#define LOAD_DEFAULT_FONT // Load default font on window initialization (module: text) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -256,7 +275,7 @@ static bool showLogo = false; // Track if showing logo at init is //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by core) //---------------------------------------------------------------------------------- -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow() extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory #endif @@ -338,7 +357,7 @@ void InitWindow(int width, int height, const char *title) // Init graphics device (display device and OpenGL context) InitGraphicsDevice(width, height); -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) // Load default font // NOTE: External function (defined in module: text) LoadDefaultFont(); @@ -450,7 +469,7 @@ void InitWindow(int width, int height, void *state) // Close Window and Terminate Context void CloseWindow(void) { -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) UnloadDefaultFont(); #endif @@ -2410,7 +2429,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Init graphics device (display device and OpenGL context) InitGraphicsDevice(screenWidth, screenHeight); - #if defined(RL_LOAD_DEFAULT_FONT) + #if defined(LOAD_DEFAULT_FONT) // Load default font // NOTE: External function (defined in module: text) LoadDefaultFont(); diff --git a/src/gestures.h b/src/gestures.h index f4dcb133..99f49d2a 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -2,6 +2,10 @@ * * raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) * +* NOTE: Memory footprint of this library is aproximately 128 bytes (global variables) +* +* CONFIGURATION: +* * #define GESTURES_IMPLEMENTATION * Generates the implementation of the library into the included file. * If not defined, the library is in header only mode and can be included in other headers @@ -11,11 +15,16 @@ * If defined, the library can be used as standalone to process gesture events with * no external dependencies. * -* NOTE: Memory footprint of this library is aproximately 128 bytes +* CONTRIBUTORS: +* Marc Palau: Initial implementation (2014) +* Albert Martos: Complete redesign and testing (2015) +* Ian Eito: Complete redesign and testing (2015) +* Ramon Santamaria: Supervision, review, update and maintenance +* +* +* LICENSE: zlib/libpng * -* Initial design by Marc Palau (2014) -* Redesigned by Albert Martos and Ian Eito (2015) -* Reviewed by Ramon Santamaria (2015-2016) +* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/models.c b/src/models.c index 43821691..bef19e10 100644 --- a/src/models.c +++ b/src/models.c @@ -1,14 +1,15 @@ /********************************************************************************************** * -* raylib.models +* raylib.models - Basic functions to draw 3d shapes and 3d models * -* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ) +* CONFIGURATION: * -* External libs: -* rlgl - raylib OpenGL abstraction layer +* #define SUPPORT_FILEFORMAT_OBJ / SUPPORT_LOAD_OBJ * -* Module Configuration Flags: -* ... +* #define SUPPORT_FILEFORMAT_MTL +* +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * diff --git a/src/physac.h b/src/physac.h index d958c701..cb0e3f3c 100644 --- a/src/physac.h +++ b/src/physac.h @@ -1,11 +1,13 @@ /********************************************************************************************** * -* Physac - 2D Physics library for videogames +* Physac v1.0 - 2D Physics library for videogames * -* Description: Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop -* to simluate physics. A physics step contains the following phases: get collision information, apply dynamics, -* collision solving and position correction. It uses a very simple struct for physic bodies with a position vector -* to be used in any 3D rendering API. +* DESCRIPTION: +* +* Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop +* to simluate physics. A physics step contains the following phases: get collision information, +* apply dynamics, collision solving and position correction. It uses a very simple struct for physic +* bodies with a position vector to be used in any 3D rendering API. * * CONFIGURATION: * @@ -37,7 +39,8 @@ * Otherwise it will include stdlib.h and use the C standard library malloc()/free() function. * * VERY THANKS TO: -* - Ramón Santamaria (@raysan5) +* Ramón Santamaria (@raysan5) +* * * LICENSE: zlib/libpng * diff --git a/src/raylib.h b/src/raylib.h index 800ab2be..3ff0d28f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1,10 +1,10 @@ /********************************************************************************************** * -* raylib 1.7.0 (www.raylib.com) +* raylib v1.7.0 (www.raylib.com) * * A simple and easy-to-use library to learn videogames programming * -* Features: +* FEATURES: * Library written in plain C code (C99) * Uses PascalCase/camelCase notation * Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0) @@ -20,7 +20,13 @@ * Minimal external dependencies (GLFW3, OpenGL, OpenAL) * Complete binding for Lua [rlua] * -* External libs: +* NOTES: +* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte) +* One custom default font could be loaded automatically when InitWindow() [core] +* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads +* If using OpenGL 3.3 or ES2, two default shaders could be loaded automatically (internally defined) +* +* DEPENDENCIES: * GLFW3 (www.glfw.org) for window/context management and input [core] * GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl] * stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures] @@ -33,13 +39,8 @@ * OpenAL Soft for audio device/context management [audio] * tinfl for data decompression (DEFLATE algorithm) [utils] * -* Some design decisions: -* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte) -* One custom default font could be loaded automatically when InitWindow() [core] -* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads -* If using OpenGL 3.3 or ES2, two default shaders could be loaded automatically (internally defined) * -* -- LICENSE -- +* LICENSE: zlib/libpng * * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software: @@ -592,8 +593,9 @@ typedef enum { HMD_FOVE_VR, } VrDevice; -// rRES data returned when reading a resource, it contains all required data for user (24 byte) -typedef struct { +// rRES data returned when reading a resource, +// it contains all required data for user (24 byte) +typedef struct RRESData { unsigned int type; // Resource type (4 byte) unsigned int param1; // Resouce parameter 1 (4 byte) @@ -604,14 +606,21 @@ typedef struct { void *data; // Resource data pointer (4 byte) } RRESData; -typedef enum { - RRES_RAW = 0, - RRES_IMAGE, - RRES_WAVE, - RRES_VERTEX, - RRES_TEXT +// RRESData type +typedef enum { + RRES_TYPE_RAW = 0, + RRES_TYPE_IMAGE, + RRES_TYPE_WAVE, + RRES_TYPE_VERTEX, + RRES_TYPE_TEXT, + RRES_TYPE_FONT_IMAGE, + RRES_TYPE_FONT_CHARDATA, // CharInfo data array + RRES_TYPE_DIRECTORY } RRESDataType; +// RRES type (pointer to RRESData array) +typedef struct RRESData *RRES; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -758,6 +767,7 @@ RLAPI void DrawCircleV(Vector2 center, float radius, Color color); RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters RLAPI void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline diff --git a/src/raymath.h b/src/raymath.h index c073b72d..a2263f19 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1,22 +1,23 @@ /********************************************************************************************** * -* raymath (header only file) +* raymath v1.0 - Some useful functions to work with Vector3, Matrix and Quaternions * -* Some useful functions to work with Vector3, Matrix and Quaternions +* CONFIGURATION: * -* You must: -* #define RAYMATH_IMPLEMENTATION -* before you include this file in *only one* C or C++ file to create the implementation. +* #define RAYMATH_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. * -* Example: -* #define RAYMATH_IMPLEMENTATION -* #include "raymath.h" +* #define RAYMATH_EXTERN_INLINE +* Inlines all functions code, so it runs faster. This requires lots of memory on system. +* +* #define RAYMATH_STANDALONE +* Avoid raylib.h header inclusion in this file. +* Vector3 and Matrix data types are defined internally in raymath module. * -* You can also use: -* #define RAYMATH_EXTERN_INLINE // Inlines all functions code, so it runs faster. -* // This requires lots of memory on system. -* #define RAYMATH_STANDALONE // Not dependent on raylib.h structs: Vector3, Matrix. * +* LICENSE: zlib/libpng * * Copyright (c) 2015 Ramon Santamaria (@raysan5) * diff --git a/src/rlgl.c b/src/rlgl.c index ce17adc3..ffc9d741 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2,6 +2,8 @@ * * rlgl - raylib OpenGL abstraction layer * +* DESCRIPTION: +* * rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to * selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0). * @@ -11,20 +13,44 @@ * rlglDraw() - Process internal buffers and send required draw calls * rlglClose() - De-initialize internal buffers data and other auxiliar resources * -* External libs: +* CONFIGURATION: +* +* #define GRAPHICS_API_OPENGL_11 +* Use OpenGL 1.1 backend +* +* #define GRAPHICS_API_OPENGL_21 +* Use OpenGL 2.1 backend +* +* #define GRAPHICS_API_OPENGL_33 +* Use OpenGL 3.3 Core profile backend +* +* #define GRAPHICS_API_OPENGL_ES2 +* Use OpenGL ES 2.0 backend +* +* #define RLGL_STANDALONE +* Use rlgl as standalone library (no raylib dependency) +* +* #define RLGL_NO_DISTORTION_SHADER +* Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion +* +* #define SUPPORT_SHADER_DEFAULT / ENABLE_SHADER_DEFAULT +* +* #define SUPPORT_SHADER_DISTORTION +* +* +* #define SUPPORT_OCULUS_RIFT_CV1 / RLGL_OCULUS_SUPPORT +* Enable Oculus Rift CV1 functionality +* +* #define SUPPORT_STEREO_RENDERING +* +* #define RLGL_NO_DEFAULT_SHADER +* +* DEPENDENCIES: * raymath - 3D math functionality (Vector3, Matrix, Quaternion) * GLAD - OpenGL extensions loading (OpenGL 3.3 Core only) * -* Module Configuration Flags: -* GRAPHICS_API_OPENGL_11 - Use OpenGL 1.1 backend -* GRAPHICS_API_OPENGL_21 - Use OpenGL 2.1 backend -* GRAPHICS_API_OPENGL_33 - Use OpenGL 3.3 Core profile backend -* GRAPHICS_API_OPENGL_ES2 - Use OpenGL ES 2.0 backend -* -* RLGL_STANDALONE - Use rlgl as standalone library (no raylib dependency) -* RLGL_NO_DISTORTION_SHADER - Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion -* RLGL_OCULUS_SUPPORT - Enable Oculus Rift CV1 functionality * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * diff --git a/src/rres.h b/src/rres.h index bed28723..362da10d 100644 --- a/src/rres.h +++ b/src/rres.h @@ -4,14 +4,18 @@ * * Basic functions to load/save rRES resource files * -* External libs: -* tinfl - DEFLATE decompression functions +* CONFIGURATION: +* +* #define RREM_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. * -* Module Configuration Flags: +* DEPENDENCIES: +* tinfl - DEFLATE decompression functions * -* #define RREM_IMPLEMENTATION -* Generates the implementation of the library into the included file. * +* LICENSE: zlib/libpng * * Copyright (c) 2016-2017 Ramon Santamaria (@raysan5) * @@ -81,7 +85,7 @@ RRES_TYPE_VERTEX, RRES_TYPE_TEXT, RRES_TYPE_FONT_IMAGE, - RRES_TYPE_FONT_DATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } + RRES_TYPE_FONT_CHARDATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } RRES_TYPE_DIRECTORY } RRESDataType; @@ -243,7 +247,7 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i // NOTE: Returns uncompressed data with parameters, search resource by id RRESDEF RRES LoadResource(const char *fileName, int rresId) { - RRES rres; + RRES rres = { 0 }; RRESFileHeader fileHeader; RRESInfoHeader infoHeader; diff --git a/src/shapes.c b/src/shapes.c index 83b80182..a42b0551 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -1,17 +1,14 @@ /********************************************************************************************** * -* raylib.shapes -* -* Basic functions to draw 2d Shapes and check collisions -* -* DEPENDENCIES: -* rlgl - raylib OpenGL abstraction layer +* raylib.shapes - Basic functions to draw 2d Shapes and check collisions * * CONFIGURATION: * * #define SUPPORT_QUADS_ONLY +* Draw shapes using only QUADS, vertex are accumulated in QUADS arrays (like textures) * - #define SUPPORT_TRIANGLES_ONLY +* #define SUPPORT_TRIANGLES_ONLY +* Draw shapes using only TRIANGLES, vertex are accumulated in TRIANGLES arrays * * * LICENSE: zlib/libpng diff --git a/src/text.c b/src/text.c index 4deae25c..6f18b391 100644 --- a/src/text.c +++ b/src/text.c @@ -1,14 +1,22 @@ /********************************************************************************************** * -* raylib.text +* raylib.text - Basic functions to load SpriteFonts and draw Text * -* Basic functions to load SpriteFonts and draw Text +* CONFIGURATION: * -* External libs: +* #define SUPPORT_FILEFORMAT_FNT +* #define SUPPORT_FILEFORMAT_TTF / INCLUDE_STB_TRUETYPE +* #define SUPPORT_FILEFORMAT_IMAGE_FONT +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define INCLUDE_DEFAULT_FONT / SUPPORT_DEFAULT_FONT +* +* DEPENDENCIES: * stb_truetype - Load TTF file and rasterize characters data * -* Module Configuration Flags: -* ... +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -262,30 +270,28 @@ SpriteFont LoadSpriteFont(const char *fileName) else if (strcmp(GetExtension(fileName),"rres") == 0) { // TODO: Read multiple resource blocks from file (RRES_FONT_IMAGE, RRES_FONT_CHARDATA) - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); // Load sprite font texture - /* - if (rres.type == RRES_FONT_IMAGE) + if (rres[0].type == RRES_TYPE_FONT_IMAGE) { // NOTE: Parameters for RRES_FONT_IMAGE type are: width, height, format, mipmaps - Image image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + Image image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3); spriteFont.texture = LoadTextureFromImage(image); UnloadImage(image); } // Load sprite characters data - if (rres.type == RRES_FONT_CHARDATA) + if (rres[1].type == RRES_TYPE_FONT_CHARDATA) { // NOTE: Parameters for RRES_FONT_CHARDATA type are: fontSize, charsCount - spriteFont.baseSize = rres.param1; - spriteFont.charsCount = rres.param2; - spriteFont.chars = rres.data; + spriteFont.baseSize = rres[1].param1; + spriteFont.charsCount = rres[1].param2; + spriteFont.chars = rres[1].data; } - */ // TODO: Do not free rres.data memory (chars info data!) - UnloadResource(rres); + //UnloadResource(rres[0]); } else { diff --git a/src/textures.c b/src/textures.c index 5b2e4775..7db3bf56 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1,16 +1,35 @@ /********************************************************************************************** * -* raylib.textures +* raylib.textures - Basic functions to load and draw Textures (2d) * -* Basic functions to load and draw Textures (2d) +* CONFIGURATION: * -* External libs: +* #define SUPPORT_STB_IMAGE / INCLUDE_STB_IMAGE +* +* #define SUPPORT_FILEFORMAT_BMP / SUPPORT_LOAD_BMP +* #define SUPPORT_FILEFORMAT_PNG / SUPPORT_LOAD_PNG +* #define SUPPORT_FILEFORMAT_TGA +* #define SUPPORT_FILEFORMAT_JPG / ENABLE_LOAD_JPG +* #define SUPPORT_FILEFORMAT_GIF +* #define SUPPORT_FILEFORMAT_HDR +* #define SUPPORT_FILEFORMAT_DDS / ENABLE_LOAD_DDS +* #define SUPPORT_FILEFORMAT_PKM +* #define SUPPORT_FILEFORMAT_KTX +* #define SUPPORT_FILEFORMAT_PVR +* #define SUPPORT_FILEFORMAT_ASTC +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define SUPPORT_IMAGE_RESIZE / INCLUDE_STB_IMAGE_RESIZE +* #define SUPPORT_IMAGE_MANIPULATION +* +* DEPENDENCIES: * stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC) * NOTE: stb_image has been slightly modified to support Android platform. * stb_image_resize - Multiple image resize algorythms * -* Module Configuration Flags: -* ... +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -143,11 +162,11 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); else if (strcmp(GetExtension(fileName),"rres") == 0) { - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); - // NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps + // NOTE: Parameters for RRES_TYPE_IMAGE are: width, height, format, mipmaps - if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + if (rres[0].type == RRES_TYPE_IMAGE) image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3); else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName); UnloadResource(rres); diff --git a/src/utils.c b/src/utils.c index e5e05955..9a2a723a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,16 +1,23 @@ /********************************************************************************************** * -* raylib.utils +* raylib.utils - Some common utility functions * -* Some utility functions +* CONFIGURATION: * -* External libs: -* tinfl - zlib DEFLATE algorithm decompression +* #define SUPPORT_SAVE_PNG +* Enable saving PNG fileformat +* NOTE: Requires stb_image_write library +* +* #define SUPPORT_SAVE_BMP +* +* #define DO_NOT_TRACE_DEBUG_MSGS +* Avoid showing DEBUG TraceLog() messages +* +* DEPENDENCIES: * stb_image_write - PNG writting functions * -* Module Configuration Flags: -* DO_NOT_TRACE_DEBUG_MSGS - Avoid showing DEBUG TraceLog() messages * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * -- cgit v1.2.3 From de103ecc5e4890c3a830245c9ca3283ed2d739dd Mon Sep 17 00:00:00 2001 From: bugcaptor Date: Thu, 2 Mar 2017 10:07:09 +0900 Subject: fix for audio.c(607): error C2036: 'void *': unknown size in Visual Studio 2015. --- src/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 690a41eb..128781a4 100644 --- a/src/audio.c +++ b/src/audio.c @@ -604,7 +604,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample) void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8); - memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8); + memcpy(data, (unsigned char*)wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8); free(wave->data); wave->data = data; -- cgit v1.2.3 From 9cfaa81a7e7741f03db1f9579aa0b49bee42cdd7 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Mar 2017 10:55:29 +0100 Subject: Added some flags and functions to manage window - SetWindowPosition(int x, int y); - SetWindowMonitor(int monitor); --- src/core.c | 46 +++++++++++++++++++++++++++++++++++----------- src/raylib.h | 17 ++++++++++------- 2 files changed, 45 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 9d40edcc..6ea54862 100644 --- a/src/core.c +++ b/src/core.c @@ -578,6 +578,26 @@ void SetWindowIcon(Image image) #endif } +// Set window position on screen (windowed mode) +void SetWindowPosition(int x, int y) +{ + glfwSetWindowPos(window, x, y); +} + +// Set monitor for the current window (fullscreen mode) +void SetWindowMonitor(int monitor) +{ + int monitorCount; + GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); + + if ((monitor >= 0) && (monitor < monitorCount)) + { + glfwSetWindowMonitor(window, monitors[monitor], 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE); + TraceLog(INFO, "Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor])); + } + else TraceLog(WARNING, "Selected monitor not found"); +} + // Get current screen width int GetScreenWidth(void) { @@ -1536,13 +1556,23 @@ static void InitGraphicsDevice(int width, int height) glfwDefaultWindowHints(); // Set default windows hints - if (configFlags & FLAG_RESIZABLE_WINDOW) + // Check some Window creation flags + if (configFlags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window + else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable + + if (configFlags & FLAG_WINDOW_DECORATED) glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window + + if (configFlags & FLAG_WINDOW_TRANSPARENT) { - glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window + // TODO: Enable transparent window (not ready yet on GLFW 3.2) } - else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable - //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window + if (configFlags & FLAG_MSAA_4X_HINT) + { + glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 + TraceLog(INFO, "Trying to enable MSAA x4"); + } + //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window @@ -1551,13 +1581,7 @@ static void InitGraphicsDevice(int width, int height) // NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // with forward compatibility to older OpenGL versions. - // For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible. - - if (configFlags & FLAG_MSAA_4X_HINT) - { - glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 - TraceLog(INFO, "Trying to enable MSAA x4"); - } + // For example, if using OpenGL 1.1, driver can provide a 4.3 context forward compatible. // Check selection OpenGL version if (rlGetVersion() == OPENGL_21) diff --git a/src/raylib.h b/src/raylib.h index 3ff0d28f..ab7d7027 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -98,13 +98,14 @@ #define RAD2DEG (180.0f/PI) // raylib Config Flags -#define FLAG_FULLSCREEN_MODE 1 -#define FLAG_RESIZABLE_WINDOW 2 -#define FLAG_SHOW_LOGO 4 -#define FLAG_SHOW_MOUSE_CURSOR 8 -#define FLAG_CENTERED_MODE 16 -#define FLAG_MSAA_4X_HINT 32 -#define FLAG_VSYNC_HINT 64 +#define FLAG_SHOW_LOGO 1 +#define FLAG_SHOW_MOUSE_CURSOR 2 +#define FLAG_FULLSCREEN_MODE 4 +#define FLAG_WINDOW_RESIZABLE 8 +#define FLAG_WINDOW_DECORATED 16 +#define FLAG_WINDOW_TRANSPARENT 32 +#define FLAG_MSAA_4X_HINT 64 +#define FLAG_VSYNC_HINT 128 // Keyboard Function Keys #define KEY_SPACE 32 @@ -644,6 +645,8 @@ RLAPI bool WindowShouldClose(void); // Detect if K RLAPI bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus) RLAPI void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP) RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP) +RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) +RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode) RLAPI int GetScreenWidth(void); // Get current screen width RLAPI int GetScreenHeight(void); // Get current screen height -- cgit v1.2.3 From 203d1a154eb5b78fc5f56e9dead04c3a89bcd39e Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Mar 2017 10:55:58 +0100 Subject: Clear music buffers on stop --- src/audio.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 128781a4..659ead0f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -762,7 +762,18 @@ void ResumeMusicStream(Music music) void StopMusicStream(Music music) { alSourceStop(music->stream.source); + + // Clear stream buffers + void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, 1); + for (int i = 0; i < MAX_STREAM_BUFFERS; i++) + { + alBufferData(music->stream.buffers[i], music->stream.format, pcm, AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, music->stream.sampleRate); + } + + free(pcm); + + // Restart music context switch (music->ctxType) { case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break; -- cgit v1.2.3 From d1c9afd1d8ae4ae3e075b117fff7a5a77f3c4d60 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Mar 2017 19:17:00 +0100 Subject: Work on timming functions... It seems Sleep() behaves weird on my computer, disabled by default returning to the busy wait loop... also re-implemented DrawFPS() to avoid frame blitting... --- src/core.c | 63 +++++++++++++++++++++++++++++++++--------------------------- src/raylib.h | 19 +++++++++--------- src/text.c | 16 ++++++++++++++- 3 files changed, 59 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index 6ea54862..a3b5f486 100644 --- a/src/core.c +++ b/src/core.c @@ -88,6 +88,8 @@ #if defined __linux || defined(PLATFORM_WEB) #include // Required for: timespec, nanosleep(), select() - POSIX +#elif defined __APPLE__ + #include // Required for: usleep() #endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) @@ -287,7 +289,7 @@ static void InitGraphicsDevice(int width, int height); // Initialize graphics d static void SetupFramebufferSize(int displayWidth, int displayHeight); static void InitTimer(void); // Initialize timer static double GetTime(void); // Returns time since InitTimer() was run -static void Wait(int ms); // Wait for some milliseconds (stop program execution) +static void Wait(float ms); // Wait for some milliseconds (stop program execution) static bool GetKeyStatus(int key); // Returns if a key has been pressed static bool GetMouseButtonStatus(int button); // Returns if a mouse button has been pressed static void PollInputEvents(void); // Register user events @@ -339,7 +341,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread #if defined(_WIN32) // NOTE: We include Sleep() function signature here to avoid windows.h inclusion - void __stdcall Sleep(unsigned long msTimeout); // Required for Delay() + void __stdcall Sleep(unsigned long msTimeout); // Required for Wait() #endif //---------------------------------------------------------------------------------- @@ -703,19 +705,19 @@ void EndDrawing(void) currentTime = GetTime(); drawTime = currentTime - previousTime; previousTime = currentTime; - + frameTime = updateTime + drawTime; // Wait for some milliseconds... if (frameTime < targetTime) { - Wait((int)((targetTime - frameTime)*1000)); + Wait((targetTime - frameTime)*1000.0f); currentTime = GetTime(); double extraTime = currentTime - previousTime; previousTime = currentTime; - frameTime = updateTime + drawTime + extraTime; + frameTime += extraTime; } } @@ -851,14 +853,14 @@ void SetTargetFPS(int fps) // Returns current FPS int GetFPS(void) { - return (int)floorf(1.0f/GetFrameTime()); + return (int)(1.0f/GetFrameTime()); } // Returns time in seconds for one frame float GetFrameTime(void) { // NOTE: We round value to milliseconds - return (roundf(frameTime*1000.0)/1000.0f); + return (float)frameTime; } // Converts Color to float array and normalizes @@ -1688,7 +1690,10 @@ static void InitGraphicsDevice(int width, int height) #endif glfwMakeContextCurrent(window); - glfwSwapInterval(0); // Disable VSync by default + + // Try to disable GPU V-Sync by default, set framerate using SetTargetFPS() + // NOTE: V-Sync can be enabled by graphic driver configuration + glfwSwapInterval(0); #if defined(PLATFORM_DESKTOP) // Load OpenGL 3.3 extensions @@ -1696,9 +1701,8 @@ static void InitGraphicsDevice(int width, int height) rlglLoadExtensions(glfwGetProcAddress); #endif - // Enables GPU v-sync, so frames are not limited to screen refresh rate (60Hz -> 60 FPS) - // If not set, swap interval uses GPU v-sync configuration - // Framerate can be setup using SetTargetFPS() + // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) + // NOTE: V-Sync can be enabled by graphic driver configuration if (configFlags & FLAG_VSYNC_HINT) { glfwSwapInterval(1); @@ -2001,27 +2005,30 @@ static double GetTime(void) } // Wait for some milliseconds (stop program execution) -static void Wait(int ms) -{ -#if defined _WIN32 - Sleep(ms); -#elif defined __linux || defined(PLATFORM_WEB) - struct timespec req = { 0 }; - time_t sec = (int)(ms/1000); - ms -= (sec*1000); - req.tv_sec=sec; - req.tv_nsec=ms*1000000L; - - // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. - while (nanosleep(&req,&req) == -1) continue; -//#elif defined __APPLE__ - // TODO: -#else +static void Wait(float ms) +{ +#define SUPPORT_BUSY_WAIT_LOOP +#if defined(SUPPORT_BUSY_WAIT_LOOP) double prevTime = GetTime(); double nextTime = 0.0; // Busy wait loop - while ((nextTime - prevTime) < (double)ms/1000.0) nextTime = GetTime(); + while ((nextTime - prevTime) < ms/1000.0f) nextTime = GetTime(); +#else + #if defined _WIN32 + Sleep(ms); + #elif defined __linux || defined(PLATFORM_WEB) + struct timespec req = { 0 }; + time_t sec = (int)(ms/1000.0f); + ms -= (sec*1000); + req.tv_sec = sec; + req.tv_nsec = ms*1000000L; + + // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. + while (nanosleep(&req, &req) == -1) continue; + #elif defined __APPLE__ + usleep(ms*1000.0f); + #endif #endif } diff --git a/src/raylib.h b/src/raylib.h index ab7d7027..beda833c 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -98,14 +98,13 @@ #define RAD2DEG (180.0f/PI) // raylib Config Flags -#define FLAG_SHOW_LOGO 1 -#define FLAG_SHOW_MOUSE_CURSOR 2 -#define FLAG_FULLSCREEN_MODE 4 -#define FLAG_WINDOW_RESIZABLE 8 -#define FLAG_WINDOW_DECORATED 16 -#define FLAG_WINDOW_TRANSPARENT 32 -#define FLAG_MSAA_4X_HINT 64 -#define FLAG_VSYNC_HINT 128 +#define FLAG_SHOW_LOGO 1 // Set this flag to show raylib logo at startup +#define FLAG_FULLSCREEN_MODE 2 // Set this flag to run program in fullscreen +#define FLAG_WINDOW_RESIZABLE 4 // Set this flag to allow resizable window +#define FLAG_WINDOW_DECORATED 8 // Set this flag to show window decoration (frame and buttons) +#define FLAG_WINDOW_TRANSPARENT 16 // Set this flag to allow transparent window +#define FLAG_MSAA_4X_HINT 32 // Set this flag to try enabling MSAA 4X +#define FLAG_VSYNC_HINT 64 // Set this flag to try enabling V-Sync on GPU // Keyboard Function Keys #define KEY_SPACE 32 @@ -674,8 +673,8 @@ RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) -RLAPI int GetFPS(void); // Returns current FPS (rounded value) -RLAPI float GetFrameTime(void); // Returns time in seconds for one frame (rounded value) +RLAPI int GetFPS(void); // Returns current FPS +RLAPI float GetFrameTime(void); // Returns time in seconds for one frame RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color diff --git a/src/text.c b/src/text.c index 6f18b391..18ebf482 100644 --- a/src/text.c +++ b/src/text.c @@ -531,8 +531,22 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i // NOTE: Uses default font void DrawFPS(int posX, int posY) { + // NOTE: We are rendering fps every second for better viewing on high framerates + + static int fps = 0; + static int counter = 0; + static int refreshRate = 20; + + if (counter < refreshRate) counter++; + else + { + fps = GetFPS(); + refreshRate = fps; + counter = 0; + } + // NOTE: We have rounding errors every frame, so it oscillates a lot - DrawText(FormatText("%2i FPS", GetFPS()), posX, posY, 20, LIME); + DrawText(FormatText("%2i FPS", fps), posX, posY, 20, LIME); } //---------------------------------------------------------------------------------- -- cgit v1.2.3 From 59038bae96bf8e9ae96ce3432ddbde96590f4642 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Mar 2017 21:04:07 +0100 Subject: Added function: DrawLineEx() Supports line thickness --- examples/core_basic_window.c | 22 +++++++++++++++++++++- src/raylib.h | 15 ++++++++------- src/shapes.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/examples/core_basic_window.c b/examples/core_basic_window.c index fb83400a..888f3460 100644 --- a/examples/core_basic_window.c +++ b/examples/core_basic_window.c @@ -39,6 +39,11 @@ int main() // Update //---------------------------------------------------------------------------------- // TODO: Update your variables here + float dx = 600 - 100; + float dy = 105 - 405; + + float d = sqrtf(dx*dx + dy*dy); + float angle = asinf(dy/d); //---------------------------------------------------------------------------------- // Draw @@ -47,7 +52,22 @@ int main() ClearBackground(RAYWHITE); - DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + //DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + + DrawRectangle(100, 400, 1, 10, BLACK); + DrawRectangle(96, 404, 10, 1, BLACK); + + DrawRectangle(600, 100, 1, 10, BLACK); + DrawRectangle(596, 104, 10, 1, BLACK); + + DrawLine(100, 405, 600, 105, RED); + + // Draw lines using textures + /* + DrawTexturePro(GetDefaultTexture(), (Rectangle){ 0, 0, GetDefaultTexture().width, GetDefaultTexture().height }, + (Rectangle){ 100, 405, (float)GetDefaultTexture().width*d, 1 }, + (Vector2){ 0, (float)GetDefaultTexture().height/2 }, -RAD2DEG*angle, BLUE); + */ EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index beda833c..b0f03bbe 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -98,13 +98,13 @@ #define RAD2DEG (180.0f/PI) // raylib Config Flags -#define FLAG_SHOW_LOGO 1 // Set this flag to show raylib logo at startup -#define FLAG_FULLSCREEN_MODE 2 // Set this flag to run program in fullscreen -#define FLAG_WINDOW_RESIZABLE 4 // Set this flag to allow resizable window -#define FLAG_WINDOW_DECORATED 8 // Set this flag to show window decoration (frame and buttons) -#define FLAG_WINDOW_TRANSPARENT 16 // Set this flag to allow transparent window -#define FLAG_MSAA_4X_HINT 32 // Set this flag to try enabling MSAA 4X -#define FLAG_VSYNC_HINT 64 // Set this flag to try enabling V-Sync on GPU +#define FLAG_SHOW_LOGO 1 // Set to show raylib logo at startup +#define FLAG_FULLSCREEN_MODE 2 // Set to run program in fullscreen +#define FLAG_WINDOW_RESIZABLE 4 // Set to allow resizable window +#define FLAG_WINDOW_DECORATED 8 // Set to show window decoration (frame and buttons) +#define FLAG_WINDOW_TRANSPARENT 16 // Set to allow transparent window +#define FLAG_MSAA_4X_HINT 32 // Set to try enabling MSAA 4X +#define FLAG_VSYNC_HINT 64 // Set to try enabling V-Sync on GPU // Keyboard Function Keys #define KEY_SPACE 32 @@ -763,6 +763,7 @@ RLAPI void DrawPixel(int posX, int posY, Color color); RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) +RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) diff --git a/src/shapes.c b/src/shapes.c index a42b0551..9cbe1da4 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -103,6 +103,36 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color) rlEnd(); } +// Draw a line defining thickness +void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color) +{ + float dx = endPos.x - startPos.x; + float dy = endPos.y - startPos.y; + + float d = sqrtf(dx*dx + dy*dy); + float angle = asinf(dy/d); + + rlEnableTexture(GetDefaultTexture().id); + + rlPushMatrix(); + rlTranslatef((float)startPos.x, (float)startPos.y, 0); + rlRotatef(-RAD2DEG*angle, 0, 0, 1); + rlTranslatef(0, -thick/2.0f, 0); + + rlBegin(RL_QUADS); + rlColor4ub(color.r, color.g, color.b, color.a); + rlNormal3f(0.0f, 0.0f, 1.0f); + + rlVertex2f(0.0f, 0.0f); + rlVertex2f(0.0f, thick); + rlVertex2f(d, thick); + rlVertex2f(d, 0.0f); + rlEnd(); + rlPopMatrix(); + + rlDisableTexture(); +} + // Draw a color-filled circle void DrawCircle(int centerX, int centerY, float radius, Color color) { -- cgit v1.2.3