From d74a505d406faf276a265beaf8925d6e8ff9cec0 Mon Sep 17 00:00:00 2001 From: jussi Date: Fri, 3 Nov 2023 23:12:55 +0200 Subject: Compress/decompress and Encode/Decode DataBase64. --- API.md | 122 +++++++++-- CMakeLists.txt | 12 +- ReiLua_API.lua | 135 ++++++++---- changelog | 5 +- devnotes | 4 +- docgen.lua | 2 + examples/compress_data/main.lua | 43 ++++ examples/heightmap/main.lua | 16 +- examples/resources/lib/gui.lua | 8 + examples/resources/lib/utillib.lua | 7 + include/core.h | 16 +- include/lua_core.h | 7 +- include/models.h | 1 + src/core.c | 435 ++++++++++++++++++++++++++++++------- src/lua_core.c | 27 ++- src/models.c | 8 +- 16 files changed, 676 insertions(+), 172 deletions(-) create mode 100644 examples/compress_data/main.lua diff --git a/API.md b/API.md index 8d22ee1..a057dde 100644 --- a/API.md +++ b/API.md @@ -3391,28 +3391,52 @@ The key was held down until it repeated ## Globals - CBuffer > BUFFER_UNSIGNED_CHAR = 0 -C type char +C type unsigned char --- > BUFFER_UNSIGNED_SHORT = 1 -C type short +C type unsigned short --- > BUFFER_UNSIGNED_INT = 2 +C type unsigned int + +--- + +> BUFFER_CHAR = 3 + +C type char + +--- + +> BUFFER_SHORT = 4 + +C type short + +--- + +> BUFFER_INT = 5 + C type int --- -> BUFFER_FLOAT = 3 +> BUFFER_FLOAT = 6 C type float --- +> BUFFER_DOUBLE = 7 + +C type double + +--- + ## Globals - Window > EVENT_WINDOW_SIZE = 0 @@ -3804,20 +3828,6 @@ Open URL with default system browser (If available) --- -> buffer = RL.LoadBuffer( data{} buffer, int type ) - -Load Buffer. Type should be one of the Buffer types - -- Success return Buffer - ---- - -> RL.UnloadBuffer( Buffer buffer ) - -Unload buffer data - ---- - > enabled = RL.IsGCUnloadEnabled() Check if Lua garbage collection is set to unload object data @@ -4494,6 +4504,42 @@ Get file modification time (Last write time) --- +## Core - Compression/Encoding functionality + +--- + +> compData = RL.CompressData( string data ) + +Compress data (DEFLATE algorithm) + +- Success return Buffer + +--- + +> data, dataSize = RL.DecompressData( Buffer compData ) + +Decompress data (DEFLATE algorithm). + +- Success return string, int + +--- + +> encodedData, outputSize = RL.EncodeDataBase64( string data ) + +Encode data to Base64 string + +- Success return string, int + +--- + +> decodedData, outputSize = RL.DecodeDataBase64( string data ) + +Decode Base64 string data + +- Success return string, int + +--- + ## Core - Camera2D --- @@ -4832,6 +4878,48 @@ Get the world space position for a 2d camera screen space position --- +## Core - Buffer + +--- + +> buffer = RL.LoadBuffer( data{} buffer, int type ) + +Load Buffer. Type should be one of the Buffer types + +- Success return Buffer + +--- + +> RL.UnloadBuffer( Buffer buffer ) + +Unload buffer data + +--- + +> data = RL.GetBufferData( Buffer buffer ) + +Get buffer data as table in the format is was stored + +- Success return data{} + +--- + +> type = RL.GetBufferType( Buffer buffer ) + +Get buffer type + +- Success return int + +--- + +> size = RL.GetBufferSize( Buffer buffer ) + +Get buffer size + +- Success return int + +--- + ## Shapes - Drawing --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0827e0b..7194d02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,10 +10,9 @@ option( SHARED "Build using dynamic libraries." off ) option( LUAJIT "Use LuaJIT." off ) option( GC_UNLOAD "Lua garbage collector unloads objects. If off, object unloading should be handled manually." on ) -if( NOT CMAKE_BUILD_TYPE ) - SET( CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." - FORCE ) +if( NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES ) + set( CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE ) + set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" ) endif() if( GC_UNLOAD ) @@ -38,7 +37,7 @@ else() # Desktop if( SHARED ) message( Shared ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSHARED" ) - find_package( raylib 4.5 REQUIRED ) # Requires at least version 4.5 + # find_package( raylib 4.5 REQUIRED ) # Requires at least version 4.5 target_link_libraries( ${PROJECT_NAME} raylib ) if( LUAJIT ) @@ -54,7 +53,8 @@ else() # Desktop set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLUAJIT" ) target_link_libraries( ${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/lib/libluajit.a ) else() - target_link_libraries( ${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/lib/liblua.a ) + # target_link_libraries( ${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/lib/liblua.a ) + target_link_libraries( ${PROJECT_NAME} lua ) endif() endif() diff --git a/ReiLua_API.lua b/ReiLua_API.lua index 269a8a7..1341931 100644 --- a/ReiLua_API.lua +++ b/ReiLua_API.lua @@ -1164,14 +1164,22 @@ RL.GLFW_REPEAT=2 -- Globals - CBuffer ----C type char +---C type unsigned char RL.BUFFER_UNSIGNED_CHAR=0 ----C type short +---C type unsigned short RL.BUFFER_UNSIGNED_SHORT=1 ----C type int +---C type unsigned int RL.BUFFER_UNSIGNED_INT=2 +---C type char +RL.BUFFER_CHAR=3 +---C type short +RL.BUFFER_SHORT=4 +---C type int +RL.BUFFER_INT=5 ---C type float -RL.BUFFER_FLOAT=3 +RL.BUFFER_FLOAT=6 +---C type double +RL.BUFFER_DOUBLE=7 -- Globals - Window @@ -1312,7 +1320,7 @@ function RL.IsWindowResized() end function RL.SetWindowIcon( image ) end ---Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) ----@param images any +---@param images table ---@return any RL.SetWindowIcons function RL.SetWindowIcons( images ) end @@ -1428,18 +1436,6 @@ function RL.GetLogLevelInvalid() end ---@return any RL.OpenURL function RL.OpenURL( url ) end ----Load Buffer. Type should be one of the Buffer types ----- Success return Buffer ----@param buffer any ----@param type integer ----@return any buffer -function RL.LoadBuffer( buffer, type ) end - ----Unload buffer data ----@param buffer any ----@return any RL.UnloadBuffer -function RL.UnloadBuffer( buffer ) end - ---Check if Lua garbage collection is set to unload object data ---- Success return bool ---@return any enabled @@ -1587,7 +1583,7 @@ function RL.SetShaderValueTexture( shader, locIndex, texture ) end ---NOTE: Even one value should be in table ---@param shader any ---@param locIndex integer ----@param values any +---@param values table ---@param uniformType integer ---@return any RL.SetShaderValue function RL.SetShaderValue( shader, locIndex, values, uniformType ) end @@ -1596,7 +1592,7 @@ function RL.SetShaderValue( shader, locIndex, values, uniformType ) end ---NOTE: Even one value should be in table ---@param shader any ---@param locIndex integer ----@param values any +---@param values table ---@param uniformType integer ---@param count integer ---@return any RL.SetShaderValueV @@ -1951,6 +1947,35 @@ function RL.LoadDroppedFiles() end ---@return any time function RL.GetFileModTime( fileName ) end +-- Core - Compression/Encoding functionality + +---Compress data (DEFLATE algorithm) +---- Success return Buffer +---@param data string +---@return any compData +function RL.CompressData( data ) end + +---Decompress data (DEFLATE algorithm). +---- Success return string, int +---@param compData any +---@return any data +---@return any dataSize +function RL.DecompressData( compData ) end + +---Encode data to Base64 string +---- Success return string, int +---@param data string +---@return any encodedData +---@return any outputSize +function RL.EncodeDataBase64( data ) end + +---Decode Base64 string data +---- Success return string, int +---@param data string +---@return any decodedData +---@return any outputSize +function RL.DecodeDataBase64( data ) end + -- Core - Camera2D ---Return camera2D set to default configuration @@ -2244,6 +2269,38 @@ function RL.GetWorldToScreen2D( position, camera ) end ---@return any position function RL.GetScreenToWorld2D( position, camera ) end +-- Core - Buffer + +---Load Buffer. Type should be one of the Buffer types +---- Success return Buffer +---@param buffer table +---@param type integer +---@return any buffer +function RL.LoadBuffer( buffer, type ) end + +---Unload buffer data +---@param buffer any +---@return any RL.UnloadBuffer +function RL.UnloadBuffer( buffer ) end + +---Get buffer data as table in the format is was stored +---- Success return data{} +---@param buffer any +---@return any data +function RL.GetBufferData( buffer ) end + +---Get buffer type +---- Success return int +---@param buffer any +---@return any type +function RL.GetBufferType( buffer ) end + +---Get buffer size +---- Success return int +---@param buffer any +---@return any size +function RL.GetBufferSize( buffer ) end + -- Shapes - Drawing ---Set texture and rectangle to be used on shapes drawing @@ -2296,7 +2353,7 @@ function RL.DrawLineBezierQuad( startPos, endPos, controlPos, thickness, color function RL.DrawLineBezierCubic( startPos, endPos, startControlPos, endControlPos, thickness, color ) end ---Draw lines sequence ----@param points any +---@param points table ---@param color table ---@return any RL.DrawLineStrip function RL.DrawLineStrip( points, color ) end @@ -2465,13 +2522,13 @@ function RL.DrawTriangle( v1, v2, v3, color ) end function RL.DrawTriangleLines( v1, v2, v3, color ) end ---Draw a triangle fan defined by points (first vertex is the center) ----@param points any +---@param points table ---@param color table ---@return any RL.DrawTriangleFan function RL.DrawTriangleFan( points, color ) end ---Draw a triangle strip defined by points ----@param points any +---@param points table ---@param color table ---@return any RL.DrawTriangleStrip function RL.DrawTriangleStrip( points, color ) end @@ -2557,7 +2614,7 @@ function RL.CheckCollisionPointTriangle( point, p1, p2, p3 ) end ---Check if point is within a polygon described by array of vertices ---- Success return bool ---@param point table ----@param points any +---@param points table ---@return any collision function RL.CheckCollisionPointPoly( point, points ) end @@ -3007,7 +3064,7 @@ function RL.LoadTextureCubemap( image, layout ) end ---Load Texture from data ---- Success return Texture ----@param textureData any +---@param textureData table ---@return any texture function RL.LoadTextureFromData( textureData ) end @@ -3019,7 +3076,7 @@ function RL.LoadRenderTexture( size ) end ---Load RenderTexture from data (framebuffer) ---- Success return RenderTexture ----@param renderTextureData any +---@param renderTextureData table ---@return any renderTexture function RL.LoadRenderTextureFromData( renderTextureData ) end @@ -3048,7 +3105,7 @@ function RL.UnloadRenderTexture( target ) end ---Update GPU texture with new data ---NOTE! Should be TEXTURE_TYPE_TEXTURE. Pixel should be in format { { 255, 255, 255, 255 }... } depending on the pixel format ---@param texture any ----@param pixels any +---@param pixels table ---@return any RL.UpdateTexture function RL.UpdateTexture( texture, pixels ) end @@ -3056,7 +3113,7 @@ function RL.UpdateTexture( texture, pixels ) end ---Pixel should be in format { { 255, 255, 255, 255 }... } depending on the pixel format ---@param texture any ---@param rec table ----@param pixels any +---@param pixels table ---@return any RL.UpdateTextureRec function RL.UpdateTextureRec( texture, rec, pixels ) end @@ -3285,7 +3342,7 @@ function RL.LoadFont( fileName ) end ---- Success return Font ---@param fileName string ---@param fontSize integer ----@param fontChars any +---@param fontChars table ---@return any font function RL.LoadFontEx( fileName, fontSize, fontChars ) end @@ -3356,7 +3413,7 @@ function RL.DrawTextCodepoint( font, codepoint, position, fontSize, tint ) end ---Draw multiple character (codepoint) ---@param font any ----@param codepoints any +---@param codepoints table ---@param position table ---@param fontSize number ---@param spacing number @@ -3587,9 +3644,9 @@ function RL.DrawPlane( centerPos, size, color ) end ---Draw 3D textured quad. (Texture coordinates opengl style 0.0 - 1.0). ---@param texture any ----@param vertices any ----@param texCoords any ----@param colors any +---@param vertices table +---@param texCoords table +---@param colors table ---@return any RL.DrawQuad3DTexture function RL.DrawQuad3DTexture( texture, vertices, texCoords, colors ) end @@ -3680,7 +3737,7 @@ function RL.GenMeshHeightmap( heightmap, size ) end ---Generate custom mesh from vertex attribute data and uploads it into a VAO (if supported) and VBO ---- Success return Mesh ----@param meshData any +---@param meshData table ---@param dynamic boolean ---@return any mesh function RL.GenMeshCustom( meshData, dynamic ) end @@ -3688,7 +3745,7 @@ function RL.GenMeshCustom( meshData, dynamic ) end ---Update mesh vertex data in GPU. ---Note! Mainly intented to be used with custom meshes. ---@param mesh any ----@param meshData any +---@param meshData table ---@return any RL.UpdateMesh function RL.UpdateMesh( mesh, meshData ) end @@ -3707,7 +3764,7 @@ function RL.DrawMesh( mesh, material, transform ) end ---Draw multiple mesh instances with material and different transforms ---@param mesh any ---@param material any ----@param transforms any +---@param transforms table ---@param instances integer ---@return any RL.DrawMeshInstanced function RL.DrawMeshInstanced( mesh, material, transforms, instances ) end @@ -3753,7 +3810,7 @@ function RL.LoadMaterialDefault() end ---Load material from table. See material table definition ---- Success return Material ----@param materialData any +---@param materialData table ---@return any material function RL.CreateMaterial( materialData ) end @@ -3797,7 +3854,7 @@ function RL.SetMaterialShader( material, shader ) end ---Set material generic parameters (if required) ---@param material any ----@param params any +---@param params table ---@return any RL.SetMaterialParams function RL.SetMaterialParams( material, params ) end @@ -6010,7 +6067,7 @@ function RL.rlSetVertexAttributeDivisor( index, divisor ) end ---Set vertex attribute default value ---@param locIndex integer ----@param value any +---@param value table ---@param attribType integer ---@return any RL.rlSetVertexAttributeDefault function RL.rlSetVertexAttributeDefault( locIndex, value, attribType ) end @@ -6157,7 +6214,7 @@ function RL.rlSetUniformSampler( locIndex, textureId ) end ---Set shader currently active (id and locations) ---@param id integer ----@param locs any +---@param locs table ---@return any RL.rlSetShader function RL.rlSetShader( id, locs ) end diff --git a/changelog b/changelog index d4f7bb7..a314732 100644 --- a/changelog +++ b/changelog @@ -35,7 +35,10 @@ DETAILED CHANGES: - ADDED: SetWindowIcons, SetWindowOpacity and GetWindowHandle. - CHANGED: Merged uluaGet*Index functions to uluaGet* functions. - FIXED: LoadFontEx. - - ADDED: DrawTextBoxed and DrawTextBoxedSelectable From raylib [text] example - Rectangle bounds + - ADDED: DrawTextBoxed and DrawTextBoxedSelectable From raylib [text] example - Rectangle bounds. + - ADDED: CompressData, DecompressData, EncodeDataBase64 and DecodeDataBase64. + - ADDED: GetBufferType and GetBufferSize. + - ADDED: Compress data example. ------------------------------------------------------------------------ Release: ReiLua version 0.5.0 Using Raylib 4.5 diff --git a/devnotes b/devnotes index 302df0a..f856cad 100644 --- a/devnotes +++ b/devnotes @@ -7,9 +7,8 @@ Backlog { * Some of the Text strings management functions could be easier to use than the Lua ones. * Audio * AudioStream. - * Core. - * Compression/Encoding functionality. * Models + * BoneInfo. * LoadMaterials (Load materials from model file). * LoadMaterialsFromModel (Could then for example edit and set back to model). * rlgl @@ -27,7 +26,6 @@ Bugs { } Needs Testing { - * UpdateMesh * rlSetUniform * rlSetShader } diff --git a/docgen.lua b/docgen.lua index 8e4a6e0..1c3b2bb 100644 --- a/docgen.lua +++ b/docgen.lua @@ -29,6 +29,8 @@ local function getParamType( param ) elseif param == "int" then return "integer" elseif param == "string" then return "string" elseif param == "bool" then return "boolean" + elseif param == "bool" then return "boolean" + elseif param:sub( #param - 1, #param ) == "{}" then return "table" else return "any" end diff --git a/examples/compress_data/main.lua b/examples/compress_data/main.lua new file mode 100644 index 0000000..bf6c162 --- /dev/null +++ b/examples/compress_data/main.lua @@ -0,0 +1,43 @@ +local textColor = RL.BLACK +local text = "Put data here" +local deCompressedText = "" +local editMode = false + +function RL.init() + RL.SetWindowTitle( "Buffer" ) + RL.SetWindowState( RL.FLAG_VSYNC_HINT ) +end + +local function compressDecompressData() + local strT = {} + + for i = 1, #text do + table.insert( strT, string.byte( text:sub( i, i ) ) ) + end + + local strBuffer = RL.LoadBuffer( strT, RL.BUFFER_UNSIGNED_CHAR ) + local compBuffer = RL.CompressData( strBuffer ) + local deCompBuffer = RL.DecompressData( compBuffer ) + + deCompressedText = "" + + for _, c in ipairs( RL.GetBufferData( deCompBuffer ) ) do + deCompressedText = deCompressedText..string.char( c ) + end +end + +function RL.draw() + RL.ClearBackground( RL.RAYWHITE ) + RL.DrawText( "Decompressed text: "..deCompressedText, { 20, 200 }, 20, textColor ) + + if RL.GuiButton( { 20, 20, 168, 32 }, "Compress/Decompress Data" ) then + compressDecompressData() + end + + local pressed = false + pressed, text = RL.GuiTextBox( { 220, 20, 400, 32 }, text, 64, editMode ) + + if pressed then + editMode = not editMode + end +end diff --git a/examples/heightmap/main.lua b/examples/heightmap/main.lua index aa693fb..51bb153 100644 --- a/examples/heightmap/main.lua +++ b/examples/heightmap/main.lua @@ -9,13 +9,12 @@ local TILE_SIZE = 32 local monitor = 0 local camera = {} -local groundRenderTexture = -1 -local groundTexture = -1 -local tilesetTex = -1 -local heigthImage = -1 -local mesh = -1 -local material = -1 -local lightmap = -1 +local groundRenderTexture = nil +local groundTexture = nil +local tilesetTex = nil +local heigthImage = nil +local mesh = nil +local material = nil local grassRec = { 6 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } local dirtRec = { 4 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } @@ -77,8 +76,6 @@ function RL.init() RL.EndTextureMode() material = RL.LoadMaterialDefault() - -- RL.GenTextureMipmaps( groundTexture ) - -- RL.SetTextureFilter( groundTexture, RL.TEXTURE_FILTER_TRILINEAR ) RL.SetMaterialTexture( material, RL.MATERIAL_MAP_ALBEDO, groundTexture ) matrix = RL.MatrixMultiply( RL.MatrixIdentity(), RL.MatrixTranslate( { -4, 0, -4 } ) ) @@ -101,6 +98,5 @@ function RL.draw() camera:beginMode3D() RL.DrawMesh( mesh, material, matrix ) - -- camera:draw() camera:endMode3D() end diff --git a/examples/resources/lib/gui.lua b/examples/resources/lib/gui.lua index 996001c..4e3b744 100644 --- a/examples/resources/lib/gui.lua +++ b/examples/resources/lib/gui.lua @@ -822,6 +822,14 @@ function Container:delete() Gui.delete( self ) end +function Container:clear() + for _, cell in ipairs( self.cells ) do + cell:delete() + end + + self.cells = {} +end + function Container:set2Top() Gui.set2Top( self ) diff --git a/examples/resources/lib/utillib.lua b/examples/resources/lib/utillib.lua index 94e33f9..899f899 100644 --- a/examples/resources/lib/utillib.lua +++ b/examples/resources/lib/utillib.lua @@ -146,6 +146,13 @@ function utillib.printt( t ) print( "}" ) end +function utillib.colorLerp( a, b, f ) + return { + utillib.round( utillib.lerp( a[1], b[1], f ) ), + utillib.round( utillib.lerp( a[2], b[2], f ) ), + utillib.round( utillib.lerp( a[3], b[3], f ) ) } +end + -- Move secuence of elements inside table. function utillib.tableMove( t, src, len, dest ) local copy = table.move( t, src, src + len - 1, 1, {} ) diff --git a/include/core.h b/include/core.h index 0a4cd2b..ffed469 100644 --- a/include/core.h +++ b/include/core.h @@ -1,5 +1,8 @@ #pragma once +#include "lua_core.h" + +void unloadBuffer( Buffer *buffer ); /* Window. */ int lcoreIsWindowReady( lua_State *L ); int lcoreIsWindowFullscreen( lua_State *L ); @@ -46,8 +49,6 @@ int lcoreSetTraceLogLevel( lua_State *L ); int lcoreSetLogLevelInvalid( lua_State *L ); int lcoreGetLogLevelInvalid( lua_State *L ); int lcoreOpenURL( lua_State *L ); -int lcoreLoadBuffer( lua_State *L ); -int lcoreUnloadBuffer( lua_State *L ); int lcoreIsGCUnloadEnabled( lua_State *L ); /* Cursor. */ int lcoreShowCursor( lua_State *L ); @@ -98,6 +99,11 @@ int lcoreIsPathFile( lua_State *L ); int lcoreIsFileDropped( lua_State *L ); int lcoreLoadDroppedFiles( lua_State *L ); int lcoreGetFileModTime( lua_State *L ); +/* Compression/Encoding functionality. */ +int lcoreCompressData( lua_State *L ); +int lcoreDecompressData( lua_State *L ); +int lcoreEncodeDataBase64( lua_State *L ); +int lcoreDecodeDataBase64( lua_State *L ); /* Camera2D. */ int lcoreCreateCamera2D( lua_State *L ); int lcoreBeginMode2D( lua_State *L ); @@ -189,3 +195,9 @@ int lcoreGetWorldToScreen( lua_State *L ); int lcoreGetWorldToScreenEx( lua_State *L ); int lcoreGetWorldToScreen2D( lua_State *L ); int lcoreGetScreenToWorld2D( lua_State *L ); +/* Buffer. */ +int lcoreLoadBuffer( lua_State *L ); +int lcoreUnloadBuffer( lua_State *L ); +int lcoreGetBufferData( lua_State *L ); +int lcoreGetBufferType( lua_State *L ); +int lcoreGetBufferSize( lua_State *L ); diff --git a/include/lua_core.h b/include/lua_core.h index 44b9ed1..a289cb0 100644 --- a/include/lua_core.h +++ b/include/lua_core.h @@ -18,14 +18,17 @@ enum BufferType { BUFFER_UNSIGNED_CHAR, BUFFER_UNSIGNED_SHORT, BUFFER_UNSIGNED_INT, + BUFFER_CHAR, + BUFFER_SHORT, + BUFFER_INT, BUFFER_FLOAT, + BUFFER_DOUBLE }; typedef struct { + int type; size_t size; void *data; - int x; - int y; } Buffer; bool luaInit( int argn, const char **argc ); diff --git a/include/models.h b/include/models.h index f97e4a4..e6e91a7 100644 --- a/include/models.h +++ b/include/models.h @@ -1,6 +1,7 @@ #pragma once /* Internals. */ +void unloadMaterial( Material *material ); /* Deleted from raylib. Need for freeing models. */ void UnloadModelKeepMeshes( Model model ); void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ); diff --git a/src/core.c b/src/core.c index ea29083..c4fbf50 100644 --- a/src/core.c +++ b/src/core.c @@ -4,6 +4,12 @@ #include "textures.h" #include "lua_core.h" +void unloadBuffer( Buffer *buffer ) { + free( buffer->data ); + + TraceLog( LOG_INFO, "BUFFER: Unloaded buffer with %u bytes of data", buffer->size ); +} + /* ## Core - Window */ @@ -591,89 +597,6 @@ int lcoreOpenURL( lua_State *L ) { return 0; } -/* -> buffer = RL.LoadBuffer( data{} buffer, int type ) - -Load Buffer. Type should be one of the Buffer types - -- Success return Buffer -*/ -int lcoreLoadBuffer( lua_State *L ) { - luaL_checktype( L, 1, LUA_TTABLE ); - int type = luaL_checkinteger( L, 2 ); - - Buffer buffer = { 0 }; - int len = uluaGetTableLen( L, 1 ); - - switch ( type ) { - case BUFFER_UNSIGNED_CHAR: - buffer.size = len * sizeof( unsigned char ); - break; - case BUFFER_UNSIGNED_SHORT: - buffer.size = len * sizeof( unsigned short ); - break; - case BUFFER_UNSIGNED_INT: - buffer.size = len * sizeof( unsigned int ); - break; - case BUFFER_FLOAT: - buffer.size = len * sizeof( float ); - break; - default: - break; - } - buffer.data = malloc( buffer.size ); - - int t = 1; - int i = 0; - unsigned char *up = buffer.data; - unsigned short *sp = buffer.data; - unsigned int *ip = buffer.data; - float *fp = buffer.data; - - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - switch ( type ) { - case BUFFER_UNSIGNED_CHAR: - *up = (unsigned char)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_UNSIGNED_SHORT: - *sp = (unsigned short)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_UNSIGNED_INT: - *ip = (unsigned int)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_FLOAT: - *fp = (float)lua_tonumber( L, -1 ); - fp++; - break; - default: - break; - } - lua_pop( L, 1 ); - i++; - } - uluaPushBuffer( L, buffer ); - - return 1; -} - -/* -> RL.UnloadBuffer( Buffer buffer ) - -Unload buffer data -*/ -int lcoreUnloadBuffer( lua_State *L ) { - Buffer *buffer = uluaGetBuffer( L, 1 ); - - free( buffer->data ); - - return 0; -} - /* > enabled = RL.IsGCUnloadEnabled() @@ -2007,6 +1930,99 @@ int lcoreGetFileModTime( lua_State *L ) { return 1; } +/* +## Core - Compression/Encoding functionality +*/ + +/* +> compData = RL.CompressData( string data ) + +Compress data (DEFLATE algorithm) + +- Success return Buffer +*/ +int lcoreCompressData( lua_State *L ) { + Buffer *inBuffer = uluaGetBuffer( L, 1 ); + Buffer outBuffer = { + .size = 0, + .type = inBuffer->type + }; + unsigned char *compData = CompressData( inBuffer->data, inBuffer->size, (int*)&outBuffer.size ); + + outBuffer.data = malloc( outBuffer.size ); + memcpy( outBuffer.data, compData, outBuffer.size ); + uluaPushBuffer( L, outBuffer ); + + free( compData ); + + return 1; +} + +/* +> data, dataSize = RL.DecompressData( Buffer compData ) + +Decompress data (DEFLATE algorithm). + +- Success return string, int +*/ +int lcoreDecompressData( lua_State *L ) { + Buffer *inBuffer = uluaGetBuffer( L, 1 ); + Buffer outBuffer = { + .size = 0, + .type = inBuffer->type + }; + unsigned char *data = DecompressData( inBuffer->data, inBuffer->size, (int*)&outBuffer.size ); + + outBuffer.data = malloc( outBuffer.size ); + memcpy( outBuffer.data, data, outBuffer.size ); + uluaPushBuffer( L, outBuffer ); + + free( data ); + + return 1; +} + +/* +> encodedData, outputSize = RL.EncodeDataBase64( string data ) + +Encode data to Base64 string + +- Success return string, int +*/ +int lcoreEncodeDataBase64( lua_State *L ) { + int dataSize = 0; + const char *string = luaL_checklstring( L, 1, (size_t*)&dataSize ); + + int outputSize = 0; + char *compData = EncodeDataBase64( string, dataSize, &outputSize ); + + lua_pushstring( L, compData ); + lua_pushinteger( L, outputSize ); + + free( compData ); + + return 2; +} + +/* +> decodedData, outputSize = RL.DecodeDataBase64( string data ) + +Decode Base64 string data + +- Success return string, int +*/ +int lcoreDecodeDataBase64( lua_State *L ) { + int outputSize = 0; + unsigned char *decodedData = DecodeDataBase64( luaL_checkstring( L, 1 ), &outputSize ); + + lua_pushstring( L, decodedData ); + lua_pushinteger( L, outputSize ); + + free( decodedData ); + + return 2; +} + /* ## Core - Camera2D */ @@ -2696,3 +2712,256 @@ int lcoreGetScreenToWorld2D( lua_State *L ) { return 1; } + +/* +## Core - Buffer +*/ + +/* +> buffer = RL.LoadBuffer( data{} buffer, int type ) + +Load Buffer. Type should be one of the Buffer types + +- Success return Buffer +*/ +int lcoreLoadBuffer( lua_State *L ) { + luaL_checktype( L, 1, LUA_TTABLE ); + int type = luaL_checkinteger( L, 2 ); + + Buffer buffer = { + .type = type + }; + int len = uluaGetTableLen( L, 1 ); + + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + buffer.size = len * sizeof( unsigned char ); + break; + case BUFFER_UNSIGNED_SHORT: + buffer.size = len * sizeof( unsigned short ); + break; + case BUFFER_UNSIGNED_INT: + buffer.size = len * sizeof( unsigned int ); + break; + case BUFFER_CHAR: + buffer.size = len * sizeof( char ); + break; + case BUFFER_SHORT: + buffer.size = len * sizeof( short ); + break; + case BUFFER_INT: + buffer.size = len * sizeof( int ); + break; + case BUFFER_FLOAT: + buffer.size = len * sizeof( float ); + break; + case BUFFER_DOUBLE: + buffer.size = len * sizeof( double ); + break; + default: + break; + } + buffer.data = malloc( buffer.size ); + + int t = 1; + int i = 0; + unsigned char *ucp = buffer.data; + unsigned short *usp = buffer.data; + unsigned int *uip = buffer.data; + char *cp = buffer.data; + short *sp = buffer.data; + int *ip = buffer.data; + float *fp = buffer.data; + double *dp = buffer.data; + + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + *ucp = (unsigned char)lua_tointeger( L, -1 ); + ucp++; + break; + case BUFFER_UNSIGNED_SHORT: + *usp = (unsigned short)lua_tointeger( L, -1 ); + usp++; + break; + case BUFFER_UNSIGNED_INT: + *uip = (unsigned int)lua_tointeger( L, -1 ); + uip++; + break; + case BUFFER_CHAR: + *cp = (char)lua_tointeger( L, -1 ); + cp++; + break; + case BUFFER_SHORT: + *sp = (short)lua_tointeger( L, -1 ); + sp++; + break; + case BUFFER_INT: + *ip = (int)lua_tointeger( L, -1 ); + ip++; + break; + case BUFFER_FLOAT: + *fp = (float)lua_tonumber( L, -1 ); + fp++; + break; + case BUFFER_DOUBLE: + *dp = (double)lua_tonumber( L, -1 ); + dp++; + break; + default: + break; + } + lua_pop( L, 1 ); + i++; + } + uluaPushBuffer( L, buffer ); + + return 1; +} + +/* +> RL.UnloadBuffer( Buffer buffer ) + +Unload buffer data +*/ +int lcoreUnloadBuffer( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + unloadBuffer( buffer ); + + return 0; +} + +/* +> data = RL.GetBufferData( Buffer buffer ) + +Get buffer data as table in the format is was stored + +- Success return data{} +*/ +int lcoreGetBufferData( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + if ( buffer->type == BUFFER_UNSIGNED_CHAR ) { + unsigned char *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned char ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned char)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_UNSIGNED_SHORT ) { + unsigned short *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned short ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned short)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_UNSIGNED_INT ) { + unsigned int *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned int ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned int)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_CHAR ) { + char *p = buffer->data; + size_t count = buffer->size / sizeof( char ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (char)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_SHORT ) { + short *p = buffer->data; + size_t count = buffer->size / sizeof( short ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (short)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_INT ) { + int *p = buffer->data; + size_t count = buffer->size / sizeof( int ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (int)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_FLOAT ) { + float *p = buffer->data; + size_t count = buffer->size / sizeof( float ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushnumber( L, (float)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_DOUBLE ) { + double *p = buffer->data; + size_t count = buffer->size / sizeof( double ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushnumber( L, (double)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + + return 1; +} + +/* +> type = RL.GetBufferType( Buffer buffer ) + +Get buffer type + +- Success return int +*/ +int lcoreGetBufferType( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + lua_pushinteger( L, buffer->type ); + + return 1; +} + +/* +> size = RL.GetBufferSize( Buffer buffer ) + +Get buffer size + +- Success return int +*/ +int lcoreGetBufferSize( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + lua_pushinteger( L, buffer->size ); + + return 1; +} diff --git a/src/lua_core.c b/src/lua_core.c index 499f2a2..37d34fc 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -20,7 +20,7 @@ static int gcBuffer( lua_State *L ) { Buffer *buffer = luaL_checkudata( L, 1, "Buffer" ); - free( buffer->data ); + unloadBuffer( buffer ); } static void defineBuffer() { @@ -219,7 +219,7 @@ static int gcMaterial( lua_State *L ) { Material *material = luaL_checkudata( L, 1, "Material" ); /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ - RL_FREE( material->maps ); + unloadMaterial( material ); // UnloadMaterial( *material ); } @@ -900,10 +900,14 @@ static void defineGlobals() { assignGlobalInt( GLFW_PRESS, "GLFW_PRESS" ); // The key or mouse button was pressed assignGlobalInt( GLFW_REPEAT, "GLFW_REPEAT" ); // The key was held down until it repeated /* CBuffer Data Types */ - assignGlobalInt( BUFFER_UNSIGNED_CHAR, "BUFFER_UNSIGNED_CHAR" ); // C type char - assignGlobalInt( BUFFER_UNSIGNED_SHORT, "BUFFER_UNSIGNED_SHORT" ); // C type short - assignGlobalInt( BUFFER_UNSIGNED_INT, "BUFFER_UNSIGNED_INT" ); // C type int + assignGlobalInt( BUFFER_UNSIGNED_CHAR, "BUFFER_UNSIGNED_CHAR" ); // C type unsigned char + assignGlobalInt( BUFFER_UNSIGNED_SHORT, "BUFFER_UNSIGNED_SHORT" ); // C type unsigned short + assignGlobalInt( BUFFER_UNSIGNED_INT, "BUFFER_UNSIGNED_INT" ); // C type unsigned int + assignGlobalInt( BUFFER_CHAR, "BUFFER_CHAR" ); // C type char + assignGlobalInt( BUFFER_SHORT, "BUFFER_SHORT" ); // C type short + assignGlobalInt( BUFFER_INT, "BUFFER_INT" ); // C type int assignGlobalInt( BUFFER_FLOAT, "BUFFER_FLOAT" ); // C type float + assignGlobalInt( BUFFER_DOUBLE, "BUFFER_DOUBLE" ); // C type double /* Window Events. */ assignGlobalInt( EVENT_WINDOW_SIZE, "EVENT_WINDOW_SIZE" ); // GLFW event window size changed assignGlobalInt( EVENT_WINDOW_MAXIMIZE, "EVENT_WINDOW_MAXIMIZE" ); // GLFW event window maximize @@ -1542,8 +1546,6 @@ void luaRegister() { assingGlobalFunction( "SetLogLevelInvalid", lcoreSetLogLevelInvalid ); assingGlobalFunction( "GetLogLevelInvalid", lcoreGetLogLevelInvalid ); assingGlobalFunction( "OpenURL", lcoreOpenURL ); - assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); - assingGlobalFunction( "UnloadBuffer", lcoreUnloadBuffer ); assingGlobalFunction( "IsGCUnloadEnabled", lcoreIsGCUnloadEnabled ); /* Cursor. */ assingGlobalFunction( "ShowCursor", lcoreShowCursor ); @@ -1594,6 +1596,11 @@ void luaRegister() { assingGlobalFunction( "IsFileDropped", lcoreIsFileDropped ); assingGlobalFunction( "LoadDroppedFiles", lcoreLoadDroppedFiles ); assingGlobalFunction( "GetFileModTime", lcoreGetFileModTime ); + /* Compression/Encoding functionality. */ + assingGlobalFunction( "CompressData", lcoreCompressData ); + assingGlobalFunction( "DecompressData", lcoreDecompressData ); + assingGlobalFunction( "EncodeDataBase64", lcoreEncodeDataBase64 ); + assingGlobalFunction( "DecodeDataBase64", lcoreDecodeDataBase64 ); /* Camera2D. */ assingGlobalFunction( "CreateCamera2D", lcoreCreateCamera2D ); assingGlobalFunction( "BeginMode2D", lcoreBeginMode2D ); @@ -1685,6 +1692,12 @@ void luaRegister() { assingGlobalFunction( "GetWorldToScreenEx", lcoreGetWorldToScreenEx ); assingGlobalFunction( "GetWorldToScreen2D", lcoreGetWorldToScreen2D ); assingGlobalFunction( "GetScreenToWorld2D", lcoreGetScreenToWorld2D ); + /* Buffer. */ + assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); + assingGlobalFunction( "UnloadBuffer", lcoreUnloadBuffer ); + assingGlobalFunction( "GetBufferData", lcoreGetBufferData ); + assingGlobalFunction( "GetBufferType", lcoreGetBufferType ); + assingGlobalFunction( "GetBufferSize", lcoreGetBufferSize ); /* Shapes. */ /* Drawing. */ diff --git a/src/models.c b/src/models.c index 64a8d3b..2db4b5b 100644 --- a/src/models.c +++ b/src/models.c @@ -6,6 +6,10 @@ #include "textures.h" #include "core.h" +void unloadMaterial( Material *material ) { + free( material->maps ); +} + // Unload model (but not meshes) from memory (RAM and/or VRAM) void UnloadModelKeepMeshes( Model model ) { // Unload materials maps @@ -23,7 +27,7 @@ void UnloadModelKeepMeshes( Model model ) { RL_FREE(model.bones); RL_FREE(model.bindPose); - TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM"); + TraceLog( LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM" ); } void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) { @@ -1194,7 +1198,7 @@ int lmodelsUnloadMaterial( lua_State *L ) { Material *material = uluaGetMaterial( L, 1 ); /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ - RL_FREE( material->maps ); + unloadMaterial( material ); // UnloadMaterial( *material ); -- cgit v1.2.3