Merge branch 'raysan5-master'
This commit is contained in:
commit
691e835181
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -82,7 +82,7 @@ DerivedData/
|
||||||
|
|
||||||
# Jetbrains project
|
# Jetbrains project
|
||||||
.idea/
|
.idea/
|
||||||
cmake-build-debug/
|
cmake-build-*/
|
||||||
|
|
||||||
# CMake stuff
|
# CMake stuff
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Here it is a list with the ones I'm aware of:
|
||||||
|
|
||||||
| name | raylib version | language | repo |
|
| name | raylib version | language | repo |
|
||||||
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
|
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
|
||||||
| raylib | **3.1-dev** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
|
| raylib | **3.5** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
|
||||||
| raylib-cpp | 3.5 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
|
| raylib-cpp | 3.5 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
|
||||||
| Raylib-cs | 3.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
|
| Raylib-cs | 3.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
|
||||||
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
|
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
|
||||||
|
|
@ -19,7 +19,7 @@ Here it is a list with the ones I'm aware of:
|
||||||
| raylib-go | 3.0 | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go |
|
| raylib-go | 3.0 | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go |
|
||||||
| raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus |
|
| raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus |
|
||||||
| ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go |
|
| ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go |
|
||||||
| go-raylib | 3.1-dev | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib |
|
| go-raylib | 3.5 | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib |
|
||||||
| raylib-rs | 3.0 | [Rust](https://www.rust-lang.org/) | https://github.com/deltaphc/raylib-rs |
|
| raylib-rs | 3.0 | [Rust](https://www.rust-lang.org/) | https://github.com/deltaphc/raylib-rs |
|
||||||
| raylib-lua | 1.7 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib-lua |
|
| raylib-lua | 1.7 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib-lua |
|
||||||
| raylib-lua-ffi | 2.0 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib/issues/693 |
|
| raylib-lua-ffi | 2.0 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib/issues/693 |
|
||||||
|
|
@ -33,6 +33,7 @@ Here it is a list with the ones I'm aware of:
|
||||||
| raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim |
|
| raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim |
|
||||||
| raylib-Forever | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/Guevara-chan/Raylib-Forever |
|
| raylib-Forever | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/Guevara-chan/Raylib-Forever |
|
||||||
| nim-raylib | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/tomc1998/nim-raylib |
|
| nim-raylib | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/tomc1998/nim-raylib |
|
||||||
|
| NimraylibNow! | 3.5-dev | [Nim](https://nim-lang.org/) | https://github.com/greenfork/nimraylib_now |
|
||||||
| raylib-haskell | 2.0 | [Haskell](https://www.haskell.org/) | https://github.com/DevJac/raylib-haskell |
|
| raylib-haskell | 2.0 | [Haskell](https://www.haskell.org/) | https://github.com/DevJac/raylib-haskell |
|
||||||
| raylib-cr | 2.5-dev | [Crystal](https://crystal-lang.org/) | https://github.com/AregevDev/raylib-cr |
|
| raylib-cr | 2.5-dev | [Crystal](https://crystal-lang.org/) | https://github.com/AregevDev/raylib-cr |
|
||||||
| cray | 1.8 | [Crystal](https://crystal-lang.org/) | https://gitlab.com/Zatherz/cray |
|
| cray | 1.8 | [Crystal](https://crystal-lang.org/) | https://gitlab.com/Zatherz/cray |
|
||||||
|
|
@ -45,12 +46,12 @@ Here it is a list with the ones I'm aware of:
|
||||||
| raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby |
|
| raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby |
|
||||||
| raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby |
|
| raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby |
|
||||||
| raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py |
|
| raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py |
|
||||||
| raylib-python-cffi | 3.1-dev | [Python](https://www.python.org/) | https://github.com/electronstudio/raylib-python-cffi |
|
| raylib-python-cffi | 3.5 | [Python](https://www.python.org/) | https://github.com/electronstudio/raylib-python-cffi |
|
||||||
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
|
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
|
||||||
| jaylib | 3.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/electronstudio/jaylib/ |
|
| jaylib | 3.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/electronstudio/jaylib/ |
|
||||||
| raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java |
|
| raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java |
|
||||||
| clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib |
|
| clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib |
|
||||||
| node-raylib | 3.0 | [Node.js](https://nodejs.org/en/) | https://github.com/RobLoach/node-raylib |
|
| node-raylib | 3.5 | [Node.js](https://nodejs.org/en/) | https://github.com/RobLoach/node-raylib |
|
||||||
| QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib |
|
| QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib |
|
||||||
| raylib-js | 2.6 | [JavaScript](https://en.wikipedia.org/wiki/JavaScript) | https://github.com/RobLoach/raylib-js |
|
| raylib-js | 2.6 | [JavaScript](https://en.wikipedia.org/wiki/JavaScript) | https://github.com/RobLoach/raylib-js |
|
||||||
| raylib-chaiscript | 2.6 | [ChaiScript](http://chaiscript.com/) | https://github.com/RobLoach/raylib-chaiscript |
|
| raylib-chaiscript | 2.6 | [ChaiScript](http://chaiscript.com/) | https://github.com/RobLoach/raylib-chaiscript |
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,27 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(raylib)
|
||||||
|
|
||||||
|
# Directory for easier includes
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
|
# RAYLIB_IS_MAIN determines whether the project is being used from root, or as a dependency.
|
||||||
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
|
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
set(RAYLIB_IS_MAIN TRUE)
|
set(RAYLIB_IS_MAIN TRUE)
|
||||||
else()
|
else()
|
||||||
set(RAYLIB_IS_MAIN FALSE)
|
set(RAYLIB_IS_MAIN FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Config options
|
# Sets compiler flags and language standard
|
||||||
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN})
|
include(CompilerFlags)
|
||||||
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
|
|
||||||
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
|
|
||||||
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
|
|
||||||
|
|
||||||
# This helps support the case where emsdk toolchain file is used
|
# Registers build options that are exposed to cmake
|
||||||
# either by setting it with -DCMAKE_TOOLCHAIN_FILE=<path_to_emsdk>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
|
include(CMakeOptions.txt)
|
||||||
# or by using "emcmake cmake -B build -S ." as described in https://emscripten.org/docs/compiling/Building-Projects.html
|
|
||||||
if(EMSCRIPTEN)
|
|
||||||
SET(PLATFORM Web CACHE STRING "Forcing PLATFORM_WEB because EMSCRIPTEN was detected")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_LESS "3.1")
|
# Checks a few environment and compiler configurations
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
include(BuildOptions)
|
||||||
set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set (CMAKE_C_STANDARD 99)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(AddIfFlagCompiles)
|
# Main sources directory (the second parameter sets the output directory name to raylib)
|
||||||
add_if_flag_compiles(-Werror=pointer-arith CMAKE_C_FLAGS)
|
add_subdirectory(src raylib)
|
||||||
add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
|
|
||||||
# src/external/jar_xm.h does shady stuff
|
|
||||||
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS)
|
|
||||||
|
|
||||||
if (ENABLE_ASAN)
|
|
||||||
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
add_if_flag_compiles(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
endif()
|
|
||||||
if (ENABLE_UBSAN)
|
|
||||||
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
add_if_flag_compiles(-fsanitize=undefined CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
endif()
|
|
||||||
if (ENABLE_MSAN)
|
|
||||||
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
add_if_flag_compiles(-fsanitize=memory CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ENABLE_MSAN AND ENABLE_ASAN)
|
|
||||||
MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
|
||||||
|
|
||||||
if (${BUILD_EXAMPLES})
|
if (${BUILD_EXAMPLES})
|
||||||
MESSAGE(STATUS "Building examples is enabled")
|
MESSAGE(STATUS "Building examples is enabled")
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@ enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM" "Platform to build f
|
||||||
|
|
||||||
enum_option(OPENGL_VERSION "OFF;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Version?")
|
enum_option(OPENGL_VERSION "OFF;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Version?")
|
||||||
|
|
||||||
|
# Configuration options
|
||||||
|
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN})
|
||||||
|
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
|
||||||
|
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
|
||||||
|
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
|
||||||
|
|
||||||
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
|
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
|
||||||
option(WITH_PIC "Compile static library as position-independent code" OFF)
|
option(WITH_PIC "Compile static library as position-independent code" OFF)
|
||||||
option(SHARED "Build raylib as a dynamic library" OFF)
|
option(SHARED "Build raylib as a dynamic library" OFF)
|
||||||
|
|
@ -80,36 +86,3 @@ option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF})
|
||||||
|
|
||||||
# utils.c
|
# utils.c
|
||||||
option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON)
|
option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON)
|
||||||
|
|
||||||
if(NOT (STATIC OR SHARED))
|
|
||||||
message(FATAL_ERROR "Nothing to do if both -DSHARED=OFF and -DSTATIC=OFF...")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (DEFINED BUILD_SHARED_LIBS)
|
|
||||||
set(SHARED ${BUILD_SHARED_LIBS})
|
|
||||||
if (${BUILD_SHARED_LIBS})
|
|
||||||
set(STATIC OFF)
|
|
||||||
else()
|
|
||||||
set(STATIC ON)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(DEFINED SHARED_RAYLIB)
|
|
||||||
set(SHARED ${SHARED_RAYLIB})
|
|
||||||
message(DEPRECATION "-DSHARED_RAYLIB is deprecated. Please use -DSHARED instead.")
|
|
||||||
endif()
|
|
||||||
if(DEFINED STATIC_RAYLIB)
|
|
||||||
set(STATIC ${STATIC_RAYLIB})
|
|
||||||
message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(${PLATFORM} MATCHES "Desktop" AND APPLE)
|
|
||||||
if(MACOS_FATLIB)
|
|
||||||
if (CMAKE_OSX_ARCHITECTURES)
|
|
||||||
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
|
|
||||||
else()
|
|
||||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# vim: ft=cmake
|
|
||||||
|
|
@ -79,6 +79,14 @@ You can download and install raylib using the [vcpkg](https://github.com/Microso
|
||||||
|
|
||||||
*The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.*
|
*The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.*
|
||||||
|
|
||||||
|
#### Installing and building raylib via conan
|
||||||
|
|
||||||
|
You can download and install raylib using the [conan](https://conan.io) dependency manager:
|
||||||
|
|
||||||
|
https://docs.conan.io/en/latest/getting_started.html
|
||||||
|
|
||||||
|
*The raylib recipe in conan is kept up to date by conan team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the conan-center-index repository.*
|
||||||
|
|
||||||
#### Building raylib on multiple platforms
|
#### Building raylib on multiple platforms
|
||||||
|
|
||||||
[raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms.
|
[raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms.
|
||||||
|
|
|
||||||
39
cmake/BuildOptions.cmake
Normal file
39
cmake/BuildOptions.cmake
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
if(NOT (STATIC OR SHARED))
|
||||||
|
message(FATAL_ERROR "Nothing to do if both -DSHARED=OFF and -DSTATIC=OFF...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (DEFINED BUILD_SHARED_LIBS)
|
||||||
|
set(SHARED ${BUILD_SHARED_LIBS})
|
||||||
|
if (${BUILD_SHARED_LIBS})
|
||||||
|
set(STATIC OFF)
|
||||||
|
else()
|
||||||
|
set(STATIC ON)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(DEFINED SHARED_RAYLIB)
|
||||||
|
set(SHARED ${SHARED_RAYLIB})
|
||||||
|
message(DEPRECATION "-DSHARED_RAYLIB is deprecated. Please use -DSHARED instead.")
|
||||||
|
endif()
|
||||||
|
if(DEFINED STATIC_RAYLIB)
|
||||||
|
set(STATIC ${STATIC_RAYLIB})
|
||||||
|
message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${PLATFORM} MATCHES "Desktop" AND APPLE)
|
||||||
|
if(MACOS_FATLIB)
|
||||||
|
if (CMAKE_OSX_ARCHITECTURES)
|
||||||
|
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
|
||||||
|
else()
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# This helps support the case where emsdk toolchain file is used
|
||||||
|
# either by setting it with -DCMAKE_TOOLCHAIN_FILE=<path_to_emsdk>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
|
||||||
|
# or by using "emcmake cmake -B build -S ." as described in https://emscripten.org/docs/compiling/Building-Projects.html
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
SET(PLATFORM Web CACHE STRING "Forcing PLATFORM_WEB because EMSCRIPTEN was detected")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# vim: ft=cmake
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
# Set a default build type if none was specified
|
|
||||||
set(default_build_type "Release")
|
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
|
||||||
set(default_build_type "Debug")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
|
||||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
|
|
||||||
STRING "Choose the type of build." FORCE)
|
|
||||||
# Set the possible values of build type for cmake-gui
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
|
||||||
"MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Taken from the https://github.com/OpenChemistry/tomviz project
|
|
||||||
# Copyright (c) 2014-2017, Kitware, Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
# list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
#
|
|
||||||
# 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
33
cmake/CompilerFlags.cmake
Normal file
33
cmake/CompilerFlags.cmake
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
include(AddIfFlagCompiles)
|
||||||
|
|
||||||
|
add_if_flag_compiles(-Werror=pointer-arith CMAKE_C_FLAGS)
|
||||||
|
add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
|
||||||
|
# src/external/jar_xm.h does shady stuff
|
||||||
|
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS)
|
||||||
|
|
||||||
|
if (ENABLE_ASAN)
|
||||||
|
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
add_if_flag_compiles(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
endif()
|
||||||
|
if (ENABLE_UBSAN)
|
||||||
|
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
add_if_flag_compiles(-fsanitize=undefined CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
endif()
|
||||||
|
if (ENABLE_MSAN)
|
||||||
|
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
add_if_flag_compiles(-fsanitize=memory CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_MSAN AND ENABLE_ASAN)
|
||||||
|
MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions("-DRAYLIB_CMAKE=1")
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS "3.1")
|
||||||
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
add_if_flag_compiles(-std=gnu99 CMAKE_C_FLAGS)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set (CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
29
cmake/GlfwImport.cmake
Normal file
29
cmake/GlfwImport.cmake
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
if(USE_EXTERNAL_GLFW STREQUAL "ON")
|
||||||
|
find_package(glfw3 3.2.1 REQUIRED)
|
||||||
|
elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE")
|
||||||
|
find_package(glfw3 3.2.1 QUIET)
|
||||||
|
endif()
|
||||||
|
if (glfw3_FOUND)
|
||||||
|
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Explicitly check against "ON", because USE_EXTERNAL_GLFW is a tristate option
|
||||||
|
# Also adding only on desktop (web also uses glfw but it is more limited and is added using an emcc linker flag)
|
||||||
|
if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MATCHES "Desktop")
|
||||||
|
MESSAGE(STATUS "Using raylib's GLFW")
|
||||||
|
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
|
||||||
|
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory(external/glfw)
|
||||||
|
|
||||||
|
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
|
||||||
|
include_directories(BEFORE SYSTEM external/glfw/include)
|
||||||
|
else()
|
||||||
|
MESSAGE(STATUS "Using external GLFW")
|
||||||
|
set(GLFW_PKG_DEPS glfw3)
|
||||||
|
endif()
|
||||||
29
cmake/InstallConfigurations.cmake
Normal file
29
cmake/InstallConfigurations.cmake
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
install(
|
||||||
|
TARGETS raylib EXPORT raylib-targets
|
||||||
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||||
|
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in
|
||||||
|
if (STATIC)
|
||||||
|
include(LibraryPathToLinkerFlags)
|
||||||
|
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
|
||||||
|
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
|
||||||
|
string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
|
||||||
|
elseif (SHARED)
|
||||||
|
set(PKG_CONFIG_LIBS_EXTRA "")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
configure_file(../raylib.pc.in raylib.pc @ONLY)
|
||||||
|
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
|
||||||
|
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
|
||||||
|
|
||||||
|
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
|
||||||
|
include(PopulateConfigVariablesLocally)
|
||||||
|
populate_config_variables_locally(raylib)
|
||||||
109
cmake/LibraryConfigurations.cmake
Normal file
109
cmake/LibraryConfigurations.cmake
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
|
||||||
|
### Config options ###
|
||||||
|
# Translate the config options to what raylib wants
|
||||||
|
configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
|
||||||
|
|
||||||
|
if(${PLATFORM} MATCHES "Desktop")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
# Need to force OpenGL 3.3 on OS X
|
||||||
|
# See: https://github.com/raysan5/raylib/issues/341
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||||
|
find_library(OPENGL_LIBRARY OpenGL)
|
||||||
|
set(LIBS_PRIVATE ${OPENGL_LIBRARY})
|
||||||
|
link_libraries("${LIBS_PRIVATE}")
|
||||||
|
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
|
||||||
|
add_definitions(-DGL_SILENCE_DEPRECATION)
|
||||||
|
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
||||||
|
endif()
|
||||||
|
elseif(WIN32)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
|
||||||
|
else()
|
||||||
|
find_library(pthread NAMES pthread)
|
||||||
|
find_package(OpenGL QUIET)
|
||||||
|
if ("${OPENGL_LIBRARIES}" STREQUAL "")
|
||||||
|
set(OPENGL_LIBRARIES "GL")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
|
||||||
|
find_library(OSS_LIBRARY ossaudio)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
elseif(${PLATFORM} MATCHES "Web")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_WEB")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
|
||||||
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||||
|
|
||||||
|
elseif(${PLATFORM} MATCHES "Android")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
include(AddIfFlagCompiles)
|
||||||
|
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
|
||||||
|
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
|
||||||
|
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
|
||||||
|
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
|
||||||
|
add_definitions(-DANDROID -D__ANDROID_API__=21)
|
||||||
|
include_directories(external/android/native_app_glue)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -uANativeActivity_onCreate")
|
||||||
|
|
||||||
|
find_library(OPENGL_LIBRARY OpenGL)
|
||||||
|
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
|
||||||
|
|
||||||
|
elseif(${PLATFORM} MATCHES "Raspberry Pi")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_RPI")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
|
||||||
|
add_definitions(-D_DEFAULT_SOURCE)
|
||||||
|
|
||||||
|
find_library(GLESV2 brcmGLESv2 HINTS /opt/vc/lib)
|
||||||
|
find_library(EGL brcmEGL HINTS /opt/vc/lib)
|
||||||
|
find_library(BCMHOST bcm_host HINTS /opt/vc/lib)
|
||||||
|
include_directories(/opt/vc/include /opt/vc/include/interface/vmcs_host/linux /opt/vc/include/interface/vcos/pthreads)
|
||||||
|
link_directories(/opt/vc/lib)
|
||||||
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
|
||||||
|
|
||||||
|
elseif(${PLATFORM} MATCHES "DRM")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
|
||||||
|
add_definitions(-D_DEFAULT_SOURCE)
|
||||||
|
add_definitions(-DEGL_NO_X11)
|
||||||
|
add_definitions(-DPLATFORM_DRM)
|
||||||
|
|
||||||
|
find_library(GLESV2 GLESv2)
|
||||||
|
find_library(EGL EGL)
|
||||||
|
find_library(DRM drm)
|
||||||
|
find_library(GBM gbm)
|
||||||
|
|
||||||
|
include_directories(/usr/include/libdrm)
|
||||||
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${OPENGL_VERSION})
|
||||||
|
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
||||||
|
if (${OPENGL_VERSION} MATCHES "3.3")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||||
|
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
|
||||||
|
elseif (${OPENGL_VERSION} MATCHES "1.1")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_11")
|
||||||
|
elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
endif()
|
||||||
|
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||||
|
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT GRAPHICS)
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||||
|
endif()
|
||||||
13
cmake/PackConfigurations.cmake
Normal file
13
cmake/PackConfigurations.cmake
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Packaging
|
||||||
|
SET(CPACK_PACKAGE_NAME "raylib")
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to enjoy videogames programming")
|
||||||
|
SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
|
||||||
|
SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
|
||||||
|
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE")
|
||||||
|
SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
|
||||||
|
SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
|
||||||
|
include(CPack)
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
SET(CMAKE_SYSTEM_NAME Linux)
|
|
||||||
SET(CMAKE_SYSTEM_PROCESSOR x86)
|
|
||||||
|
|
||||||
if (CMAKE_HOST_WIN32)
|
|
||||||
SET(EMSCRIPTEN_EXTENSION ".bat")
|
|
||||||
else ()
|
|
||||||
SET(EMSCRIPTEN_EXTENSION "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
SET(CMAKE_C_COMPILER emcc${EMSCRIPTEN_EXTENSION})
|
|
||||||
SET(CMAKE_CXX_COMPILER em++${EMSCRIPTEN_EXTENSION})
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_AR)
|
|
||||||
find_program(CMAKE_AR NAMES emar${EMSCRIPTEN_EXTENSION})
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED CMAKE_RANLIB)
|
|
||||||
find_program(CMAKE_RANLIB NAMES emranlib${EMSCRIPTEN_EXTENSION})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
|
||||||
|
|
@ -28,7 +28,6 @@ if (APPLE AND NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
|
||||||
add_definitions(-DGL_SILENCE_DEPRECATION)
|
add_definitions(-DGL_SILENCE_DEPRECATION)
|
||||||
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
||||||
endif()
|
endif()
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
|
||||||
|
|
||||||
include(CheckIncludeFile)
|
include(CheckIncludeFile)
|
||||||
CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H)
|
CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H)
|
||||||
|
|
@ -119,19 +118,5 @@ foreach(example_source ${example_sources})
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if (${PLATFORM} MATCHES "Desktop")
|
|
||||||
# rlgl_standalone can't be linked with raylib because of duplicate rlgl symbols
|
|
||||||
foreach (example_source "others/rlgl_standalone.c")
|
|
||||||
# Create the basename for the example
|
|
||||||
get_filename_component(example_name ${example_source} NAME)
|
|
||||||
string(REPLACE ".c" "" example_name ${example_name})
|
|
||||||
add_executable(${example_name} ${example_source})
|
|
||||||
add_dependencies(${example_name} raylib)
|
|
||||||
target_link_libraries(${example_name} ${raylib_LDFLAGS})
|
|
||||||
target_include_directories(${example_name} PRIVATE ${raylib_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Copy all of the resource files to the destination
|
# Copy all of the resource files to the destination
|
||||||
file(COPY ${example_resources} DESTINATION "resources/")
|
file(COPY ${example_resources} DESTINATION "resources/")
|
||||||
|
|
|
||||||
|
|
@ -1,213 +1,61 @@
|
||||||
# Setup the project and settings
|
# Setup the project and settings
|
||||||
project(raylib C)
|
project(raylib C)
|
||||||
include(GNUInstallDirs)
|
|
||||||
include(JoinPaths)
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
|
||||||
|
|
||||||
set(PROJECT_VERSION 3.5.0)
|
set(PROJECT_VERSION 3.5.0)
|
||||||
set(API_VERSION 351)
|
set(API_VERSION 351)
|
||||||
|
|
||||||
include("CMakeOptions.txt")
|
include(GNUInstallDirs)
|
||||||
include(BuildType)
|
include(JoinPaths)
|
||||||
configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
|
|
||||||
include_directories(${CMAKE_BINARY_DIR} .)
|
# Sets build type if not set by now
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
if(RAYLIB_IS_MAIN)
|
||||||
|
set(default_build_type Debug)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Get the sources together
|
# Get the sources together
|
||||||
file(GLOB raylib_sources *.c)
|
set(raylib_public_headers
|
||||||
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c)
|
raylib.h
|
||||||
|
rlgl.h
|
||||||
|
physac.h
|
||||||
|
raymath.h
|
||||||
|
raudio.h
|
||||||
|
)
|
||||||
|
|
||||||
if(USE_EXTERNAL_GLFW STREQUAL "ON")
|
set(raylib_sources
|
||||||
find_package(glfw3 3.2.1 REQUIRED)
|
core.c
|
||||||
elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE")
|
models.c
|
||||||
find_package(glfw3 3.2.1 QUIET)
|
shapes.c
|
||||||
endif()
|
text.c
|
||||||
if (glfw3_FOUND)
|
textures.c
|
||||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
|
utils.c
|
||||||
endif()
|
)
|
||||||
|
|
||||||
# Explicitly check against "ON", because USE_EXTERNAL_GLFW is a tristate option
|
# cmake/GlfwImport.cmake handles the details around the inclusion of glfw
|
||||||
if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MATCHES "Desktop")
|
include(GlfwImport)
|
||||||
MESSAGE(STATUS "Using raylib's GLFW")
|
|
||||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
|
||||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
||||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
||||||
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
|
||||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
|
|
||||||
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
|
|
||||||
|
|
||||||
add_subdirectory(external/glfw)
|
|
||||||
|
|
||||||
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
|
|
||||||
include_directories(BEFORE SYSTEM external/glfw/include)
|
|
||||||
else()
|
|
||||||
MESSAGE(STATUS "Using external GLFW")
|
|
||||||
set(GLFW_PKG_DEPS glfw3)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions("-DRAYLIB_CMAKE=1")
|
|
||||||
|
|
||||||
if (USE_AUDIO)
|
if (USE_AUDIO)
|
||||||
MESSAGE(STATUS "Audio Backend: miniaudio")
|
MESSAGE(STATUS "Audio Backend: miniaudio")
|
||||||
set(sources ${raylib_sources})
|
list(APPEND raylib_sources raudio.c)
|
||||||
else ()
|
else ()
|
||||||
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
||||||
set(RAYLIB_MODULE_AUDIO 0)
|
|
||||||
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/raudio.c)
|
|
||||||
set(sources ${raylib_sources})
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
### Config options ###
|
include(LibraryConfigurations)
|
||||||
# Translate the config options to what raylib wants
|
|
||||||
if(${PLATFORM} MATCHES "Desktop")
|
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
# Need to force OpenGL 3.3 on OS X
|
|
||||||
# See: https://github.com/raysan5/raylib/issues/341
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
|
||||||
find_library(OPENGL_LIBRARY OpenGL)
|
|
||||||
set(LIBS_PRIVATE ${OPENGL_LIBRARY})
|
|
||||||
link_libraries("${LIBS_PRIVATE}")
|
|
||||||
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
|
|
||||||
add_definitions(-DGL_SILENCE_DEPRECATION)
|
|
||||||
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
|
||||||
endif()
|
|
||||||
elseif(WIN32)
|
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
|
|
||||||
else()
|
|
||||||
find_library(pthread NAMES pthread)
|
|
||||||
find_package(OpenGL QUIET)
|
|
||||||
if ("${OPENGL_LIBRARIES}" STREQUAL "")
|
|
||||||
set(OPENGL_LIBRARIES "GL")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
|
|
||||||
find_library(OSS_LIBRARY ossaudio)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
elseif(${PLATFORM} MATCHES "Web")
|
|
||||||
set(PLATFORM_CPP "PLATFORM_WEB")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
|
|
||||||
|
|
||||||
# Change the name of the output library
|
|
||||||
|
|
||||||
elseif(${PLATFORM} MATCHES "Android")
|
|
||||||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
include(AddIfFlagCompiles)
|
|
||||||
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
|
|
||||||
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
|
|
||||||
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
|
|
||||||
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
|
|
||||||
add_definitions(-DANDROID -D__ANDROID_API__=21)
|
|
||||||
include_directories(external/android/native_app_glue)
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -uANativeActivity_onCreate")
|
|
||||||
|
|
||||||
find_library(OPENGL_LIBRARY OpenGL)
|
|
||||||
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
|
|
||||||
|
|
||||||
elseif(${PLATFORM} MATCHES "Raspberry Pi")
|
|
||||||
set(PLATFORM_CPP "PLATFORM_RPI")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
|
|
||||||
add_definitions(-D_DEFAULT_SOURCE)
|
|
||||||
|
|
||||||
find_library(GLESV2 brcmGLESv2 HINTS /opt/vc/lib)
|
|
||||||
find_library(EGL brcmEGL HINTS /opt/vc/lib)
|
|
||||||
find_library(BCMHOST bcm_host HINTS /opt/vc/lib)
|
|
||||||
include_directories(/opt/vc/include /opt/vc/include/interface/vmcs_host/linux /opt/vc/include/interface/vcos/pthreads)
|
|
||||||
link_directories(/opt/vc/lib)
|
|
||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
|
|
||||||
|
|
||||||
elseif(${PLATFORM} MATCHES "DRM")
|
|
||||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
|
|
||||||
add_definitions(-D_DEFAULT_SOURCE)
|
|
||||||
add_definitions(-DEGL_NO_X11)
|
|
||||||
add_definitions(-DPLATFORM_DRM)
|
|
||||||
|
|
||||||
find_library(GLESV2 GLESv2)
|
|
||||||
find_library(EGL EGL)
|
|
||||||
find_library(DRM drm)
|
|
||||||
find_library(GBM gbm)
|
|
||||||
|
|
||||||
include_directories(/usr/include/libdrm)
|
|
||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (${OPENGL_VERSION})
|
|
||||||
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
|
||||||
if (${OPENGL_VERSION} MATCHES "3.3")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
|
||||||
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
|
|
||||||
elseif (${OPENGL_VERSION} MATCHES "1.1")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_11")
|
|
||||||
elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
endif()
|
|
||||||
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
|
||||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT GRAPHICS)
|
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories(${OPENGL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR})
|
|
||||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
|
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
|
||||||
include(LibraryPathToLinkerFlags)
|
|
||||||
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
|
|
||||||
|
|
||||||
if (STATIC)
|
if (STATIC)
|
||||||
MESSAGE(STATUS "Building raylib static library")
|
MESSAGE(STATUS "Building raylib static library")
|
||||||
if(${PLATFORM} MATCHES "Web")
|
|
||||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(raylib_static STATIC ${sources})
|
add_library(raylib STATIC ${raylib_sources} ${raylib_public_headers})
|
||||||
|
add_library(raylib_static ALIAS raylib)
|
||||||
target_compile_definitions(raylib_static
|
|
||||||
PUBLIC ${PLATFORM_CPP}
|
|
||||||
PUBLIC PLATFORM=${PLATFORM_CPP}
|
|
||||||
PUBLIC ${GRAPHICS}
|
|
||||||
PUBLIC GRAPHICS=${GRAPHICS}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(raylib_static
|
|
||||||
PUBLIC ${LIBS_PRIVATE}
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
|
|
||||||
string (REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
|
|
||||||
if (${PLATFORM} MATCHES "Desktop")
|
|
||||||
target_link_libraries(raylib_static PRIVATE glfw ${GLFW_LIBRARIES} ${LIBS_PRIVATE})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WITH_PIC)
|
|
||||||
set_property(TARGET raylib_static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
||||||
endif()
|
|
||||||
set_target_properties(raylib_static PROPERTIES PUBLIC_HEADER "raylib.h")
|
|
||||||
if(NOT MSVC) # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
|
|
||||||
set_target_properties(raylib_static PROPERTIES OUTPUT_NAME raylib)
|
|
||||||
endif()
|
|
||||||
install(
|
|
||||||
TARGETS raylib_static
|
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
||||||
)
|
|
||||||
set_target_properties(raylib_static PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
|
|
||||||
add_test("pkg-config--static" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh --static)
|
add_test("pkg-config--static" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh --static)
|
||||||
endif (STATIC)
|
endif (STATIC)
|
||||||
|
|
@ -215,12 +63,7 @@ endif(STATIC)
|
||||||
|
|
||||||
if (SHARED)
|
if (SHARED)
|
||||||
MESSAGE(STATUS "Building raylib shared library")
|
MESSAGE(STATUS "Building raylib shared library")
|
||||||
add_library(raylib SHARED ${sources})
|
add_library(raylib SHARED ${raylib_sources} ${raylib_public_headers})
|
||||||
|
|
||||||
target_compile_definitions(raylib
|
|
||||||
PUBLIC ${PLATFORM_CPP}
|
|
||||||
PUBLIC ${GRAPHICS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_definitions(raylib
|
target_compile_definitions(raylib
|
||||||
|
|
@ -229,75 +72,48 @@ if(SHARED)
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(PKG_CONFIG_LIBS_EXTRA "")
|
add_test("pkg-config" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh)
|
||||||
|
|
||||||
set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
||||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
||||||
set(CMAKE_MACOSX_RPATH ON)
|
|
||||||
|
|
||||||
target_link_libraries(raylib ${LIBS_PRIVATE})
|
|
||||||
if (${PLATFORM} MATCHES "Desktop")
|
|
||||||
target_link_libraries(raylib glfw)
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# Setting target properties
|
||||||
set_target_properties(raylib PROPERTIES
|
set_target_properties(raylib PROPERTIES
|
||||||
PUBLIC_HEADER "raylib.h"
|
PUBLIC_HEADER "${raylib_public_headers}"
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
SOVERSION ${API_VERSION}
|
SOVERSION ${API_VERSION}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (WITH_PIC OR SHARED)
|
||||||
install(
|
set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
TARGETS raylib
|
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
|
||||||
PUBLIC_HEADER DESTINATION "include"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
install(
|
|
||||||
TARGETS raylib
|
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
set_target_properties(raylib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
|
|
||||||
add_test("pkg-config" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh)
|
|
||||||
else(SHARED)
|
|
||||||
add_library(raylib ALIAS raylib_static)
|
|
||||||
endif(SHARED)
|
|
||||||
|
|
||||||
if (NOT DEFINED PKG_CONFIG_LIBS_EXTRA)
|
|
||||||
set(PKG_CONFIG_LIBS_EXTRA "${PKG_CONFIG_LIBS_PRIVATE}")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
|
# Linking libraries
|
||||||
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
target_link_libraries(raylib "${LIBS_PRIVATE}")
|
||||||
|
if (${PLATFORM} MATCHES "Desktop")
|
||||||
|
target_link_libraries(raylib glfw)
|
||||||
|
endif ()
|
||||||
|
|
||||||
configure_file(../raylib.pc.in raylib.pc @ONLY)
|
# Adding compile definitions
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
target_compile_definitions(raylib
|
||||||
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
|
PUBLIC "${PLATFORM_CPP}"
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
|
PUBLIC "${GRAPHICS}"
|
||||||
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
|
)
|
||||||
|
|
||||||
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
|
# Registering include directories
|
||||||
include(PopulateConfigVariablesLocally)
|
target_include_directories(raylib
|
||||||
populate_config_variables_locally(raylib)
|
PUBLIC
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
|
PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_BINARY_DIR} # For cmake/config.h
|
||||||
|
${OPENGL_INCLUDE_DIR}
|
||||||
|
${OPENAL_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
# Copy the header files to the build directory
|
# Copy the header files to the build directory for convenience
|
||||||
file(COPY "raylib.h" DESTINATION ".")
|
file(COPY ${raylib_public_headers} DESTINATION "include")
|
||||||
file(COPY "rlgl.h" DESTINATION ".")
|
|
||||||
file(COPY "physac.h" DESTINATION ".")
|
|
||||||
file(COPY "raymath.h" DESTINATION ".")
|
|
||||||
file(COPY "raudio.h" DESTINATION ".")
|
|
||||||
|
|
||||||
# Also install them
|
include(InstallConfigurations)
|
||||||
install(FILES "raylib.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
install(FILES "rlgl.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
install(FILES "physac.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
install(FILES "raymath.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
install(FILES "raudio.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
|
|
||||||
# Print the flags for the user
|
# Print the flags for the user
|
||||||
if (DEFINED CMAKE_BUILD_TYPE)
|
if (DEFINED CMAKE_BUILD_TYPE)
|
||||||
|
|
@ -305,22 +121,11 @@ if (DEFINED CMAKE_BUILD_TYPE)
|
||||||
else ()
|
else ()
|
||||||
message(STATUS "Generated config types: ${CMAKE_CONFIGURATION_TYPES}")
|
message(STATUS "Generated config types: ${CMAKE_CONFIGURATION_TYPES}")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Compiling with the flags:")
|
message(STATUS "Compiling with the flags:")
|
||||||
message(STATUS " PLATFORM=" ${PLATFORM_CPP})
|
message(STATUS " PLATFORM=" ${PLATFORM_CPP})
|
||||||
message(STATUS " GRAPHICS=" ${GRAPHICS})
|
message(STATUS " GRAPHICS=" ${GRAPHICS})
|
||||||
|
|
||||||
# Packaging
|
include(PackConfigurations)
|
||||||
SET(CPACK_PACKAGE_NAME "raylib")
|
|
||||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to enjoy videogames programming")
|
|
||||||
SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
|
||||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
|
|
||||||
SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
|
|
||||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE")
|
|
||||||
SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
|
|
||||||
SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
|
|
||||||
include(CPack)
|
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
// Edit to control what features Makefile'd raylib is compiled with
|
// Edit to control what features Makefile'd raylib is compiled with
|
||||||
#if defined(RAYLIB_CMAKE)
|
#if defined(RAYLIB_CMAKE)
|
||||||
// Edit CMakeOptions.txt for CMake instead
|
// Edit cmake/RaylibOptions.cmake for CMake instead
|
||||||
#include "cmake/config.h"
|
#include "cmake/config.h"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
@ -77,6 +77,8 @@
|
||||||
|
|
||||||
#define STORAGE_DATA_FILE "storage.data" // Automatic storage filename
|
#define STORAGE_DATA_FILE "storage.data" // Automatic storage filename
|
||||||
|
|
||||||
|
#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module: rlgl - Configuration Flags
|
// Module: rlgl - Configuration Flags
|
||||||
|
|
|
||||||
191
src/core.c
191
src/core.c
|
|
@ -150,6 +150,14 @@
|
||||||
#include "external/msf_gif.h" // Support GIF recording
|
#include "external/msf_gif.h" // Support GIF recording
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SUPPORT_COMPRESSION_API)
|
||||||
|
#define SINFL_IMPLEMENTATION
|
||||||
|
#include "external/sinfl.h"
|
||||||
|
|
||||||
|
#define SDEFL_IMPLEMENTATION
|
||||||
|
#include "external/sdefl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
||||||
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
|
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
|
||||||
#include <string.h> // Required for: strrchr(), strcmp(), strlen()
|
#include <string.h> // Required for: strrchr(), strcmp(), strlen()
|
||||||
|
|
@ -333,12 +341,6 @@ typedef struct {
|
||||||
bool isKeyboard; // True if device has letter keycodes
|
bool isKeyboard; // True if device has letter keycodes
|
||||||
bool isGamepad; // True if device has gamepad buttons
|
bool isGamepad; // True if device has gamepad buttons
|
||||||
} InputEventWorker;
|
} InputEventWorker;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int contents[8]; // Key events FIFO contents (8 positions)
|
|
||||||
char head; // Key events FIFO head position
|
|
||||||
char tail; // Key events FIFO tail position
|
|
||||||
} KeyEventFifo;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct { int x; int y; } Point;
|
typedef struct { int x; int y; } Point;
|
||||||
|
|
@ -420,7 +422,7 @@ typedef struct CoreData {
|
||||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||||
int defaultMode; // Default keyboard mode
|
int defaultMode; // Default keyboard mode
|
||||||
struct termios defaultSettings; // Default keyboard settings
|
struct termios defaultSettings; // Default keyboard settings
|
||||||
KeyEventFifo lastKeyPressed; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers)
|
int fd; // File descriptor for the evdev keyboard
|
||||||
#endif
|
#endif
|
||||||
} Keyboard;
|
} Keyboard;
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -559,7 +561,8 @@ static void RestoreTerminal(void); // Restore terminal
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void InitEvdevInput(void); // Evdev inputs initialization
|
static void InitEvdevInput(void); // Evdev inputs initialization
|
||||||
static void EventThreadSpawn(char *device); // Identifies a input device and spawns a thread to handle it if needed
|
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||||
|
static void PollKeyboardEvents(void); // Process evdev keyboard events.
|
||||||
static void *EventThread(void *arg); // Input device events reading thread
|
static void *EventThread(void *arg); // Input device events reading thread
|
||||||
|
|
||||||
static void InitGamepad(void); // Init raw gamepad input
|
static void InitGamepad(void); // Init raw gamepad input
|
||||||
|
|
@ -899,6 +902,13 @@ void CloseWindow(void)
|
||||||
|
|
||||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||||
|
|
||||||
|
// Close the evdev keyboard
|
||||||
|
if (CORE.Input.Keyboard.fd != -1)
|
||||||
|
{
|
||||||
|
close(CORE.Input.Keyboard.fd);
|
||||||
|
CORE.Input.Keyboard.fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||||
{
|
{
|
||||||
if (CORE.Input.eventWorker[i].threadId)
|
if (CORE.Input.eventWorker[i].threadId)
|
||||||
|
|
@ -907,6 +917,7 @@ void CloseWindow(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -2342,7 +2353,7 @@ const char *GetFileName(const char *filePath)
|
||||||
const char *fileName = NULL;
|
const char *fileName = NULL;
|
||||||
if (filePath != NULL) fileName = strprbrk(filePath, "\\/");
|
if (filePath != NULL) fileName = strprbrk(filePath, "\\/");
|
||||||
|
|
||||||
if (!fileName || (fileName == filePath)) return filePath;
|
if (!fileName) return filePath;
|
||||||
|
|
||||||
return fileName + 1;
|
return fileName + 1;
|
||||||
}
|
}
|
||||||
|
|
@ -2388,9 +2399,9 @@ const char *GetDirectoryPath(const char *filePath)
|
||||||
static char dirPath[MAX_FILEPATH_LENGTH];
|
static char dirPath[MAX_FILEPATH_LENGTH];
|
||||||
memset(dirPath, 0, MAX_FILEPATH_LENGTH);
|
memset(dirPath, 0, MAX_FILEPATH_LENGTH);
|
||||||
|
|
||||||
// In case provided path does not contains a root drive letter (C:\, D:\),
|
// In case provided path does not contain a root drive letter (C:\, D:\) nor leading path separator (\, /),
|
||||||
// we add the current directory path to dirPath
|
// we add the current directory path to dirPath
|
||||||
if (filePath[1] != ':')
|
if (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/')
|
||||||
{
|
{
|
||||||
// For security, we set starting path to current directory,
|
// For security, we set starting path to current directory,
|
||||||
// obtained path will be concated to this
|
// obtained path will be concated to this
|
||||||
|
|
@ -2400,10 +2411,19 @@ const char *GetDirectoryPath(const char *filePath)
|
||||||
|
|
||||||
lastSlash = strprbrk(filePath, "\\/");
|
lastSlash = strprbrk(filePath, "\\/");
|
||||||
if (lastSlash)
|
if (lastSlash)
|
||||||
|
{
|
||||||
|
if (lastSlash == filePath)
|
||||||
|
{
|
||||||
|
// The last and only slash is the leading one: path is in a root directory
|
||||||
|
dirPath[0] = filePath[0];
|
||||||
|
dirPath[1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
|
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
|
||||||
memcpy(dirPath + ((filePath[1] != ':')? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1));
|
memcpy(dirPath + (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/' ? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1));
|
||||||
dirPath[strlen(filePath) - strlen(lastSlash) + ((filePath[1] != ':')? 2 : 0)] = '\0'; // Add '\0' manually
|
dirPath[strlen(filePath) - strlen(lastSlash) + (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/' ? 2 : 0)] = '\0'; // Add '\0' manually
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dirPath;
|
return dirPath;
|
||||||
|
|
@ -2555,7 +2575,13 @@ unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLe
|
||||||
unsigned char *compData = NULL;
|
unsigned char *compData = NULL;
|
||||||
|
|
||||||
#if defined(SUPPORT_COMPRESSION_API)
|
#if defined(SUPPORT_COMPRESSION_API)
|
||||||
compData = stbi_zlib_compress(data, dataLength, compDataLength, COMPRESSION_QUALITY_DEFLATE);
|
// Compress data and generate a valid DEFLATE stream
|
||||||
|
struct sdefl sdefl = { 0 };
|
||||||
|
int bounds = sdefl_bound(dataLength);
|
||||||
|
compData = (unsigned char *)RL_CALLOC(bounds, 1);
|
||||||
|
*compDataLength = sdeflate(&sdefl, compData, data, dataLength, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbwi
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "SYSTEM: Data compressed: Original size: %i -> Comp. size: %i\n", dataLength, compDataLength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return compData;
|
return compData;
|
||||||
|
|
@ -2567,7 +2593,13 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
|
|
||||||
#if defined(SUPPORT_COMPRESSION_API)
|
#if defined(SUPPORT_COMPRESSION_API)
|
||||||
data = stbi_zlib_decode_malloc((char *)compData, compDataLength, dataLength);
|
// Decompress data from a valid DEFLATE stream
|
||||||
|
data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1);
|
||||||
|
int length = sinflate(data, compData, compDataLength);
|
||||||
|
RL_REALLOC(data, length);
|
||||||
|
*dataLength = length;
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "SYSTEM: Data compressed: Original size: %i -> Comp. size: %i\n", dataLength, compDataLength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (unsigned char *)data;
|
return (unsigned char *)data;
|
||||||
|
|
@ -4275,14 +4307,7 @@ static void PollInputEvents(void)
|
||||||
// Register previous keys states
|
// Register previous keys states
|
||||||
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
|
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
|
||||||
|
|
||||||
// Grab a keypress from the evdev fifo if avalable
|
PollKeyboardEvents();
|
||||||
if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail)
|
|
||||||
{
|
|
||||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer
|
|
||||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
|
||||||
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register previous mouse states
|
// Register previous mouse states
|
||||||
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
||||||
|
|
@ -5353,6 +5378,9 @@ static void InitEvdevInput(void)
|
||||||
DIR *directory;
|
DIR *directory;
|
||||||
struct dirent *entity;
|
struct dirent *entity;
|
||||||
|
|
||||||
|
// Initialise keyboard file descriptor
|
||||||
|
CORE.Input.Keyboard.fd = -1;
|
||||||
|
|
||||||
// Reset variables
|
// Reset variables
|
||||||
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -5360,10 +5388,6 @@ static void InitEvdevInput(void)
|
||||||
CORE.Input.Touch.position[i].y = -1;
|
CORE.Input.Touch.position[i].y = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset keypress buffer
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.head = 0;
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.tail = 0;
|
|
||||||
|
|
||||||
// Reset keyboard key state
|
// Reset keyboard key state
|
||||||
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
|
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
|
||||||
|
|
||||||
|
|
@ -5377,7 +5401,7 @@ static void InitEvdevInput(void)
|
||||||
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
|
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
|
||||||
{
|
{
|
||||||
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
||||||
EventThreadSpawn(path); // Identify the device and spawn a thread for it
|
ConfigureEvdevDevice(path); // Configure the device if appropriate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5386,8 +5410,8 @@ static void InitEvdevInput(void)
|
||||||
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
|
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identifies a input device and spawns a thread to handle it if needed
|
// Identifies a input device and configures it for use if appropriate
|
||||||
static void EventThreadSpawn(char *device)
|
static void ConfigureEvdevDevice(char *device)
|
||||||
{
|
{
|
||||||
#define BITS_PER_LONG (8*sizeof(long))
|
#define BITS_PER_LONG (8*sizeof(long))
|
||||||
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
|
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
|
||||||
|
|
@ -5459,7 +5483,7 @@ static void EventThreadSpawn(char *device)
|
||||||
|
|
||||||
// Identify the device
|
// Identify the device
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the avalable device properties
|
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties
|
||||||
|
|
||||||
// Check for absolute input devices
|
// Check for absolute input devices
|
||||||
if (TEST_BIT(evBits, EV_ABS))
|
if (TEST_BIT(evBits, EV_ABS))
|
||||||
|
|
@ -5535,15 +5559,22 @@ static void EventThreadSpawn(char *device)
|
||||||
|
|
||||||
// Decide what to do with the device
|
// Decide what to do with the device
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
if (worker->isTouch || worker->isMouse || worker->isKeyboard)
|
if (worker->isKeyboard && CORE.Input.Keyboard.fd == -1)
|
||||||
|
{
|
||||||
|
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
||||||
|
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
||||||
|
// threads so that they don't drop events when the frame rate is slow.
|
||||||
|
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
|
||||||
|
CORE.Input.Keyboard.fd = worker->fd;
|
||||||
|
}
|
||||||
|
else if (worker->isTouch || worker->isMouse)
|
||||||
{
|
{
|
||||||
// Looks like an interesting device
|
// Looks like an interesting device
|
||||||
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s%s)", device,
|
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device,
|
||||||
worker->isMouse? "mouse " : "",
|
worker->isMouse? "mouse " : "",
|
||||||
worker->isMultitouch? "multitouch " : "",
|
worker->isMultitouch? "multitouch " : "",
|
||||||
worker->isTouch? "touchscreen " : "",
|
worker->isTouch? "touchscreen " : "",
|
||||||
worker->isGamepad? "gamepad " : "",
|
worker->isGamepad? "gamepad " : "");
|
||||||
worker->isKeyboard? "keyboard " : "");
|
|
||||||
|
|
||||||
// Create a thread for this device
|
// Create a thread for this device
|
||||||
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
|
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
|
||||||
|
|
@ -5563,7 +5594,7 @@ static void EventThreadSpawn(char *device)
|
||||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find toucnscreens with lower indexes
|
// Find touchscreens with lower indexes
|
||||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||||
{
|
{
|
||||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
||||||
|
|
@ -5582,8 +5613,7 @@ static void EventThreadSpawn(char *device)
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input device events reading thread
|
static void PollKeyboardEvents(void)
|
||||||
static void *EventThread(void *arg)
|
|
||||||
{
|
{
|
||||||
// Scancode to keycode mapping for US keyboards
|
// Scancode to keycode mapping for US keyboards
|
||||||
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
|
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
|
||||||
|
|
@ -5605,12 +5635,62 @@ static void *EventThread(void *arg)
|
||||||
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
|
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
|
||||||
243,244,245,246,247,248,0,0,0,0,0,0,0, };
|
243,244,245,246,247,248,0,0,0,0,0,0,0, };
|
||||||
|
|
||||||
|
int fd = CORE.Input.Keyboard.fd;
|
||||||
|
if (fd == -1) return;
|
||||||
|
|
||||||
|
struct input_event event;
|
||||||
|
int keycode;
|
||||||
|
|
||||||
|
// Try to read data from the keyboard and only continue if successful
|
||||||
|
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
|
||||||
|
{
|
||||||
|
// Button parsing
|
||||||
|
if (event.type == EV_KEY)
|
||||||
|
{
|
||||||
|
// Keyboard button parsing
|
||||||
|
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
||||||
|
{
|
||||||
|
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
|
||||||
|
|
||||||
|
// Make sure we got a valid keycode
|
||||||
|
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
|
||||||
|
{
|
||||||
|
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
|
||||||
|
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
|
||||||
|
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
|
||||||
|
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
|
||||||
|
if (event.value >= 1)
|
||||||
|
{
|
||||||
|
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
|
||||||
|
CORE.Input.Keyboard.keyPressedQueueCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||||
|
// Check screen capture key (raylib key: KEY_F12)
|
||||||
|
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
|
||||||
|
{
|
||||||
|
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||||
|
screenshotCounter++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
|
||||||
|
|
||||||
|
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input device events reading thread
|
||||||
|
static void *EventThread(void *arg)
|
||||||
|
{
|
||||||
struct input_event event;
|
struct input_event event;
|
||||||
InputEventWorker *worker = (InputEventWorker *)arg;
|
InputEventWorker *worker = (InputEventWorker *)arg;
|
||||||
|
|
||||||
int touchAction = -1;
|
int touchAction = -1;
|
||||||
bool gestureUpdate = false;
|
bool gestureUpdate = false;
|
||||||
int keycode;
|
|
||||||
|
|
||||||
while (!CORE.Window.shouldClose)
|
while (!CORE.Window.shouldClose)
|
||||||
{
|
{
|
||||||
|
|
@ -5710,39 +5790,6 @@ static void *EventThread(void *arg)
|
||||||
|
|
||||||
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
|
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
|
||||||
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
|
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
|
||||||
|
|
||||||
// Keyboard button parsing
|
|
||||||
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
|
||||||
{
|
|
||||||
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
|
|
||||||
|
|
||||||
// Make sure we got a valid keycode
|
|
||||||
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
|
|
||||||
{
|
|
||||||
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
|
|
||||||
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
|
|
||||||
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
|
|
||||||
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
|
|
||||||
if (event.value >= 1)
|
|
||||||
{
|
|
||||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
|
|
||||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
|
||||||
// Check screen capture key (raylib key: KEY_F12)
|
|
||||||
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
|
|
||||||
{
|
|
||||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
|
||||||
screenshotCounter++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
|
|
||||||
|
|
||||||
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Screen confinement
|
// Screen confinement
|
||||||
|
|
|
||||||
2422
src/external/miniaudio.h
vendored
2422
src/external/miniaudio.h
vendored
File diff suppressed because it is too large
Load Diff
697
src/external/sdefl.h
vendored
Normal file
697
src/external/sdefl.h
vendored
Normal file
|
|
@ -0,0 +1,697 @@
|
||||||
|
/*
|
||||||
|
# Small Deflate
|
||||||
|
`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
|
||||||
|
which implements the Deflate (RFC 1951) compressed data format specification standard.
|
||||||
|
It is mainly tuned to get as much speed and compression ratio from as little code
|
||||||
|
as needed to keep the implementation as concise as possible.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Portable single header and source file duo written in ANSI C (ISO C90)
|
||||||
|
- Dual license with either MIT or public domain
|
||||||
|
- Small implementation
|
||||||
|
- Deflate: 525 LoC
|
||||||
|
- Inflate: 320 LoC
|
||||||
|
- Webassembly:
|
||||||
|
- Deflate ~3.7 KB (~2.2KB compressed)
|
||||||
|
- Inflate ~3.6 KB (~2.2KB compressed)
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
This file behaves differently depending on what symbols you define
|
||||||
|
before including it.
|
||||||
|
|
||||||
|
Header-File mode:
|
||||||
|
If you do not define `SDEFL_IMPLEMENTATION` before including this file, it
|
||||||
|
will operate in header only mode. In this mode it declares all used structs
|
||||||
|
and the API of the library without including the implementation of the library.
|
||||||
|
|
||||||
|
Implementation mode:
|
||||||
|
If you define `SDEFL_IMPLEMENTATION` before including this file, it will
|
||||||
|
compile the implementation . Make sure that you only include
|
||||||
|
this file implementation in *one* C or C++ file to prevent collisions.
|
||||||
|
|
||||||
|
### Benchmark
|
||||||
|
|
||||||
|
| Compressor name | Compression| Decompress.| Compr. size | Ratio |
|
||||||
|
| ------------------------| -----------| -----------| ----------- | ----- |
|
||||||
|
| sdefl 1.0 -0 | 127 MB/s | 233 MB/s | 40004116 | 39.88 |
|
||||||
|
| sdefl 1.0 -1 | 111 MB/s | 259 MB/s | 38940674 | 38.82 |
|
||||||
|
| sdefl 1.0 -5 | 45 MB/s | 275 MB/s | 36577183 | 36.46 |
|
||||||
|
| sdefl 1.0 -7 | 38 MB/s | 276 MB/s | 36523781 | 36.41 |
|
||||||
|
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
|
||||||
|
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
|
||||||
|
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
|
||||||
|
| miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
|
||||||
|
| miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
|
||||||
|
| miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
|
||||||
|
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
|
||||||
|
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
|
||||||
|
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
|
||||||
|
| libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
|
||||||
|
|
||||||
|
### Compression
|
||||||
|
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
|
||||||
|
|
||||||
|
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
|
||||||
|
| :------ | ---------: | -----------------: | ---------: | ----------: |
|
||||||
|
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
|
||||||
|
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
|
||||||
|
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
|
||||||
|
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
|
||||||
|
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
|
||||||
|
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
|
||||||
|
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
|
||||||
|
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
|
||||||
|
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
|
||||||
|
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
|
||||||
|
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
|
||||||
|
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
|
||||||
|
|
||||||
|
## License
|
||||||
|
```
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This software is available under 2 licenses -- choose whichever you prefer.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE A - MIT License
|
||||||
|
Copyright (c) 2020 Micha Mettke
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and successors. We intend this dedication to be an
|
||||||
|
overt act of relinquishment in perpetuity of all present and future rights to
|
||||||
|
this software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
#ifndef SDEFL_H_INCLUDED
|
||||||
|
#define SDEFL_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDEFL_MAX_OFF (1 << 15)
|
||||||
|
#define SDEFL_WIN_SIZ SDEFL_MAX_OFF
|
||||||
|
#define SDEFL_WIN_MSK (SDEFL_WIN_SIZ-1)
|
||||||
|
|
||||||
|
#define SDEFL_HASH_BITS 15
|
||||||
|
#define SDEFL_HASH_SIZ (1 << SDEFL_HASH_BITS)
|
||||||
|
#define SDEFL_HASH_MSK (SDEFL_HASH_SIZ-1)
|
||||||
|
|
||||||
|
#define SDEFL_MIN_MATCH 4
|
||||||
|
#define SDEFL_BLK_MAX (256*1024)
|
||||||
|
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX + SDEFL_MIN_MATCH)/SDEFL_MIN_MATCH)
|
||||||
|
|
||||||
|
#define SDEFL_SYM_MAX (288)
|
||||||
|
#define SDEFL_OFF_MAX (32)
|
||||||
|
#define SDEFL_PRE_MAX (19)
|
||||||
|
|
||||||
|
#define SDEFL_LVL_MIN 0
|
||||||
|
#define SDEFL_LVL_DEF 5
|
||||||
|
#define SDEFL_LVL_MAX 8
|
||||||
|
|
||||||
|
struct sdefl_freq {
|
||||||
|
unsigned lit[SDEFL_SYM_MAX];
|
||||||
|
unsigned off[SDEFL_OFF_MAX];
|
||||||
|
};
|
||||||
|
struct sdefl_code_words {
|
||||||
|
unsigned lit[SDEFL_SYM_MAX];
|
||||||
|
unsigned off[SDEFL_OFF_MAX];
|
||||||
|
};
|
||||||
|
struct sdefl_lens {
|
||||||
|
unsigned char lit[SDEFL_SYM_MAX];
|
||||||
|
unsigned char off[SDEFL_OFF_MAX];
|
||||||
|
};
|
||||||
|
struct sdefl_codes {
|
||||||
|
struct sdefl_code_words word;
|
||||||
|
struct sdefl_lens len;
|
||||||
|
};
|
||||||
|
struct sdefl_seqt {
|
||||||
|
int off, len;
|
||||||
|
};
|
||||||
|
struct sdefl {
|
||||||
|
int bits, bitcnt;
|
||||||
|
int tbl[SDEFL_HASH_SIZ];
|
||||||
|
int prv[SDEFL_WIN_SIZ];
|
||||||
|
|
||||||
|
int seq_cnt;
|
||||||
|
struct sdefl_seqt seq[SDEFL_SEQ_SIZ];
|
||||||
|
struct sdefl_freq freq;
|
||||||
|
struct sdefl_codes cod;
|
||||||
|
};
|
||||||
|
extern int sdefl_bound(int in_len);
|
||||||
|
extern int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
|
||||||
|
extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SDEFL_H_INCLUDED */
|
||||||
|
|
||||||
|
#ifdef SDEFL_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include <assert.h> /* assert */
|
||||||
|
#include <string.h> /* memcpy */
|
||||||
|
#include <limits.h> /* CHAR_BIT */
|
||||||
|
|
||||||
|
#define SDEFL_NIL (-1)
|
||||||
|
#define SDEFL_MAX_MATCH 258
|
||||||
|
#define SDEFL_MAX_CODE_LEN (15)
|
||||||
|
#define SDEFL_SYM_BITS (10u)
|
||||||
|
#define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
|
||||||
|
#define SDEFL_LIT_LEN_CODES (14)
|
||||||
|
#define SDEFL_OFF_CODES (15)
|
||||||
|
#define SDEFL_PRE_CODES (7)
|
||||||
|
#define SDEFL_CNT_NUM(n) ((((n)+3u/4u)+3u)&~3u)
|
||||||
|
#define SDEFL_EOB (256)
|
||||||
|
|
||||||
|
#define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
|
||||||
|
|
||||||
|
static int
|
||||||
|
sdefl_ilog2(int n) {
|
||||||
|
if (!n) return 0;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
unsigned long msbp = 0;
|
||||||
|
_BitScanReverse(&msbp, (unsigned long)n);
|
||||||
|
return (int)msbp;
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
return (int)sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl((unsigned long)n);
|
||||||
|
#else
|
||||||
|
#define lt(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
|
||||||
|
static const char tbl[256] = {
|
||||||
|
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4), lt(5), lt(5), lt(6), lt(6), lt(6), lt(6),
|
||||||
|
lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7)};
|
||||||
|
int tt, t;
|
||||||
|
if ((tt = (n >> 16))) {
|
||||||
|
return (t = (tt >> 8)) ? 24 + tbl[t] : 16 + tbl[tt];
|
||||||
|
} else {
|
||||||
|
return (t = (n >> 8)) ? 8 + tbl[t] : tbl[n];
|
||||||
|
}
|
||||||
|
#undef lt
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sdefl_uload32(const void *p) {
|
||||||
|
/* hopefully will be optimized to an unaligned read */
|
||||||
|
unsigned n = 0;
|
||||||
|
memcpy(&n, p, sizeof(n));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sdefl_hash32(const void *p) {
|
||||||
|
unsigned n = sdefl_uload32(p);
|
||||||
|
return (n * 0x9E377989) >> (32 - SDEFL_HASH_BITS);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_put(unsigned char **dst, struct sdefl *s, int code, int bitcnt) {
|
||||||
|
s->bits |= (code << s->bitcnt);
|
||||||
|
s->bitcnt += bitcnt;
|
||||||
|
while (s->bitcnt >= 8) {
|
||||||
|
unsigned char *tar = *dst;
|
||||||
|
*tar = (unsigned char)(s->bits & 0xFF);
|
||||||
|
s->bits >>= 8;
|
||||||
|
s->bitcnt -= 8;
|
||||||
|
*dst = *dst + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_heap_sub(unsigned A[], unsigned len, unsigned sub) {
|
||||||
|
unsigned c, p = sub;
|
||||||
|
unsigned v = A[sub];
|
||||||
|
while ((c = p << 1) <= len) {
|
||||||
|
if (c < len && A[c + 1] > A[c]) c++;
|
||||||
|
if (v >= A[c]) break;
|
||||||
|
A[p] = A[c], p = c;
|
||||||
|
}
|
||||||
|
A[p] = v;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_heap_array(unsigned *A, unsigned len) {
|
||||||
|
unsigned sub;
|
||||||
|
for (sub = len >> 1; sub >= 1; sub--)
|
||||||
|
sdefl_heap_sub(A, len, sub);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_heap_sort(unsigned *A, unsigned n) {
|
||||||
|
A--;
|
||||||
|
sdefl_heap_array(A, n);
|
||||||
|
while (n >= 2) {
|
||||||
|
unsigned tmp = A[n];
|
||||||
|
A[n--] = A[1];
|
||||||
|
A[1] = tmp;
|
||||||
|
sdefl_heap_sub(A, n, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sdefl_sort_sym(unsigned sym_cnt, unsigned *freqs,
|
||||||
|
unsigned char *lens, unsigned *sym_out) {
|
||||||
|
unsigned cnts[SDEFL_CNT_NUM(SDEFL_SYM_MAX)] = {0};
|
||||||
|
unsigned cnt_num = SDEFL_CNT_NUM(sym_cnt);
|
||||||
|
unsigned used_sym = 0;
|
||||||
|
unsigned sym, i;
|
||||||
|
for (sym = 0; sym < sym_cnt; sym++)
|
||||||
|
cnts[freqs[sym] < cnt_num-1 ? freqs[sym]: cnt_num-1]++;
|
||||||
|
for (i = 1; i < cnt_num; i++) {
|
||||||
|
unsigned cnt = cnts[i];
|
||||||
|
cnts[i] = used_sym;
|
||||||
|
used_sym += cnt;
|
||||||
|
}
|
||||||
|
for (sym = 0; sym < sym_cnt; sym++) {
|
||||||
|
unsigned freq = freqs[sym];
|
||||||
|
if (freq) {
|
||||||
|
unsigned idx = freq < cnt_num-1 ? freq : cnt_num-1;
|
||||||
|
sym_out[cnts[idx]++] = sym | (freq << SDEFL_SYM_BITS);
|
||||||
|
} else lens[sym] = 0;
|
||||||
|
}
|
||||||
|
sdefl_heap_sort(sym_out + cnts[cnt_num-2], cnts[cnt_num-1] - cnts[cnt_num-2]);
|
||||||
|
return used_sym;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_build_tree(unsigned *A, unsigned sym_cnt) {
|
||||||
|
unsigned i = 0, b = 0, e = 0;
|
||||||
|
do {
|
||||||
|
unsigned m, n, freq_shift;
|
||||||
|
if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
|
||||||
|
m = i++;
|
||||||
|
else m = b++;
|
||||||
|
if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
|
||||||
|
n = i++;
|
||||||
|
else n = b++;
|
||||||
|
|
||||||
|
freq_shift = (A[m] & ~SDEFL_SYM_MSK) + (A[n] & ~SDEFL_SYM_MSK);
|
||||||
|
A[m] = (A[m] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
|
||||||
|
A[n] = (A[n] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
|
||||||
|
A[e] = (A[e] & SDEFL_SYM_MSK) | freq_shift;
|
||||||
|
} while (sym_cnt - ++e > 1);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_gen_len_cnt(unsigned *A, unsigned root, unsigned *len_cnt,
|
||||||
|
unsigned max_code_len) {
|
||||||
|
int n;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i <= max_code_len; i++)
|
||||||
|
len_cnt[i] = 0;
|
||||||
|
len_cnt[1] = 2;
|
||||||
|
|
||||||
|
A[root] &= SDEFL_SYM_MSK;
|
||||||
|
for (n = (int)root - 1; n >= 0; n--) {
|
||||||
|
unsigned p = A[n] >> SDEFL_SYM_BITS;
|
||||||
|
unsigned pdepth = A[p] >> SDEFL_SYM_BITS;
|
||||||
|
unsigned depth = pdepth + 1;
|
||||||
|
unsigned len = depth;
|
||||||
|
|
||||||
|
A[n] = (A[n] & SDEFL_SYM_MSK) | (depth << SDEFL_SYM_BITS);
|
||||||
|
if (len >= max_code_len) {
|
||||||
|
len = max_code_len;
|
||||||
|
do len--; while (!len_cnt[len]);
|
||||||
|
}
|
||||||
|
len_cnt[len]--;
|
||||||
|
len_cnt[len+1] += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_gen_codes(unsigned *A, unsigned char *lens, const unsigned *len_cnt,
|
||||||
|
unsigned max_code_word_len, unsigned sym_cnt) {
|
||||||
|
unsigned i, sym, len, nxt[SDEFL_MAX_CODE_LEN + 1];
|
||||||
|
for (i = 0, len = max_code_word_len; len >= 1; len--) {
|
||||||
|
unsigned cnt = len_cnt[len];
|
||||||
|
while (cnt--) lens[A[i++] & SDEFL_SYM_MSK] = (unsigned char)len;
|
||||||
|
}
|
||||||
|
nxt[0] = nxt[1] = 0;
|
||||||
|
for (len = 2; len <= max_code_word_len; len++)
|
||||||
|
nxt[len] = (nxt[len-1] + len_cnt[len-1]) << 1;
|
||||||
|
for (sym = 0; sym < sym_cnt; sym++)
|
||||||
|
A[sym] = nxt[lens[sym]]++;
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sdefl_rev(unsigned c, unsigned char n) {
|
||||||
|
c = ((c & 0x5555) << 1) | ((c & 0xAAAA) >> 1);
|
||||||
|
c = ((c & 0x3333) << 2) | ((c & 0xCCCC) >> 2);
|
||||||
|
c = ((c & 0x0F0F) << 4) | ((c & 0xF0F0) >> 4);
|
||||||
|
c = ((c & 0x00FF) << 8) | ((c & 0xFF00) >> 8);
|
||||||
|
return c >> (16-n);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_huff(unsigned char *lens, unsigned *codes, unsigned *freqs,
|
||||||
|
unsigned num_syms, unsigned max_code_len) {
|
||||||
|
unsigned c, *A = codes;
|
||||||
|
unsigned len_cnt[SDEFL_MAX_CODE_LEN + 1];
|
||||||
|
unsigned used_syms = sdefl_sort_sym(num_syms, freqs, lens, A);
|
||||||
|
if (!used_syms) return;
|
||||||
|
if (used_syms == 1) {
|
||||||
|
unsigned s = A[0] & SDEFL_SYM_MSK;
|
||||||
|
unsigned i = s ? s : 1;
|
||||||
|
codes[0] = 0, lens[0] = 1;
|
||||||
|
codes[i] = 1, lens[i] = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sdefl_build_tree(A, used_syms);
|
||||||
|
sdefl_gen_len_cnt(A, used_syms-2, len_cnt, max_code_len);
|
||||||
|
sdefl_gen_codes(A, lens, len_cnt, max_code_len, num_syms);
|
||||||
|
for (c = 0; c < num_syms; c++) {
|
||||||
|
codes[c] = sdefl_rev(codes[c], lens[c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct sdefl_symcnt {
|
||||||
|
int items;
|
||||||
|
int lit;
|
||||||
|
int off;
|
||||||
|
};
|
||||||
|
static void
|
||||||
|
sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
|
||||||
|
const unsigned char *litlen, const unsigned char *offlen) {
|
||||||
|
unsigned *at = items;
|
||||||
|
unsigned run_start = 0;
|
||||||
|
|
||||||
|
unsigned total = 0;
|
||||||
|
unsigned char lens[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
|
||||||
|
for (cnt->lit = SDEFL_SYM_MAX; cnt->lit > 257; cnt->lit--)
|
||||||
|
if (litlen[cnt->lit - 1]) break;
|
||||||
|
for (cnt->off = SDEFL_OFF_MAX; cnt->off > 1; cnt->off--)
|
||||||
|
if (offlen[cnt->off - 1]) break;
|
||||||
|
|
||||||
|
total = (unsigned)(cnt->lit + cnt->off);
|
||||||
|
memcpy(lens, litlen, sizeof(unsigned char) * cnt->lit);
|
||||||
|
memcpy(lens + cnt->lit, offlen, sizeof(unsigned char) * cnt->off);
|
||||||
|
do {
|
||||||
|
unsigned len = lens[run_start];
|
||||||
|
unsigned run_end = run_start;
|
||||||
|
do run_end++; while (run_end != total && len == lens[run_end]);
|
||||||
|
if (!len) {
|
||||||
|
while ((run_end - run_start) >= 11) {
|
||||||
|
unsigned n = (run_end - run_start) - 11;
|
||||||
|
unsigned xbits = n < 0x7f ? n : 0x7f;
|
||||||
|
freqs[18]++;
|
||||||
|
*at++ = 18u | (xbits << 5u);
|
||||||
|
run_start += 11 + xbits;
|
||||||
|
}
|
||||||
|
if ((run_end - run_start) >= 3) {
|
||||||
|
unsigned n = (run_end - run_start) - 3;
|
||||||
|
unsigned xbits = n < 0x7 ? n : 0x7;
|
||||||
|
freqs[17]++;
|
||||||
|
*at++ = 17u | (xbits << 5u);
|
||||||
|
run_start += 3 + xbits;
|
||||||
|
}
|
||||||
|
} else if ((run_end - run_start) >= 4) {
|
||||||
|
freqs[len]++;
|
||||||
|
*at++ = len;
|
||||||
|
run_start++;
|
||||||
|
do {
|
||||||
|
unsigned xbits = (run_end - run_start) - 3;
|
||||||
|
xbits = xbits < 0x03 ? xbits : 0x03;
|
||||||
|
*at++ = 16 | (xbits << 5);
|
||||||
|
run_start += 3 + xbits;
|
||||||
|
freqs[16]++;
|
||||||
|
} while ((run_end - run_start) >= 3);
|
||||||
|
}
|
||||||
|
while (run_start != run_end) {
|
||||||
|
freqs[len]++;
|
||||||
|
*at++ = len;
|
||||||
|
run_start++;
|
||||||
|
}
|
||||||
|
} while (run_start != total);
|
||||||
|
cnt->items = (int)(at - items);
|
||||||
|
}
|
||||||
|
struct sdefl_match_codes {
|
||||||
|
int ls, lc;
|
||||||
|
int dc, dx;
|
||||||
|
};
|
||||||
|
static void
|
||||||
|
sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
|
||||||
|
static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
|
||||||
|
static const unsigned char lslot[258+1] = {
|
||||||
|
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
|
||||||
|
12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,
|
||||||
|
16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,
|
||||||
|
18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
|
20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||||
|
21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||||
|
22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
|
||||||
|
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||||
|
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
|
||||||
|
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||||
|
26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||||
|
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||||
|
27, 27, 28
|
||||||
|
};
|
||||||
|
cod->ls = lslot[len];
|
||||||
|
cod->lc = 257 + cod->ls;
|
||||||
|
cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
|
||||||
|
cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
|
||||||
|
static const char lxn[] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
|
||||||
|
static const short lmin[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,
|
||||||
|
51,59,67,83,99,115,131,163,195,227,258};
|
||||||
|
static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
|
||||||
|
385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
|
||||||
|
|
||||||
|
struct sdefl_match_codes cod;
|
||||||
|
sdefl_match_codes(&cod, dist, len);
|
||||||
|
sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
|
||||||
|
sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
|
||||||
|
sdefl_put(dst, s, (int)s->cod.word.off[cod.dc], s->cod.len.off[cod.dc]);
|
||||||
|
sdefl_put(dst, s, dist - dmin[cod.dc], cod.dx);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
|
||||||
|
const unsigned char *in) {
|
||||||
|
int j, i = 0, item_cnt = 0;
|
||||||
|
struct sdefl_symcnt symcnt = {0};
|
||||||
|
unsigned codes[SDEFL_PRE_MAX];
|
||||||
|
unsigned char lens[SDEFL_PRE_MAX];
|
||||||
|
unsigned freqs[SDEFL_PRE_MAX] = {0};
|
||||||
|
unsigned items[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
|
||||||
|
static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
|
||||||
|
4,12,3,13,2,14,1,15};
|
||||||
|
|
||||||
|
/* huffman codes */
|
||||||
|
s->freq.lit[SDEFL_EOB]++;
|
||||||
|
sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
|
||||||
|
sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
|
||||||
|
sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
|
||||||
|
sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
|
||||||
|
for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
|
||||||
|
if (lens[perm[item_cnt - 1]]) break;
|
||||||
|
}
|
||||||
|
/* block header */
|
||||||
|
sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */
|
||||||
|
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
|
||||||
|
sdefl_put(dst, s, symcnt.lit - 257, 5);
|
||||||
|
sdefl_put(dst, s, symcnt.off - 1, 5);
|
||||||
|
sdefl_put(dst, s, item_cnt - 4, 4);
|
||||||
|
for (i = 0; i < item_cnt; ++i)
|
||||||
|
sdefl_put(dst, s, lens[perm[i]], 3);
|
||||||
|
for (i = 0; i < symcnt.items; ++i) {
|
||||||
|
unsigned sym = items[i] & 0x1F;
|
||||||
|
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
|
||||||
|
if (sym < 16) continue;
|
||||||
|
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
|
||||||
|
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
|
||||||
|
else sdefl_put(dst, s, items[i] >> 5, 7);
|
||||||
|
}
|
||||||
|
/* block sequences */
|
||||||
|
for (i = 0; i < s->seq_cnt; ++i) {
|
||||||
|
if (s->seq[i].off >= 0)
|
||||||
|
for (j = 0; j < s->seq[i].len; ++j) {
|
||||||
|
int c = in[s->seq[i].off + j];
|
||||||
|
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
|
||||||
|
}
|
||||||
|
else sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
|
||||||
|
}
|
||||||
|
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
|
||||||
|
memset(&s->freq, 0, sizeof(s->freq));
|
||||||
|
s->seq_cnt = 0;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_seq(struct sdefl *s, int off, int len) {
|
||||||
|
assert(s->seq_cnt + 2 < SDEFL_SEQ_SIZ);
|
||||||
|
s->seq[s->seq_cnt].off = off;
|
||||||
|
s->seq[s->seq_cnt].len = len;
|
||||||
|
s->seq_cnt++;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sdefl_reg_match(struct sdefl *s, int off, int len) {
|
||||||
|
struct sdefl_match_codes cod;
|
||||||
|
sdefl_match_codes(&cod, off, len);
|
||||||
|
s->freq.lit[cod.lc]++;
|
||||||
|
s->freq.off[cod.dc]++;
|
||||||
|
}
|
||||||
|
struct sdefl_match {
|
||||||
|
int off;
|
||||||
|
int len;
|
||||||
|
};
|
||||||
|
static void
|
||||||
|
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s,
|
||||||
|
int chain_len, int max_match, const unsigned char *in, int p) {
|
||||||
|
int i = s->tbl[sdefl_hash32(&in[p])];
|
||||||
|
int limit = ((p-SDEFL_WIN_SIZ)<SDEFL_NIL)?SDEFL_NIL:(p-SDEFL_WIN_SIZ);
|
||||||
|
while (i > limit) {
|
||||||
|
if (in[i+m->len] == in[p+m->len] &&
|
||||||
|
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))){
|
||||||
|
int n = SDEFL_MIN_MATCH;
|
||||||
|
while (n < max_match && in[i+n] == in[p+n]) n++;
|
||||||
|
if (n > m->len) {
|
||||||
|
m->len = n, m->off = p - i;
|
||||||
|
if (n == max_match) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(--chain_len)) break;
|
||||||
|
i = s->prv[i&SDEFL_WIN_MSK];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
|
||||||
|
int in_len, int lvl) {
|
||||||
|
unsigned char *q = out;
|
||||||
|
static const unsigned char pref[] = {8,10,14,24,30,48,65,96,130};
|
||||||
|
int max_chain = (lvl < 8) ? (1 << (lvl + 1)): (1 << 13);
|
||||||
|
int n, i = 0, litlen = 0;
|
||||||
|
for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
|
||||||
|
s->tbl[n] = SDEFL_NIL;
|
||||||
|
}
|
||||||
|
do {int blk_end = i + SDEFL_BLK_MAX < in_len ? i + SDEFL_BLK_MAX : in_len;
|
||||||
|
while (i < blk_end) {
|
||||||
|
struct sdefl_match m = {0};
|
||||||
|
int max_match = ((in_len-i)>SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH:(in_len-i);
|
||||||
|
int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
|
||||||
|
int run = 1, inc = 1, run_inc;
|
||||||
|
if (max_match > SDEFL_MIN_MATCH) {
|
||||||
|
sdefl_fnd(&m, s, max_chain, max_match, in, i);
|
||||||
|
}
|
||||||
|
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len < nice_match){
|
||||||
|
struct sdefl_match m2 = {0};
|
||||||
|
sdefl_fnd(&m2, s, max_chain, m.len+1, in, i+1);
|
||||||
|
m.len = (m2.len > m.len) ? 0 : m.len;
|
||||||
|
}
|
||||||
|
if (m.len >= SDEFL_MIN_MATCH) {
|
||||||
|
if (litlen) {
|
||||||
|
sdefl_seq(s, i - litlen, litlen);
|
||||||
|
litlen = 0;
|
||||||
|
}
|
||||||
|
sdefl_seq(s, -m.off, m.len);
|
||||||
|
sdefl_reg_match(s, m.off, m.len);
|
||||||
|
if (lvl < 2 && m.len >= nice_match) {
|
||||||
|
inc = m.len;
|
||||||
|
} else {
|
||||||
|
run = m.len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s->freq.lit[in[i]]++;
|
||||||
|
litlen++;
|
||||||
|
}
|
||||||
|
run_inc = run * inc;
|
||||||
|
if (in_len - (i + run_inc) > SDEFL_MIN_MATCH) {
|
||||||
|
while (run-- > 0) {
|
||||||
|
unsigned h = sdefl_hash32(&in[i]);
|
||||||
|
s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
|
||||||
|
s->tbl[h] = i, i += inc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i += run_inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (litlen) {
|
||||||
|
sdefl_seq(s, i - litlen, litlen);
|
||||||
|
litlen = 0;
|
||||||
|
}
|
||||||
|
sdefl_flush(&q, s, blk_end == in_len, in);
|
||||||
|
} while (i < in_len);
|
||||||
|
|
||||||
|
if (s->bitcnt)
|
||||||
|
sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
|
||||||
|
return (int)(q - out);
|
||||||
|
}
|
||||||
|
extern int
|
||||||
|
sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
|
||||||
|
s->bits = s->bitcnt = 0;
|
||||||
|
return sdefl_compr(s, (unsigned char*)out, (const unsigned char*)in, n, lvl);
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sdefl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
|
||||||
|
#define SDEFL_ADLER_INIT (1)
|
||||||
|
const unsigned ADLER_MOD = 65521;
|
||||||
|
unsigned s1 = adler32 & 0xffff;
|
||||||
|
unsigned s2 = adler32 >> 16;
|
||||||
|
unsigned blk_len, i;
|
||||||
|
|
||||||
|
blk_len = in_len % 5552;
|
||||||
|
while (in_len) {
|
||||||
|
for (i = 0; i + 7 < blk_len; i += 8) {
|
||||||
|
s1 += in[0]; s2 += s1;
|
||||||
|
s1 += in[1]; s2 += s1;
|
||||||
|
s1 += in[2]; s2 += s1;
|
||||||
|
s1 += in[3]; s2 += s1;
|
||||||
|
s1 += in[4]; s2 += s1;
|
||||||
|
s1 += in[5]; s2 += s1;
|
||||||
|
s1 += in[6]; s2 += s1;
|
||||||
|
s1 += in[7]; s2 += s1;
|
||||||
|
in += 8;
|
||||||
|
}
|
||||||
|
for (; i < blk_len; ++i) {
|
||||||
|
s1 += *in++, s2 += s1;
|
||||||
|
}
|
||||||
|
s1 %= ADLER_MOD;
|
||||||
|
s2 %= ADLER_MOD;
|
||||||
|
in_len -= blk_len;
|
||||||
|
blk_len = 5552;
|
||||||
|
}
|
||||||
|
return (unsigned)(s2 << 16) + (unsigned)s1;
|
||||||
|
}
|
||||||
|
extern int
|
||||||
|
zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
|
||||||
|
int p = 0;
|
||||||
|
unsigned a = 0;
|
||||||
|
unsigned char *q = (unsigned char*)out;
|
||||||
|
|
||||||
|
s->bits = s->bitcnt = 0;
|
||||||
|
sdefl_put(&q, s, 0x78, 8); /* deflate, 32k window */
|
||||||
|
sdefl_put(&q, s, 0x01, 8); /* fast compression */
|
||||||
|
q += sdefl_compr(s, q, (const unsigned char*)in, n, lvl);
|
||||||
|
|
||||||
|
/* append adler checksum */
|
||||||
|
a = sdefl_adler32(SDEFL_ADLER_INIT, (const unsigned char*)in, n);
|
||||||
|
for (p = 0; p < 4; ++p) {
|
||||||
|
sdefl_put(&q, s, (a >> 24) & 0xFF, 8);
|
||||||
|
a <<= 8;
|
||||||
|
}
|
||||||
|
return (int)(q - (unsigned char*)out);
|
||||||
|
}
|
||||||
|
extern int
|
||||||
|
sdefl_bound(int len) {
|
||||||
|
int a = 128 + (len * 110) / 100;
|
||||||
|
int b = 128 + len + ((len / (31 * 1024)) + 1) * 5;
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
#endif /* SDEFL_IMPLEMENTATION */
|
||||||
|
|
||||||
464
src/external/sinfl.h
vendored
Normal file
464
src/external/sinfl.h
vendored
Normal file
|
|
@ -0,0 +1,464 @@
|
||||||
|
/*
|
||||||
|
# Small Deflate
|
||||||
|
`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
|
||||||
|
which implements the Deflate (RFC 1951) compressed data format specification standard.
|
||||||
|
It is mainly tuned to get as much speed and compression ratio from as little code
|
||||||
|
as needed to keep the implementation as concise as possible.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Portable single header and source file duo written in ANSI C (ISO C90)
|
||||||
|
- Dual license with either MIT or public domain
|
||||||
|
- Small implementation
|
||||||
|
- Deflate: 525 LoC
|
||||||
|
- Inflate: 320 LoC
|
||||||
|
- Webassembly:
|
||||||
|
- Deflate ~3.7 KB (~2.2KB compressed)
|
||||||
|
- Inflate ~3.6 KB (~2.2KB compressed)
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
This file behaves differently depending on what symbols you define
|
||||||
|
before including it.
|
||||||
|
|
||||||
|
Header-File mode:
|
||||||
|
If you do not define `SINFL_IMPLEMENTATION` before including this file, it
|
||||||
|
will operate in header only mode. In this mode it declares all used structs
|
||||||
|
and the API of the library without including the implementation of the library.
|
||||||
|
|
||||||
|
Implementation mode:
|
||||||
|
If you define `SINFL_IMPLEMENTATION` before including this file, it will
|
||||||
|
compile the implementation. Make sure that you only include
|
||||||
|
this file implementation in *one* C or C++ file to prevent collisions.
|
||||||
|
|
||||||
|
### Benchmark
|
||||||
|
|
||||||
|
| Compressor name | Compression| Decompress.| Compr. size | Ratio |
|
||||||
|
| ------------------------| -----------| -----------| ----------- | ----- |
|
||||||
|
| sdefl 1.0 -0 | 127 MB/s | 233 MB/s | 40004116 | 39.88 |
|
||||||
|
| sdefl 1.0 -1 | 111 MB/s | 259 MB/s | 38940674 | 38.82 |
|
||||||
|
| sdefl 1.0 -5 | 45 MB/s | 275 MB/s | 36577183 | 36.46 |
|
||||||
|
| sdefl 1.0 -7 | 38 MB/s | 276 MB/s | 36523781 | 36.41 |
|
||||||
|
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
|
||||||
|
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
|
||||||
|
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
|
||||||
|
| miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
|
||||||
|
| miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
|
||||||
|
| miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
|
||||||
|
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
|
||||||
|
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
|
||||||
|
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
|
||||||
|
| libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
|
||||||
|
|
||||||
|
### Compression
|
||||||
|
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
|
||||||
|
|
||||||
|
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
|
||||||
|
| :------ | ---------: | -----------------: | ---------: | ----------: |
|
||||||
|
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
|
||||||
|
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
|
||||||
|
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
|
||||||
|
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
|
||||||
|
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
|
||||||
|
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
|
||||||
|
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
|
||||||
|
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
|
||||||
|
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
|
||||||
|
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
|
||||||
|
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
|
||||||
|
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
|
||||||
|
|
||||||
|
## License
|
||||||
|
```
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This software is available under 2 licenses -- choose whichever you prefer.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE A - MIT License
|
||||||
|
Copyright (c) 2020 Micha Mettke
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and successors. We intend this dedication to be an
|
||||||
|
overt act of relinquishment in perpetuity of all present and future rights to
|
||||||
|
this software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
#ifndef SINFL_H_INCLUDED
|
||||||
|
#define SINFL_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SINFL_PRE_TBL_SIZE 128
|
||||||
|
#define SINFL_LIT_TBL_SIZE 1334
|
||||||
|
#define SINFL_OFF_TBL_SIZE 402
|
||||||
|
|
||||||
|
struct sinfl {
|
||||||
|
int bits, bitcnt;
|
||||||
|
unsigned lits[SINFL_LIT_TBL_SIZE];
|
||||||
|
unsigned dsts[SINFL_OFF_TBL_SIZE];
|
||||||
|
};
|
||||||
|
extern int sinflate(void *out, const void *in, int size);
|
||||||
|
extern int zsinflate(void *out, const void *in, int size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SINFL_H_INCLUDED */
|
||||||
|
|
||||||
|
#ifdef SINFL_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include <string.h> /* memcpy, memset */
|
||||||
|
|
||||||
|
static int
|
||||||
|
sinfl_bsr(unsigned n) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_BitScanReverse(&n, n);
|
||||||
|
return n;
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
return 31 - __builtin_clz(n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
sinfl_get(const unsigned char **src, const unsigned char *end, struct sinfl *s,
|
||||||
|
int n) {
|
||||||
|
const unsigned char *in = *src;
|
||||||
|
int v = s->bits & ((1 << n)-1);
|
||||||
|
s->bits >>= n;
|
||||||
|
s->bitcnt = s->bitcnt - n;
|
||||||
|
s->bitcnt = s->bitcnt < 0 ? 0 : s->bitcnt;
|
||||||
|
while (s->bitcnt < 16 && in < end) {
|
||||||
|
s->bits |= (*in++) << s->bitcnt;
|
||||||
|
s->bitcnt += 8;
|
||||||
|
}
|
||||||
|
*src = in;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
struct sinfl_gen {
|
||||||
|
int len;
|
||||||
|
int cnt;
|
||||||
|
int word;
|
||||||
|
short* sorted;
|
||||||
|
};
|
||||||
|
static int
|
||||||
|
sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
|
||||||
|
const int *cnt) {
|
||||||
|
int tbl_end = 0;
|
||||||
|
while (!(gen->cnt = cnt[gen->len])) {
|
||||||
|
++gen->len;
|
||||||
|
}
|
||||||
|
tbl_end = 1 << gen->len;
|
||||||
|
while (gen->len <= tbl_bits) {
|
||||||
|
do {unsigned bit = 0;
|
||||||
|
tbl[gen->word] = (*gen->sorted++ << 16) | gen->len;
|
||||||
|
if (gen->word == tbl_end - 1) {
|
||||||
|
for (; gen->len < tbl_bits; gen->len++) {
|
||||||
|
memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
|
||||||
|
tbl_end <<= 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1)));
|
||||||
|
gen->word &= bit - 1;
|
||||||
|
gen->word |= bit;
|
||||||
|
} while (--gen->cnt);
|
||||||
|
do {
|
||||||
|
if (++gen->len <= tbl_bits) {
|
||||||
|
memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
|
||||||
|
tbl_end <<= 1;
|
||||||
|
}
|
||||||
|
} while (!(gen->cnt = cnt[gen->len]));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
|
||||||
|
const int *cnt) {
|
||||||
|
int sub_bits = 0;
|
||||||
|
int sub_start = 0;
|
||||||
|
int sub_prefix = -1;
|
||||||
|
int tbl_end = 1 << tbl_bits;
|
||||||
|
while (1) {
|
||||||
|
unsigned entry;
|
||||||
|
int bit, stride, i;
|
||||||
|
/* start new subtable */
|
||||||
|
if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
|
||||||
|
int used = 0;
|
||||||
|
sub_prefix = gen->word & ((1 << tbl_bits)-1);
|
||||||
|
sub_start = tbl_end;
|
||||||
|
sub_bits = gen->len - tbl_bits;
|
||||||
|
used = gen->cnt;
|
||||||
|
while (used < (1 << sub_bits)) {
|
||||||
|
sub_bits++;
|
||||||
|
used = (used << 1) + cnt[tbl_bits + sub_bits];
|
||||||
|
}
|
||||||
|
tbl_end = sub_start + (1 << sub_bits);
|
||||||
|
tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
|
||||||
|
}
|
||||||
|
/* fill subtable */
|
||||||
|
entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
|
||||||
|
gen->sorted++;
|
||||||
|
i = sub_start + (gen->word >> tbl_bits);
|
||||||
|
stride = 1 << (gen->len - tbl_bits);
|
||||||
|
do {
|
||||||
|
tbl[i] = entry;
|
||||||
|
i += stride;
|
||||||
|
} while (i < tbl_end);
|
||||||
|
if (gen->word == (1 << gen->len)-1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1));
|
||||||
|
gen->word &= bit - 1;
|
||||||
|
gen->word |= bit;
|
||||||
|
gen->cnt--;
|
||||||
|
while (!gen->cnt) {
|
||||||
|
gen->cnt = cnt[++gen->len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
|
||||||
|
int symcnt) {
|
||||||
|
int i, used = 0;
|
||||||
|
short sort[288];
|
||||||
|
int cnt[16] = {0}, off[16]= {0};
|
||||||
|
struct sinfl_gen gen = {0};
|
||||||
|
gen.sorted = sort;
|
||||||
|
gen.len = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < symcnt; ++i)
|
||||||
|
cnt[lens[i]]++;
|
||||||
|
off[1] = cnt[0];
|
||||||
|
for (i = 1; i < maxlen; ++i) {
|
||||||
|
off[i + 1] = off[i] + cnt[i];
|
||||||
|
used = (used << 1) + cnt[i];
|
||||||
|
}
|
||||||
|
used = (used << 1) + cnt[i];
|
||||||
|
for (i = 0; i < symcnt; ++i)
|
||||||
|
gen.sorted[off[lens[i]]++] = (short)i;
|
||||||
|
gen.sorted += off[0];
|
||||||
|
|
||||||
|
if (used < (1 << maxlen)){
|
||||||
|
for (i = 0; i < 1 << tbl_bits; ++i)
|
||||||
|
tbl[i] = (0 << 16u) | 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){
|
||||||
|
sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
sinfl_decode(const unsigned char **in, const unsigned char *end,
|
||||||
|
struct sinfl *s, const unsigned *tbl, int bit_len) {
|
||||||
|
int idx = s->bits & ((1 << bit_len) - 1);
|
||||||
|
unsigned key = tbl[idx];
|
||||||
|
if (key & 0x10) {
|
||||||
|
/* sub-table lookup */
|
||||||
|
int len = key & 0x0f;
|
||||||
|
sinfl_get(in, end, s, bit_len);
|
||||||
|
idx = s->bits & ((1 << len)-1);
|
||||||
|
key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
|
||||||
|
}
|
||||||
|
sinfl_get(in, end, s, key & 0x0f);
|
||||||
|
return (key >> 16) & 0x0fff;
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
sinfl_decompress(unsigned char *out, const unsigned char *in, int size) {
|
||||||
|
static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
|
||||||
|
static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
|
||||||
|
257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
|
||||||
|
static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
|
||||||
|
10,10,11,11,12,12,13,13,0,0};
|
||||||
|
static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,
|
||||||
|
43,51,59,67,83,99,115,131,163,195,227,258,0,0};
|
||||||
|
static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
|
||||||
|
4,4,4,5,5,5,5,0,0,0};
|
||||||
|
|
||||||
|
const unsigned char *e = in + size, *o = out;
|
||||||
|
enum sinfl_states {hdr,stored,fixed,dyn,blk};
|
||||||
|
enum sinfl_states state = hdr;
|
||||||
|
struct sinfl s = {0};
|
||||||
|
int last = 0;
|
||||||
|
|
||||||
|
sinfl_get(&in,e,&s,0); /* buffer input */
|
||||||
|
while (in < e || s.bitcnt) {
|
||||||
|
switch (state) {
|
||||||
|
case hdr: {
|
||||||
|
int type = 0; /* block header */
|
||||||
|
last = sinfl_get(&in,e,&s,1);
|
||||||
|
type = sinfl_get(&in,e,&s,2);
|
||||||
|
|
||||||
|
switch (type) {default: return (int)(out-o);
|
||||||
|
case 0x00: state = stored; break;
|
||||||
|
case 0x01: state = fixed; break;
|
||||||
|
case 0x02: state = dyn; break;}
|
||||||
|
} break;
|
||||||
|
case stored: {
|
||||||
|
int len, nlen; /* uncompressed block */
|
||||||
|
sinfl_get(&in,e,&s,s.bitcnt & 7);
|
||||||
|
len = sinfl_get(&in,e,&s,16);
|
||||||
|
nlen = sinfl_get(&in,e,&s,16);
|
||||||
|
in -= 2; s.bitcnt = 0;
|
||||||
|
|
||||||
|
if (len > (e-in) || !len)
|
||||||
|
return (int)(out-o);
|
||||||
|
memcpy(out, in, (size_t)len);
|
||||||
|
in += len, out += len;
|
||||||
|
state = hdr;
|
||||||
|
} break;
|
||||||
|
case fixed: {
|
||||||
|
/* fixed huffman codes */
|
||||||
|
int n; unsigned char lens[288+32];
|
||||||
|
for (n = 0; n <= 143; n++) lens[n] = 8;
|
||||||
|
for (n = 144; n <= 255; n++) lens[n] = 9;
|
||||||
|
for (n = 256; n <= 279; n++) lens[n] = 7;
|
||||||
|
for (n = 280; n <= 287; n++) lens[n] = 8;
|
||||||
|
for (n = 0; n < 32; n++) lens[288+n] = 5;
|
||||||
|
|
||||||
|
/* build lit/dist tables */
|
||||||
|
sinfl_build(s.lits, lens, 10, 15, 288);
|
||||||
|
sinfl_build(s.dsts, lens + 288, 8, 15, 32);
|
||||||
|
state = blk;
|
||||||
|
} break;
|
||||||
|
case dyn: {
|
||||||
|
/* dynamic huffman codes */
|
||||||
|
int n, i;
|
||||||
|
unsigned hlens[SINFL_PRE_TBL_SIZE];
|
||||||
|
unsigned char nlens[19] = {0}, lens[288+32];
|
||||||
|
int nlit = 257 + sinfl_get(&in,e,&s,5);
|
||||||
|
int ndist = 1 + sinfl_get(&in,e,&s,5);
|
||||||
|
int nlen = 4 + sinfl_get(&in,e,&s,4);
|
||||||
|
for (n = 0; n < nlen; n++)
|
||||||
|
nlens[order[n]] = (unsigned char)sinfl_get(&in,e,&s,3);
|
||||||
|
sinfl_build(hlens, nlens, 7, 7, 19);
|
||||||
|
|
||||||
|
/* decode code lengths */
|
||||||
|
for (n = 0; n < nlit + ndist;) {
|
||||||
|
int sym = sinfl_decode(&in, e, &s, hlens, 7);
|
||||||
|
switch (sym) {default: lens[n++] = (unsigned char)sym; break;
|
||||||
|
case 16: for (i=3+sinfl_get(&in,e,&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
|
||||||
|
case 17: for (i=3+sinfl_get(&in,e,&s,3);i;i--,n++) lens[n]=0; break;
|
||||||
|
case 18: for (i=11+sinfl_get(&in,e,&s,7);i;i--,n++) lens[n]=0; break;}
|
||||||
|
}
|
||||||
|
/* build lit/dist tables */
|
||||||
|
sinfl_build(s.lits, lens, 10, 15, nlit);
|
||||||
|
sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
|
||||||
|
state = blk;
|
||||||
|
} break;
|
||||||
|
case blk: {
|
||||||
|
/* decompress block */
|
||||||
|
int i, sym = sinfl_decode(&in, e, &s, s.lits, 10);
|
||||||
|
if (sym > 256) {sym -= 257; /* match symbol */
|
||||||
|
{int len = sinfl_get(&in, e, &s, lbits[sym]) + lbase[sym];
|
||||||
|
int dsym = sinfl_decode(&in, e, &s, s.dsts, 8);
|
||||||
|
int offs = sinfl_get(&in, e, &s, dbits[dsym]) + dbase[dsym];
|
||||||
|
if (offs > (int)(out-o)) {
|
||||||
|
return (int)(out-o);
|
||||||
|
} else if (offs == 1) {
|
||||||
|
/* rle match copying */
|
||||||
|
unsigned char c = *(out - offs);
|
||||||
|
unsigned long w = (c << 24) | (c << 16) | (c << 8) | c;
|
||||||
|
for (i = 0; i < len >> 2; ++i) {
|
||||||
|
memcpy(out, &w, 4);
|
||||||
|
out += 4;
|
||||||
|
}
|
||||||
|
len = len & 3;
|
||||||
|
} else if (offs >= 4) {
|
||||||
|
/* copy match */
|
||||||
|
int wcnt = len >> 2;
|
||||||
|
for (i = 0; i < wcnt; ++i) {
|
||||||
|
unsigned long w = 0;
|
||||||
|
memcpy(&w, out - offs, 4);
|
||||||
|
memcpy(out, &w, 4);
|
||||||
|
out += 4;
|
||||||
|
}
|
||||||
|
len = len & 3;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{*out = *(out-offs), out++;}
|
||||||
|
}
|
||||||
|
} else if (sym == 256) {
|
||||||
|
/* end of block */
|
||||||
|
if (last) return (int)(out-o);
|
||||||
|
state = hdr;
|
||||||
|
break;
|
||||||
|
/* literal */
|
||||||
|
} else *out++ = (unsigned char)sym;
|
||||||
|
} break;}
|
||||||
|
}
|
||||||
|
return (int)(out-o);
|
||||||
|
}
|
||||||
|
extern int
|
||||||
|
sinflate(void *out, const void *in, int size) {
|
||||||
|
return sinfl_decompress((unsigned char*)out, (const unsigned char*)in, size);
|
||||||
|
}
|
||||||
|
static unsigned
|
||||||
|
sinfl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
|
||||||
|
const unsigned ADLER_MOD = 65521;
|
||||||
|
unsigned s1 = adler32 & 0xffff;
|
||||||
|
unsigned s2 = adler32 >> 16;
|
||||||
|
unsigned blk_len, i;
|
||||||
|
|
||||||
|
blk_len = in_len % 5552;
|
||||||
|
while (in_len) {
|
||||||
|
for (i=0; i + 7 < blk_len; i += 8) {
|
||||||
|
s1 += in[0]; s2 += s1;
|
||||||
|
s1 += in[1]; s2 += s1;
|
||||||
|
s1 += in[2]; s2 += s1;
|
||||||
|
s1 += in[3]; s2 += s1;
|
||||||
|
s1 += in[4]; s2 += s1;
|
||||||
|
s1 += in[5]; s2 += s1;
|
||||||
|
s1 += in[6]; s2 += s1;
|
||||||
|
s1 += in[7]; s2 += s1;
|
||||||
|
in += 8;
|
||||||
|
}
|
||||||
|
for (; i < blk_len; ++i)
|
||||||
|
s1 += *in++, s2 += s1;
|
||||||
|
s1 %= ADLER_MOD; s2 %= ADLER_MOD;
|
||||||
|
in_len -= blk_len;
|
||||||
|
blk_len = 5552;
|
||||||
|
} return (unsigned)(s2 << 16) + (unsigned)s1;
|
||||||
|
}
|
||||||
|
extern int
|
||||||
|
zsinflate(void *out, const void *mem, int size) {
|
||||||
|
const unsigned char *in = (const unsigned char*)mem;
|
||||||
|
if (size >= 6) {
|
||||||
|
const unsigned char *eob = in + size - 4;
|
||||||
|
int n = sinfl_decompress((unsigned char*)out, in + 2u, size);
|
||||||
|
unsigned a = sinfl_adler32(1u, (unsigned char*)out, n);
|
||||||
|
unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0;
|
||||||
|
return a == h ? n : -1;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
122
src/physac.h
122
src/physac.h
|
|
@ -125,11 +125,72 @@
|
||||||
} Vector2;
|
} Vector2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Data Types Structure Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef enum PhysicsShapeType { PHYSICS_CIRCLE, PHYSICS_POLYGON } PhysicsShapeType;
|
typedef enum PhysicsShapeType { PHYSICS_CIRCLE, PHYSICS_POLYGON } PhysicsShapeType;
|
||||||
|
|
||||||
// Previously defined to be used in PhysicsShape struct as circular dependencies
|
// Previously defined to be used in PhysicsShape struct as circular dependencies
|
||||||
typedef struct PhysicsBodyData *PhysicsBody;
|
typedef struct PhysicsBodyData *PhysicsBody;
|
||||||
|
|
||||||
|
// Matrix2x2 type (used for polygon shape rotation matrix)
|
||||||
|
typedef struct Matrix2x2 {
|
||||||
|
float m00;
|
||||||
|
float m01;
|
||||||
|
float m10;
|
||||||
|
float m11;
|
||||||
|
} Matrix2x2;
|
||||||
|
|
||||||
|
typedef struct PolygonData {
|
||||||
|
unsigned int vertexCount; // Current used vertex and normals count
|
||||||
|
Vector2 positions[PHYSAC_MAX_VERTICES]; // Polygon vertex positions vectors
|
||||||
|
Vector2 normals[PHYSAC_MAX_VERTICES]; // Polygon vertex normals vectors
|
||||||
|
} PolygonData;
|
||||||
|
|
||||||
|
typedef struct PhysicsShape {
|
||||||
|
PhysicsShapeType type; // Physics shape type (circle or polygon)
|
||||||
|
PhysicsBody body; // Shape physics body reference
|
||||||
|
float radius; // Circle shape radius (used for circle shapes)
|
||||||
|
Matrix2x2 transform; // Vertices transform matrix 2x2
|
||||||
|
PolygonData vertexData; // Polygon shape vertices position and normals data (just used for polygon shapes)
|
||||||
|
} PhysicsShape;
|
||||||
|
|
||||||
|
typedef struct PhysicsBodyData {
|
||||||
|
unsigned int id; // Reference unique identifier
|
||||||
|
bool enabled; // Enabled dynamics state (collisions are calculated anyway)
|
||||||
|
Vector2 position; // Physics body shape pivot
|
||||||
|
Vector2 velocity; // Current linear velocity applied to position
|
||||||
|
Vector2 force; // Current linear force (reset to 0 every step)
|
||||||
|
float angularVelocity; // Current angular velocity applied to orient
|
||||||
|
float torque; // Current angular force (reset to 0 every step)
|
||||||
|
float orient; // Rotation in radians
|
||||||
|
float inertia; // Moment of inertia
|
||||||
|
float inverseInertia; // Inverse value of inertia
|
||||||
|
float mass; // Physics body mass
|
||||||
|
float inverseMass; // Inverse value of mass
|
||||||
|
float staticFriction; // Friction when the body has not movement (0 to 1)
|
||||||
|
float dynamicFriction; // Friction when the body has movement (0 to 1)
|
||||||
|
float restitution; // Restitution coefficient of the body (0 to 1)
|
||||||
|
bool useGravity; // Apply gravity force to dynamics
|
||||||
|
bool isGrounded; // Physics grounded on other body state
|
||||||
|
bool freezeOrient; // Physics rotation constraint
|
||||||
|
PhysicsShape shape; // Physics body shape information (type, radius, vertices, normals)
|
||||||
|
} PhysicsBodyData;
|
||||||
|
|
||||||
|
typedef struct PhysicsManifoldData {
|
||||||
|
unsigned int id; // Reference unique identifier
|
||||||
|
PhysicsBody bodyA; // Manifold first physics body reference
|
||||||
|
PhysicsBody bodyB; // Manifold second physics body reference
|
||||||
|
float penetration; // Depth of penetration from collision
|
||||||
|
Vector2 normal; // Normal direction vector from 'a' to 'b'
|
||||||
|
Vector2 contacts[2]; // Points of contact during collision
|
||||||
|
unsigned int contactsCount; // Current collision number of contacts
|
||||||
|
float restitution; // Mixed restitution during collision
|
||||||
|
float dynamicFriction; // Mixed dynamic friction during collision
|
||||||
|
float staticFriction; // Mixed static friction during collision
|
||||||
|
} PhysicsManifoldData, *PhysicsManifold;
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" { // Prevents name mangling of functions
|
extern "C" { // Prevents name mangling of functions
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -221,67 +282,6 @@ PHYSACDEF void ClosePhysics(void);
|
||||||
#define PHYSAC_K 1.0f/3.0f
|
#define PHYSAC_K 1.0f/3.0f
|
||||||
#define PHYSAC_VECTOR_ZERO (Vector2){ 0.0f, 0.0f }
|
#define PHYSAC_VECTOR_ZERO (Vector2){ 0.0f, 0.0f }
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
// Data Types Structure Definition
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Matrix2x2 type (used for polygon shape rotation matrix)
|
|
||||||
typedef struct Matrix2x2 {
|
|
||||||
float m00;
|
|
||||||
float m01;
|
|
||||||
float m10;
|
|
||||||
float m11;
|
|
||||||
} Matrix2x2;
|
|
||||||
|
|
||||||
typedef struct PolygonData {
|
|
||||||
unsigned int vertexCount; // Current used vertex and normals count
|
|
||||||
Vector2 positions[PHYSAC_MAX_VERTICES]; // Polygon vertex positions vectors
|
|
||||||
Vector2 normals[PHYSAC_MAX_VERTICES]; // Polygon vertex normals vectors
|
|
||||||
} PolygonData;
|
|
||||||
|
|
||||||
typedef struct PhysicsShape {
|
|
||||||
PhysicsShapeType type; // Physics shape type (circle or polygon)
|
|
||||||
PhysicsBody body; // Shape physics body reference
|
|
||||||
float radius; // Circle shape radius (used for circle shapes)
|
|
||||||
Matrix2x2 transform; // Vertices transform matrix 2x2
|
|
||||||
PolygonData vertexData; // Polygon shape vertices position and normals data (just used for polygon shapes)
|
|
||||||
} PhysicsShape;
|
|
||||||
|
|
||||||
typedef struct PhysicsBodyData {
|
|
||||||
unsigned int id; // Reference unique identifier
|
|
||||||
bool enabled; // Enabled dynamics state (collisions are calculated anyway)
|
|
||||||
Vector2 position; // Physics body shape pivot
|
|
||||||
Vector2 velocity; // Current linear velocity applied to position
|
|
||||||
Vector2 force; // Current linear force (reset to 0 every step)
|
|
||||||
float angularVelocity; // Current angular velocity applied to orient
|
|
||||||
float torque; // Current angular force (reset to 0 every step)
|
|
||||||
float orient; // Rotation in radians
|
|
||||||
float inertia; // Moment of inertia
|
|
||||||
float inverseInertia; // Inverse value of inertia
|
|
||||||
float mass; // Physics body mass
|
|
||||||
float inverseMass; // Inverse value of mass
|
|
||||||
float staticFriction; // Friction when the body has not movement (0 to 1)
|
|
||||||
float dynamicFriction; // Friction when the body has movement (0 to 1)
|
|
||||||
float restitution; // Restitution coefficient of the body (0 to 1)
|
|
||||||
bool useGravity; // Apply gravity force to dynamics
|
|
||||||
bool isGrounded; // Physics grounded on other body state
|
|
||||||
bool freezeOrient; // Physics rotation constraint
|
|
||||||
PhysicsShape shape; // Physics body shape information (type, radius, vertices, normals)
|
|
||||||
} PhysicsBodyData;
|
|
||||||
|
|
||||||
typedef struct PhysicsManifoldData {
|
|
||||||
unsigned int id; // Reference unique identifier
|
|
||||||
PhysicsBody bodyA; // Manifold first physics body reference
|
|
||||||
PhysicsBody bodyB; // Manifold second physics body reference
|
|
||||||
float penetration; // Depth of penetration from collision
|
|
||||||
Vector2 normal; // Normal direction vector from 'a' to 'b'
|
|
||||||
Vector2 contacts[2]; // Points of contact during collision
|
|
||||||
unsigned int contactsCount; // Current collision number of contacts
|
|
||||||
float restitution; // Mixed restitution during collision
|
|
||||||
float dynamicFriction; // Mixed dynamic friction during collision
|
|
||||||
float staticFriction; // Mixed static friction during collision
|
|
||||||
} PhysicsManifoldData, *PhysicsManifold;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1966,13 +1966,13 @@ static int SaveWAV(Wave wave, const char *fileName)
|
||||||
format.sampleRate = wave.sampleRate;
|
format.sampleRate = wave.sampleRate;
|
||||||
format.bitsPerSample = wave.sampleSize;
|
format.bitsPerSample = wave.sampleSize;
|
||||||
|
|
||||||
unsigned char *fileData = NULL;
|
void *fileData = NULL;
|
||||||
size_t fileDataSize = 0;
|
size_t fileDataSize = 0;
|
||||||
success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
|
success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
|
||||||
if (success) success = (int)drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data);
|
if (success) success = (int)drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data);
|
||||||
drwav_result result = drwav_uninit(&wav);
|
drwav_result result = drwav_uninit(&wav);
|
||||||
|
|
||||||
if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, fileData, (unsigned int)fileDataSize);
|
if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize);
|
||||||
|
|
||||||
drwav_free(fileData, NULL);
|
drwav_free(fileData, NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -831,7 +831,7 @@ typedef enum {
|
||||||
BLEND_MULTIPLIED, // Blend textures multiplying colors
|
BLEND_MULTIPLIED, // Blend textures multiplying colors
|
||||||
BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
|
BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
|
||||||
BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
|
BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
|
||||||
BLEND_CUSTOM // Belnd textures using custom src/dst factors (use SetBlendModeCustom())
|
BLEND_CUSTOM // Belnd textures using custom src/dst factors (use rlSetBlendMode())
|
||||||
} BlendMode;
|
} BlendMode;
|
||||||
|
|
||||||
// Gestures type
|
// Gestures type
|
||||||
|
|
|
||||||
|
|
@ -1100,13 +1100,12 @@ void rlFrustum(double left, double right, double bottom, double top, double znea
|
||||||
// Multiply the current matrix by an orthographic matrix generated by parameters
|
// Multiply the current matrix by an orthographic matrix generated by parameters
|
||||||
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
||||||
{
|
{
|
||||||
if (((right - left) > 0) && ((bottom - top) > 0))
|
// NOTE: If left-right and top-botton values are equal it could create
|
||||||
{
|
// a division by zero on MatrixOrtho(), response to it is platform/compiler dependant
|
||||||
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
|
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
|
||||||
|
|
||||||
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
||||||
}
|
}
|
||||||
else *RLGL.State.currentMatrix = MatrixIdentity();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
48
src/text.c
48
src/text.c
|
|
@ -838,30 +838,6 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw one character (codepoint)
|
|
||||||
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint)
|
|
||||||
{
|
|
||||||
// Character index position in sprite font
|
|
||||||
// NOTE: In case a codepoint is not available in the font, index returned points to '?'
|
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
|
||||||
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
|
|
||||||
|
|
||||||
// Character destination rectangle on screen
|
|
||||||
// NOTE: We consider charsPadding on drawing
|
|
||||||
Rectangle dstRec = { position.x + font.chars[index].offsetX*scaleFactor - (float)font.charsPadding*scaleFactor,
|
|
||||||
position.y + font.chars[index].offsetY*scaleFactor - (float)font.charsPadding*scaleFactor,
|
|
||||||
(font.recs[index].width + 2.0f*font.charsPadding)*scaleFactor,
|
|
||||||
(font.recs[index].height + 2.0f*font.charsPadding)*scaleFactor };
|
|
||||||
|
|
||||||
// Character source rectangle from font texture atlas
|
|
||||||
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
|
|
||||||
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
|
|
||||||
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
|
|
||||||
|
|
||||||
// Draw the character texture on the screen
|
|
||||||
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw text using Font
|
// Draw text using Font
|
||||||
// NOTE: chars spacing is NOT proportional to fontSize
|
// NOTE: chars spacing is NOT proportional to fontSize
|
||||||
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
|
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
|
||||||
|
|
@ -1043,6 +1019,30 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw one character (codepoint)
|
||||||
|
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint)
|
||||||
|
{
|
||||||
|
// Character index position in sprite font
|
||||||
|
// NOTE: In case a codepoint is not available in the font, index returned points to '?'
|
||||||
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
|
||||||
|
|
||||||
|
// Character destination rectangle on screen
|
||||||
|
// NOTE: We consider charsPadding on drawing
|
||||||
|
Rectangle dstRec = { position.x + font.chars[index].offsetX*scaleFactor - (float)font.charsPadding*scaleFactor,
|
||||||
|
position.y + font.chars[index].offsetY*scaleFactor - (float)font.charsPadding*scaleFactor,
|
||||||
|
(font.recs[index].width + 2.0f*font.charsPadding)*scaleFactor,
|
||||||
|
(font.recs[index].height + 2.0f*font.charsPadding)*scaleFactor };
|
||||||
|
|
||||||
|
// Character source rectangle from font texture atlas
|
||||||
|
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
|
||||||
|
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
|
||||||
|
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
|
||||||
|
|
||||||
|
// Draw the character texture on the screen
|
||||||
|
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
|
||||||
|
}
|
||||||
|
|
||||||
// Measure string width for default font
|
// Measure string width for default font
|
||||||
int MeasureText(const char *text, int fontSize)
|
int MeasureText(const char *text, int fontSize)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||||
ifeq ($(PLATFORM_OS),LINUX)
|
ifeq ($(PLATFORM_OS),LINUX)
|
||||||
# Reset everything.
|
# Reset everything.
|
||||||
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
|
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
|
||||||
#INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
|
|
||||||
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external
|
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,15 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||||
PLATFORM_OS=LINUX
|
PLATFORM_OS=LINUX
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
|
UNAMEOS=$(shell uname)
|
||||||
|
ifeq ($(UNAMEOS),Linux)
|
||||||
|
PLATFORM_OS=LINUX
|
||||||
|
endif
|
||||||
|
ifeq ($(UNAMEOS),Darwin)
|
||||||
|
PLATFORM_OS=OSX
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# RAYLIB_PATH adjustment for different platforms.
|
# RAYLIB_PATH adjustment for different platforms.
|
||||||
# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
|
# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
|
||||||
|
|
@ -388,6 +397,15 @@ OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES))
|
||||||
# For Android platform we call a custom Makefile.Android
|
# For Android platform we call a custom Makefile.Android
|
||||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
MAKEFILE_PARAMS = -f Makefile.Android
|
MAKEFILE_PARAMS = -f Makefile.Android
|
||||||
|
# For Linux and macOS set make and makefile
|
||||||
|
ifeq ($(PLATFORM_OS),LINUX)
|
||||||
|
MAKE = make
|
||||||
|
MAKEFILE_PARAMS = -f Makefile.Android.linux
|
||||||
|
endif
|
||||||
|
ifeq ($(PLATFORM_OS),OSX)
|
||||||
|
MAKE = make
|
||||||
|
MAKEFILE_PARAMS = -f Makefile.Android.macos
|
||||||
|
endif
|
||||||
export PROJECT_NAME
|
export PROJECT_NAME
|
||||||
export PROJECT_SOURCE_FILES
|
export PROJECT_SOURCE_FILES
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
# Define required raylib variables
|
# Define required raylib variables
|
||||||
PLATFORM ?= PLATFORM_ANDROID
|
PLATFORM ?= PLATFORM_ANDROID
|
||||||
RAYLIB_PATH ?= $(HOME)/raylib_sources.ln
|
RAYLIB_PATH ?= ../../
|
||||||
|
|
||||||
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
|
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
|
||||||
ANDROID_ARCH ?= ARM64
|
ANDROID_ARCH ?= ARM64
|
||||||
|
|
@ -48,9 +48,9 @@ endif
|
||||||
# no need to define JAVA_HOME , JAVA_BIN in linux environment (binaries are in $PATH)
|
# no need to define JAVA_HOME , JAVA_BIN in linux environment (binaries are in $PATH)
|
||||||
#JAVA_HOME ?= C:/JavaJDK/
|
#JAVA_HOME ?= C:/JavaJDK/
|
||||||
#JAVA_BIN ?= $(JAVA_HOME)/bin/
|
#JAVA_BIN ?= $(JAVA_HOME)/bin/
|
||||||
ANDROID_HOME = /opt/android-sdk
|
ANDROID_HOME ?= /opt/android-sdk
|
||||||
#ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
|
#ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
|
||||||
ANDROID_TOOLCHAIN = /opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/
|
ANDROID_TOOLCHAIN ?= /opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/
|
||||||
|
|
||||||
# find the highest version available of build tools
|
# find the highest version available of build tools
|
||||||
ANDROID_BUILD_TOOLS = $(shell ls -1d $(ANDROID_HOME)/build-tools/* | tail -n 1)/
|
ANDROID_BUILD_TOOLS = $(shell ls -1d $(ANDROID_HOME)/build-tools/* | tail -n 1)/
|
||||||
|
|
@ -94,11 +94,10 @@ APP_SCREEN_ORIENTATION ?= landscape
|
||||||
APP_KEYSTORE_PASS ?= raylib
|
APP_KEYSTORE_PASS ?= raylib
|
||||||
|
|
||||||
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
|
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
|
||||||
# attention, ne fonctionne pas avec STATIC (manque la libm quelque part)
|
RAYLIB_LIBTYPE ?= STATIC
|
||||||
RAYLIB_LIBTYPE ?= SHARED
|
|
||||||
|
|
||||||
# Library path for libraylib.a/libraylib.so
|
# Library path for libraylib.a/libraylib.so
|
||||||
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src/android/
|
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src/
|
||||||
|
|
||||||
# Shared libs must be added to APK if required
|
# Shared libs must be added to APK if required
|
||||||
# NOTE: Generated NativeLoader.java automatically load those libraries
|
# NOTE: Generated NativeLoader.java automatically load those libraries
|
||||||
|
|
@ -141,7 +140,7 @@ LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl
|
||||||
# Force linking of library module to define symbol
|
# Force linking of library module to define symbol
|
||||||
LDFLAGS += -u ANativeActivity_onCreate
|
LDFLAGS += -u ANativeActivity_onCreate
|
||||||
# Library paths containing required libs
|
# Library paths containing required libs
|
||||||
LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME) -L$(ANDROID_TOOLCHAIN)/sysroot/usr/lib/$(ANDROID_TOOLCHAIN_LIBS)
|
LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)
|
||||||
|
|
||||||
# Define any libraries to link into executable
|
# Define any libraries to link into executable
|
||||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user