mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-12-06 13:16:35 +01:00
Compare commits
31 Commits
v0.8.2
...
2ea7a1529a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ea7a1529a | ||
|
|
e6403f0582 | ||
|
|
e64354e824 | ||
| cd0b35b465 | |||
| c051d36a64 | |||
| 202ba31d79 | |||
| df949a5afc | |||
| 9b173c64a6 | |||
| 3a885ee250 | |||
| 00e48f9967 | |||
| c791f4c6a1 | |||
| 7a3823db78 | |||
| 1722f61250 | |||
| 0abb860185 | |||
| 22dc949cc5 | |||
| 196ea7b93b | |||
| f655da82d5 | |||
| d672f8a52c | |||
| 6df865de3e | |||
| e9c62f9201 | |||
| 7bce78167b | |||
| a45da5c2b0 | |||
| 4ab1d99529 | |||
| f27300a8fa | |||
| 8d24976a13 | |||
| 8036fdf2a9 | |||
| 5148ea7217 | |||
| ab0e5afb94 | |||
| 191e9f6b44 | |||
| 86c52c4fac | |||
| 0c1a98cfd5 |
25
.github/workflows/cmake.yml
vendored
25
.github/workflows/cmake.yml
vendored
@@ -9,12 +9,12 @@ on:
|
|||||||
env:
|
env:
|
||||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||||
BUILD_TYPE: Debug
|
BUILD_TYPE: Debug
|
||||||
EM_VERSION: 2.0.24
|
EM_VERSION: 3.1.32
|
||||||
EM_CACHE_FOLDER: 'emsdk-cache'
|
EM_CACHE_FOLDER: 'emsdk-cache'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
timeout-minutes: 10
|
timeout-minutes: 15
|
||||||
|
|
||||||
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
|
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
|
||||||
# You can convert this to a matrix build if you need cross-platform coverage.
|
# You can convert this to a matrix build if you need cross-platform coverage.
|
||||||
@@ -26,8 +26,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
# TODO: cache
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: sudo apt update && sudo apt -y install libsdl2-dev xserver-xorg-video-dummy
|
run: sudo apt update && sudo apt -y install libsdl2-dev xserver-xorg-video-dummy
|
||||||
|
|
||||||
@@ -62,8 +60,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
# TODO: cache
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: sudo apt update && sudo apt -y install libsdl2-dev
|
run: sudo apt update && sudo apt -y install libsdl2-dev
|
||||||
|
|
||||||
@@ -102,17 +98,17 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
#- name: Install Dependencies
|
- name: Setup em cache
|
||||||
#run: sudo apt update && sudo apt -y install libsdl2-dev
|
id: em-cache-system-libraries
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{env.EM_CACHE_FOLDER}}
|
||||||
|
key: ${{env.EM_VERSION}}-${{ runner.os }}
|
||||||
|
|
||||||
- name: Setup emsdk
|
- name: Setup emsdk
|
||||||
uses: mymindstorm/setup-emsdk@v11
|
uses: mymindstorm/setup-emsdk@v14
|
||||||
with:
|
with:
|
||||||
# Make sure to set a version number!
|
|
||||||
version: ${{env.EM_VERSION}}
|
version: ${{env.EM_VERSION}}
|
||||||
# This is the name of the cache folder.
|
|
||||||
# The cache folder will be placed in the build directory,
|
|
||||||
# so make sure it doesn't conflict with anything!
|
|
||||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||||
|
|
||||||
- name: Verify
|
- name: Verify
|
||||||
@@ -134,8 +130,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
# TODO: cache
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: brew install sdl2
|
run: brew install sdl2
|
||||||
|
|
||||||
@@ -156,7 +150,6 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
# TODO: cache
|
# TODO: cache
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install sdl2[core,vulkan]:x64-windows
|
run: vcpkg install sdl2[core,vulkan]:x64-windows
|
||||||
|
|
||||||
|
|||||||
28
.vimspector.json
Normal file
28
.vimspector.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"configurations": {
|
||||||
|
"run_ctest_native": {
|
||||||
|
"default": true,
|
||||||
|
"adapter": "CodeLLDB",
|
||||||
|
"configuration": {
|
||||||
|
"request": "launch",
|
||||||
|
"stopOnEntry": true,
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"program": "ctest",
|
||||||
|
"cwd": "${workspaceRoot}/build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"run_native": {
|
||||||
|
"adapter": "CodeLLDB",
|
||||||
|
"variables": {
|
||||||
|
"Executable": "s6zer_test"
|
||||||
|
},
|
||||||
|
"configuration": {
|
||||||
|
"request": "launch",
|
||||||
|
"stopOnEntry": true,
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"program": "${workspaceRoot}/build/bin/${Executable}",
|
||||||
|
"cwd": "${workspaceRoot}/build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
|
|
||||||
if(NOT EMSCRIPTEN)
|
if(NOT EMSCRIPTEN)
|
||||||
|
|
||||||
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
|
FIND_PATH(SDL2_INCLUDE_DIR_TEMP SDL.h
|
||||||
HINTS
|
HINTS
|
||||||
$ENV{SDL2}
|
$ENV{SDL2}
|
||||||
PATH_SUFFIXES include/SDL2 include SDL2
|
PATH_SUFFIXES include/SDL2 include SDL2
|
||||||
@@ -153,7 +153,7 @@ ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|||||||
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
|
||||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
IF(NOT "${SDL2_INCLUDE_DIR_TEMP}" MATCHES ".framework")
|
||||||
# Non-OS X framework versions expect you to also dynamically link to
|
# Non-OS X framework versions expect you to also dynamically link to
|
||||||
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||||
# seem to provide SDL2main for compatibility even though they don't
|
# seem to provide SDL2main for compatibility even though they don't
|
||||||
@@ -189,7 +189,7 @@ IF(NOT SDL2_BUILDING_LIBRARY)
|
|||||||
/opt
|
/opt
|
||||||
)
|
)
|
||||||
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
ENDIF(NOT "${SDL2_INCLUDE_DIR_TEMP}" MATCHES ".framework")
|
||||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
|
|
||||||
# SDL2 may require threads on your system.
|
# SDL2 may require threads on your system.
|
||||||
@@ -208,7 +208,7 @@ IF(MINGW)
|
|||||||
ENDIF(MINGW)
|
ENDIF(MINGW)
|
||||||
|
|
||||||
SET(SDL2_FOUND "NO")
|
SET(SDL2_FOUND "NO")
|
||||||
IF(SDL2_LIBRARY_TEMP)
|
IF(SDL2_LIBRARY_TEMP)
|
||||||
# For SDL2main
|
# For SDL2main
|
||||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
IF(SDL2MAIN_LIBRARY)
|
IF(SDL2MAIN_LIBRARY)
|
||||||
@@ -243,23 +243,32 @@ SET(SDL2_FOUND "NO")
|
|||||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||||
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||||
|
|
||||||
############add_library(SDL UNKNOWN IMPORTED)
|
set(SDL2_INCLUDE_DIR ${SDL2_INCLUDE_DIR_TEMP} CACHE STRING "Where the SDL2 Headers can be found")
|
||||||
#target_link_libraries(SDL INTERFACE ${SDL2_LIBRARY})
|
SET(SDL2_INCLUDE_DIR_TEMP "${SDL2_INCLUDE_DIR_TEMP}" CACHE INTERNAL "")
|
||||||
#target_include_directories(SDL INTERFACE ${SDL2_INCLUDE_DIR})
|
|
||||||
#set_target_properties(SDL PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${SDL2_LIBRARY}")
|
|
||||||
|
|
||||||
#set_target_properties(SDL PROPERTIES
|
|
||||||
#INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}")
|
|
||||||
|
|
||||||
#set_target_properties(SDL PROPERTIES
|
|
||||||
#IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
|
||||||
#IMPORTED_LINK_INTERFACE_LIBRARIES "${SDL2_LIBRARY}"
|
|
||||||
#LINK_INTERFACE_LIBRARIES "${SDL2_LIBRARY}")
|
|
||||||
|
|
||||||
#IMPORTED_LOCATION "${SDL2_LIBRARY}")
|
|
||||||
|
|
||||||
|
|
||||||
SET(SDL2_FOUND "YES")
|
SET(SDL2_FOUND "YES")
|
||||||
|
else() # SDL2_LIBRARY_TEMP
|
||||||
|
# try to pkg-config fallback
|
||||||
|
find_package(PkgConfig)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PKG_C_SDL2 QUIET sdl2)
|
||||||
|
if (PKG_C_SDL2_FOUND)
|
||||||
|
SET(SDL2_LIBRARY_TEMP ${PKG_C_SDL2_LIBRARIES})
|
||||||
|
SET(SDL2_INCLUDE_DIR_TEMP ${PKG_C_SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# Set the final string here so the GUI reflects the final state.
|
||||||
|
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
|
||||||
|
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||||
|
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||||
|
|
||||||
|
set(SDL2_INCLUDE_DIR ${SDL2_INCLUDE_DIR_TEMP} CACHE STRING "Where the SDL2 Headers can be found")
|
||||||
|
SET(SDL2_INCLUDE_DIR_TEMP "${SDL2_INCLUDE_DIR_TEMP}" CACHE INTERNAL "")
|
||||||
|
|
||||||
|
#message("II set include dir to ${SDL2_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
SET(SDL2_FOUND "YES")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
ENDIF(SDL2_LIBRARY_TEMP)
|
ENDIF(SDL2_LIBRARY_TEMP)
|
||||||
|
|
||||||
else() #emsripten
|
else() #emsripten
|
||||||
@@ -288,4 +297,11 @@ INCLUDE(FindPackageHandleStandardArgs)
|
|||||||
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if (SDL2_FOUND)
|
||||||
|
if (NOT TARGET SDL2::SDL2)
|
||||||
|
add_library(SDL2::SDL2 INTERFACE IMPORTED)
|
||||||
|
target_include_directories(SDL2::SDL2 INTERFACE ${SDL2_INCLUDE_DIR})
|
||||||
|
target_link_libraries(SDL2::SDL2 INTERFACE ${SDL2_LIBRARY})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|||||||
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
@@ -21,7 +21,6 @@ set(JSON_BuildTests OFF CACHE INTERNAL "")
|
|||||||
set(JSON_MultipleHeaders ON CACHE INTERNAL "")
|
set(JSON_MultipleHeaders ON CACHE INTERNAL "")
|
||||||
add_subdirectory("json") # link with "nlohmann_json::nlohmann_json"
|
add_subdirectory("json") # link with "nlohmann_json::nlohmann_json"
|
||||||
|
|
||||||
set(PHYSFS_BUILD_SHARED FALSE CACHE INTERNAL "")
|
|
||||||
add_subdirectory("physfs")
|
add_subdirectory("physfs")
|
||||||
|
|
||||||
if(NOT MM_HEADLESS)
|
if(NOT MM_HEADLESS)
|
||||||
|
|||||||
2
external/entt
vendored
2
external/entt
vendored
Submodule external/entt updated: e4ccb878f4...344e03ac64
2
external/glm
vendored
2
external/glm
vendored
Submodule external/glm updated: bf71a83494...0af55ccecd
30
external/imgui/CMakeLists.txt
vendored
30
external/imgui/CMakeLists.txt
vendored
@@ -2,43 +2,31 @@ cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
|||||||
|
|
||||||
project(imgui C CXX)
|
project(imgui C CXX)
|
||||||
|
|
||||||
set(CPP_FILES
|
add_library(imgui
|
||||||
|
"imgui/imgui.h"
|
||||||
"imgui/imgui.cpp"
|
"imgui/imgui.cpp"
|
||||||
"imgui/imgui_draw.cpp"
|
"imgui/imgui_draw.cpp"
|
||||||
"imgui/imgui_widgets.cpp"
|
"imgui/imgui_widgets.cpp"
|
||||||
"imgui/imgui_tables.cpp"
|
"imgui/imgui_tables.cpp"
|
||||||
"imgui/imgui_demo.cpp"
|
"imgui/imgui_demo.cpp"
|
||||||
|
|
||||||
"imgui/misc/cpp/imgui_stdlib.cpp"
|
|
||||||
|
|
||||||
"imgui_plot_var.cpp"
|
|
||||||
|
|
||||||
#"imgui_impl_sdl_gl3.cpp" # very old
|
|
||||||
#"imgui_impl_sdl.cpp" # old
|
|
||||||
#"imgui_impl_opengl3.cpp" # old
|
|
||||||
"imgui/backends/imgui_impl_sdl.cpp"
|
|
||||||
"imgui/backends/imgui_impl_opengl3.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(HPP_FILES
|
|
||||||
"imgui/imgui.h"
|
|
||||||
"imgui/imstb_rectpack.h"
|
"imgui/imstb_rectpack.h"
|
||||||
"imgui/imstb_textedit.h"
|
"imgui/imstb_textedit.h"
|
||||||
"imgui/imstb_truetype.h"
|
"imgui/imstb_truetype.h"
|
||||||
|
|
||||||
"imgui/misc/cpp/imgui_stdlib.h"
|
"imgui/misc/cpp/imgui_stdlib.h"
|
||||||
|
"imgui/misc/cpp/imgui_stdlib.cpp"
|
||||||
|
|
||||||
"imgui_plot_var.hpp"
|
"imgui_plot_var.hpp"
|
||||||
|
"imgui_plot_var.cpp"
|
||||||
|
|
||||||
#"imgui_impl_sdl_gl3.h" # very old
|
# TODO: seperate backends into libs
|
||||||
#"imgui_impl_sdl.h" # old
|
"imgui/backends/imgui_impl_sdl2.h"
|
||||||
#"imgui_impl_opengl3.h" # old
|
"imgui/backends/imgui_impl_sdl2.cpp"
|
||||||
"imgui/backends/imgui_impl_sdl.h"
|
|
||||||
"imgui/backends/imgui_impl_opengl3.h"
|
"imgui/backends/imgui_impl_opengl3.h"
|
||||||
|
"imgui/backends/imgui_impl_opengl3.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(imgui ${CPP_FILES} ${HPP_FILES})
|
|
||||||
|
|
||||||
target_compile_features(imgui PUBLIC cxx_std_11)
|
target_compile_features(imgui PUBLIC cxx_std_11)
|
||||||
|
|
||||||
if(MM_OPENGL_3_GLES)
|
if(MM_OPENGL_3_GLES)
|
||||||
@@ -53,7 +41,7 @@ target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
|||||||
#target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/imgui")
|
#target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/imgui")
|
||||||
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui") # im sad
|
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui") # im sad
|
||||||
|
|
||||||
target_compile_definitions(imgui PUBLIC IMGUI_DISABLE_OBSOLETE_FUNCTIONS=1)
|
#target_compile_definitions(imgui PUBLIC IMGUI_DISABLE_OBSOLETE_FUNCTIONS=1) # more sad
|
||||||
|
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
target_compile_options(imgui PUBLIC -sUSE_SDL=2)
|
target_compile_options(imgui PUBLIC -sUSE_SDL=2)
|
||||||
|
|||||||
2
external/imgui/imgui
vendored
2
external/imgui/imgui
vendored
Submodule external/imgui/imgui updated: 9aae45eb4a...c6e0284ac5
235
external/physfs/CMakeLists.txt
vendored
235
external/physfs/CMakeLists.txt
vendored
@@ -1,235 +1,6 @@
|
|||||||
# file taken from offical physfs repo and modified
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# PhysicsFS; a portable, flexible file i/o abstraction.
|
|
||||||
#
|
|
||||||
# Please see the file LICENSE.txt in the source's root directory.
|
|
||||||
|
|
||||||
# The CMake project file is meant to get this compiling on all sorts of
|
|
||||||
# platforms quickly, and serve as the way Unix platforms and Linux distros
|
|
||||||
# package up official builds, but you don't _need_ to use this; we have
|
|
||||||
# built PhysicsFS to (hopefully) be able to drop into your project and
|
|
||||||
# compile, using preprocessor checks for platform-specific bits instead of
|
|
||||||
# testing in here.
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
|
|
||||||
project(PhysicsFS)
|
set(PHYSFS_BUILD_SHARED FALSE CACHE INTERNAL "")
|
||||||
set(PHYSFS_VERSION 3.1.0)
|
set(PHYSFS_BUILD_TEST FALSE CACHE INTERNAL "")
|
||||||
|
add_subdirectory("physfs")
|
||||||
# Increment this if/when we break backwards compatibility.
|
|
||||||
set(PHYSFS_SOVERSION 1)
|
|
||||||
|
|
||||||
# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
|
|
||||||
if(WIN32 AND NOT WINDOWS)
|
|
||||||
set(WINDOWS TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
set(PHYSFS_M_SRCS physfs/src/physfs_platform_apple.m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
# Don't use -rpath.
|
|
||||||
set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
|
|
||||||
add_definitions(-erroff=E_EMPTY_TRANSLATION_UNIT)
|
|
||||||
add_definitions(-xldscope=hidden)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(HAIKU)
|
|
||||||
# We add this explicitly, since we don't want CMake to think this
|
|
||||||
# is a C++ project unless we're on Haiku.
|
|
||||||
set(PHYSFS_CPP_SRCS physfs/src/physfs_platform_haiku.cpp)
|
|
||||||
find_library(BE_LIBRARY be)
|
|
||||||
find_library(ROOT_LIBRARY root)
|
|
||||||
set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${BE_LIBRARY} ${ROOT_LIBRARY})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
|
||||||
set(WINRT TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WINRT)
|
|
||||||
set(PHYSFS_CPP_SRCS physfs/src/physfs_platform_winrt.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(UNIX AND NOT WINDOWS AND NOT APPLE) # (MingW and such might be UNIX _and_ WINDOWS!)
|
|
||||||
find_library(PTHREAD_LIBRARY pthread)
|
|
||||||
if(PTHREAD_LIBRARY)
|
|
||||||
set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${PTHREAD_LIBRARY})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Almost everything is "compiled" here, but things that don't apply to the
|
|
||||||
# build are #ifdef'd out. This is to make it easy to embed PhysicsFS into
|
|
||||||
# another project or bring up a new build system: just compile all the source
|
|
||||||
# code and #define the things you want.
|
|
||||||
set(PHYSFS_SRCS
|
|
||||||
physfs/src/physfs.c
|
|
||||||
physfs/src/physfs_byteorder.c
|
|
||||||
physfs/src/physfs_unicode.c
|
|
||||||
physfs/src/physfs_platform_posix.c
|
|
||||||
physfs/src/physfs_platform_unix.c
|
|
||||||
physfs/src/physfs_platform_windows.c
|
|
||||||
physfs/src/physfs_platform_os2.c
|
|
||||||
physfs/src/physfs_platform_qnx.c
|
|
||||||
physfs/src/physfs_platform_android.c
|
|
||||||
physfs/src/physfs_archiver_dir.c
|
|
||||||
physfs/src/physfs_archiver_unpacked.c
|
|
||||||
physfs/src/physfs_archiver_grp.c
|
|
||||||
physfs/src/physfs_archiver_hog.c
|
|
||||||
physfs/src/physfs_archiver_7z.c
|
|
||||||
physfs/src/physfs_archiver_mvl.c
|
|
||||||
physfs/src/physfs_archiver_qpak.c
|
|
||||||
physfs/src/physfs_archiver_wad.c
|
|
||||||
physfs/src/physfs_archiver_zip.c
|
|
||||||
physfs/src/physfs_archiver_slb.c
|
|
||||||
physfs/src/physfs_archiver_iso9660.c
|
|
||||||
physfs/src/physfs_archiver_vdf.c
|
|
||||||
|
|
||||||
physfs/src/physfs.h
|
|
||||||
physfs/src/physfs_casefolding.h
|
|
||||||
physfs/src/physfs_internal.h
|
|
||||||
physfs/src/physfs_lzmasdk.h
|
|
||||||
physfs/src/physfs_miniz.h
|
|
||||||
physfs/src/physfs_platforms.h
|
|
||||||
|
|
||||||
${PHYSFS_CPP_SRCS}
|
|
||||||
${PHYSFS_M_SRCS}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Archivers ...
|
|
||||||
# These are (mostly) on by default now, so these options are only useful for
|
|
||||||
# disabling them.
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_ZIP "Enable ZIP support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_ZIP)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_ZIP=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_7Z "Enable 7zip support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_7Z)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_7Z=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_GRP "Enable Build Engine GRP support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_GRP)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_GRP=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_WAD "Enable Doom WAD support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_WAD)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_WAD=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_HOG)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_HOG=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_MVL "Enable Descent I/II MVL support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_MVL)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_MVL=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_QPAK "Enable Quake I/II QPAK support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_QPAK)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_QPAK=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_SLB "Enable I-War / Independence War SLB support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_SLB)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_SLB=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_ISO9660 "Enable ISO9660 support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_ISO9660)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_ISO9660=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_VDF "Enable Gothic I/II VDF archive support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_VDF)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_VDF=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
|
|
||||||
if(PHYSFS_BUILD_STATIC)
|
|
||||||
add_library(physfs-static STATIC ${PHYSFS_SRCS})
|
|
||||||
# Don't rename this on Windows, since DLLs will also produce an import
|
|
||||||
# library named "physfs.lib" which would conflict; Unix tend to like the
|
|
||||||
# same library name with a different extension for static libs, but
|
|
||||||
# Windows can just have a separate name.
|
|
||||||
if(NOT MSVC)
|
|
||||||
set_target_properties(physfs-static PROPERTIES OUTPUT_NAME "physfs")
|
|
||||||
endif()
|
|
||||||
if(WINRT)
|
|
||||||
# Ignore LNK4264 warnings; we don't author any WinRT components, just consume them, so we're okay in a static library.
|
|
||||||
set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True)
|
|
||||||
set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
|
|
||||||
endif()
|
|
||||||
if(APPLE)
|
|
||||||
target_link_libraries(physfs-static PUBLIC "-framework IOKit")
|
|
||||||
target_link_libraries(physfs-static PUBLIC "-framework Foundation") # do i need this?
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(physfs-static PUBLIC "physfs/src")
|
|
||||||
|
|
||||||
set(PHYSFS_LIB_TARGET physfs-static)
|
|
||||||
set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs-static")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT PHYSFS_BUILD_STATIC)
|
|
||||||
message(FATAL "static libraries are disabled!")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# CMake FAQ says I need this...
|
|
||||||
if(PHYSFS_BUILD_STATIC AND NOT WINDOWS)
|
|
||||||
set_target_properties(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT MSVC)
|
|
||||||
configure_file(
|
|
||||||
"physfs/extras/physfs.pc.in"
|
|
||||||
"physfs/extras/physfs.pc"
|
|
||||||
@ONLY
|
|
||||||
)
|
|
||||||
install(
|
|
||||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/extras/physfs.pc"
|
|
||||||
DESTINATION "lib${LIB_SUFFIX}/pkgconfig"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
macro(message_bool_option _NAME _VALUE)
|
|
||||||
if(${_VALUE})
|
|
||||||
message(STATUS " ${_NAME}: enabled")
|
|
||||||
else()
|
|
||||||
message(STATUS " ${_NAME}: disabled")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
message(STATUS "PhysicsFS will build with the following options:")
|
|
||||||
message_bool_option("ZIP support" PHYSFS_ARCHIVE_ZIP)
|
|
||||||
message_bool_option("7zip support" PHYSFS_ARCHIVE_7Z)
|
|
||||||
message_bool_option("GRP support" PHYSFS_ARCHIVE_GRP)
|
|
||||||
message_bool_option("WAD support" PHYSFS_ARCHIVE_WAD)
|
|
||||||
message_bool_option("HOG support" PHYSFS_ARCHIVE_HOG)
|
|
||||||
message_bool_option("MVL support" PHYSFS_ARCHIVE_MVL)
|
|
||||||
message_bool_option("QPAK support" PHYSFS_ARCHIVE_QPAK)
|
|
||||||
message_bool_option("SLB support" PHYSFS_ARCHIVE_SLB)
|
|
||||||
message_bool_option("VDF support" PHYSFS_ARCHIVE_VDF)
|
|
||||||
message_bool_option("ISO9660 support" PHYSFS_ARCHIVE_ISO9660)
|
|
||||||
message_bool_option("Build static library" PHYSFS_BUILD_STATIC)
|
|
||||||
message_bool_option("Build shared library" PHYSFS_BUILD_SHARED)
|
|
||||||
message_bool_option("Build stdio test program" PHYSFS_BUILD_TEST)
|
|
||||||
if(PHYSFS_BUILD_TEST)
|
|
||||||
message_bool_option(" Use readline in test program" HAVE_SYSTEM_READLINE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# end of CMakeLists.txt ...
|
|
||||||
|
|
||||||
|
|||||||
2
external/physfs/physfs
vendored
2
external/physfs/physfs
vendored
Submodule external/physfs/physfs updated: fdd38a3f8a...b1a2f1f18b
2
external/spdlog
vendored
2
external/spdlog
vendored
Submodule external/spdlog updated: ad0e89cbfb...7e635fca68
5
external/stb/CMakeLists.txt
vendored
5
external/stb/CMakeLists.txt
vendored
@@ -11,9 +11,8 @@ target_link_libraries(stb_image stb)
|
|||||||
add_library(stb_image_write "stb/stb_image_write.h" "stb_image_write.cpp")
|
add_library(stb_image_write "stb/stb_image_write.h" "stb_image_write.cpp")
|
||||||
target_link_libraries(stb_image_write stb)
|
target_link_libraries(stb_image_write stb)
|
||||||
|
|
||||||
# lel TODO: add back in when patent expires
|
add_library(stb_perlin "stb/stb_perlin.h" "stb_perlin.cpp")
|
||||||
#add_library(stb_perlin "stb/stb_perlin.h" "stb_perlin.cpp")
|
target_link_libraries(stb_perlin stb)
|
||||||
#target_link_libraries(stb_perlin stb)
|
|
||||||
|
|
||||||
add_library(stb_rect_pack "stb/stb_rect_pack.h" "stb_rect_pack.cpp")
|
add_library(stb_rect_pack "stb/stb_rect_pack.h" "stb_rect_pack.cpp")
|
||||||
target_link_libraries(stb_rect_pack stb)
|
target_link_libraries(stb_rect_pack stb)
|
||||||
|
|||||||
2
external/stb/stb
vendored
2
external/stb/stb
vendored
Submodule external/stb/stb updated: af1a5bc352...802cd454f2
2
external/tracy/CMakeLists.txt
vendored
2
external/tracy/CMakeLists.txt
vendored
@@ -10,6 +10,8 @@ if(NOT EMSCRIPTEN)
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/tracy/public/TracyClient.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/tracy/public/TracyClient.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option(TRACY_ENABLE "Enable tracy profiling" OFF)
|
||||||
|
|
||||||
if(TRACY_ENABLE)
|
if(TRACY_ENABLE)
|
||||||
target_compile_definitions(tracy_client PUBLIC TRACY_ENABLE)
|
target_compile_definitions(tracy_client PUBLIC TRACY_ENABLE)
|
||||||
#target_compile_definitions(tracy_client PUBLIC TRACY_NO_SYSTEM_TRACING)
|
#target_compile_definitions(tracy_client PUBLIC TRACY_NO_SYSTEM_TRACING)
|
||||||
|
|||||||
2
external/tracy/tracy
vendored
2
external/tracy/tracy
vendored
Submodule external/tracy/tracy updated: 5a1f5371b7...897aec5b06
@@ -5,6 +5,7 @@ project(framework)
|
|||||||
add_subdirectory(engine)
|
add_subdirectory(engine)
|
||||||
add_subdirectory(logger)
|
add_subdirectory(logger)
|
||||||
add_subdirectory(resource_manager)
|
add_subdirectory(resource_manager)
|
||||||
|
add_subdirectory(s6zer)
|
||||||
add_subdirectory(common_components)
|
add_subdirectory(common_components)
|
||||||
add_subdirectory(std_utils)
|
add_subdirectory(std_utils)
|
||||||
add_subdirectory(random)
|
add_subdirectory(random)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ project(common_components CXX)
|
|||||||
|
|
||||||
add_library(common_components INTERFACE)
|
add_library(common_components INTERFACE)
|
||||||
|
|
||||||
|
add_library(MM::common_components ALIAS common_components)
|
||||||
|
|
||||||
target_include_directories(common_components INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
target_include_directories(common_components INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
target_link_libraries(common_components INTERFACE
|
target_link_libraries(common_components INTERFACE
|
||||||
@@ -13,8 +15,23 @@ target_link_libraries(common_components INTERFACE
|
|||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
|
||||||
|
add_library(common_components_serialize_s6zer INTERFACE)
|
||||||
|
|
||||||
|
add_library(MM::common_components_serialize_s6zer ALIAS common_components_serialize_s6zer)
|
||||||
|
|
||||||
|
target_include_directories(common_components_serialize_s6zer INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
|
target_link_libraries(common_components_serialize_s6zer INTERFACE
|
||||||
|
common_components
|
||||||
|
s6zer
|
||||||
|
)
|
||||||
|
|
||||||
|
##########################
|
||||||
|
|
||||||
add_library(common_components_serialize_json INTERFACE)
|
add_library(common_components_serialize_json INTERFACE)
|
||||||
|
|
||||||
|
add_library(MM::common_components_serialize_json ALIAS common_components_serialize_json)
|
||||||
|
|
||||||
target_include_directories(common_components_serialize_json INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
target_include_directories(common_components_serialize_json INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
target_link_libraries(common_components_serialize_json INTERFACE
|
target_link_libraries(common_components_serialize_json INTERFACE
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
struct Name {
|
struct Name {
|
||||||
static const size_t max_str_len = 64;
|
static const size_t max_str_len {64u};
|
||||||
std::string str;
|
std::string str;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace MM::Components {
|
|||||||
|
|
||||||
// used to lift 2D into 3D space. like a z-index in css/svg
|
// used to lift 2D into 3D space. like a z-index in css/svg
|
||||||
struct Position2D_ZOffset {
|
struct Position2D_ZOffset {
|
||||||
float z_offset = 500.f; // default camera allows values to be between 0 and 1000
|
float z_offset {500.f}; // default camera allows values to be between 0 and 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Color, color)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Color, color)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
namespace glm {
|
namespace glm {
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2, x, y)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(vec2, x, y)
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3, x, y, z)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(vec3, x, y, z)
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4, x, y, z, w)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(vec4, x, y, z, w)
|
||||||
|
|
||||||
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(mat4x4, [0], y, z, w)
|
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(mat4x4, [0], y, z, w)
|
||||||
inline void to_json(nlohmann::json& nlohmann_json_j, const mat4x4& nlohmann_json_t) {
|
inline void to_json(nlohmann::json& nlohmann_json_j, const mat4x4& nlohmann_json_t) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <mm/components/name.hpp>
|
#include <mm/components/name.hpp>
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
|
// TODO: manual with str len limit
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Name, str)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Name, str)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Position2D, pos)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Position2D, pos)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Position2D_ZOffset, z_offset)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Position2D_ZOffset, z_offset)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Position3D, pos)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Position3D, pos)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Rotation2D, rot)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Rotation2D, rot)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Scale2D, scale)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Scale2D, scale)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Transform4x4, trans)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Transform4x4, trans)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Velocity2DPosition, pos_vel)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Velocity2DPosition, pos_vel)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Velocity2DPositionIntent, intent)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Velocity2DPositionIntent, intent)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
#include "./json_glm.hpp"
|
#include "./json_glm.hpp"
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Velocity2DRotation, rot_vel)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Velocity2DRotation, rot_vel)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
#include <mm/components/view_dir2d.hpp>
|
#include <mm/components/view_dir2d.hpp>
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ViewDir2D, dir)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(ViewDir2D, dir)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
#include <mm/components/view_dir3d.hpp>
|
#include <mm/components/view_dir3d.hpp>
|
||||||
|
|
||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ViewDir3D, yaw, pitch, roll)
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(ViewDir3D, yaw, pitch, roll)
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mm/s6zer/serialize.hpp>
|
||||||
|
|
||||||
|
#include <mm/components/color.hpp>
|
||||||
|
|
||||||
|
namespace MM::Components {
|
||||||
|
|
||||||
|
MM_DEFINE_SERIALIZE(Color,
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloat(data.color.r))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloat(data.color.g))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloat(data.color.b))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloat(data.color.a))
|
||||||
|
)
|
||||||
|
|
||||||
|
} // MM::Components
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
|
|
||||||
struct ViewDir2D {
|
struct ViewDir2D {
|
||||||
float dir = 0.f; // rad
|
float dir {0.f}; // rad
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
namespace MM::Components {
|
namespace MM::Components {
|
||||||
|
|
||||||
struct ViewDir3D {
|
struct ViewDir3D {
|
||||||
float yaw = 0.f; // rad
|
float yaw {0.f}; // rad
|
||||||
float pitch = 0.f; // rad
|
float pitch {0.f}; // rad
|
||||||
float roll = 0.f; // rad
|
float roll {0.f}; // rad
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM::Components
|
} // MM::Components
|
||||||
|
|||||||
@@ -7,10 +7,25 @@ target_include_directories(common_component_json_serialization_test PRIVATE ".")
|
|||||||
|
|
||||||
target_link_libraries(common_component_json_serialization_test
|
target_link_libraries(common_component_json_serialization_test
|
||||||
common_components_serialize_json
|
common_components_serialize_json
|
||||||
engine
|
|
||||||
|
|
||||||
gtest_main
|
gtest_main
|
||||||
)
|
)
|
||||||
|
|
||||||
add_test(NAME common_component_json_serialization_test COMMAND common_component_json_serialization_test)
|
add_test(NAME common_component_json_serialization_test COMMAND common_component_json_serialization_test)
|
||||||
|
|
||||||
|
########################################
|
||||||
|
|
||||||
|
add_executable(common_component_s6zer_serialization_test
|
||||||
|
component_s6zer_serialization_test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(common_component_s6zer_serialization_test PRIVATE ".")
|
||||||
|
|
||||||
|
target_link_libraries(common_component_s6zer_serialization_test
|
||||||
|
common_components_serialize_s6zer
|
||||||
|
|
||||||
|
gtest_main
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME common_component_s6zer_serialization_test COMMAND common_component_s6zer_serialization_test)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "mm/components/position2d.hpp"
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <mm/components/serialize/json_name.hpp>
|
#include <mm/components/serialize/json_name.hpp>
|
||||||
|
|||||||
@@ -0,0 +1,289 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <mm/s6zer/serialize.hpp>
|
||||||
|
|
||||||
|
//#include <mm/components/serialize/json_name.hpp>
|
||||||
|
#include <mm/components/serialize/s6zer_color.hpp>
|
||||||
|
|
||||||
|
//#include <mm/components/serialize/json_position2d.hpp>
|
||||||
|
//#include <mm/components/serialize/json_position2d_zoffset.hpp>
|
||||||
|
//#include <mm/components/serialize/json_position3d.hpp>
|
||||||
|
//#include <mm/components/serialize/json_rotation2d.hpp>
|
||||||
|
//#include <mm/components/serialize/json_scale2d.hpp>
|
||||||
|
//#include <mm/components/serialize/json_transform4x4.hpp>
|
||||||
|
//#include <mm/components/serialize/json_velocity2d_position.hpp>
|
||||||
|
//#include <mm/components/serialize/json_velocity2d_position_intent.hpp>
|
||||||
|
//#include <mm/components/serialize/json_velocity2d_rotation.hpp>
|
||||||
|
//#include <mm/components/serialize/json_view_dir2d.hpp>
|
||||||
|
//#include <mm/components/serialize/json_view_dir3d.hpp>
|
||||||
|
|
||||||
|
#define TEST_JSON_SERL_EXPAND(x) x
|
||||||
|
#define TEST_JSON_SERL_IN_OUT(TYPE, JSON_STR, TEST_CORPUS) \
|
||||||
|
TEST(common_components_json_serialization, in_out_##TYPE) { \
|
||||||
|
MM::Components::TYPE comp; \
|
||||||
|
{ /* in */ \
|
||||||
|
auto j = nlohmann::json::parse(JSON_STR); \
|
||||||
|
comp = j; \
|
||||||
|
TEST_CORPUS \
|
||||||
|
} \
|
||||||
|
{ /* out */ \
|
||||||
|
nlohmann::json j; \
|
||||||
|
j = comp; \
|
||||||
|
ASSERT_EQ(JSON_STR, j.dump()); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TEST(common_components_json_serialization, in_out_name) {
|
||||||
|
//MM::Components::Name comp;
|
||||||
|
|
||||||
|
//const char* json_test_file = "{\"str\":\"test_name\"}";
|
||||||
|
|
||||||
|
//{ // in
|
||||||
|
//auto j = nlohmann::json::parse(json_test_file);
|
||||||
|
|
||||||
|
//EXPECT_NO_THROW({
|
||||||
|
//comp = j;
|
||||||
|
//});
|
||||||
|
|
||||||
|
//ASSERT_EQ(comp.str, "test_name");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{ // out
|
||||||
|
//nlohmann::json j;
|
||||||
|
|
||||||
|
//EXPECT_NO_THROW({
|
||||||
|
//j = comp;
|
||||||
|
//});
|
||||||
|
|
||||||
|
//ASSERT_EQ(json_test_file, j.dump());
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
|
//TEST(common_components_json_serialization, in_out_name_fail) {
|
||||||
|
//MM::Components::Name name_comp;
|
||||||
|
|
||||||
|
//// intentional malformed json string
|
||||||
|
//const char* json_test_file = "{\"strasdf\":\"test_name\"}";
|
||||||
|
|
||||||
|
//{ // in
|
||||||
|
//auto j = nlohmann::json::parse(json_test_file);
|
||||||
|
|
||||||
|
//ASSERT_ANY_THROW({
|
||||||
|
//name_comp = j;
|
||||||
|
//});
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
//TEST_S6ZER_SERL_IN_OUT(
|
||||||
|
//Color,
|
||||||
|
//R"({"color":{"w":1337.0,"x":0.0,"y":1.0,"z":3.0}})",
|
||||||
|
//TEST_JSON_SERL_EXPAND({
|
||||||
|
//glm::vec4 comp_val(0.f, 1.f, 3.f, 1337.f);
|
||||||
|
//ASSERT_EQ(comp.color.x, comp_val.x);
|
||||||
|
//ASSERT_EQ(comp.color.y, comp_val.y);
|
||||||
|
//ASSERT_EQ(comp.color.z, comp_val.z);
|
||||||
|
//ASSERT_EQ(comp.color.w, comp_val.w);
|
||||||
|
//})
|
||||||
|
//)
|
||||||
|
|
||||||
|
TEST(common_components_s6zer_serialization, out_in_color) {
|
||||||
|
const MM::Components::Color comp_out{
|
||||||
|
{1337.f, 0.f, 1.f, 3.f}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<uint32_t, 128> buffer;
|
||||||
|
size_t buffer_size = buffer.size()*sizeof(uint32_t);
|
||||||
|
|
||||||
|
{ // to bits
|
||||||
|
MM::s6zer::StreamWriter writer{buffer.data(), buffer_size};
|
||||||
|
ASSERT_TRUE(MM::Components::mm_serialize(writer, comp_out));
|
||||||
|
|
||||||
|
ASSERT_TRUE(writer.flush());
|
||||||
|
buffer_size = writer.bytesWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
MM::Components::Color comp_in;
|
||||||
|
|
||||||
|
{ // from bits
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
ASSERT_TRUE(MM::Components::mm_serialize(reader, comp_in));
|
||||||
|
|
||||||
|
ASSERT_EQ(reader.bytesRead(), buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_EQ(comp_out.color.x, comp_in.color.x);
|
||||||
|
ASSERT_EQ(comp_out.color.y, comp_in.color.y);
|
||||||
|
ASSERT_EQ(comp_out.color.z, comp_in.color.z);
|
||||||
|
ASSERT_EQ(comp_out.color.w, comp_in.color.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Position2D,
|
||||||
|
R"({"pos":{"x":42.0,"y":6.0}})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.pos.x, 42.f);
|
||||||
|
ASSERT_EQ(comp.pos.y, 6.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Position2D_ZOffset,
|
||||||
|
R"({"z_offset":3.0})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.z_offset, 3.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Position3D,
|
||||||
|
R"({"pos":{"x":42.0,"y":6.0,"z":44.0}})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.pos.x, 42.f);
|
||||||
|
ASSERT_EQ(comp.pos.y, 6.f);
|
||||||
|
ASSERT_EQ(comp.pos.z, 44.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Rotation2D,
|
||||||
|
R"({"rot":42.0})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.rot, 42.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Scale2D,
|
||||||
|
R"({"scale":{"x":42.0,"y":6.0}})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.scale.x, 42.f);
|
||||||
|
ASSERT_EQ(comp.scale.y, 6.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Transform4x4,
|
||||||
|
R"({"trans":[{"w":0.0,"x":1.0,"y":0.0,"z":0.0},{"w":0.0,"x":0.0,"y":1.0,"z":0.0},{"w":0.0,"x":0.0,"y":0.0,"z":1.0},{"w":1.0,"x":0.0,"y":0.0,"z":0.0}]})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.trans, glm::mat4x4{1.f});
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Velocity2DPosition,
|
||||||
|
R"({"pos_vel":{"x":42.0,"y":6.0}})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.pos_vel.x, 42.f);
|
||||||
|
ASSERT_EQ(comp.pos_vel.y, 6.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Velocity2DPositionIntent,
|
||||||
|
R"({"intent":{"x":42.0,"y":6.0}})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.intent.x, 42.f);
|
||||||
|
ASSERT_EQ(comp.intent.y, 6.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST_JSON_SERL_IN_OUT(
|
||||||
|
Velocity2DRotation,
|
||||||
|
R"({"rot_vel":42.0})",
|
||||||
|
TEST_JSON_SERL_EXPAND(
|
||||||
|
ASSERT_EQ(comp.rot_vel, 42.f);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST(common_components_json_serialization, in_out_view_dir2d) {
|
||||||
|
MM::Components::ViewDir2D comp;
|
||||||
|
|
||||||
|
const char* json_test_file = R"({"dir":6.0})";
|
||||||
|
|
||||||
|
{ // in
|
||||||
|
auto j = nlohmann::json::parse(json_test_file);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW({
|
||||||
|
comp = j;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_EQ(comp.dir, 6.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // out
|
||||||
|
nlohmann::json j;
|
||||||
|
|
||||||
|
EXPECT_NO_THROW({
|
||||||
|
j = comp;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_EQ(json_test_file, j.dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##############################################################
|
||||||
|
|
||||||
|
TEST(common_components_json_serialization, in_out_view_dir3d) {
|
||||||
|
MM::Components::ViewDir3D comp;
|
||||||
|
|
||||||
|
const char* json_test_file = R"({"pitch":6.0,"roll":99.0,"yaw":42.0})";
|
||||||
|
|
||||||
|
{ // in
|
||||||
|
auto j = nlohmann::json::parse(json_test_file);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW({
|
||||||
|
comp = j;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_EQ(comp.yaw, 42.f);
|
||||||
|
ASSERT_EQ(comp.pitch, 6.f);
|
||||||
|
ASSERT_EQ(comp.roll, 99.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // out
|
||||||
|
nlohmann::json j;
|
||||||
|
|
||||||
|
EXPECT_NO_THROW({
|
||||||
|
j = comp;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_EQ(json_test_file, j.dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@ namespace MM::Services {
|
|||||||
public: // send/recv
|
public: // send/recv
|
||||||
|
|
||||||
// sends a packet of max getMaxPacketSize() bytes
|
// sends a packet of max getMaxPacketSize() bytes
|
||||||
virtual bool sendPacket(peer_id peer, channel_id channel, uint8_t* data, size_t data_size) = 0;
|
virtual bool sendPacket(peer_id peer, channel_id channel, const uint8_t* data, size_t data_size) = 0;
|
||||||
|
|
||||||
// sends a packet, automatically split if too big
|
// sends a packet, automatically split if too big
|
||||||
// !! only on lossless channels
|
// !! only on lossless channels
|
||||||
virtual bool sendPacketLarge(peer_id peer, channel_id channel, uint8_t* data, size_t data_size) = 0;
|
virtual bool sendPacketLarge(peer_id peer, channel_id channel, const uint8_t* data, size_t data_size) = 0;
|
||||||
|
|
||||||
// TODO: broadcast?
|
// TODO: broadcast?
|
||||||
// has any?
|
// has any?
|
||||||
|
|||||||
@@ -316,6 +316,31 @@ nlohmann::json FilesystemService::readJson(const char* filepath) const {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::ordered_json FilesystemService::readJsonOrdered(fs_file_t file) const {
|
||||||
|
if (!file)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
seek(file, 0);
|
||||||
|
|
||||||
|
std::string buffer;
|
||||||
|
readString(file, buffer);
|
||||||
|
|
||||||
|
// disable exeptions
|
||||||
|
// TODO: use callback instead of readString()
|
||||||
|
return nlohmann::ordered_json::parse(buffer, nullptr, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::ordered_json FilesystemService::readJsonOrdered(const char* filepath) const {
|
||||||
|
if (!isFile(filepath)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto h = open(filepath, READ);
|
||||||
|
auto r = readJsonOrdered(h);
|
||||||
|
close(h);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
bool FilesystemService::writeJson(fs_file_t file, nlohmann::json& j, const int indent, const char indent_char) const {
|
bool FilesystemService::writeJson(fs_file_t file, nlohmann::json& j, const int indent, const char indent_char) const {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_ERROR("writing json to invalid file");
|
LOG_ERROR("writing json to invalid file");
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ class FilesystemService : public Service {
|
|||||||
nlohmann::json readJson(fs_file_t file) const;
|
nlohmann::json readJson(fs_file_t file) const;
|
||||||
nlohmann::json readJson(const char* filepath) const;
|
nlohmann::json readJson(const char* filepath) const;
|
||||||
|
|
||||||
|
nlohmann::ordered_json readJsonOrdered(fs_file_t file) const;
|
||||||
|
nlohmann::ordered_json readJsonOrdered(const char* filepath) const;
|
||||||
|
|
||||||
bool writeJson(fs_file_t file, nlohmann::json& j, const int indent = -1, const char indent_char = ' ') const;
|
bool writeJson(fs_file_t file, nlohmann::json& j, const int indent = -1, const char indent_char = ' ') const;
|
||||||
bool writeJson(const char* filepath, nlohmann::json& j, const int indent = -1, const char indent_char = ' ') const;
|
bool writeJson(const char* filepath, nlohmann::json& j, const int indent = -1, const char indent_char = ' ') const;
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ private:
|
|||||||
|
|
||||||
bool entityHasComponent(Registry& registry, EntityType& entity, ComponentTypeID type_id)
|
bool entityHasComponent(Registry& registry, EntityType& entity, ComponentTypeID type_id)
|
||||||
{
|
{
|
||||||
const auto storage_it = registry.storage(type_id);
|
const auto* storage_ptr = registry.storage(type_id);
|
||||||
return storage_it != registry.storage().end() && storage_it->second.contains(entity);
|
return storage_ptr != nullptr && storage_ptr->contains(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -134,10 +134,10 @@ public:
|
|||||||
e = registry.create();
|
e = registry.create();
|
||||||
|
|
||||||
// create a copy of an entity component by component
|
// create a copy of an entity component by component
|
||||||
for (auto &&curr: registry.storage()) {
|
for(auto &&curr: registry.storage()) {
|
||||||
if (auto &storage = curr.second; storage.contains(old_e)) {
|
if(auto &storage = curr.second; storage.contains(old_e)) {
|
||||||
// TODO: do something with the return value. returns false on failure.
|
// TODO: do something with the return value. returns false on failure.
|
||||||
storage.emplace(e, storage.get(old_e));
|
storage.push(e, storage.value(old_e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,17 +237,17 @@ public:
|
|||||||
|
|
||||||
if (comp_list.empty()) {
|
if (comp_list.empty()) {
|
||||||
ImGui::Text("Orphans:");
|
ImGui::Text("Orphans:");
|
||||||
registry.each([®istry](auto e){
|
for (EntityType e : registry.template storage<EntityType>()) {
|
||||||
if (registry.orphan(e)) {
|
if (registry.orphan(e)) {
|
||||||
MM_IEEE_ENTITY_WIDGET(e, registry, false);
|
MM_IEEE_ENTITY_WIDGET(e, registry, false);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} else {
|
} else {
|
||||||
entt::basic_runtime_view<entt::basic_sparse_set<EntityType>> view{};
|
entt::runtime_view view{};
|
||||||
for (const auto type : comp_list) {
|
for (const auto type : comp_list) {
|
||||||
auto storage_it = registry.storage(type);
|
auto* storage_ptr = registry.storage(type);
|
||||||
if (storage_it != registry.storage().end()) {
|
if (storage_ptr != nullptr) {
|
||||||
view.iterate(registry.storage(type)->second);
|
view.iterate(*storage_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,17 +264,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[deprecated("Use renderEditor() instead. And manage the window yourself.")]]
|
|
||||||
void render(Registry& registry, EntityType& e)
|
|
||||||
{
|
|
||||||
if (show_window) {
|
|
||||||
if (ImGui::Begin("Entity Editor", &show_window)) {
|
|
||||||
renderEditor(registry, e);
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// displays both, editor and list
|
// displays both, editor and list
|
||||||
// uses static internally, use only as a quick way to get going!
|
// uses static internally, use only as a quick way to get going!
|
||||||
void renderSimpleCombo(Registry& registry, EntityType& e)
|
void renderSimpleCombo(Registry& registry, EntityType& e)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void Camera3D(MM::Scene& scene) {
|
|||||||
ImGui::TextUnformatted("NO CAMERA!");
|
ImGui::TextUnformatted("NO CAMERA!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& camera = scene.ctx().at<MM::OpenGL::Camera3D>();
|
auto& camera = scene.ctx().get<MM::OpenGL::Camera3D>();
|
||||||
|
|
||||||
static bool follow_entity = false;
|
static bool follow_entity = false;
|
||||||
static MM::Entity tracking = entt::null;
|
static MM::Entity tracking = entt::null;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <imgui/misc/cpp/imgui_stdlib.h>
|
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
namespace MM::ImGuiWidgets {
|
namespace MM::ImGuiWidgets {
|
||||||
|
|
||||||
@@ -55,16 +56,16 @@ void JsonViewerSimple(const char* name, const JsonObjectType& json) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_integer:
|
case JsonObjectType::value_t::number_integer:
|
||||||
ImGui::TextColored(int_color, "%ld", json.template get<int64_t>());
|
ImGui::TextColored(int_color, "%" PRId64, json.template get<int64_t>());
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_unsigned:
|
case JsonObjectType::value_t::number_unsigned:
|
||||||
ImGui::TextColored(unsigned_color, "%lu", json.template get<uint64_t>());
|
ImGui::TextColored(unsigned_color, "%" PRIu64, json.template get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_float:
|
case JsonObjectType::value_t::number_float:
|
||||||
ImGui::TextColored(float_color, "%f", json.template get<float>());
|
ImGui::TextColored(float_color, "%f", json.template get<float>());
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::object:
|
case JsonObjectType::value_t::object:
|
||||||
ImGui::TextDisabled("{%d}", json.size());
|
ImGui::TextDisabled("{%zu}", json.size());
|
||||||
|
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
for (auto& [key, value] : json.items()) {
|
for (auto& [key, value] : json.items()) {
|
||||||
@@ -74,7 +75,7 @@ void JsonViewerSimple(const char* name, const JsonObjectType& json) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::array:
|
case JsonObjectType::value_t::array:
|
||||||
ImGui::TextDisabled("[%d]", json.size());
|
ImGui::TextDisabled("[%zu]", json.size());
|
||||||
|
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
for (auto& [key, value] : json.items()) {
|
for (auto& [key, value] : json.items()) {
|
||||||
@@ -103,9 +104,9 @@ void JsonViewerTree(const char* name, const JsonObjectType& json) {
|
|||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (json.is_object()) {
|
if (json.is_object()) {
|
||||||
ImGui::TextDisabled("{%d}", json.size());
|
ImGui::TextDisabled("{%zu}", json.size());
|
||||||
} else { // is_array()
|
} else { // is_array()
|
||||||
ImGui::TextDisabled("[%d]", json.size());
|
ImGui::TextDisabled("[%zu]", json.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree_open) {
|
if (tree_open) {
|
||||||
@@ -143,10 +144,10 @@ void JsonViewerTree(const char* name, const JsonObjectType& json) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_integer:
|
case JsonObjectType::value_t::number_integer:
|
||||||
ImGui::TextColored(int_color, "%ld", json.template get<int64_t>());
|
ImGui::TextColored(int_color, "%" PRId64, json.template get<int64_t>());
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_unsigned:
|
case JsonObjectType::value_t::number_unsigned:
|
||||||
ImGui::TextColored(unsigned_color, "%lu", json.template get<uint64_t>());
|
ImGui::TextColored(unsigned_color, "%" PRIu64, json.template get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
case JsonObjectType::value_t::number_float:
|
case JsonObjectType::value_t::number_float:
|
||||||
ImGui::TextColored(float_color, "%f", json.template get<float>());
|
ImGui::TextColored(float_color, "%f", json.template get<float>());
|
||||||
@@ -200,9 +201,9 @@ void JsonEditor(const char* name, JsonObjectType& json) {
|
|||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (json.is_object()) {
|
if (json.is_object()) {
|
||||||
ImGui::TextDisabled("{%d}", json.size());
|
ImGui::TextDisabled("{%zu}", json.size());
|
||||||
} else { // is_array()
|
} else { // is_array()
|
||||||
ImGui::TextDisabled("[%d]", json.size());
|
ImGui::TextDisabled("[%zu]", json.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree_open) {
|
if (tree_open) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "./imgui_s.hpp"
|
#include "./imgui_s.hpp"
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
#include <imgui/backends/imgui_impl_sdl.h>
|
#include <imgui/backends/imgui_impl_sdl2.h>
|
||||||
|
|
||||||
#ifdef MM_OPENGL_3
|
#ifdef MM_OPENGL_3
|
||||||
#include <imgui/backends/imgui_impl_opengl3.h>
|
#include <imgui/backends/imgui_impl_opengl3.h>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "./scene_tools.hpp"
|
#include "./scene_tools.hpp"
|
||||||
|
#include "mm/engine_fwd.hpp"
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
|
|
||||||
@@ -109,17 +110,20 @@ namespace MM::Services {
|
|||||||
|
|
||||||
if (_show_scene_metrics) {
|
if (_show_scene_metrics) {
|
||||||
if (ImGui::Begin("Scene Metrics##ImGuiSceneToolsService", &_show_scene_metrics)) {
|
if (ImGui::Begin("Scene Metrics##ImGuiSceneToolsService", &_show_scene_metrics)) {
|
||||||
ImGui::Text("capacity: %lu", scene.capacity());
|
ImGui::Text("capacity: %zu", scene.storage<::MM::Entity>().capacity());
|
||||||
ImGui::Text("size: %lu", scene.size());
|
ImGui::Text("size: %zu", scene.storage<::MM::Entity>().size());
|
||||||
ImGui::Text("alive: %lu", scene.alive());
|
ImGui::Text("alive: %zu", scene.storage<::MM::Entity>().in_use());
|
||||||
|
if (ImGui::CollapsingHeader("orphans")) {
|
||||||
|
// iterating all entities is expensive
|
||||||
size_t orphans = 0;
|
size_t orphans = 0;
|
||||||
scene.each([&orphans, &scene](auto entity) {
|
for (const auto it : scene.storage<MM::Entity>().each()) {
|
||||||
if (scene.orphan(entity)) {
|
if (scene.orphan(std::get<0>(it))) {
|
||||||
orphans++;
|
orphans++;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
ImGui::Text("orphans: %lu", orphans);
|
ImGui::Text("orphans: %lu", orphans);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +161,7 @@ namespace MM::Services {
|
|||||||
if (_show_time_delta_ctx) {
|
if (_show_time_delta_ctx) {
|
||||||
if (ImGui::Begin("Scene TimeDelta Context", &_show_time_delta_ctx)) {
|
if (ImGui::Begin("Scene TimeDelta Context", &_show_time_delta_ctx)) {
|
||||||
if (scene.ctx().contains<MM::Components::TimeDelta>()) {
|
if (scene.ctx().contains<MM::Components::TimeDelta>()) {
|
||||||
auto& td = scene.ctx().at<MM::Components::TimeDelta>();
|
auto& td = scene.ctx().get<MM::Components::TimeDelta>();
|
||||||
ImGui::Value("tickDelta", td.tickDelta);
|
ImGui::Value("tickDelta", td.tickDelta);
|
||||||
ImGui::SliderFloat("deltaFactor", &td.deltaFactor, 0.f, 10.f, "%.5f", ImGuiSliderFlags_Logarithmic);
|
ImGui::SliderFloat("deltaFactor", &td.deltaFactor, 0.f, 10.f, "%.5f", ImGuiSliderFlags_Logarithmic);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ Texture::handle_t Texture::createEmptyMultiSampled(int32_t internalFormat, int32
|
|||||||
(void)height;
|
(void)height;
|
||||||
(void)samples;
|
(void)samples;
|
||||||
assert(false && "GLES has no multisampling support");
|
assert(false && "GLES has no multisampling support");
|
||||||
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,14 +29,20 @@ void setup_bloom(
|
|||||||
const auto bloom_internal_format = GL_RGB565; // prolly fine. NOPE its not. it causes green pixely halos
|
const auto bloom_internal_format = GL_RGB565; // prolly fine. NOPE its not. it causes green pixely halos
|
||||||
const auto bloom_format_type = GL_UNSIGNED_BYTE;
|
const auto bloom_format_type = GL_UNSIGNED_BYTE;
|
||||||
#else
|
#else
|
||||||
//const auto bloom_internal_format = GL_RGBA16F;
|
const auto bloom_format_type = GL_RGBA;
|
||||||
const auto bloom_internal_format = GL_R11F_G11F_B10F;
|
const auto bloom_internal_format = GL_RGBA16F;
|
||||||
const auto bloom_format_type = GL_FLOAT;
|
//const auto bloom_internal_format = GL_R11F_G11F_B10F;
|
||||||
|
const auto bloom_data_type = GL_FLOAT;
|
||||||
|
|
||||||
|
//const auto bloom_format_type = GL_RGBA_INTEGER;
|
||||||
|
//const auto bloom_internal_format = GL_RGBA16I;
|
||||||
|
//const auto bloom_data_type = GL_SHORT;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
//const auto bloom_internal_format = GL_RGB16F;
|
const auto bloom_format_type = GL_RGB;
|
||||||
const auto bloom_internal_format = GL_R11F_G11F_B10F;
|
const auto bloom_internal_format = GL_RGB16F; // opengl silently upgrades to RGBA
|
||||||
const auto bloom_format_type = GL_FLOAT;
|
//const auto bloom_internal_format = GL_R11F_G11F_B10F; // no sign
|
||||||
|
const auto bloom_data_type = GL_FLOAT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ // bloom in (bloom extraction)
|
{ // bloom in (bloom extraction)
|
||||||
@@ -44,7 +50,7 @@ void setup_bloom(
|
|||||||
"bloom_in",
|
"bloom_in",
|
||||||
bloom_internal_format,
|
bloom_internal_format,
|
||||||
w * bloom_in_scale, h * bloom_in_scale,
|
w * bloom_in_scale, h * bloom_in_scale,
|
||||||
GL_RGB, bloom_format_type
|
bloom_format_type, bloom_data_type
|
||||||
);
|
);
|
||||||
{ // filter
|
{ // filter
|
||||||
rm_t.get("bloom_in"_hs)->bind(0);
|
rm_t.get("bloom_in"_hs)->bind(0);
|
||||||
@@ -72,7 +78,7 @@ void setup_bloom(
|
|||||||
tex_out_id,
|
tex_out_id,
|
||||||
bloom_internal_format,
|
bloom_internal_format,
|
||||||
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
|
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
|
||||||
GL_RGB, bloom_format_type
|
bloom_format_type, bloom_data_type
|
||||||
);
|
);
|
||||||
{ // filter
|
{ // filter
|
||||||
rm_t.get(tex_out_id)->bind(0);
|
rm_t.get(tex_out_id)->bind(0);
|
||||||
@@ -89,7 +95,7 @@ void setup_bloom(
|
|||||||
tex_tmp_id,
|
tex_tmp_id,
|
||||||
bloom_internal_format,
|
bloom_internal_format,
|
||||||
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
|
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
|
||||||
GL_RGB, bloom_format_type
|
bloom_format_type, bloom_data_type
|
||||||
);
|
);
|
||||||
{ // filter
|
{ // filter
|
||||||
rm_t.get(tex_tmp_id)->bind(0);
|
rm_t.get(tex_tmp_id)->bind(0);
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ void BatchedSpriteSheet::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
|||||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
auto& cam = scene.ctx().at<Camera3D>();
|
auto& cam = scene.ctx().get<Camera3D>();
|
||||||
|
|
||||||
auto vp = cam.getViewProjection();
|
auto vp = cam.getViewProjection();
|
||||||
_shader->setUniformMat4f("_VP", vp);
|
_shader->setUniformMat4f("_VP", vp);
|
||||||
|
|||||||
@@ -102,11 +102,31 @@ in vec2 _uv;
|
|||||||
|
|
||||||
out vec3 _out_color;
|
out vec3 _out_color;
|
||||||
|
|
||||||
|
// global config, keep it constant
|
||||||
|
const float fake_halation_strenth = 1.0;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 color = texture(color_tex, _uv).rgb;
|
vec3 color = texture(color_tex, _uv).rgb;
|
||||||
|
|
||||||
// TODO: expose threshold
|
// TODO: expose threshold
|
||||||
_out_color = max(vec3(0.0), color - vec3(1.0));
|
//_out_color = max(vec3(0.0), color - vec3(1.0));
|
||||||
|
|
||||||
|
//_out_color = mix(
|
||||||
|
//color, // < 0.0
|
||||||
|
//max(vec3(0.0), color - vec3(1.0)), // > 0.0
|
||||||
|
//step(vec3(0.0), color)
|
||||||
|
//);
|
||||||
|
|
||||||
|
const vec3 fake_halation_base = vec3(0.03, 0.01, 0.0) * vec3(fake_halation_strenth);
|
||||||
|
const vec3 fake_halation_extraction_offset = vec3(1.0) - fake_halation_base;
|
||||||
|
const vec3 fake_halation_bloom_fact = vec3(1.0) + fake_halation_base;
|
||||||
|
|
||||||
|
if (fake_halation_strenth <= 0.001) {
|
||||||
|
_out_color = max(min(color, vec3(0.0)), color - vec3(1.0));
|
||||||
|
} else {
|
||||||
|
_out_color = max(min(color, vec3(0.0)), color - fake_halation_extraction_offset) * fake_halation_bloom_fact;
|
||||||
|
//_out_color = max(min(color, vec3(0.0)), color - vec3(0.95, 0.97, 1.0)) * vec3(1.10, 1.05, 1.0);
|
||||||
|
}
|
||||||
})")
|
})")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ void main() {
|
|||||||
vec3 color = texture(color_tex, _uv).rgb;
|
vec3 color = texture(color_tex, _uv).rgb;
|
||||||
vec3 bloom = texture(bloom_tex, _uv).rgb;
|
vec3 bloom = texture(bloom_tex, _uv).rgb;
|
||||||
|
|
||||||
vec3 comp = color + bloom * vec3(bloom_factor);
|
vec3 comp = max(vec3(0.0), color + bloom * vec3(bloom_factor));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
const vec3 tint = vec3(1.5, 0.8, 1.1);
|
const vec3 tint = vec3(1.5, 0.8, 1.1);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void FastSky::render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) {
|
|||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& cam = scene.ctx().at<MM::OpenGL::Camera3D>();
|
auto& cam = scene.ctx().get<MM::OpenGL::Camera3D>();
|
||||||
MM::OpenGL::Camera3D tmp_cam = cam;
|
MM::OpenGL::Camera3D tmp_cam = cam;
|
||||||
// create cam with y up, bc shader says so
|
// create cam with y up, bc shader says so
|
||||||
tmp_cam.up = {0, 1, 0};
|
tmp_cam.up = {0, 1, 0};
|
||||||
@@ -95,7 +95,7 @@ void FastSky::render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) {
|
|||||||
//}
|
//}
|
||||||
auto* ctx_ptr = &_default_context;
|
auto* ctx_ptr = &_default_context;
|
||||||
if (scene.ctx().contains<FastSkyContext>()) {
|
if (scene.ctx().contains<FastSkyContext>()) {
|
||||||
ctx_ptr = &scene.ctx().at<FastSkyContext>();
|
ctx_ptr = &scene.ctx().get<FastSkyContext>();
|
||||||
}
|
}
|
||||||
|
|
||||||
_shader->setUniform1f("time", ctx_ptr->time);
|
_shader->setUniform1f("time", ctx_ptr->time);
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ void LiteParticles2D::uploadParticles(Services::OpenGLRenderer&, Scene& scene) {
|
|||||||
return; // nothing to upload
|
return; // nothing to upload
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& queue = scene.ctx().at<Components::LiteParticles2DUploadQueue>();
|
auto& queue = scene.ctx().get<Components::LiteParticles2DUploadQueue>();
|
||||||
|
|
||||||
while (!queue.queue.empty()) {
|
while (!queue.queue.empty()) {
|
||||||
// get range
|
// get range
|
||||||
@@ -200,7 +200,7 @@ void LiteParticles2D::computeParticles(Services::OpenGLRenderer&, Scene& scene)
|
|||||||
std::chrono::duration<double, std::ratio<1, 1>> deltaTime = newNow - _last_time;
|
std::chrono::duration<double, std::ratio<1, 1>> deltaTime = newNow - _last_time;
|
||||||
_last_time = newNow;
|
_last_time = newNow;
|
||||||
|
|
||||||
float time_delta = deltaTime.count() * scene.ctx().at<MM::Components::TimeDelta>().deltaFactor;
|
float time_delta = deltaTime.count() * scene.ctx().get<MM::Components::TimeDelta>().deltaFactor;
|
||||||
_time += time_delta;
|
_time += time_delta;
|
||||||
_tf_shader->setUniform1f("_time_delta", time_delta);
|
_tf_shader->setUniform1f("_time_delta", time_delta);
|
||||||
_tf_shader->setUniform1f("_time", _time);
|
_tf_shader->setUniform1f("_time", _time);
|
||||||
@@ -269,7 +269,7 @@ void LiteParticles2D::renderParticles(Services::OpenGLRenderer& rs, Scene& scene
|
|||||||
auto& rm_t = MM::ResourceManager<Texture>::ref();
|
auto& rm_t = MM::ResourceManager<Texture>::ref();
|
||||||
rm_t.get("MM::LiteParticles2DTypes::Render"_hs)->bind(0);
|
rm_t.get("MM::LiteParticles2DTypes::Render"_hs)->bind(0);
|
||||||
|
|
||||||
Camera3D& cam = scene.ctx().at<Camera3D>();
|
Camera3D& cam = scene.ctx().get<Camera3D>();
|
||||||
_points_shader->setUniformMat4f("_vp", cam.getViewProjection());
|
_points_shader->setUniformMat4f("_vp", cam.getViewProjection());
|
||||||
|
|
||||||
GLint view_port[4];
|
GLint view_port[4];
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void SimpleRect::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
|||||||
_shader->bind();
|
_shader->bind();
|
||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
Camera3D& cam = scene.ctx().at<Camera3D>();
|
Camera3D& cam = scene.ctx().get<Camera3D>();
|
||||||
auto vp = cam.getViewProjection();
|
auto vp = cam.getViewProjection();
|
||||||
|
|
||||||
scene.view<const Components::Transform4x4>().each([this, &scene, &vp](entt::entity e, const auto& t) {
|
scene.view<const Components::Transform4x4>().each([this, &scene, &vp](entt::entity e, const auto& t) {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void SimpleSprite::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
|||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
|
|
||||||
Camera3D& cam = scene.ctx().at<Camera3D>();
|
Camera3D& cam = scene.ctx().get<Camera3D>();
|
||||||
auto vp = cam.getViewProjection();
|
auto vp = cam.getViewProjection();
|
||||||
|
|
||||||
scene.view<const Components::Transform4x4, Components::OpenGL::Texture>().each([this, &scene, &vp](entt::entity e, const auto& t, auto& tex) {
|
scene.view<const Components::Transform4x4, Components::OpenGL::Texture>().each([this, &scene, &vp](entt::entity e, const auto& t, auto& tex) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ void SimpleSpriteSheet::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
|||||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
Camera3D& cam = scene.ctx().at<Camera3D>();
|
Camera3D& cam = scene.ctx().get<Camera3D>();
|
||||||
auto vp = cam.getViewProjection();
|
auto vp = cam.getViewProjection();
|
||||||
|
|
||||||
scene.view<const Components::Transform4x4, SpriteSheetRenderable>().each([this, &scene, &vp](entt::entity e, const auto& t, auto& spr) {
|
scene.view<const Components::Transform4x4, SpriteSheetRenderable>().each([this, &scene, &vp](entt::entity e, const auto& t, auto& spr) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void Tilemap::render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) {
|
|||||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||||
_vao->bind();
|
_vao->bind();
|
||||||
|
|
||||||
MM::OpenGL::Camera3D& cam = scene.ctx().at<MM::OpenGL::Camera3D>();
|
MM::OpenGL::Camera3D& cam = scene.ctx().get<MM::OpenGL::Camera3D>();
|
||||||
auto vp = cam.getViewProjection();
|
auto vp = cam.getViewProjection();
|
||||||
|
|
||||||
_shader->setUniform3f("_ambient_color", ambient_color);
|
_shader->setUniform3f("_ambient_color", ambient_color);
|
||||||
@@ -150,7 +150,7 @@ layout(location = 2) in uint _atlasIndex;
|
|||||||
//layout(location = 3) in vec3 _tColor;
|
//layout(location = 3) in vec3 _tColor;
|
||||||
|
|
||||||
//out vec4 _color;
|
//out vec4 _color;
|
||||||
out vec2 _tex_pos;
|
centroid out vec2 _tex_pos;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
//gl_Position = vec4(_WVP * vec3(_vertexPosition, 1), 1);
|
//gl_Position = vec4(_WVP * vec3(_vertexPosition, 1), 1);
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ static void setup_fbos(MM::Engine& engine) {
|
|||||||
assert(rs.targets["game_view"]);
|
assert(rs.targets["game_view"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MM::Engine engine;
|
||||||
|
|
||||||
TEST(hdr_bloom_pipeline, it) {
|
TEST(hdr_bloom_pipeline, it) {
|
||||||
MM::Engine engine;
|
|
||||||
|
|
||||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||||
@@ -228,7 +229,7 @@ TEST(hdr_bloom_pipeline, it) {
|
|||||||
col.color = {3.f, 3.f, 3.f, 1.f};
|
col.color = {3.f, 3.f, 3.f, 1.f};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
auto e = scene.create();
|
auto e = scene.create();
|
||||||
auto& p = scene.emplace<MM::Components::Position2D>(e);
|
auto& p = scene.emplace<MM::Components::Position2D>(e);
|
||||||
p.pos.x = i * 9.f - 40;
|
p.pos.x = i * 9.f - 40;
|
||||||
@@ -247,7 +248,43 @@ TEST(hdr_bloom_pipeline, it) {
|
|||||||
col.color = {rng.zeroToOne()*2.f, rng.zeroToOne()*2.f, rng.zeroToOne()*2.f, 1.f};
|
col.color = {rng.zeroToOne()*2.f, rng.zeroToOne()*2.f, rng.zeroToOne()*2.f, 1.f};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 5; i < 10; i++) {
|
||||||
|
auto e = scene.create();
|
||||||
|
auto& p = scene.emplace<MM::Components::Position2D>(e);
|
||||||
|
p.pos.x = i * 9.f - 40;
|
||||||
|
|
||||||
|
// zoffset is created by event
|
||||||
|
|
||||||
|
auto& s = scene.emplace<MM::Components::Scale2D>(e);
|
||||||
|
s.scale = {5,5};
|
||||||
|
|
||||||
|
scene.emplace<MM::Components::Rotation2D>(e);
|
||||||
|
|
||||||
|
auto& v = scene.emplace<MM::Components::Velocity2DRotation>(e);
|
||||||
|
v.rot_vel = i * 0.3f;
|
||||||
|
|
||||||
|
auto& col = scene.emplace<MM::Components::Color>(e);
|
||||||
|
col.color = {rng.zeroToOne()*-2.f, rng.zeroToOne()*-2.f, rng.zeroToOne()*-2.f, 1.f};
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // white background for negatives
|
||||||
|
auto e = scene.create();
|
||||||
|
auto& p = scene.emplace<MM::Components::Position2D>(e);
|
||||||
|
p.pos.y = 30.f;
|
||||||
|
p.pos.x = 25.f;
|
||||||
|
|
||||||
|
auto& s = scene.emplace<MM::Components::Scale2D>(e);
|
||||||
|
s.scale = {50,150};
|
||||||
|
|
||||||
|
auto& col = scene.emplace<MM::Components::Color>(e);
|
||||||
|
col.color = {1.f, 1.f, 1.f, 1.f};
|
||||||
|
}
|
||||||
|
|
||||||
engine.run();
|
engine.run();
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
engine.cleanup();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ void OrganizerSceneService::sceneFixedUpdate(Engine&) {
|
|||||||
_accumulator -= f_delta;
|
_accumulator -= f_delta;
|
||||||
continuous_counter++;
|
continuous_counter++;
|
||||||
|
|
||||||
for (auto&& v : _scene->ctx().at<std::vector<entt::organizer::vertex>>()) {
|
for (auto&& v : _scene->ctx().get<std::vector<entt::organizer::vertex>>()) {
|
||||||
v.callback()(v.data(), *_scene);
|
v.callback()(v.data(), *_scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,8 @@ void OrganizerSceneService::updateOrganizerVertices(Scene& scene) {
|
|||||||
scene.ctx().emplace<MM::Components::TimeDelta>();
|
scene.ctx().emplace<MM::Components::TimeDelta>();
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_DEBUG("graph:\n{}", scene.ctx().at<std::vector<entt::organizer::vertex>>());
|
// TODO: use entt::dot instead
|
||||||
|
SPDLOG_DEBUG("graph:\n{}", scene.ctx().get<std::vector<entt::organizer::vertex>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrganizerSceneService::resetTime(void) {
|
void OrganizerSceneService::resetTime(void) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ struct SRNG {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool roll(float prob) {
|
bool roll(float prob) {
|
||||||
return zeroToOne() <= prob;
|
return zeroToOne() <= prob; // TODO: just < ?
|
||||||
}
|
}
|
||||||
|
|
||||||
// more advanced
|
// more advanced
|
||||||
|
|||||||
@@ -75,13 +75,13 @@ class ResourceManager {
|
|||||||
return reload<Loader>(entt::hashed_string{id}.value(), std::forward<Args>(args)...);
|
return reload<Loader>(entt::hashed_string{id}.value(), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void discard(const res_id_type id) ENTT_NOEXCEPT {
|
void discard(const res_id_type id) noexcept {
|
||||||
if (auto it = _storage.find(id); it != _storage.end()) {
|
if (auto it = _storage.find(id); it != _storage.end()) {
|
||||||
_storage.erase(it);
|
_storage.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void discard(const char* id) ENTT_NOEXCEPT {
|
void discard(const char* id) noexcept {
|
||||||
discard(entt::hashed_string{id}.value());
|
discard(entt::hashed_string{id}.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,11 +100,11 @@ class ResourceManager {
|
|||||||
return _storage.empty();
|
return _storage.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(void) ENTT_NOEXCEPT {
|
void clear(void) noexcept {
|
||||||
_storage.clear();
|
_storage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains(const res_id_type id) const ENTT_NOEXCEPT {
|
bool contains(const res_id_type id) const noexcept {
|
||||||
return (_storage.find(id) != _storage.cend());
|
return (_storage.find(id) != _storage.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
framework/s6zer/CMakeLists.txt
Normal file
23
framework/s6zer/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(s6zer CXX)
|
||||||
|
|
||||||
|
add_library(s6zer INTERFACE
|
||||||
|
#./src/s6zer/stream.hpp
|
||||||
|
#./src/s6zer/serialize.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(MM::s6zer ALIAS s6zer)
|
||||||
|
|
||||||
|
target_include_directories(s6zer INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
|
target_compile_features(s6zer INTERFACE cxx_std_17)
|
||||||
|
|
||||||
|
#target_link_libraries(s6zer
|
||||||
|
#INTERFACE
|
||||||
|
#)
|
||||||
|
|
||||||
|
if (BUILD_TESTING)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
|
|
||||||
33
framework/s6zer/src/mm/s6zer/serialize.hpp
Normal file
33
framework/s6zer/src/mm/s6zer/serialize.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "./stream.hpp"
|
||||||
|
|
||||||
|
namespace MM::s6zer {
|
||||||
|
|
||||||
|
// serialize macros
|
||||||
|
|
||||||
|
// TODO: make use of ADL, like nlohmann::json does.
|
||||||
|
|
||||||
|
/*
|
||||||
|
defines mm_serialize functions for you.
|
||||||
|
a "stream" object is in scope (StreamWriter/StreamReader),
|
||||||
|
as well as the object of Type called "data".
|
||||||
|
eg:
|
||||||
|
MM_DEFINE_SERIALIZE(Test1,
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBits(data.seq, 16))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBits(data.data1, 8))
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
// TODO: refine, so we dont have to do MM_S6ZER_BAIL() everytime
|
||||||
|
#define MM_DEFINE_SERIALIZE(Type, ...) \
|
||||||
|
inline bool mm_serialize(MM::s6zer::StreamWriter& stream, const Type& data) { \
|
||||||
|
__VA_ARGS__ \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
inline bool mm_serialize(MM::s6zer::StreamReader& stream, Type& data) { \
|
||||||
|
__VA_ARGS__ \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MM::s6zer
|
||||||
|
|
||||||
327
framework/s6zer/src/mm/s6zer/stream.hpp
Normal file
327
framework/s6zer/src/mm/s6zer/stream.hpp
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef> // size_t
|
||||||
|
#include <cstdint> // uint8_t, etc
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// TODO: make asserts redefinable
|
||||||
|
|
||||||
|
namespace MM::s6zer {
|
||||||
|
|
||||||
|
// this is heavily inspired by Glenn Fiedler's (Gaffer On Games) serializers
|
||||||
|
// https://www.gafferongames.com/post/reading_and_writing_packets/
|
||||||
|
// https://www.gafferongames.com/post/serialization_strategies/
|
||||||
|
|
||||||
|
// internal helpers
|
||||||
|
namespace detail {
|
||||||
|
// TODO: ugly, replace when c++20
|
||||||
|
[[nodiscard]] constexpr size_t first_bit_set8(const uint8_t number) {
|
||||||
|
return
|
||||||
|
(number & 0b10000000) ? 8 :
|
||||||
|
(number & 0b01000000) ? 7 :
|
||||||
|
(number & 0b00100000) ? 6 :
|
||||||
|
(number & 0b00010000) ? 5 :
|
||||||
|
(number & 0b00001000) ? 4 :
|
||||||
|
(number & 0b00000100) ? 3 :
|
||||||
|
(number & 0b00000010) ? 2 :
|
||||||
|
(number & 0b00000001) ? 1 :
|
||||||
|
0
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr size_t first_bit_set32(const uint32_t number) {
|
||||||
|
return
|
||||||
|
(number & 0xff000000) ? first_bit_set8((number >> 24) & 0xff) + 24 :
|
||||||
|
(number & 0x00ff0000) ? first_bit_set8((number >> 16) & 0xff) + 16 :
|
||||||
|
(number & 0x0000ff00) ? first_bit_set8((number >> 8) & 0xff) + 8 :
|
||||||
|
(number & 0x000000ff) ? first_bit_set8(number & 0xff) :
|
||||||
|
0
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr uint32_t byte_swap(const uint32_t value) noexcept {
|
||||||
|
return
|
||||||
|
((value & 0xff000000) >> 24) |
|
||||||
|
((value & 0x00ff0000) >> 8) |
|
||||||
|
((value & 0x0000ff00) << 8) |
|
||||||
|
((value & 0x000000ff) << 24)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr uint16_t byte_swap(const uint16_t value) noexcept {
|
||||||
|
return
|
||||||
|
((value & 0xff00) >> 8) |
|
||||||
|
((value & 0x00ff) << 8)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr uint8_t byte_swap(const uint8_t value) noexcept {
|
||||||
|
// noop
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] constexpr const T& max(const T& a, const T& b) noexcept {
|
||||||
|
return (a < b) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
// TODO: maybe 64bit?
|
||||||
|
// TODO: is this detail?
|
||||||
|
[[nodiscard]] constexpr size_t bits_required(const uint32_t numbers) {
|
||||||
|
return detail::first_bit_set32(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr uint32_t serialize_byte_order(const uint32_t value) {
|
||||||
|
// TODO: only works on little endian for now
|
||||||
|
if constexpr (true) { // native is little endian
|
||||||
|
return value;
|
||||||
|
} else { // native is big endian
|
||||||
|
return detail::byte_swap(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper for fake exceptions
|
||||||
|
#ifndef MM_S6ZER_BAIL
|
||||||
|
#define MM_S6ZER_BAIL(...) { \
|
||||||
|
if (! __VA_ARGS__) { \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct StreamWriter {
|
||||||
|
StreamWriter(void) = delete;
|
||||||
|
StreamWriter(uint32_t* data, size_t size) : _data(data), _data_size(size) {
|
||||||
|
assert(size != 0);
|
||||||
|
assert(size % sizeof(uint32_t) == 0);
|
||||||
|
assert(data != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do i still need them?
|
||||||
|
[[nodiscard]] static constexpr bool isWriting(void) noexcept { return true; }
|
||||||
|
[[nodiscard]] static constexpr bool isReading(void) noexcept { return false; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool flush(void) noexcept {
|
||||||
|
if (_scratch_bits != 0) {
|
||||||
|
// check if space in buffer
|
||||||
|
if (_data_size < (_word_index + 1) * sizeof(uint32_t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_data[_word_index] = serialize_byte_order(static_cast<uint32_t>(_scratch & 0xffffffff));
|
||||||
|
_scratch >>= 32; // new bits are allways unset, so we can just allways 32
|
||||||
|
// we dont like negative
|
||||||
|
_scratch_bits = detail::max(static_cast<int32_t>(_scratch_bits) - 32, 0);
|
||||||
|
_word_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] bool serializeBits(const T value, const size_t number_of_bits = sizeof(T)*8) noexcept {
|
||||||
|
static_assert(std::is_integral_v<T>, "type needs to be an integer");
|
||||||
|
static_assert(std::is_unsigned_v<T>, "type needs to be unsigned");
|
||||||
|
static_assert(sizeof(T) <= 4, "not yet defined for > 32bit");
|
||||||
|
assert(number_of_bits <= sizeof(T)*8);
|
||||||
|
assert(number_of_bits > 0);
|
||||||
|
|
||||||
|
// do scratching
|
||||||
|
_scratch |= static_cast<uint64_t>(value) << _scratch_bits;
|
||||||
|
_scratch_bits += number_of_bits;
|
||||||
|
_bits_written += number_of_bits;
|
||||||
|
|
||||||
|
if (_scratch_bits >= 32) {
|
||||||
|
return flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeBool(const bool value) noexcept {
|
||||||
|
return serializeBits(static_cast<uint32_t>(value), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] bool serializeInt(const T value, const T min, const T max) noexcept {
|
||||||
|
static_assert(std::is_integral_v<T>, "type needs to be an integer");
|
||||||
|
static_assert(sizeof(T) <= 4, "not yet defined for > 32bit");
|
||||||
|
assert(max >= min);
|
||||||
|
assert(value >= min);
|
||||||
|
assert(value <= max);
|
||||||
|
|
||||||
|
const size_t bits = bits_required(max - min);
|
||||||
|
|
||||||
|
return serializeBits(static_cast<uint32_t>(value - min), bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeFloat(const float value) noexcept {
|
||||||
|
// TODO: dont use loop
|
||||||
|
for (size_t i = 0; i < sizeof(float); i++) {
|
||||||
|
MM_S6ZER_BAIL(serializeBits(reinterpret_cast<const uint8_t*>(&value)[i], 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeDouble(const double value) noexcept {
|
||||||
|
// TODO: dont use loop
|
||||||
|
for (size_t i = 0; i < sizeof(double); i++) {
|
||||||
|
MM_S6ZER_BAIL(serializeBits(reinterpret_cast<const uint8_t*>(&value)[i], 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeFloatCompressed(const float value, const float min, const float max, const float resolution) noexcept {
|
||||||
|
assert(max >= min);
|
||||||
|
assert(value >= min);
|
||||||
|
assert(value <= max);
|
||||||
|
|
||||||
|
// TODO: handle those rounding errors
|
||||||
|
|
||||||
|
const float numbers = (max - min) / resolution;
|
||||||
|
const size_t bits = bits_required(static_cast<uint32_t>(numbers));
|
||||||
|
|
||||||
|
const uint32_t tmp_value = static_cast<uint32_t>((value - min) / resolution);
|
||||||
|
|
||||||
|
return serializeBits(tmp_value, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t bytesWritten(void) noexcept {
|
||||||
|
return (_bits_written+7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* _data {nullptr};
|
||||||
|
size_t _data_size {0};
|
||||||
|
|
||||||
|
uint64_t _scratch {0};
|
||||||
|
size_t _scratch_bits {0};
|
||||||
|
size_t _word_index {0};
|
||||||
|
size_t _bits_written {0}; // includes bits still in scratch
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StreamReader {
|
||||||
|
StreamReader(void) = delete;
|
||||||
|
// !! StreamReader assumes the data buffer has whole uint32_t,
|
||||||
|
// so at the end, even though data_size might be less then 4 bytes,
|
||||||
|
// here is actually a full, empty uint32
|
||||||
|
// !! enable AddressSanitzier during development and testing
|
||||||
|
StreamReader(const uint32_t* data, size_t size) : _data(data), _data_size(size) {
|
||||||
|
assert(size != 0);
|
||||||
|
//assert(size % sizeof(uint32_t) == 0);
|
||||||
|
assert(data != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do i still need them?
|
||||||
|
[[nodiscard]] static constexpr bool isWriting(void) noexcept { return false; }
|
||||||
|
[[nodiscard]] static constexpr bool isReading(void) noexcept { return true; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] bool serializeBits(T& value, const size_t number_of_bits = sizeof(T)*8) noexcept {
|
||||||
|
static_assert(std::is_integral_v<T>, "type needs to be an integer");
|
||||||
|
static_assert(std::is_unsigned_v<T>, "type needs to be unsigned");
|
||||||
|
static_assert(sizeof(T) <= 4, "not yet defined for > 32bit");
|
||||||
|
assert(number_of_bits <= sizeof(T)*8);
|
||||||
|
assert(number_of_bits > 0);
|
||||||
|
|
||||||
|
if (_scratch_bits < number_of_bits) {
|
||||||
|
if (_bits_read + number_of_bits > _data_size*8) {
|
||||||
|
// would read past end
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_scratch |= static_cast<uint64_t>(serialize_byte_order(_data[_word_index])) << _scratch_bits;
|
||||||
|
_word_index++;
|
||||||
|
_scratch_bits += 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = _scratch & ((uint64_t(1) << number_of_bits) - 1);
|
||||||
|
|
||||||
|
_scratch >>= number_of_bits;
|
||||||
|
_scratch_bits -= number_of_bits;
|
||||||
|
_bits_read += number_of_bits;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeBool(bool& value) noexcept {
|
||||||
|
uint32_t tmp_value {0};
|
||||||
|
MM_S6ZER_BAIL(serializeBits(tmp_value, 1));
|
||||||
|
|
||||||
|
// :)
|
||||||
|
value = tmp_value != 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] bool serializeInt(T& value, const T min, const T max) noexcept {
|
||||||
|
static_assert(std::is_integral_v<T>, "type needs to be an integer");
|
||||||
|
static_assert(sizeof(T) <= 4, "not yet defined for > 32bit");
|
||||||
|
assert(max >= min);
|
||||||
|
|
||||||
|
const size_t bits = bits_required(max - min);
|
||||||
|
|
||||||
|
uint32_t tmp_val {0};
|
||||||
|
MM_S6ZER_BAIL(serializeBits(tmp_val, bits));
|
||||||
|
|
||||||
|
value = static_cast<T>(tmp_val) + min;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeFloat(float& value) noexcept {
|
||||||
|
// TODO: dont use loop
|
||||||
|
for (size_t i = 0; i < sizeof(float); i++) {
|
||||||
|
MM_S6ZER_BAIL(serializeBits(reinterpret_cast<uint8_t*>(&value)[i], 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeDouble(double& value) noexcept {
|
||||||
|
// TODO: dont use loop
|
||||||
|
for (size_t i = 0; i < sizeof(double); i++) {
|
||||||
|
MM_S6ZER_BAIL(serializeBits(reinterpret_cast<uint8_t*>(&value)[i], 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool serializeFloatCompressed(float& value, const float min, const float max, const float resolution) noexcept {
|
||||||
|
assert(max >= min);
|
||||||
|
|
||||||
|
// TODO: use rounding, rn it snaps (floor)
|
||||||
|
|
||||||
|
const float numbers = (max - min) / resolution;
|
||||||
|
const size_t bits = bits_required(static_cast<uint32_t>(numbers));
|
||||||
|
|
||||||
|
uint32_t tmp_value {0};
|
||||||
|
MM_S6ZER_BAIL(serializeBits(tmp_value, bits));
|
||||||
|
|
||||||
|
value = static_cast<float>(tmp_value) * resolution + min;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t bytesRead(void) noexcept {
|
||||||
|
return (_bits_read+7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t* _data {nullptr};
|
||||||
|
size_t _data_size {0};
|
||||||
|
|
||||||
|
uint64_t _scratch {0};
|
||||||
|
size_t _scratch_bits {0};
|
||||||
|
size_t _word_index {0};
|
||||||
|
size_t _bits_read {0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // MM::s6zer
|
||||||
|
|
||||||
18
framework/s6zer/test/CMakeLists.txt
Normal file
18
framework/s6zer/test/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
add_executable(s6zer_test
|
||||||
|
test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(s6zer_test PRIVATE ".")
|
||||||
|
|
||||||
|
target_compile_features(s6zer_test PRIVATE cxx_std_17)
|
||||||
|
|
||||||
|
target_link_libraries(s6zer_test
|
||||||
|
gtest_main
|
||||||
|
|
||||||
|
s6zer
|
||||||
|
|
||||||
|
random
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME s6zer_test COMMAND s6zer_test)
|
||||||
|
|
||||||
553
framework/s6zer/test/test.cpp
Normal file
553
framework/s6zer/test/test.cpp
Normal file
@@ -0,0 +1,553 @@
|
|||||||
|
#include <mm/s6zer/serialize.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include <mm/random/srng.hpp>
|
||||||
|
#include <mm/scalar_range2.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace MM {
|
||||||
|
template<typename Char, typename T>
|
||||||
|
std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& out, const MM::ScalarRange2<T>& range) {
|
||||||
|
return out << "{ min: " << static_cast<int64_t>(range.min()) << ", max: " << static_cast<int64_t>(range.max()) << " }";
|
||||||
|
}
|
||||||
|
} // MM
|
||||||
|
|
||||||
|
TEST(s6zer, bits_required_static) {
|
||||||
|
static_assert(MM::s6zer::bits_required(0)== 0);
|
||||||
|
static_assert(MM::s6zer::bits_required(1)== 1);
|
||||||
|
static_assert(MM::s6zer::bits_required(2)== 2);
|
||||||
|
static_assert(MM::s6zer::bits_required(3)== 2);
|
||||||
|
static_assert(MM::s6zer::bits_required(4)== 3);
|
||||||
|
static_assert(MM::s6zer::bits_required(32)== 6);
|
||||||
|
static_assert(MM::s6zer::bits_required(0xffffffff)== 32);
|
||||||
|
static_assert(MM::s6zer::bits_required(0xffffff00)== 32);
|
||||||
|
static_assert(MM::s6zer::bits_required(0xf0000a00)== 32);
|
||||||
|
static_assert(MM::s6zer::bits_required(0x0f000000)== 28);
|
||||||
|
static_assert(MM::s6zer::bits_required(0x0000f000)== 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(s6zer, byte_swap) {
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint8_t>(0x00)) == 0x00);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint8_t>(0xff)) == 0xff);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint8_t>(0x10)) == 0x10);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint8_t>(0xfe)) == 0xfe);
|
||||||
|
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint16_t>(0x0000)) == 0x0000);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint16_t>(0xffff)) == 0xffff);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint16_t>(0x00fe)) == 0xfe00);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint16_t>(0xfefe)) == 0xfefe);
|
||||||
|
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint32_t>(0x00000000)) == 0x00000000);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint32_t>(0xffffffff)) == 0xffffffff);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint32_t>(0xf0f00000)) == 0x0000f0f0);
|
||||||
|
static_assert(MM::s6zer::detail::byte_swap(static_cast<uint32_t>(0xfe0000ef)) == 0xef0000fe);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(s6zer, stream_normalcase1) {
|
||||||
|
const uint32_t num1_orig {0b111};
|
||||||
|
const uint32_t num1_orig_bits {3};
|
||||||
|
const uint32_t num2_orig {0b1111111111};
|
||||||
|
const uint32_t num2_orig_bits {10};
|
||||||
|
const uint32_t num3_orig {0b111111111111111111111111};
|
||||||
|
const uint32_t num3_orig_bits {24};
|
||||||
|
|
||||||
|
std::array<uint32_t, 2> buffer;
|
||||||
|
size_t buffer_size = buffer.size()*sizeof(uint32_t);
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamWriter writer{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(writer._scratch, 0x0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, 0);
|
||||||
|
ASSERT_EQ(writer.bytesWritten(), 0);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num1_orig, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b0000000000000000000000000000000000000000000000000000000000000'111);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 3);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num2_orig, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b000000000000000000000000000000000000000000000000000'111'1111111111);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 3+10);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num3_orig, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b00000000000000000000000000000000000000000000000000000000000'11111);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, (3+10+24)-32);
|
||||||
|
ASSERT_EQ(writer._word_index, 1);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits);
|
||||||
|
|
||||||
|
r = writer.flush();
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._word_index, 2);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits); // flush does not change bits written
|
||||||
|
ASSERT_EQ(writer.bytesWritten(), 5); // 4.625 , so ceil
|
||||||
|
|
||||||
|
buffer_size = writer.bytesWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "buffer_size: " << buffer_size << "\n";
|
||||||
|
|
||||||
|
ASSERT_EQ(buffer[0], 0xffffffff);
|
||||||
|
ASSERT_EQ(buffer[1], 0b000000000000000000000000000'11111);
|
||||||
|
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(reader._word_index, 0);
|
||||||
|
|
||||||
|
uint32_t num1 {0};
|
||||||
|
r = reader.serializeBits(num1, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num1, num1_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0b00000000'00000000'00000000'00000000'000'11111111111111111111111111111);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 29);
|
||||||
|
ASSERT_EQ(reader._word_index, 1); // index refers to next dword
|
||||||
|
|
||||||
|
uint32_t num2 {0};
|
||||||
|
r = reader.serializeBits(num2, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num2, num2_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0b00000000'00000000'00000000'00000000'000'00000'00000'1111111111111111111);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 19);
|
||||||
|
ASSERT_EQ(reader._word_index, 1); // <=32, so should not yet have read next dword
|
||||||
|
|
||||||
|
uint32_t num3 {0};
|
||||||
|
r = reader.serializeBits(num3, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num3, num3_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0); // no data left
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 27);
|
||||||
|
ASSERT_EQ(reader._word_index, 2);
|
||||||
|
|
||||||
|
// error case
|
||||||
|
uint32_t num4 {0};
|
||||||
|
r = reader.serializeBits(num4, 32);
|
||||||
|
ASSERT_FALSE(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(s6zer, stream_normalcase1_1) {
|
||||||
|
const uint32_t num1_orig {0b101};
|
||||||
|
const uint32_t num1_orig_bits {3};
|
||||||
|
const uint32_t num2_orig {0b1010101010};
|
||||||
|
const uint32_t num2_orig_bits {10};
|
||||||
|
const uint32_t num3_orig {0b101010101010101010101010};
|
||||||
|
const uint32_t num3_orig_bits {24};
|
||||||
|
|
||||||
|
std::array<uint32_t, 2> buffer;
|
||||||
|
size_t buffer_size = buffer.size()*sizeof(uint32_t);
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamWriter writer{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(writer._scratch, 0x0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, 0);
|
||||||
|
ASSERT_EQ(writer.bytesWritten(), 0);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num1_orig, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b0000000000000000000000000000000000000000000000000000000000000'101);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 3);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num2_orig, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b000000000000000000000000000000000000000000000000000'1010101010'101);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 3+10);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num3_orig, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0b00000000000000000000000000000000000000000000000000000000000'10101); // the high bits of the 24
|
||||||
|
ASSERT_EQ(writer._scratch_bits, (3+10+24)-32);
|
||||||
|
ASSERT_EQ(writer._word_index, 1);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits);
|
||||||
|
|
||||||
|
r = writer.flush();
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._word_index, 2);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits); // flush does not change bits written
|
||||||
|
ASSERT_EQ(writer.bytesWritten(), 5); // 4.625 , so ceil
|
||||||
|
|
||||||
|
buffer_size = writer.bytesWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "buffer_size: " << buffer_size << "\n";
|
||||||
|
|
||||||
|
ASSERT_EQ(buffer[0], 0b0101010101010101010'1010101010'101);
|
||||||
|
ASSERT_EQ(buffer[1], 0b000000000000000000000000000'10101);
|
||||||
|
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(reader._word_index, 0);
|
||||||
|
|
||||||
|
uint32_t num1 {0};
|
||||||
|
r = reader.serializeBits(num1, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num1, num1_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0b00000000'00000000'00000000'00000000'000'0101010101010101010'1010101010);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 29);
|
||||||
|
ASSERT_EQ(reader._word_index, 1); // index refers to next dword
|
||||||
|
|
||||||
|
uint32_t num2 {0};
|
||||||
|
r = reader.serializeBits(num2, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num2, num2_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0b00000000'00000000'00000000'00000000'000'00000'00000'0101010101010101010);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 19);
|
||||||
|
ASSERT_EQ(reader._word_index, 1); // <=32, so should not yet have read next dword
|
||||||
|
|
||||||
|
uint32_t num3 {0};
|
||||||
|
r = reader.serializeBits(num3, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num3, num3_orig);
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0); // no data left
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 27);
|
||||||
|
ASSERT_EQ(reader._word_index, 2);
|
||||||
|
|
||||||
|
// error case
|
||||||
|
uint32_t num4 {0};
|
||||||
|
r = reader.serializeBits(num4, 32);
|
||||||
|
ASSERT_FALSE(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(s6zer, stream_normalcase2) {
|
||||||
|
// we now take each number as its maximum, synthetic for testing
|
||||||
|
const uint32_t num1_orig {17};
|
||||||
|
const uint32_t num1_orig_bits {MM::s6zer::bits_required(num1_orig)};
|
||||||
|
const uint32_t num2_orig {1};
|
||||||
|
const uint32_t num2_orig_bits {MM::s6zer::bits_required(num2_orig)};
|
||||||
|
const uint32_t num3_orig {1298989};
|
||||||
|
const uint32_t num3_orig_bits {MM::s6zer::bits_required(num3_orig)};
|
||||||
|
|
||||||
|
std::array<uint32_t, 2> buffer;
|
||||||
|
size_t buffer_size = buffer.size()*sizeof(uint32_t);
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamWriter writer{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
// fewer asserts
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(writer._scratch, 0x0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._word_index, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, 0);
|
||||||
|
ASSERT_EQ(writer.bytesWritten(), 0);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num1_orig, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num2_orig, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits);
|
||||||
|
|
||||||
|
r = writer.serializeBits(num3_orig, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits);
|
||||||
|
|
||||||
|
r = writer.flush();
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(writer._scratch, 0);
|
||||||
|
ASSERT_EQ(writer._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(writer._bits_written, num1_orig_bits+num2_orig_bits+num3_orig_bits); // flush does not change bits written
|
||||||
|
|
||||||
|
buffer_size = writer.bytesWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "buffer_size: " << buffer_size << "\n";
|
||||||
|
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0);
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 0);
|
||||||
|
ASSERT_EQ(reader._word_index, 0);
|
||||||
|
ASSERT_EQ(reader._bits_read, 0);
|
||||||
|
|
||||||
|
uint32_t num1 {0};
|
||||||
|
r = reader.serializeBits(num1, num1_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num1, num1_orig);
|
||||||
|
|
||||||
|
uint32_t num2 {0};
|
||||||
|
r = reader.serializeBits(num2, num2_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num2, num2_orig);
|
||||||
|
|
||||||
|
uint32_t num3 {0};
|
||||||
|
r = reader.serializeBits(num3, num3_orig_bits);
|
||||||
|
ASSERT_TRUE(r);
|
||||||
|
ASSERT_EQ(num3, num3_orig);
|
||||||
|
|
||||||
|
// error case
|
||||||
|
uint32_t num4 {0};
|
||||||
|
r = reader.serializeBits(num4, 32);
|
||||||
|
ASSERT_FALSE(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// emscripten cant do this
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
bool serialize_int_death_fn(void) {
|
||||||
|
std::array<uint32_t, 32> dummy_buffer;
|
||||||
|
MM::s6zer::StreamReader reader{dummy_buffer.data(), dummy_buffer.size()*sizeof(uint32_t)};
|
||||||
|
int32_t value{0};
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(reader.serializeInt(value, 20, -20)); // wrong order
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(s6zer, serialize_int_death) {
|
||||||
|
ASSERT_DEATH({
|
||||||
|
[[maybe_unused]] bool ret = serialize_int_death_fn();
|
||||||
|
}, "failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST(s6zer, reader_bits_bug1) {
|
||||||
|
const std::array<uint32_t, 2> buffer {
|
||||||
|
0x27'5c'19'a1,
|
||||||
|
0x00'00'3a'c3
|
||||||
|
};
|
||||||
|
const size_t buffer_size {6};
|
||||||
|
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
uint8_t value_0 {0};
|
||||||
|
ASSERT_TRUE(reader.serializeBits(value_0));
|
||||||
|
ASSERT_EQ(value_0, 0xa1);
|
||||||
|
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 24);
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0000000000'27'5c'19);
|
||||||
|
|
||||||
|
uint32_t value_1 {0};
|
||||||
|
ASSERT_TRUE(reader.serializeBits(value_1));
|
||||||
|
ASSERT_EQ(value_1, 0xc3'27'5c'19);
|
||||||
|
|
||||||
|
ASSERT_EQ(reader._scratch_bits, 24);
|
||||||
|
ASSERT_EQ(reader._scratch, 0x00000000000000'3a);
|
||||||
|
|
||||||
|
uint8_t value_2 {0};
|
||||||
|
ASSERT_TRUE(reader.serializeBits(value_2));
|
||||||
|
ASSERT_EQ(value_2, 0x3a);
|
||||||
|
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0000000000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestStruct {
|
||||||
|
// integers bits
|
||||||
|
uint8_t u8 {0};
|
||||||
|
uint16_t u16 {0};
|
||||||
|
uint32_t u32 {0};
|
||||||
|
//uint64_t u64 {0};
|
||||||
|
|
||||||
|
bool b1 {false};
|
||||||
|
|
||||||
|
// integers ranges
|
||||||
|
uint8_t r_u8 {0};
|
||||||
|
constexpr static MM::ScalarRange2<uint8_t> r_u8_r{10, 60};
|
||||||
|
int8_t r_i8 {0};
|
||||||
|
constexpr static MM::ScalarRange2<int8_t> r_i8_r{-10, 5};
|
||||||
|
uint16_t r_u16 {0};
|
||||||
|
constexpr static MM::ScalarRange2<uint16_t> r_u16_r{1, 1026};
|
||||||
|
int16_t r_i16 {0};
|
||||||
|
constexpr static MM::ScalarRange2<int16_t> r_i16_r{-1, 1026};
|
||||||
|
uint32_t r_u32 {0};
|
||||||
|
constexpr static MM::ScalarRange2<uint32_t> r_u32_r{0, 12341234};
|
||||||
|
int32_t r_i32 {0};
|
||||||
|
constexpr static MM::ScalarRange2<int32_t> r_i32_r{-12341234, 10};
|
||||||
|
|
||||||
|
// floats
|
||||||
|
float f32 {0.f};
|
||||||
|
double f64 {0.};
|
||||||
|
|
||||||
|
// float compressed [0; 1] range
|
||||||
|
constexpr static float c0_f32_resolution = 0.001f;
|
||||||
|
constexpr static MM::ScalarRange2<float> c0_f32_r{0.f, 1.f};
|
||||||
|
float c0_f32_0 {0.f};
|
||||||
|
float c0_f32_1 {0.f};
|
||||||
|
float c0_f32_2 {0.f};
|
||||||
|
float c0_f32_3 {0.f};
|
||||||
|
|
||||||
|
// float compressed [-1; 1] range
|
||||||
|
constexpr static float c1_f32_resolution = 0.05f;
|
||||||
|
constexpr static MM::ScalarRange2<float> c1_f32_r{-1.f, 1.f};
|
||||||
|
float c1_f32_0 {0.f};
|
||||||
|
float c1_f32_1 {0.f};
|
||||||
|
float c1_f32_2 {0.f};
|
||||||
|
float c1_f32_3 {0.f};
|
||||||
|
|
||||||
|
// float compressed [-1000; 1000] range
|
||||||
|
constexpr static float c2_f32_resolution = 0.01f;
|
||||||
|
constexpr static MM::ScalarRange2<float> c2_f32_r{-1000.f, 1000.f};
|
||||||
|
float c2_f32_0 {0.f};
|
||||||
|
float c2_f32_1 {0.f};
|
||||||
|
float c2_f32_2 {0.f};
|
||||||
|
float c2_f32_3 {0.f};
|
||||||
|
};
|
||||||
|
|
||||||
|
MM_DEFINE_SERIALIZE(TestStruct,
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBits(data.u8))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBits(data.u16))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBits(data.u32))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeBool(data.b1))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_u8, data.r_u8_r.min(), data.r_u8_r.max()))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_i8, data.r_i8_r.min(), data.r_i8_r.max()))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_u16, data.r_u16_r.min(), data.r_u16_r.max()))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_i16, data.r_i16_r.min(), data.r_i16_r.max()))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_u32, data.r_u32_r.min(), data.r_u32_r.max()))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeInt(data.r_i32, data.r_i32_r.min(), data.r_i32_r.max()))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloat(data.f32))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeDouble(data.f64))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c0_f32_0, data.c0_f32_r.min(), data.c0_f32_r.max(), data.c0_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c0_f32_1, data.c0_f32_r.min(), data.c0_f32_r.max(), data.c0_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c0_f32_2, data.c0_f32_r.min(), data.c0_f32_r.max(), data.c0_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c0_f32_3, data.c0_f32_r.min(), data.c0_f32_r.max(), data.c0_f32_resolution))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c1_f32_0, data.c1_f32_r.min(), data.c1_f32_r.max(), data.c1_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c1_f32_1, data.c1_f32_r.min(), data.c1_f32_r.max(), data.c1_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c1_f32_2, data.c1_f32_r.min(), data.c1_f32_r.max(), data.c1_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c1_f32_3, data.c1_f32_r.min(), data.c1_f32_r.max(), data.c1_f32_resolution))
|
||||||
|
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c2_f32_0, data.c2_f32_r.min(), data.c2_f32_r.max(), data.c2_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c2_f32_1, data.c2_f32_r.min(), data.c2_f32_r.max(), data.c2_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c2_f32_2, data.c2_f32_r.min(), data.c2_f32_r.max(), data.c2_f32_resolution))
|
||||||
|
MM_S6ZER_BAIL(stream.serializeFloatCompressed(data.c2_f32_3, data.c2_f32_r.min(), data.c2_f32_r.max(), data.c2_f32_resolution))
|
||||||
|
)
|
||||||
|
|
||||||
|
TEST(s6zer, stream_normalfull) {
|
||||||
|
std::array<uint32_t, 128> buffer;
|
||||||
|
size_t buffer_size = buffer.size()*sizeof(uint32_t);
|
||||||
|
|
||||||
|
MM::Random::SRNG rng{1337, 0};
|
||||||
|
|
||||||
|
const TestStruct data_in{
|
||||||
|
static_cast<uint8_t>(rng()),
|
||||||
|
static_cast<uint16_t>(rng()),
|
||||||
|
static_cast<uint32_t>(rng()),
|
||||||
|
|
||||||
|
rng.roll(0.5f),
|
||||||
|
|
||||||
|
rng.range(TestStruct::r_u8_r),
|
||||||
|
rng.range(TestStruct::r_i8_r),
|
||||||
|
rng.range(TestStruct::r_u16_r),
|
||||||
|
rng.range(TestStruct::r_i16_r),
|
||||||
|
rng.range(TestStruct::r_u32_r),
|
||||||
|
rng.range(TestStruct::r_i32_r),
|
||||||
|
|
||||||
|
rng.negOneToOne() * 10000000.f,
|
||||||
|
rng.negOneToOne() * 10000000.,
|
||||||
|
|
||||||
|
rng.range(TestStruct::c0_f32_r),
|
||||||
|
rng.range(TestStruct::c0_f32_r),
|
||||||
|
rng.range(TestStruct::c0_f32_r),
|
||||||
|
rng.range(TestStruct::c0_f32_r),
|
||||||
|
|
||||||
|
rng.range(TestStruct::c1_f32_r),
|
||||||
|
rng.range(TestStruct::c1_f32_r),
|
||||||
|
rng.range(TestStruct::c1_f32_r),
|
||||||
|
rng.range(TestStruct::c1_f32_r),
|
||||||
|
|
||||||
|
rng.range(TestStruct::c2_f32_r),
|
||||||
|
rng.range(TestStruct::c2_f32_r),
|
||||||
|
rng.range(TestStruct::c2_f32_r),
|
||||||
|
rng.range(TestStruct::c2_f32_r),
|
||||||
|
};
|
||||||
|
|
||||||
|
std::cout << "struct size: " << sizeof(TestStruct) << "\n";
|
||||||
|
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamWriter writer{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
ASSERT_TRUE(mm_serialize(writer, data_in));
|
||||||
|
|
||||||
|
ASSERT_TRUE(writer.flush());
|
||||||
|
buffer_size = writer.bytesWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "buffer_size: " << buffer_size << "\n";
|
||||||
|
|
||||||
|
TestStruct data_out{}; // all zero
|
||||||
|
|
||||||
|
{
|
||||||
|
MM::s6zer::StreamReader reader{buffer.data(), buffer_size};
|
||||||
|
|
||||||
|
ASSERT_TRUE(mm_serialize(reader, data_out));
|
||||||
|
|
||||||
|
ASSERT_EQ(reader._scratch, 0x0000000000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "buffer: ";
|
||||||
|
for (size_t i = 0; i < buffer_size; i++) {
|
||||||
|
std::cout << std::hex << static_cast<uint32_t>(reinterpret_cast<uint8_t*>(buffer.data())[i]) << "'";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
//std::cout << "data_out: \n" << data_out;
|
||||||
|
|
||||||
|
ASSERT_EQ(data_in.u8, data_out.u8);
|
||||||
|
ASSERT_EQ(data_in.u16, data_out.u16);
|
||||||
|
ASSERT_EQ(data_in.u32, data_out.u32);
|
||||||
|
|
||||||
|
ASSERT_EQ(data_in.b1, data_out.b1);
|
||||||
|
|
||||||
|
ASSERT_EQ(data_in.r_u8, data_out.r_u8) << "value range: " << TestStruct::r_u8_r;
|
||||||
|
ASSERT_EQ(data_in.r_i8, data_out.r_i8) << "value range: " << TestStruct::r_i8_r;
|
||||||
|
ASSERT_EQ(data_in.r_u16, data_out.r_u16) << "value range: " << TestStruct::r_u16_r;
|
||||||
|
ASSERT_EQ(data_in.r_i16, data_out.r_i16) << "value range: " << TestStruct::r_i16_r;
|
||||||
|
ASSERT_EQ(data_in.r_u32, data_out.r_u32) << "value range: " << TestStruct::r_u32_r;
|
||||||
|
ASSERT_EQ(data_in.r_i32, data_out.r_i32) << "value range: " << TestStruct::r_i32_r;
|
||||||
|
|
||||||
|
// bit perfect copies, can have wrong results for special values <.<
|
||||||
|
ASSERT_EQ(data_in.f32, data_out.f32);
|
||||||
|
ASSERT_EQ(data_in.f64, data_out.f64);
|
||||||
|
|
||||||
|
ASSERT_NEAR(data_in.c0_f32_0, data_out.c0_f32_0, TestStruct::c0_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c0_f32_1, data_out.c0_f32_1, TestStruct::c0_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c0_f32_2, data_out.c0_f32_2, TestStruct::c0_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c0_f32_3, data_out.c0_f32_3, TestStruct::c0_f32_resolution);
|
||||||
|
|
||||||
|
ASSERT_NEAR(data_in.c1_f32_0, data_out.c1_f32_0, TestStruct::c1_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c1_f32_1, data_out.c1_f32_1, TestStruct::c1_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c1_f32_2, data_out.c1_f32_2, TestStruct::c1_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c1_f32_3, data_out.c1_f32_3, TestStruct::c1_f32_resolution);
|
||||||
|
|
||||||
|
ASSERT_NEAR(data_in.c2_f32_0, data_out.c2_f32_0, TestStruct::c2_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c2_f32_1, data_out.c2_f32_1, TestStruct::c2_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c2_f32_2, data_out.c2_f32_2, TestStruct::c2_f32_resolution);
|
||||||
|
ASSERT_NEAR(data_in.c2_f32_3, data_out.c2_f32_3, TestStruct::c2_f32_resolution);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -31,9 +31,10 @@ namespace MM::Services {
|
|||||||
SDLService::SDLService(uint32_t _sdl_init_flags) {
|
SDLService::SDLService(uint32_t _sdl_init_flags) {
|
||||||
MM::Logger::initSectionLogger("SDLService");
|
MM::Logger::initSectionLogger("SDLService");
|
||||||
|
|
||||||
//#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
//_sdl_init_flags &= ~SDL_INIT_HAPTIC;
|
_sdl_init_flags &= ~SDL_INIT_HAPTIC;
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
#if 1 // hack for mingw + wine
|
#if 1 // hack for mingw + wine
|
||||||
_sdl_init_flags &= ~SDL_INIT_SENSOR;
|
_sdl_init_flags &= ~SDL_INIT_SENSOR;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,21 +19,6 @@ target_link_libraries(sound_service
|
|||||||
|
|
||||||
###############################
|
###############################
|
||||||
|
|
||||||
add_library(filesystem_soloud_file
|
|
||||||
./src/mm/soloud_filesystem_file_impl.hpp
|
|
||||||
./src/mm/soloud_filesystem_file_impl.cpp
|
|
||||||
|
|
||||||
./src/mm/sound_loader_wav.hpp
|
|
||||||
./src/mm/sound_loader_wav.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(filesystem_soloud_file
|
|
||||||
filesystem_service
|
|
||||||
soloud
|
|
||||||
)
|
|
||||||
|
|
||||||
###############################
|
|
||||||
|
|
||||||
add_library(soloud_json
|
add_library(soloud_json
|
||||||
./src/mm/soloud_json.hpp
|
./src/mm/soloud_json.hpp
|
||||||
./src/mm/soloud_json.cpp
|
./src/mm/soloud_json.cpp
|
||||||
@@ -46,6 +31,24 @@ target_link_libraries(soloud_json
|
|||||||
nlohmann_json::nlohmann_json
|
nlohmann_json::nlohmann_json
|
||||||
)
|
)
|
||||||
|
|
||||||
|
###############################
|
||||||
|
|
||||||
|
add_library(filesystem_soloud_file
|
||||||
|
./src/mm/soloud_filesystem_file_impl.hpp
|
||||||
|
./src/mm/soloud_filesystem_file_impl.cpp
|
||||||
|
|
||||||
|
./src/mm/sound_loader_wav.hpp
|
||||||
|
./src/mm/sound_loader_wav.cpp
|
||||||
|
./src/mm/sound_loader_sfxr.hpp
|
||||||
|
./src/mm/sound_loader_sfxr.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(filesystem_soloud_file
|
||||||
|
filesystem_service
|
||||||
|
soloud
|
||||||
|
soloud_json
|
||||||
|
)
|
||||||
|
|
||||||
if (BUILD_TESTING)
|
if (BUILD_TESTING)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
38
framework/sound/src/mm/sound_loader_sfxr.cpp
Normal file
38
framework/sound/src/mm/sound_loader_sfxr.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include "./sound_loader_sfxr.hpp"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include "./soloud_json.hpp"
|
||||||
|
|
||||||
|
#include <mm/services/filesystem.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace MM {
|
||||||
|
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> SoundLoaderSfxrPreset::load(const ::SoLoud::Sfxr::SFXR_PRESETS preset, const int seed) const {
|
||||||
|
auto sfxr = std::make_shared<::SoLoud::Sfxr>();
|
||||||
|
sfxr->loadPreset(preset, seed);
|
||||||
|
return sfxr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> SoundLoaderSfxrJson::load(const nlohmann::json& j) const {
|
||||||
|
auto sfxr = std::make_shared<::SoLoud::Sfxr>();
|
||||||
|
*sfxr = j;
|
||||||
|
return sfxr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> SoundLoaderSfxrFile::load(const std::string& path, MM::Engine& engine) const {
|
||||||
|
auto& fs = engine.getService<MM::Services::FilesystemService>();
|
||||||
|
|
||||||
|
if (!fs.isFile(path.c_str())) {
|
||||||
|
// TODO: log error
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto j = fs.readJson(path.c_str());
|
||||||
|
|
||||||
|
return SoundLoaderSfxrJson{}.load(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MM
|
||||||
|
|
||||||
28
framework/sound/src/mm/sound_loader_sfxr.hpp
Normal file
28
framework/sound/src/mm/sound_loader_sfxr.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <soloud_sfxr.h>
|
||||||
|
|
||||||
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
namespace MM {
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class Engine;
|
||||||
|
|
||||||
|
struct SoundLoaderSfxrPreset {
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> load(const ::SoLoud::Sfxr::SFXR_PRESETS preset, const int seed) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SoundLoaderSfxrJson {
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> load(const nlohmann::json& j) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SoundLoaderSfxrFile {
|
||||||
|
std::shared_ptr<::SoLoud::Sfxr> load(const std::string& path, MM::Engine& engine) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // MM
|
||||||
|
|
||||||
@@ -9,8 +9,10 @@ namespace MM {
|
|||||||
std::shared_ptr<::SoLoud::Wav> SoundLoaderWavFile::load(const std::string& path, Engine& engine) const {
|
std::shared_ptr<::SoLoud::Wav> SoundLoaderWavFile::load(const std::string& path, Engine& engine) const {
|
||||||
auto& fs = engine.getService<Services::FilesystemService>();
|
auto& fs = engine.getService<Services::FilesystemService>();
|
||||||
|
|
||||||
if (!fs.isFile(path.c_str()))
|
if (!fs.isFile(path.c_str())) {
|
||||||
|
// TODO: log error
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto h = fs.open(path.c_str());
|
auto h = fs.open(path.c_str());
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ std::shared_ptr<::SoLoud::Wav> SoundLoaderWavFile::load(const std::string& path,
|
|||||||
auto ptr = std::make_shared<::SoLoud::Wav>();
|
auto ptr = std::make_shared<::SoLoud::Wav>();
|
||||||
auto r = ptr->loadFile(&sl_f);
|
auto r = ptr->loadFile(&sl_f);
|
||||||
if (r != ::SoLoud::SO_NO_ERROR) {
|
if (r != ::SoLoud::SO_NO_ERROR) {
|
||||||
// log error
|
// TODO: log error
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
#include <mm/soloud_filesystem_file_impl.hpp>
|
#include <mm/soloud_filesystem_file_impl.hpp>
|
||||||
#include <mm/sound_loader_wav.hpp>
|
#include <mm/sound_loader_wav.hpp>
|
||||||
|
#include <mm/sound_loader_sfxr.hpp>
|
||||||
|
|
||||||
#include <mm/resource_manager.hpp>
|
#include <mm/resource_manager.hpp>
|
||||||
|
|
||||||
|
#include <soloud_sfxr.h>
|
||||||
#include <soloud_wav.h>
|
#include <soloud_wav.h>
|
||||||
#include <soloud_wavstream.h>
|
#include <soloud_wavstream.h>
|
||||||
#include <soloud_monotone.h>
|
#include <soloud_monotone.h>
|
||||||
@@ -21,7 +23,7 @@ using namespace entt::literals;
|
|||||||
|
|
||||||
extern char* argv0;
|
extern char* argv0;
|
||||||
|
|
||||||
TEST(soloud_fs_loader, basic) {
|
TEST(soloud_fs_loader, wav) {
|
||||||
MM::Engine engine;
|
MM::Engine engine;
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
@@ -59,3 +61,38 @@ TEST(soloud_fs_loader, basic) {
|
|||||||
rm.clear();
|
rm.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(soloud_fs_loader, sfxr) {
|
||||||
|
MM::Engine engine;
|
||||||
|
|
||||||
|
// setup
|
||||||
|
auto& sound = engine.addService<MM::Services::SoundService>();
|
||||||
|
ASSERT_TRUE(engine.enableService<MM::Services::SoundService>());
|
||||||
|
|
||||||
|
engine.addService<MM::Services::FilesystemService>(argv0, "soloud_filesystem_loader_test");
|
||||||
|
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||||
|
|
||||||
|
auto& rm = MM::ResourceManager<SoLoud::Sfxr>::ref();
|
||||||
|
|
||||||
|
sound.engine.setGlobalVolume(0.4f);
|
||||||
|
|
||||||
|
ASSERT_FALSE(rm.contains("test_preset"_hs));
|
||||||
|
rm.load<MM::SoundLoaderSfxrPreset>("test_preset", ::SoLoud::Sfxr::SFXR_PRESETS::EXPLOSION, 0);
|
||||||
|
ASSERT_TRUE(rm.contains("test_preset"_hs));
|
||||||
|
|
||||||
|
// TODO: add load from json
|
||||||
|
// TODO: add load from json from file
|
||||||
|
|
||||||
|
{
|
||||||
|
auto sh = rm.get("test_preset"_hs);
|
||||||
|
|
||||||
|
sound.engine.play(*sh);
|
||||||
|
|
||||||
|
while (sound.engine.getActiveVoiceCount()) {
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
std::this_thread::sleep_for(5ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rm.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ struct ScalarRange2 {
|
|||||||
T v_min {};
|
T v_min {};
|
||||||
T v_max {};
|
T v_max {};
|
||||||
|
|
||||||
ScalarRange2(void) = default;
|
constexpr ScalarRange2(void) = default;
|
||||||
|
|
||||||
ScalarRange2(const T& both) noexcept {
|
constexpr ScalarRange2(const T& both) noexcept {
|
||||||
v_min = both;
|
v_min = both;
|
||||||
v_max = both;
|
v_max = both;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScalarRange2(const T& min, const T& max) noexcept {
|
constexpr ScalarRange2(const T& min, const T& max) noexcept {
|
||||||
if (min <= max) {
|
if (min <= max) {
|
||||||
v_min = min;
|
v_min = min;
|
||||||
v_max = max;
|
v_max = max;
|
||||||
@@ -24,19 +24,19 @@ struct ScalarRange2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ScalarRange2<T>& rhs) const {
|
constexpr bool operator==(const ScalarRange2<T>& rhs) const {
|
||||||
return min() == rhs.min() && max() == rhs.max();
|
return min() == rhs.min() && max() == rhs.max();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ScalarRange2<T>& rhs) const {
|
constexpr bool operator!=(const ScalarRange2<T>& rhs) const {
|
||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] T& min(void) { return v_min; }
|
[[nodiscard]] constexpr T& min(void) { return v_min; }
|
||||||
[[nodiscard]] T& max(void) { return v_max; }
|
[[nodiscard]] constexpr T& max(void) { return v_max; }
|
||||||
|
|
||||||
[[nodiscard]] const T& min(void) const { return v_min; }
|
[[nodiscard]] constexpr const T& min(void) const { return v_min; }
|
||||||
[[nodiscard]] const T& max(void) const { return v_max; }
|
[[nodiscard]] constexpr const T& max(void) const { return v_max; }
|
||||||
|
|
||||||
void setMin(const T& new_min) {
|
void setMin(const T& new_min) {
|
||||||
min() = new_min;
|
min() = new_min;
|
||||||
@@ -57,9 +57,19 @@ struct ScalarRange2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool inRange(T&& value) const {
|
[[nodiscard]] constexpr bool inRange(T&& value) const {
|
||||||
return value >= min() && value <= max();
|
return value >= min() && value <= max();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lerp between min and max
|
||||||
|
[[nodiscard]] constexpr T map(const float a) const {
|
||||||
|
return min() * (1.f-a) + max() * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse map
|
||||||
|
[[nodiscard]] constexpr float unmap(const T& v) const {
|
||||||
|
return (v - min()) / static_cast<float>(max() - min());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM
|
} // MM
|
||||||
|
|||||||
BIN
res/mm2.ico
Normal file
BIN
res/mm2.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Reference in New Issue
Block a user