diff options
| author | untodesu <kirill@untode.su> | 2025-12-11 15:14:26 +0500 |
|---|---|---|
| committer | untodesu <kirill@untode.su> | 2025-12-11 15:14:26 +0500 |
| commit | f40d09cb8f712e87691af4912f3630d92d692779 (patch) | |
| tree | 7ac3a4168ff722689372fd489c6f94d0a2546e8f | |
| parent | 8bcbd2729388edc63c82d77d314b583af1447c49 (diff) | |
| download | voxelius-f40d09cb8f712e87691af4912f3630d92d692779.tar.bz2 voxelius-f40d09cb8f712e87691af4912f3630d92d692779.zip | |
Shuffle stuff around
- Use the new and improved hierarchy I figured out when making Prospero chat
- Re-add NSIS scripts, again from Prospero
- Update most build and utility scripts with their most recent versions
| -rw-r--r-- | .clang-format | 4 | ||||
| -rw-r--r-- | .gitattributes | 4 | ||||
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | .vscode/c_cpp_properties.json | 34 | ||||
| -rw-r--r-- | CMakeLists.txt | 64 | ||||
| -rw-r--r-- | CMakeSettings.json | 36 | ||||
| -rw-r--r-- | LICENSE.txt (renamed from LICENSE) | 44 | ||||
| -rw-r--r-- | assets/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | assets/fonts/unscii-16.ttf (renamed from data/fonts/unscii-16.ttf) | bin | 280672 -> 280672 bytes | |||
| -rw-r--r-- | assets/fonts/unscii-8.ttf (renamed from data/fonts/unscii-8.ttf) | bin | 245268 -> 245268 bytes | |||
| -rw-r--r-- | assets/lang/lang.en_US.json (renamed from data/lang/lang.en_US.json) | 0 | ||||
| -rw-r--r-- | assets/lang/manifest.json (renamed from data/lang/manifest.json) | 0 | ||||
| -rw-r--r-- | assets/misc/gamecontrollerdb.txt (renamed from data/misc/gamecontrollerdb.txt) | 0 | ||||
| -rw-r--r-- | assets/misc/splashes_client.txt (renamed from data/misc/splashes_client.txt) | 0 | ||||
| -rw-r--r-- | assets/misc/splashes_server.txt (renamed from data/misc/splashes_server.txt) | 0 | ||||
| -rw-r--r-- | assets/shaders/chunk_quad.frag (renamed from data/shaders/chunk_quad.frag) | 0 | ||||
| -rw-r--r-- | assets/shaders/chunk_quad.vert (renamed from data/shaders/chunk_quad.vert) | 0 | ||||
| -rw-r--r-- | assets/shaders/outline.frag (renamed from data/shaders/outline.frag) | 0 | ||||
| -rw-r--r-- | assets/shaders/outline.vert (renamed from data/shaders/outline.vert) | 0 | ||||
| -rw-r--r-- | assets/sounds/surface/default1.wav (renamed from data/sounds/surface/default1.wav) | bin | 17210 -> 17210 bytes | |||
| -rw-r--r-- | assets/sounds/surface/default2.wav (renamed from data/sounds/surface/default2.wav) | bin | 15090 -> 15090 bytes | |||
| -rw-r--r-- | assets/sounds/surface/default3.wav (renamed from data/sounds/surface/default3.wav) | bin | 12324 -> 12324 bytes | |||
| -rw-r--r-- | assets/sounds/surface/default4.wav (renamed from data/sounds/surface/default4.wav) | bin | 15450 -> 15450 bytes | |||
| -rw-r--r-- | assets/sounds/surface/dirt1.wav (renamed from data/sounds/surface/dirt1.wav) | bin | 8588 -> 8588 bytes | |||
| -rw-r--r-- | assets/sounds/surface/grass1.wav (renamed from data/sounds/surface/grass1.wav) | bin | 13366 -> 13366 bytes | |||
| -rw-r--r-- | assets/sounds/surface/grass2.wav (renamed from data/sounds/surface/grass2.wav) | bin | 13216 -> 13216 bytes | |||
| -rw-r--r-- | assets/sounds/surface/grass3.wav (renamed from data/sounds/surface/grass3.wav) | bin | 11066 -> 11066 bytes | |||
| -rw-r--r-- | assets/sounds/surface/gravel1.wav (renamed from data/sounds/surface/gravel1.wav) | bin | 9594 -> 9594 bytes | |||
| -rw-r--r-- | assets/sounds/surface/sand1.wav (renamed from data/sounds/surface/sand1.wav) | bin | 7296 -> 7296 bytes | |||
| -rw-r--r-- | assets/sounds/surface/sand2.wav (renamed from data/sounds/surface/sand2.wav) | bin | 12776 -> 12776 bytes | |||
| -rw-r--r-- | assets/sounds/surface/wood1.wav (renamed from data/sounds/surface/wood1.wav) | bin | 7570 -> 7570 bytes | |||
| -rw-r--r-- | assets/sounds/surface/wood2.wav (renamed from data/sounds/surface/wood2.wav) | bin | 6978 -> 6978 bytes | |||
| -rw-r--r-- | assets/sounds/surface/wood3.wav (renamed from data/sounds/surface/wood3.wav) | bin | 9652 -> 9652 bytes | |||
| -rw-r--r-- | assets/sounds/ui/chat_message.wav (renamed from data/sounds/ui/chat_message.wav) | bin | 3406 -> 3406 bytes | |||
| -rw-r--r-- | assets/textures/gui/background.png (renamed from data/textures/gui/background.png) | bin | 5203 -> 5203 bytes | |||
| -rw-r--r-- | assets/textures/gui/client_splash.png (renamed from data/textures/gui/client_splash.png) | bin | 3500 -> 3500 bytes | |||
| -rw-r--r-- | assets/textures/gui/hud_crosshair.png (renamed from data/textures/gui/hud_crosshair.png) | bin | 4446 -> 4446 bytes | |||
| -rw-r--r-- | assets/textures/gui/hud_hotbar.png (renamed from data/textures/gui/hud_hotbar.png) | bin | 6518 -> 6518 bytes | |||
| -rw-r--r-- | assets/textures/gui/hud_selector.png (renamed from data/textures/gui/hud_selector.png) | bin | 5896 -> 5896 bytes | |||
| -rw-r--r-- | assets/textures/gui/menu_title.png (renamed from data/textures/gui/menu_title.png) | bin | 235525 -> 235525 bytes | |||
| -rw-r--r-- | assets/textures/gui/window_icon.png (renamed from data/textures/gui/window_icon.png) | bin | 17587 -> 17587 bytes | |||
| -rw-r--r-- | assets/textures/item/cobblestone.png (renamed from data/textures/item/cobblestone.png) | bin | 2073 -> 2073 bytes | |||
| -rw-r--r-- | assets/textures/item/dirt.png (renamed from data/textures/item/dirt.png) | bin | 5704 -> 5704 bytes | |||
| -rw-r--r-- | assets/textures/item/glass.png (renamed from data/textures/item/glass.png) | bin | 5794 -> 5794 bytes | |||
| -rw-r--r-- | assets/textures/item/grass.png (renamed from data/textures/item/grass.png) | bin | 5678 -> 5678 bytes | |||
| -rw-r--r-- | assets/textures/item/oak_leaves.png (renamed from data/textures/item/oak_leaves.png) | bin | 5822 -> 5822 bytes | |||
| -rw-r--r-- | assets/textures/item/oak_log.png (renamed from data/textures/item/oak_log.png) | bin | 5063 -> 5063 bytes | |||
| -rw-r--r-- | assets/textures/item/oak_planks.png (renamed from data/textures/item/oak_planks.png) | bin | 5622 -> 5622 bytes | |||
| -rw-r--r-- | assets/textures/item/slime.png (renamed from data/textures/item/slime.png) | bin | 4887 -> 4887 bytes | |||
| -rw-r--r-- | assets/textures/item/stone.png (renamed from data/textures/item/stone.png) | bin | 1594 -> 1594 bytes | |||
| -rw-r--r-- | assets/textures/item/template.png (renamed from data/textures/item/template.png) | bin | 658 -> 658 bytes | |||
| -rw-r--r-- | assets/textures/voxel/chromakey.png (renamed from data/textures/voxel/chromakey.png) | bin | 559 -> 559 bytes | |||
| -rw-r--r-- | assets/textures/voxel/cobblestone_01.png (renamed from data/textures/voxel/cobblestone_01.png) | bin | 643 -> 643 bytes | |||
| -rw-r--r-- | assets/textures/voxel/cobblestone_02.png (renamed from data/textures/voxel/cobblestone_02.png) | bin | 638 -> 638 bytes | |||
| -rw-r--r-- | assets/textures/voxel/dirt_01.png (renamed from data/textures/voxel/dirt_01.png) | bin | 6922 -> 6922 bytes | |||
| -rw-r--r-- | assets/textures/voxel/dirt_02.png (renamed from data/textures/voxel/dirt_02.png) | bin | 6918 -> 6918 bytes | |||
| -rw-r--r-- | assets/textures/voxel/dirt_03.png (renamed from data/textures/voxel/dirt_03.png) | bin | 6953 -> 6953 bytes | |||
| -rw-r--r-- | assets/textures/voxel/dirt_04.png (renamed from data/textures/voxel/dirt_04.png) | bin | 6894 -> 6894 bytes | |||
| -rw-r--r-- | assets/textures/voxel/glass_01.png (renamed from data/textures/voxel/glass_01.png) | bin | 4532 -> 4532 bytes | |||
| -rw-r--r-- | assets/textures/voxel/grass_01.png (renamed from data/textures/voxel/grass_01.png) | bin | 6962 -> 6962 bytes | |||
| -rw-r--r-- | assets/textures/voxel/grass_02.png (renamed from data/textures/voxel/grass_02.png) | bin | 6962 -> 6962 bytes | |||
| -rw-r--r-- | assets/textures/voxel/grass_side_01.png (renamed from data/textures/voxel/grass_side_01.png) | bin | 7416 -> 7416 bytes | |||
| -rw-r--r-- | assets/textures/voxel/grass_side_02.png (renamed from data/textures/voxel/grass_side_02.png) | bin | 7451 -> 7451 bytes | |||
| -rw-r--r-- | assets/textures/voxel/mud_01.png (renamed from data/textures/voxel/mud_01.png) | bin | 5148 -> 5148 bytes | |||
| -rw-r--r-- | assets/textures/voxel/mud_02.png (renamed from data/textures/voxel/mud_02.png) | bin | 4909 -> 4909 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_leaves.png (renamed from data/textures/voxel/oak_leaves.png) | bin | 963 -> 963 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_planks_01.png (renamed from data/textures/voxel/oak_planks_01.png) | bin | 643 -> 643 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_planks_02.png (renamed from data/textures/voxel/oak_planks_02.png) | bin | 670 -> 670 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_wood_01.png (renamed from data/textures/voxel/oak_wood_01.png) | bin | 6868 -> 6868 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_wood_02.png (renamed from data/textures/voxel/oak_wood_02.png) | bin | 6882 -> 6882 bytes | |||
| -rw-r--r-- | assets/textures/voxel/oak_wood_top.png (renamed from data/textures/voxel/oak_wood_top.png) | bin | 619 -> 619 bytes | |||
| -rw-r--r-- | assets/textures/voxel/slate_01.png (renamed from data/textures/voxel/slate_01.png) | bin | 463 -> 463 bytes | |||
| -rw-r--r-- | assets/textures/voxel/slate_02.png (renamed from data/textures/voxel/slate_02.png) | bin | 506 -> 506 bytes | |||
| -rw-r--r-- | assets/textures/voxel/slime_01.png (renamed from data/textures/voxel/slime_01.png) | bin | 953 -> 953 bytes | |||
| -rw-r--r-- | assets/textures/voxel/stone_01.png (renamed from data/textures/voxel/stone_01.png) | bin | 4606 -> 4606 bytes | |||
| -rw-r--r-- | assets/textures/voxel/stone_02.png (renamed from data/textures/voxel/stone_02.png) | bin | 4843 -> 4843 bytes | |||
| -rw-r--r-- | assets/textures/voxel/stone_03.png (renamed from data/textures/voxel/stone_03.png) | bin | 4842 -> 4842 bytes | |||
| -rw-r--r-- | assets/textures/voxel/stone_04.png (renamed from data/textures/voxel/stone_04.png) | bin | 4837 -> 4837 bytes | |||
| -rw-r--r-- | assets/textures/voxel/vtest_F1.png (renamed from data/textures/voxel/vtest_F1.png) | bin | 652 -> 652 bytes | |||
| -rw-r--r-- | assets/textures/voxel/vtest_F2.png (renamed from data/textures/voxel/vtest_F2.png) | bin | 652 -> 652 bytes | |||
| -rw-r--r-- | assets/textures/voxel/vtest_F3.png (renamed from data/textures/voxel/vtest_F3.png) | bin | 651 -> 651 bytes | |||
| -rw-r--r-- | assets/textures/voxel/vtest_F4.png (renamed from data/textures/voxel/vtest_F4.png) | bin | 653 -> 653 bytes | |||
| -rw-r--r-- | core/version.cc.in | 12 | ||||
| -rw-r--r-- | core/version.hh | 14 | ||||
| -rw-r--r-- | deps/CMakeLists.txt | 24 | ||||
| -rw-r--r-- | external/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | external/dr_libs/CMakeLists.txt (renamed from deps/dr_libs/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/dr_libs/DESCRIPTION (renamed from deps/dr_libs/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/dr_libs/LICENSE (renamed from deps/dr_libs/LICENSE) | 0 | ||||
| -rw-r--r-- | external/dr_libs/include/dr_flac.h (renamed from deps/dr_libs/include/dr_flac.h) | 0 | ||||
| -rw-r--r-- | external/dr_libs/include/dr_mp3.h (renamed from deps/dr_libs/include/dr_mp3.h) | 0 | ||||
| -rw-r--r-- | external/dr_libs/include/dr_wav.h (renamed from deps/dr_libs/include/dr_wav.h) | 0 | ||||
| -rw-r--r-- | external/dr_libs/src/dr_impl.c (renamed from deps/dr_libs/src/dr_impl.c) | 0 | ||||
| -rw-r--r-- | external/emhash/CMakeLists.txt (renamed from deps/emhash/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/emhash/DESCRIPTION (renamed from deps/emhash/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/emhash/LICENSE (renamed from deps/emhash/LICENSE) | 0 | ||||
| -rw-r--r-- | external/emhash/include/emhash/hash_set8.hpp (renamed from deps/emhash/include/emhash/hash_set8.hpp) | 0 | ||||
| -rw-r--r-- | external/emhash/include/emhash/hash_table8.hpp (renamed from deps/emhash/include/emhash/hash_table8.hpp) | 0 | ||||
| -rw-r--r-- | external/enet/CMakeLists.txt (renamed from deps/enet/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/enet/DESCRIPTION (renamed from deps/enet/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/enet/LICENSE (renamed from deps/enet/LICENSE) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/callbacks.h (renamed from deps/enet/include/enet/callbacks.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/enet.h (renamed from deps/enet/include/enet/enet.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/list.h (renamed from deps/enet/include/enet/list.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/protocol.h (renamed from deps/enet/include/enet/protocol.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/time.h (renamed from deps/enet/include/enet/time.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/types.h (renamed from deps/enet/include/enet/types.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/unix.h (renamed from deps/enet/include/enet/unix.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/utility.h (renamed from deps/enet/include/enet/utility.h) | 0 | ||||
| -rw-r--r-- | external/enet/include/enet/win32.h (renamed from deps/enet/include/enet/win32.h) | 0 | ||||
| -rw-r--r-- | external/enet/src/callbacks.c (renamed from deps/enet/src/callbacks.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/compress.c (renamed from deps/enet/src/compress.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/host.c (renamed from deps/enet/src/host.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/list.c (renamed from deps/enet/src/list.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/packet.c (renamed from deps/enet/src/packet.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/peer.c (renamed from deps/enet/src/peer.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/protocol.c (renamed from deps/enet/src/protocol.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/unix.c (renamed from deps/enet/src/unix.c) | 0 | ||||
| -rw-r--r-- | external/enet/src/win32.c (renamed from deps/enet/src/win32.c) | 0 | ||||
| -rw-r--r-- | external/entt/CMakeLists.txt (renamed from deps/entt/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/entt/DESCRIPTION (renamed from deps/entt/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/entt/LICENSE (renamed from deps/entt/LICENSE) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/config/config.h (renamed from deps/entt/include/entt/config/config.h) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/config/macro.h (renamed from deps/entt/include/entt/config/macro.h) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/config/version.h (renamed from deps/entt/include/entt/config/version.h) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/container/dense_map.hpp (renamed from deps/entt/include/entt/container/dense_map.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/container/dense_set.hpp (renamed from deps/entt/include/entt/container/dense_set.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/container/fwd.hpp (renamed from deps/entt/include/entt/container/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/container/table.hpp (renamed from deps/entt/include/entt/container/table.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/algorithm.hpp (renamed from deps/entt/include/entt/core/algorithm.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/any.hpp (renamed from deps/entt/include/entt/core/any.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/attribute.h (renamed from deps/entt/include/entt/core/attribute.h) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/bit.hpp (renamed from deps/entt/include/entt/core/bit.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/compressed_pair.hpp (renamed from deps/entt/include/entt/core/compressed_pair.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/enum.hpp (renamed from deps/entt/include/entt/core/enum.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/family.hpp (renamed from deps/entt/include/entt/core/family.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/fwd.hpp (renamed from deps/entt/include/entt/core/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/hashed_string.hpp (renamed from deps/entt/include/entt/core/hashed_string.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/ident.hpp (renamed from deps/entt/include/entt/core/ident.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/iterator.hpp (renamed from deps/entt/include/entt/core/iterator.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/memory.hpp (renamed from deps/entt/include/entt/core/memory.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/monostate.hpp (renamed from deps/entt/include/entt/core/monostate.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/ranges.hpp (renamed from deps/entt/include/entt/core/ranges.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/tuple.hpp (renamed from deps/entt/include/entt/core/tuple.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/type_info.hpp (renamed from deps/entt/include/entt/core/type_info.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/type_traits.hpp (renamed from deps/entt/include/entt/core/type_traits.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/core/utility.hpp (renamed from deps/entt/include/entt/core/utility.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/component.hpp (renamed from deps/entt/include/entt/entity/component.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/entity.hpp (renamed from deps/entt/include/entt/entity/entity.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/fwd.hpp (renamed from deps/entt/include/entt/entity/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/group.hpp (renamed from deps/entt/include/entt/entity/group.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/handle.hpp (renamed from deps/entt/include/entt/entity/handle.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/helper.hpp (renamed from deps/entt/include/entt/entity/helper.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/mixin.hpp (renamed from deps/entt/include/entt/entity/mixin.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/observer.hpp (renamed from deps/entt/include/entt/entity/observer.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/organizer.hpp (renamed from deps/entt/include/entt/entity/organizer.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/ranges.hpp (renamed from deps/entt/include/entt/entity/ranges.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/registry.hpp (renamed from deps/entt/include/entt/entity/registry.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/runtime_view.hpp (renamed from deps/entt/include/entt/entity/runtime_view.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/snapshot.hpp (renamed from deps/entt/include/entt/entity/snapshot.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/sparse_set.hpp (renamed from deps/entt/include/entt/entity/sparse_set.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/storage.hpp (renamed from deps/entt/include/entt/entity/storage.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/storage_mixin.hpp (renamed from deps/entt/include/entt/entity/storage_mixin.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entity/view.hpp (renamed from deps/entt/include/entt/entity/view.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/entt.hpp (renamed from deps/entt/include/entt/entt.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/fwd.hpp (renamed from deps/entt/include/entt/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/graph/adjacency_matrix.hpp (renamed from deps/entt/include/entt/graph/adjacency_matrix.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/graph/dot.hpp (renamed from deps/entt/include/entt/graph/dot.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/graph/flow.hpp (renamed from deps/entt/include/entt/graph/flow.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/graph/fwd.hpp (renamed from deps/entt/include/entt/graph/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/locator/locator.hpp (renamed from deps/entt/include/entt/locator/locator.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/adl_pointer.hpp (renamed from deps/entt/include/entt/meta/adl_pointer.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/container.hpp (renamed from deps/entt/include/entt/meta/container.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/context.hpp (renamed from deps/entt/include/entt/meta/context.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/factory.hpp (renamed from deps/entt/include/entt/meta/factory.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/fwd.hpp (renamed from deps/entt/include/entt/meta/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/meta.hpp (renamed from deps/entt/include/entt/meta/meta.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/node.hpp (renamed from deps/entt/include/entt/meta/node.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/pointer.hpp (renamed from deps/entt/include/entt/meta/pointer.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/policy.hpp (renamed from deps/entt/include/entt/meta/policy.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/range.hpp (renamed from deps/entt/include/entt/meta/range.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/resolve.hpp (renamed from deps/entt/include/entt/meta/resolve.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/template.hpp (renamed from deps/entt/include/entt/meta/template.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/type_traits.hpp (renamed from deps/entt/include/entt/meta/type_traits.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/meta/utility.hpp (renamed from deps/entt/include/entt/meta/utility.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/platform/android-ndk-r17.hpp (renamed from deps/entt/include/entt/platform/android-ndk-r17.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/poly/fwd.hpp (renamed from deps/entt/include/entt/poly/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/poly/poly.hpp (renamed from deps/entt/include/entt/poly/poly.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/process/fwd.hpp (renamed from deps/entt/include/entt/process/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/process/process.hpp (renamed from deps/entt/include/entt/process/process.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/process/scheduler.hpp (renamed from deps/entt/include/entt/process/scheduler.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/resource/cache.hpp (renamed from deps/entt/include/entt/resource/cache.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/resource/fwd.hpp (renamed from deps/entt/include/entt/resource/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/resource/loader.hpp (renamed from deps/entt/include/entt/resource/loader.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/resource/resource.hpp (renamed from deps/entt/include/entt/resource/resource.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/signal/delegate.hpp (renamed from deps/entt/include/entt/signal/delegate.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/signal/dispatcher.hpp (renamed from deps/entt/include/entt/signal/dispatcher.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/signal/emitter.hpp (renamed from deps/entt/include/entt/signal/emitter.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/signal/fwd.hpp (renamed from deps/entt/include/entt/signal/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/entt/include/entt/signal/sigh.hpp (renamed from deps/entt/include/entt/signal/sigh.hpp) | 0 | ||||
| -rw-r--r-- | external/fastnoiselite/CMakeLists.txt (renamed from deps/fastnoiselite/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/fastnoiselite/DESCRIPTION (renamed from deps/fastnoiselite/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/fastnoiselite/LICENSE (renamed from deps/fastnoiselite/LICENSE) | 0 | ||||
| -rw-r--r-- | external/fastnoiselite/include/fastnoiselite.h (renamed from deps/fastnoiselite/include/fastnoiselite.h) | 0 | ||||
| -rw-r--r-- | external/fastnoiselite/src/fastnoiselite.c (renamed from deps/fastnoiselite/src/fastnoiselite.c) | 0 | ||||
| -rw-r--r-- | external/gamecontrollerdb/DESCRIPTION (renamed from deps/gamecontrollerdb/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/gamecontrollerdb/LICENSE (renamed from deps/gamecontrollerdb/LICENSE) | 0 | ||||
| -rw-r--r-- | external/glad/CMakeLists.txt (renamed from deps/glad/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/glad/include/KHR/khrplatform.h (renamed from deps/glad/include/KHR/khrplatform.h) | 0 | ||||
| -rw-r--r-- | external/glad/include/glad/gl.h (renamed from deps/glad/include/glad/gl.h) | 0 | ||||
| -rw-r--r-- | external/glad/src/gl.c (renamed from deps/glad/src/gl.c) | 0 | ||||
| -rw-r--r-- | external/glfw/CMakeLists.txt (renamed from deps/glfw/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/glfw/DESCRIPTION (renamed from deps/glfw/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/glfw/LICENSE (renamed from deps/glfw/LICENSE) | 0 | ||||
| -rw-r--r-- | external/glm/CMakeLists.txt (renamed from deps/glm/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/glm/DESCRIPTION (renamed from deps/glm/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/glm/LICENSE (renamed from deps/glm/LICENSE) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/CMakeLists.txt (renamed from deps/glm/include/glm/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/common.hpp (renamed from deps/glm/include/glm/common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_features.hpp (renamed from deps/glm/include/glm/detail/_features.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_fixes.hpp (renamed from deps/glm/include/glm/detail/_fixes.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_noise.hpp (renamed from deps/glm/include/glm/detail/_noise.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_swizzle.hpp (renamed from deps/glm/include/glm/detail/_swizzle.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_swizzle_func.hpp (renamed from deps/glm/include/glm/detail/_swizzle_func.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/_vectorize.hpp (renamed from deps/glm/include/glm/detail/_vectorize.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/compute_common.hpp (renamed from deps/glm/include/glm/detail/compute_common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/compute_vector_decl.hpp (renamed from deps/glm/include/glm/detail/compute_vector_decl.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/compute_vector_relational.hpp (renamed from deps/glm/include/glm/detail/compute_vector_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_common.inl (renamed from deps/glm/include/glm/detail/func_common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_common_simd.inl (renamed from deps/glm/include/glm/detail/func_common_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_exponential.inl (renamed from deps/glm/include/glm/detail/func_exponential.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_exponential_simd.inl (renamed from deps/glm/include/glm/detail/func_exponential_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_geometric.inl (renamed from deps/glm/include/glm/detail/func_geometric.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_geometric_simd.inl (renamed from deps/glm/include/glm/detail/func_geometric_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_integer.inl (renamed from deps/glm/include/glm/detail/func_integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_integer_simd.inl (renamed from deps/glm/include/glm/detail/func_integer_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_matrix.inl (renamed from deps/glm/include/glm/detail/func_matrix.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_matrix_simd.inl (renamed from deps/glm/include/glm/detail/func_matrix_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_packing.inl (renamed from deps/glm/include/glm/detail/func_packing.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_packing_simd.inl (renamed from deps/glm/include/glm/detail/func_packing_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_trigonometric.inl (renamed from deps/glm/include/glm/detail/func_trigonometric.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_trigonometric_simd.inl (renamed from deps/glm/include/glm/detail/func_trigonometric_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_vector_relational.inl (renamed from deps/glm/include/glm/detail/func_vector_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/func_vector_relational_simd.inl (renamed from deps/glm/include/glm/detail/func_vector_relational_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/glm.cpp (renamed from deps/glm/include/glm/detail/glm.cpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/qualifier.hpp (renamed from deps/glm/include/glm/detail/qualifier.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/setup.hpp (renamed from deps/glm/include/glm/detail/setup.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_float.hpp (renamed from deps/glm/include/glm/detail/type_float.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_half.hpp (renamed from deps/glm/include/glm/detail/type_half.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_half.inl (renamed from deps/glm/include/glm/detail/type_half.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x2.hpp (renamed from deps/glm/include/glm/detail/type_mat2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x2.inl (renamed from deps/glm/include/glm/detail/type_mat2x2.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x3.hpp (renamed from deps/glm/include/glm/detail/type_mat2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x3.inl (renamed from deps/glm/include/glm/detail/type_mat2x3.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x4.hpp (renamed from deps/glm/include/glm/detail/type_mat2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat2x4.inl (renamed from deps/glm/include/glm/detail/type_mat2x4.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x2.hpp (renamed from deps/glm/include/glm/detail/type_mat3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x2.inl (renamed from deps/glm/include/glm/detail/type_mat3x2.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x3.hpp (renamed from deps/glm/include/glm/detail/type_mat3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x3.inl (renamed from deps/glm/include/glm/detail/type_mat3x3.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x4.hpp (renamed from deps/glm/include/glm/detail/type_mat3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat3x4.inl (renamed from deps/glm/include/glm/detail/type_mat3x4.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x2.hpp (renamed from deps/glm/include/glm/detail/type_mat4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x2.inl (renamed from deps/glm/include/glm/detail/type_mat4x2.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x3.hpp (renamed from deps/glm/include/glm/detail/type_mat4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x3.inl (renamed from deps/glm/include/glm/detail/type_mat4x3.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x4.hpp (renamed from deps/glm/include/glm/detail/type_mat4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x4.inl (renamed from deps/glm/include/glm/detail/type_mat4x4.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_mat4x4_simd.inl (renamed from deps/glm/include/glm/detail/type_mat4x4_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_quat.hpp (renamed from deps/glm/include/glm/detail/type_quat.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_quat.inl (renamed from deps/glm/include/glm/detail/type_quat.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_quat_simd.inl (renamed from deps/glm/include/glm/detail/type_quat_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec1.hpp (renamed from deps/glm/include/glm/detail/type_vec1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec1.inl (renamed from deps/glm/include/glm/detail/type_vec1.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec2.hpp (renamed from deps/glm/include/glm/detail/type_vec2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec2.inl (renamed from deps/glm/include/glm/detail/type_vec2.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec3.hpp (renamed from deps/glm/include/glm/detail/type_vec3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec3.inl (renamed from deps/glm/include/glm/detail/type_vec3.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec4.hpp (renamed from deps/glm/include/glm/detail/type_vec4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec4.inl (renamed from deps/glm/include/glm/detail/type_vec4.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/detail/type_vec4_simd.inl (renamed from deps/glm/include/glm/detail/type_vec4_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/exponential.hpp (renamed from deps/glm/include/glm/exponential.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext.hpp (renamed from deps/glm/include/glm/ext.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/_matrix_vectorize.hpp (renamed from deps/glm/include/glm/ext/_matrix_vectorize.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_clip_space.hpp (renamed from deps/glm/include/glm/ext/matrix_clip_space.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_clip_space.inl (renamed from deps/glm/include/glm/ext/matrix_clip_space.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_common.hpp (renamed from deps/glm/include/glm/ext/matrix_common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_common.inl (renamed from deps/glm/include/glm/ext/matrix_common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x2.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x3.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x4.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double2x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double2x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x2.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x3.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x4.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double3x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double3x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x2.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x3.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x4.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_double4x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_double4x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x2.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x3.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x4.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float2x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float2x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x2.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x3.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x4.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float3x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float3x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x2.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x2_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x3.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x3_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x4.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_float4x4_precision.hpp (renamed from deps/glm/include/glm/ext/matrix_float4x4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x2.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x3.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x4.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int2x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int2x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x2.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x3.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x4.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int3x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int3x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x2.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x3.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x4.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_int4x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_int4x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_integer.hpp (renamed from deps/glm/include/glm/ext/matrix_integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_integer.inl (renamed from deps/glm/include/glm/ext/matrix_integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_projection.hpp (renamed from deps/glm/include/glm/ext/matrix_projection.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_projection.inl (renamed from deps/glm/include/glm/ext/matrix_projection.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_relational.hpp (renamed from deps/glm/include/glm/ext/matrix_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_relational.inl (renamed from deps/glm/include/glm/ext/matrix_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_transform.hpp (renamed from deps/glm/include/glm/ext/matrix_transform.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_transform.inl (renamed from deps/glm/include/glm/ext/matrix_transform.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x2.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x3.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x4.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint2x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint2x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x2.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x3.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x4.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint3x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint3x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x2.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x2_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x3.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x3_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x4.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/matrix_uint4x4_sized.hpp (renamed from deps/glm/include/glm/ext/matrix_uint4x4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_common.hpp (renamed from deps/glm/include/glm/ext/quaternion_common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_common.inl (renamed from deps/glm/include/glm/ext/quaternion_common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_common_simd.inl (renamed from deps/glm/include/glm/ext/quaternion_common_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_double.hpp (renamed from deps/glm/include/glm/ext/quaternion_double.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_double_precision.hpp (renamed from deps/glm/include/glm/ext/quaternion_double_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_exponential.hpp (renamed from deps/glm/include/glm/ext/quaternion_exponential.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_exponential.inl (renamed from deps/glm/include/glm/ext/quaternion_exponential.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_float.hpp (renamed from deps/glm/include/glm/ext/quaternion_float.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_float_precision.hpp (renamed from deps/glm/include/glm/ext/quaternion_float_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_geometric.hpp (renamed from deps/glm/include/glm/ext/quaternion_geometric.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_geometric.inl (renamed from deps/glm/include/glm/ext/quaternion_geometric.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_relational.hpp (renamed from deps/glm/include/glm/ext/quaternion_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_relational.inl (renamed from deps/glm/include/glm/ext/quaternion_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_transform.hpp (renamed from deps/glm/include/glm/ext/quaternion_transform.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_transform.inl (renamed from deps/glm/include/glm/ext/quaternion_transform.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_trigonometric.hpp (renamed from deps/glm/include/glm/ext/quaternion_trigonometric.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/quaternion_trigonometric.inl (renamed from deps/glm/include/glm/ext/quaternion_trigonometric.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_common.hpp (renamed from deps/glm/include/glm/ext/scalar_common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_common.inl (renamed from deps/glm/include/glm/ext/scalar_common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_constants.hpp (renamed from deps/glm/include/glm/ext/scalar_constants.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_constants.inl (renamed from deps/glm/include/glm/ext/scalar_constants.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_int_sized.hpp (renamed from deps/glm/include/glm/ext/scalar_int_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_integer.hpp (renamed from deps/glm/include/glm/ext/scalar_integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_integer.inl (renamed from deps/glm/include/glm/ext/scalar_integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_packing.hpp (renamed from deps/glm/include/glm/ext/scalar_packing.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_packing.inl (renamed from deps/glm/include/glm/ext/scalar_packing.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_reciprocal.hpp (renamed from deps/glm/include/glm/ext/scalar_reciprocal.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_reciprocal.inl (renamed from deps/glm/include/glm/ext/scalar_reciprocal.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_relational.hpp (renamed from deps/glm/include/glm/ext/scalar_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_relational.inl (renamed from deps/glm/include/glm/ext/scalar_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_uint_sized.hpp (renamed from deps/glm/include/glm/ext/scalar_uint_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_ulp.hpp (renamed from deps/glm/include/glm/ext/scalar_ulp.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/scalar_ulp.inl (renamed from deps/glm/include/glm/ext/scalar_ulp.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool1.hpp (renamed from deps/glm/include/glm/ext/vector_bool1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool1_precision.hpp (renamed from deps/glm/include/glm/ext/vector_bool1_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool2.hpp (renamed from deps/glm/include/glm/ext/vector_bool2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool2_precision.hpp (renamed from deps/glm/include/glm/ext/vector_bool2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool3.hpp (renamed from deps/glm/include/glm/ext/vector_bool3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool3_precision.hpp (renamed from deps/glm/include/glm/ext/vector_bool3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool4.hpp (renamed from deps/glm/include/glm/ext/vector_bool4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_bool4_precision.hpp (renamed from deps/glm/include/glm/ext/vector_bool4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_common.hpp (renamed from deps/glm/include/glm/ext/vector_common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_common.inl (renamed from deps/glm/include/glm/ext/vector_common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double1.hpp (renamed from deps/glm/include/glm/ext/vector_double1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double1_precision.hpp (renamed from deps/glm/include/glm/ext/vector_double1_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double2.hpp (renamed from deps/glm/include/glm/ext/vector_double2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double2_precision.hpp (renamed from deps/glm/include/glm/ext/vector_double2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double3.hpp (renamed from deps/glm/include/glm/ext/vector_double3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double3_precision.hpp (renamed from deps/glm/include/glm/ext/vector_double3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double4.hpp (renamed from deps/glm/include/glm/ext/vector_double4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_double4_precision.hpp (renamed from deps/glm/include/glm/ext/vector_double4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float1.hpp (renamed from deps/glm/include/glm/ext/vector_float1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float1_precision.hpp (renamed from deps/glm/include/glm/ext/vector_float1_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float2.hpp (renamed from deps/glm/include/glm/ext/vector_float2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float2_precision.hpp (renamed from deps/glm/include/glm/ext/vector_float2_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float3.hpp (renamed from deps/glm/include/glm/ext/vector_float3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float3_precision.hpp (renamed from deps/glm/include/glm/ext/vector_float3_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float4.hpp (renamed from deps/glm/include/glm/ext/vector_float4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_float4_precision.hpp (renamed from deps/glm/include/glm/ext/vector_float4_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int1.hpp (renamed from deps/glm/include/glm/ext/vector_int1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int1_sized.hpp (renamed from deps/glm/include/glm/ext/vector_int1_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int2.hpp (renamed from deps/glm/include/glm/ext/vector_int2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int2_sized.hpp (renamed from deps/glm/include/glm/ext/vector_int2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int3.hpp (renamed from deps/glm/include/glm/ext/vector_int3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int3_sized.hpp (renamed from deps/glm/include/glm/ext/vector_int3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int4.hpp (renamed from deps/glm/include/glm/ext/vector_int4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_int4_sized.hpp (renamed from deps/glm/include/glm/ext/vector_int4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_integer.hpp (renamed from deps/glm/include/glm/ext/vector_integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_integer.inl (renamed from deps/glm/include/glm/ext/vector_integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_packing.hpp (renamed from deps/glm/include/glm/ext/vector_packing.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_packing.inl (renamed from deps/glm/include/glm/ext/vector_packing.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_reciprocal.hpp (renamed from deps/glm/include/glm/ext/vector_reciprocal.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_reciprocal.inl (renamed from deps/glm/include/glm/ext/vector_reciprocal.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_relational.hpp (renamed from deps/glm/include/glm/ext/vector_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_relational.inl (renamed from deps/glm/include/glm/ext/vector_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint1.hpp (renamed from deps/glm/include/glm/ext/vector_uint1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint1_sized.hpp (renamed from deps/glm/include/glm/ext/vector_uint1_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint2.hpp (renamed from deps/glm/include/glm/ext/vector_uint2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint2_sized.hpp (renamed from deps/glm/include/glm/ext/vector_uint2_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint3.hpp (renamed from deps/glm/include/glm/ext/vector_uint3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint3_sized.hpp (renamed from deps/glm/include/glm/ext/vector_uint3_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint4.hpp (renamed from deps/glm/include/glm/ext/vector_uint4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_uint4_sized.hpp (renamed from deps/glm/include/glm/ext/vector_uint4_sized.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_ulp.hpp (renamed from deps/glm/include/glm/ext/vector_ulp.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/ext/vector_ulp.inl (renamed from deps/glm/include/glm/ext/vector_ulp.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/fwd.hpp (renamed from deps/glm/include/glm/fwd.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/geometric.hpp (renamed from deps/glm/include/glm/geometric.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/glm.cppm (renamed from deps/glm/include/glm/glm.cppm) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/glm.hpp (renamed from deps/glm/include/glm/glm.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/bitfield.hpp (renamed from deps/glm/include/glm/gtc/bitfield.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/bitfield.inl (renamed from deps/glm/include/glm/gtc/bitfield.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/color_space.hpp (renamed from deps/glm/include/glm/gtc/color_space.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/color_space.inl (renamed from deps/glm/include/glm/gtc/color_space.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/constants.hpp (renamed from deps/glm/include/glm/gtc/constants.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/constants.inl (renamed from deps/glm/include/glm/gtc/constants.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/epsilon.hpp (renamed from deps/glm/include/glm/gtc/epsilon.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/epsilon.inl (renamed from deps/glm/include/glm/gtc/epsilon.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/integer.hpp (renamed from deps/glm/include/glm/gtc/integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/integer.inl (renamed from deps/glm/include/glm/gtc/integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_access.hpp (renamed from deps/glm/include/glm/gtc/matrix_access.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_access.inl (renamed from deps/glm/include/glm/gtc/matrix_access.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_integer.hpp (renamed from deps/glm/include/glm/gtc/matrix_integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_inverse.hpp (renamed from deps/glm/include/glm/gtc/matrix_inverse.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_inverse.inl (renamed from deps/glm/include/glm/gtc/matrix_inverse.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_transform.hpp (renamed from deps/glm/include/glm/gtc/matrix_transform.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/matrix_transform.inl (renamed from deps/glm/include/glm/gtc/matrix_transform.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/noise.hpp (renamed from deps/glm/include/glm/gtc/noise.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/noise.inl (renamed from deps/glm/include/glm/gtc/noise.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/packing.hpp (renamed from deps/glm/include/glm/gtc/packing.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/packing.inl (renamed from deps/glm/include/glm/gtc/packing.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/quaternion.hpp (renamed from deps/glm/include/glm/gtc/quaternion.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/quaternion.inl (renamed from deps/glm/include/glm/gtc/quaternion.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/quaternion_simd.inl (renamed from deps/glm/include/glm/gtc/quaternion_simd.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/random.hpp (renamed from deps/glm/include/glm/gtc/random.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/random.inl (renamed from deps/glm/include/glm/gtc/random.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/reciprocal.hpp (renamed from deps/glm/include/glm/gtc/reciprocal.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/round.hpp (renamed from deps/glm/include/glm/gtc/round.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/round.inl (renamed from deps/glm/include/glm/gtc/round.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/type_aligned.hpp (renamed from deps/glm/include/glm/gtc/type_aligned.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/type_precision.hpp (renamed from deps/glm/include/glm/gtc/type_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/type_precision.inl (renamed from deps/glm/include/glm/gtc/type_precision.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/type_ptr.hpp (renamed from deps/glm/include/glm/gtc/type_ptr.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/type_ptr.inl (renamed from deps/glm/include/glm/gtc/type_ptr.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/ulp.hpp (renamed from deps/glm/include/glm/gtc/ulp.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/ulp.inl (renamed from deps/glm/include/glm/gtc/ulp.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtc/vec1.hpp (renamed from deps/glm/include/glm/gtc/vec1.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/associated_min_max.hpp (renamed from deps/glm/include/glm/gtx/associated_min_max.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/associated_min_max.inl (renamed from deps/glm/include/glm/gtx/associated_min_max.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/bit.hpp (renamed from deps/glm/include/glm/gtx/bit.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/bit.inl (renamed from deps/glm/include/glm/gtx/bit.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/closest_point.hpp (renamed from deps/glm/include/glm/gtx/closest_point.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/closest_point.inl (renamed from deps/glm/include/glm/gtx/closest_point.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_encoding.hpp (renamed from deps/glm/include/glm/gtx/color_encoding.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_encoding.inl (renamed from deps/glm/include/glm/gtx/color_encoding.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_space.hpp (renamed from deps/glm/include/glm/gtx/color_space.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_space.inl (renamed from deps/glm/include/glm/gtx/color_space.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_space_YCoCg.hpp (renamed from deps/glm/include/glm/gtx/color_space_YCoCg.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/color_space_YCoCg.inl (renamed from deps/glm/include/glm/gtx/color_space_YCoCg.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/common.hpp (renamed from deps/glm/include/glm/gtx/common.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/common.inl (renamed from deps/glm/include/glm/gtx/common.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/compatibility.hpp (renamed from deps/glm/include/glm/gtx/compatibility.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/compatibility.inl (renamed from deps/glm/include/glm/gtx/compatibility.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/component_wise.hpp (renamed from deps/glm/include/glm/gtx/component_wise.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/component_wise.inl (renamed from deps/glm/include/glm/gtx/component_wise.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/dual_quaternion.hpp (renamed from deps/glm/include/glm/gtx/dual_quaternion.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/dual_quaternion.inl (renamed from deps/glm/include/glm/gtx/dual_quaternion.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/easing.hpp (renamed from deps/glm/include/glm/gtx/easing.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/easing.inl (renamed from deps/glm/include/glm/gtx/easing.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/euler_angles.hpp (renamed from deps/glm/include/glm/gtx/euler_angles.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/euler_angles.inl (renamed from deps/glm/include/glm/gtx/euler_angles.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/extend.hpp (renamed from deps/glm/include/glm/gtx/extend.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/extend.inl (renamed from deps/glm/include/glm/gtx/extend.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/extended_min_max.hpp (renamed from deps/glm/include/glm/gtx/extended_min_max.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/extended_min_max.inl (renamed from deps/glm/include/glm/gtx/extended_min_max.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/exterior_product.hpp (renamed from deps/glm/include/glm/gtx/exterior_product.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/exterior_product.inl (renamed from deps/glm/include/glm/gtx/exterior_product.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_exponential.hpp (renamed from deps/glm/include/glm/gtx/fast_exponential.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_exponential.inl (renamed from deps/glm/include/glm/gtx/fast_exponential.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_square_root.hpp (renamed from deps/glm/include/glm/gtx/fast_square_root.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_square_root.inl (renamed from deps/glm/include/glm/gtx/fast_square_root.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_trigonometry.hpp (renamed from deps/glm/include/glm/gtx/fast_trigonometry.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/fast_trigonometry.inl (renamed from deps/glm/include/glm/gtx/fast_trigonometry.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/float_notmalize.inl (renamed from deps/glm/include/glm/gtx/float_notmalize.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/functions.hpp (renamed from deps/glm/include/glm/gtx/functions.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/functions.inl (renamed from deps/glm/include/glm/gtx/functions.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/gradient_paint.hpp (renamed from deps/glm/include/glm/gtx/gradient_paint.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/gradient_paint.inl (renamed from deps/glm/include/glm/gtx/gradient_paint.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/handed_coordinate_space.hpp (renamed from deps/glm/include/glm/gtx/handed_coordinate_space.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/handed_coordinate_space.inl (renamed from deps/glm/include/glm/gtx/handed_coordinate_space.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/hash.hpp (renamed from deps/glm/include/glm/gtx/hash.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/hash.inl (renamed from deps/glm/include/glm/gtx/hash.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/integer.hpp (renamed from deps/glm/include/glm/gtx/integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/integer.inl (renamed from deps/glm/include/glm/gtx/integer.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/intersect.hpp (renamed from deps/glm/include/glm/gtx/intersect.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/intersect.inl (renamed from deps/glm/include/glm/gtx/intersect.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/io.hpp (renamed from deps/glm/include/glm/gtx/io.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/io.inl (renamed from deps/glm/include/glm/gtx/io.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/log_base.hpp (renamed from deps/glm/include/glm/gtx/log_base.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/log_base.inl (renamed from deps/glm/include/glm/gtx/log_base.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_cross_product.hpp (renamed from deps/glm/include/glm/gtx/matrix_cross_product.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_cross_product.inl (renamed from deps/glm/include/glm/gtx/matrix_cross_product.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_decompose.hpp (renamed from deps/glm/include/glm/gtx/matrix_decompose.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_decompose.inl (renamed from deps/glm/include/glm/gtx/matrix_decompose.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_factorisation.hpp (renamed from deps/glm/include/glm/gtx/matrix_factorisation.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_factorisation.inl (renamed from deps/glm/include/glm/gtx/matrix_factorisation.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_interpolation.hpp (renamed from deps/glm/include/glm/gtx/matrix_interpolation.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_interpolation.inl (renamed from deps/glm/include/glm/gtx/matrix_interpolation.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_major_storage.hpp (renamed from deps/glm/include/glm/gtx/matrix_major_storage.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_major_storage.inl (renamed from deps/glm/include/glm/gtx/matrix_major_storage.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_operation.hpp (renamed from deps/glm/include/glm/gtx/matrix_operation.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_operation.inl (renamed from deps/glm/include/glm/gtx/matrix_operation.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_query.hpp (renamed from deps/glm/include/glm/gtx/matrix_query.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_query.inl (renamed from deps/glm/include/glm/gtx/matrix_query.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_transform_2d.hpp (renamed from deps/glm/include/glm/gtx/matrix_transform_2d.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/matrix_transform_2d.inl (renamed from deps/glm/include/glm/gtx/matrix_transform_2d.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/mixed_product.hpp (renamed from deps/glm/include/glm/gtx/mixed_product.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/mixed_product.inl (renamed from deps/glm/include/glm/gtx/mixed_product.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/norm.hpp (renamed from deps/glm/include/glm/gtx/norm.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/norm.inl (renamed from deps/glm/include/glm/gtx/norm.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/normal.hpp (renamed from deps/glm/include/glm/gtx/normal.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/normal.inl (renamed from deps/glm/include/glm/gtx/normal.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/normalize_dot.hpp (renamed from deps/glm/include/glm/gtx/normalize_dot.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/normalize_dot.inl (renamed from deps/glm/include/glm/gtx/normalize_dot.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/number_precision.hpp (renamed from deps/glm/include/glm/gtx/number_precision.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/optimum_pow.hpp (renamed from deps/glm/include/glm/gtx/optimum_pow.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/optimum_pow.inl (renamed from deps/glm/include/glm/gtx/optimum_pow.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/orthonormalize.hpp (renamed from deps/glm/include/glm/gtx/orthonormalize.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/orthonormalize.inl (renamed from deps/glm/include/glm/gtx/orthonormalize.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/pca.hpp (renamed from deps/glm/include/glm/gtx/pca.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/pca.inl (renamed from deps/glm/include/glm/gtx/pca.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/perpendicular.hpp (renamed from deps/glm/include/glm/gtx/perpendicular.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/perpendicular.inl (renamed from deps/glm/include/glm/gtx/perpendicular.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/polar_coordinates.hpp (renamed from deps/glm/include/glm/gtx/polar_coordinates.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/polar_coordinates.inl (renamed from deps/glm/include/glm/gtx/polar_coordinates.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/projection.hpp (renamed from deps/glm/include/glm/gtx/projection.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/projection.inl (renamed from deps/glm/include/glm/gtx/projection.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/quaternion.hpp (renamed from deps/glm/include/glm/gtx/quaternion.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/quaternion.inl (renamed from deps/glm/include/glm/gtx/quaternion.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/range.hpp (renamed from deps/glm/include/glm/gtx/range.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/raw_data.hpp (renamed from deps/glm/include/glm/gtx/raw_data.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/raw_data.inl (renamed from deps/glm/include/glm/gtx/raw_data.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/rotate_normalized_axis.hpp (renamed from deps/glm/include/glm/gtx/rotate_normalized_axis.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/rotate_normalized_axis.inl (renamed from deps/glm/include/glm/gtx/rotate_normalized_axis.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/rotate_vector.hpp (renamed from deps/glm/include/glm/gtx/rotate_vector.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/rotate_vector.inl (renamed from deps/glm/include/glm/gtx/rotate_vector.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/scalar_multiplication.hpp (renamed from deps/glm/include/glm/gtx/scalar_multiplication.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/scalar_relational.hpp (renamed from deps/glm/include/glm/gtx/scalar_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/scalar_relational.inl (renamed from deps/glm/include/glm/gtx/scalar_relational.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/spline.hpp (renamed from deps/glm/include/glm/gtx/spline.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/spline.inl (renamed from deps/glm/include/glm/gtx/spline.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/std_based_type.hpp (renamed from deps/glm/include/glm/gtx/std_based_type.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/std_based_type.inl (renamed from deps/glm/include/glm/gtx/std_based_type.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/string_cast.hpp (renamed from deps/glm/include/glm/gtx/string_cast.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/string_cast.inl (renamed from deps/glm/include/glm/gtx/string_cast.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/texture.hpp (renamed from deps/glm/include/glm/gtx/texture.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/texture.inl (renamed from deps/glm/include/glm/gtx/texture.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/transform.hpp (renamed from deps/glm/include/glm/gtx/transform.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/transform.inl (renamed from deps/glm/include/glm/gtx/transform.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/transform2.hpp (renamed from deps/glm/include/glm/gtx/transform2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/transform2.inl (renamed from deps/glm/include/glm/gtx/transform2.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/type_aligned.hpp (renamed from deps/glm/include/glm/gtx/type_aligned.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/type_aligned.inl (renamed from deps/glm/include/glm/gtx/type_aligned.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/type_trait.hpp (renamed from deps/glm/include/glm/gtx/type_trait.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/type_trait.inl (renamed from deps/glm/include/glm/gtx/type_trait.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/vec_swizzle.hpp (renamed from deps/glm/include/glm/gtx/vec_swizzle.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/vector_angle.hpp (renamed from deps/glm/include/glm/gtx/vector_angle.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/vector_angle.inl (renamed from deps/glm/include/glm/gtx/vector_angle.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/vector_query.hpp (renamed from deps/glm/include/glm/gtx/vector_query.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/vector_query.inl (renamed from deps/glm/include/glm/gtx/vector_query.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/wrap.hpp (renamed from deps/glm/include/glm/gtx/wrap.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/gtx/wrap.inl (renamed from deps/glm/include/glm/gtx/wrap.inl) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/integer.hpp (renamed from deps/glm/include/glm/integer.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat2x2.hpp (renamed from deps/glm/include/glm/mat2x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat2x3.hpp (renamed from deps/glm/include/glm/mat2x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat2x4.hpp (renamed from deps/glm/include/glm/mat2x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat3x2.hpp (renamed from deps/glm/include/glm/mat3x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat3x3.hpp (renamed from deps/glm/include/glm/mat3x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat3x4.hpp (renamed from deps/glm/include/glm/mat3x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat4x2.hpp (renamed from deps/glm/include/glm/mat4x2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat4x3.hpp (renamed from deps/glm/include/glm/mat4x3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/mat4x4.hpp (renamed from deps/glm/include/glm/mat4x4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/matrix.hpp (renamed from deps/glm/include/glm/matrix.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/packing.hpp (renamed from deps/glm/include/glm/packing.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/common.h (renamed from deps/glm/include/glm/simd/common.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/exponential.h (renamed from deps/glm/include/glm/simd/exponential.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/geometric.h (renamed from deps/glm/include/glm/simd/geometric.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/integer.h (renamed from deps/glm/include/glm/simd/integer.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/matrix.h (renamed from deps/glm/include/glm/simd/matrix.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/neon.h (renamed from deps/glm/include/glm/simd/neon.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/packing.h (renamed from deps/glm/include/glm/simd/packing.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/platform.h (renamed from deps/glm/include/glm/simd/platform.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/trigonometric.h (renamed from deps/glm/include/glm/simd/trigonometric.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/simd/vector_relational.h (renamed from deps/glm/include/glm/simd/vector_relational.h) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/trigonometric.hpp (renamed from deps/glm/include/glm/trigonometric.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/vec2.hpp (renamed from deps/glm/include/glm/vec2.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/vec3.hpp (renamed from deps/glm/include/glm/vec3.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/vec4.hpp (renamed from deps/glm/include/glm/vec4.hpp) | 0 | ||||
| -rw-r--r-- | external/glm/include/glm/vector_relational.hpp (renamed from deps/glm/include/glm/vector_relational.hpp) | 0 | ||||
| -rw-r--r-- | external/imgui/CMakeLists.txt (renamed from deps/imgui/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/imgui/DESCRIPTION (renamed from deps/imgui/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/imgui/LICENSE (renamed from deps/imgui/LICENSE) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imconfig.h (renamed from deps/imgui/include/imconfig.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imgui.h (renamed from deps/imgui/include/imgui.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imgui_impl_glfw.h (renamed from deps/imgui/include/imgui_impl_glfw.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imgui_impl_opengl3.h (renamed from deps/imgui/include/imgui_impl_opengl3.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imgui_impl_opengl3_loader.h (renamed from deps/imgui/include/imgui_impl_opengl3_loader.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imgui_stdlib.h (renamed from deps/imgui/include/imgui_stdlib.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imstb_rectpack.h (renamed from deps/imgui/include/imstb_rectpack.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imstb_textedit.h (renamed from deps/imgui/include/imstb_textedit.h) | 0 | ||||
| -rw-r--r-- | external/imgui/include/imstb_truetype.h (renamed from deps/imgui/include/imstb_truetype.h) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui.cpp (renamed from deps/imgui/src/imgui.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_demo.cpp (renamed from deps/imgui/src/imgui_demo.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_draw.cpp (renamed from deps/imgui/src/imgui_draw.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_impl_glfw.cpp (renamed from deps/imgui/src/imgui_impl_glfw.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_impl_opengl3.cpp (renamed from deps/imgui/src/imgui_impl_opengl3.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_internal.h (renamed from deps/imgui/src/imgui_internal.h) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_stdlib.cpp (renamed from deps/imgui/src/imgui_stdlib.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_tables.cpp (renamed from deps/imgui/src/imgui_tables.cpp) | 0 | ||||
| -rw-r--r-- | external/imgui/src/imgui_widgets.cpp (renamed from deps/imgui/src/imgui_widgets.cpp) | 0 | ||||
| -rw-r--r-- | external/miniz/CMakeLists.txt (renamed from deps/miniz/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/miniz/DESCRIPTION (renamed from deps/miniz/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/miniz/LICENSE (renamed from deps/miniz/LICENSE) | 0 | ||||
| -rw-r--r-- | external/miniz/include/miniz.h (renamed from deps/miniz/include/miniz.h) | 0 | ||||
| -rw-r--r-- | external/miniz/src/miniz.c (renamed from deps/miniz/src/miniz.c) | 0 | ||||
| -rw-r--r-- | external/parson/CMakeLists.txt (renamed from deps/parson/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/parson/DESCRIPTION (renamed from deps/parson/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/parson/LICENSE (renamed from deps/parson/LICENSE) | 0 | ||||
| -rw-r--r-- | external/parson/include/parson.h (renamed from deps/parson/include/parson.h) | 0 | ||||
| -rw-r--r-- | external/parson/src/parson.c (renamed from deps/parson/src/parson.c) | 0 | ||||
| -rw-r--r-- | external/physfs/CMakeLists.txt (renamed from deps/physfs/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/physfs/DESCRIPTION (renamed from deps/physfs/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/physfs/LICENSE (renamed from deps/physfs/LICENSE) | 0 | ||||
| -rw-r--r-- | external/physfs/include/physfs.h (renamed from deps/physfs/include/physfs.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs.c (renamed from deps/physfs/src/physfs.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_7z.c (renamed from deps/physfs/src/physfs_archiver_7z.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_dir.c (renamed from deps/physfs/src/physfs_archiver_dir.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_grp.c (renamed from deps/physfs/src/physfs_archiver_grp.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_hog.c (renamed from deps/physfs/src/physfs_archiver_hog.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_iso9660.c (renamed from deps/physfs/src/physfs_archiver_iso9660.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_mvl.c (renamed from deps/physfs/src/physfs_archiver_mvl.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_qpak.c (renamed from deps/physfs/src/physfs_archiver_qpak.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_slb.c (renamed from deps/physfs/src/physfs_archiver_slb.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_unpacked.c (renamed from deps/physfs/src/physfs_archiver_unpacked.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_vdf.c (renamed from deps/physfs/src/physfs_archiver_vdf.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_wad.c (renamed from deps/physfs/src/physfs_archiver_wad.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_archiver_zip.c (renamed from deps/physfs/src/physfs_archiver_zip.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_byteorder.c (renamed from deps/physfs/src/physfs_byteorder.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_casefolding.h (renamed from deps/physfs/src/physfs_casefolding.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_internal.h (renamed from deps/physfs/src/physfs_internal.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_lzmasdk.h (renamed from deps/physfs/src/physfs_lzmasdk.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_miniz.h (renamed from deps/physfs/src/physfs_miniz.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_android.c (renamed from deps/physfs/src/physfs_platform_android.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_apple.m (renamed from deps/physfs/src/physfs_platform_apple.m) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_os2.c (renamed from deps/physfs/src/physfs_platform_os2.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_posix.c (renamed from deps/physfs/src/physfs_platform_posix.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_qnx.c (renamed from deps/physfs/src/physfs_platform_qnx.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_unix.c (renamed from deps/physfs/src/physfs_platform_unix.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_windows.c (renamed from deps/physfs/src/physfs_platform_windows.c) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platform_winrt.cpp (renamed from deps/physfs/src/physfs_platform_winrt.cpp) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_platforms.h (renamed from deps/physfs/src/physfs_platforms.h) | 0 | ||||
| -rw-r--r-- | external/physfs/src/physfs_unicode.c (renamed from deps/physfs/src/physfs_unicode.c) | 0 | ||||
| -rw-r--r-- | external/salad/CMakeLists.txt (renamed from deps/salad/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/salad/DESCRIPTION (renamed from deps/salad/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/salad/LICENSE (renamed from deps/salad/LICENSE) | 0 | ||||
| -rw-r--r-- | external/salad/include/AL/al.h (renamed from deps/salad/include/AL/al.h) | 0 | ||||
| -rw-r--r-- | external/salad/include/AL/alc.h (renamed from deps/salad/include/AL/alc.h) | 0 | ||||
| -rw-r--r-- | external/salad/include/AL/efx.h (renamed from deps/salad/include/AL/efx.h) | 0 | ||||
| -rw-r--r-- | external/salad/include/AL/salad.h (renamed from deps/salad/include/AL/salad.h) | 0 | ||||
| -rw-r--r-- | external/salad/src/salad.c (renamed from deps/salad/src/salad.c) | 0 | ||||
| -rw-r--r-- | external/spdlog/CMakeLists.txt (renamed from deps/spdlog/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/spdlog/DESCRIPTION (renamed from deps/spdlog/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/spdlog/LICENSE (renamed from deps/spdlog/LICENSE) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/async.h (renamed from deps/spdlog/include/spdlog/async.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/async_logger-inl.h (renamed from deps/spdlog/include/spdlog/async_logger-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/async_logger.h (renamed from deps/spdlog/include/spdlog/async_logger.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/cfg/argv.h (renamed from deps/spdlog/include/spdlog/cfg/argv.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/cfg/env.h (renamed from deps/spdlog/include/spdlog/cfg/env.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/cfg/helpers-inl.h (renamed from deps/spdlog/include/spdlog/cfg/helpers-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/cfg/helpers.h (renamed from deps/spdlog/include/spdlog/cfg/helpers.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/common-inl.h (renamed from deps/spdlog/include/spdlog/common-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/common.h (renamed from deps/spdlog/include/spdlog/common.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/backtracer-inl.h (renamed from deps/spdlog/include/spdlog/details/backtracer-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/backtracer.h (renamed from deps/spdlog/include/spdlog/details/backtracer.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/circular_q.h (renamed from deps/spdlog/include/spdlog/details/circular_q.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/console_globals.h (renamed from deps/spdlog/include/spdlog/details/console_globals.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/file_helper-inl.h (renamed from deps/spdlog/include/spdlog/details/file_helper-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/file_helper.h (renamed from deps/spdlog/include/spdlog/details/file_helper.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/fmt_helper.h (renamed from deps/spdlog/include/spdlog/details/fmt_helper.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/log_msg-inl.h (renamed from deps/spdlog/include/spdlog/details/log_msg-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/log_msg.h (renamed from deps/spdlog/include/spdlog/details/log_msg.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/log_msg_buffer-inl.h (renamed from deps/spdlog/include/spdlog/details/log_msg_buffer-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/log_msg_buffer.h (renamed from deps/spdlog/include/spdlog/details/log_msg_buffer.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/mpmc_blocking_q.h (renamed from deps/spdlog/include/spdlog/details/mpmc_blocking_q.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/null_mutex.h (renamed from deps/spdlog/include/spdlog/details/null_mutex.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/os-inl.h (renamed from deps/spdlog/include/spdlog/details/os-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/os.h (renamed from deps/spdlog/include/spdlog/details/os.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/periodic_worker-inl.h (renamed from deps/spdlog/include/spdlog/details/periodic_worker-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/periodic_worker.h (renamed from deps/spdlog/include/spdlog/details/periodic_worker.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/registry-inl.h (renamed from deps/spdlog/include/spdlog/details/registry-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/registry.h (renamed from deps/spdlog/include/spdlog/details/registry.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/synchronous_factory.h (renamed from deps/spdlog/include/spdlog/details/synchronous_factory.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/tcp_client-windows.h (renamed from deps/spdlog/include/spdlog/details/tcp_client-windows.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/tcp_client.h (renamed from deps/spdlog/include/spdlog/details/tcp_client.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/thread_pool-inl.h (renamed from deps/spdlog/include/spdlog/details/thread_pool-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/thread_pool.h (renamed from deps/spdlog/include/spdlog/details/thread_pool.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/udp_client-windows.h (renamed from deps/spdlog/include/spdlog/details/udp_client-windows.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/udp_client.h (renamed from deps/spdlog/include/spdlog/details/udp_client.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/details/windows_include.h (renamed from deps/spdlog/include/spdlog/details/windows_include.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/bin_to_hex.h (renamed from deps/spdlog/include/spdlog/fmt/bin_to_hex.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/chrono.h (renamed from deps/spdlog/include/spdlog/fmt/chrono.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/compile.h (renamed from deps/spdlog/include/spdlog/fmt/compile.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/fmt.h (renamed from deps/spdlog/include/spdlog/fmt/fmt.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/ostr.h (renamed from deps/spdlog/include/spdlog/fmt/ostr.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/ranges.h (renamed from deps/spdlog/include/spdlog/fmt/ranges.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/std.h (renamed from deps/spdlog/include/spdlog/fmt/std.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fmt/xchar.h (renamed from deps/spdlog/include/spdlog/fmt/xchar.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/formatter.h (renamed from deps/spdlog/include/spdlog/formatter.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/fwd.h (renamed from deps/spdlog/include/spdlog/fwd.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/logger-inl.h (renamed from deps/spdlog/include/spdlog/logger-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/logger.h (renamed from deps/spdlog/include/spdlog/logger.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/mdc.h (renamed from deps/spdlog/include/spdlog/mdc.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/pattern_formatter-inl.h (renamed from deps/spdlog/include/spdlog/pattern_formatter-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/pattern_formatter.h (renamed from deps/spdlog/include/spdlog/pattern_formatter.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/android_sink.h (renamed from deps/spdlog/include/spdlog/sinks/android_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/ansicolor_sink.h (renamed from deps/spdlog/include/spdlog/sinks/ansicolor_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/base_sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/base_sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/base_sink.h (renamed from deps/spdlog/include/spdlog/sinks/base_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/basic_file_sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/basic_file_sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/basic_file_sink.h (renamed from deps/spdlog/include/spdlog/sinks/basic_file_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/callback_sink.h (renamed from deps/spdlog/include/spdlog/sinks/callback_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/daily_file_sink.h (renamed from deps/spdlog/include/spdlog/sinks/daily_file_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/dist_sink.h (renamed from deps/spdlog/include/spdlog/sinks/dist_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/dup_filter_sink.h (renamed from deps/spdlog/include/spdlog/sinks/dup_filter_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/hourly_file_sink.h (renamed from deps/spdlog/include/spdlog/sinks/hourly_file_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/kafka_sink.h (renamed from deps/spdlog/include/spdlog/sinks/kafka_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/mongo_sink.h (renamed from deps/spdlog/include/spdlog/sinks/mongo_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/msvc_sink.h (renamed from deps/spdlog/include/spdlog/sinks/msvc_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/null_sink.h (renamed from deps/spdlog/include/spdlog/sinks/null_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/ostream_sink.h (renamed from deps/spdlog/include/spdlog/sinks/ostream_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/qt_sinks.h (renamed from deps/spdlog/include/spdlog/sinks/qt_sinks.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/ringbuffer_sink.h (renamed from deps/spdlog/include/spdlog/sinks/ringbuffer_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/rotating_file_sink.h (renamed from deps/spdlog/include/spdlog/sinks/rotating_file_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/sink.h (renamed from deps/spdlog/include/spdlog/sinks/sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h (renamed from deps/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/stdout_color_sinks.h (renamed from deps/spdlog/include/spdlog/sinks/stdout_color_sinks.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/stdout_sinks-inl.h (renamed from deps/spdlog/include/spdlog/sinks/stdout_sinks-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/stdout_sinks.h (renamed from deps/spdlog/include/spdlog/sinks/stdout_sinks.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/syslog_sink.h (renamed from deps/spdlog/include/spdlog/sinks/syslog_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/systemd_sink.h (renamed from deps/spdlog/include/spdlog/sinks/systemd_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/tcp_sink.h (renamed from deps/spdlog/include/spdlog/sinks/tcp_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/udp_sink.h (renamed from deps/spdlog/include/spdlog/sinks/udp_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/win_eventlog_sink.h (renamed from deps/spdlog/include/spdlog/sinks/win_eventlog_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/wincolor_sink-inl.h (renamed from deps/spdlog/include/spdlog/sinks/wincolor_sink-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/sinks/wincolor_sink.h (renamed from deps/spdlog/include/spdlog/sinks/wincolor_sink.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/spdlog-inl.h (renamed from deps/spdlog/include/spdlog/spdlog-inl.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/spdlog.h (renamed from deps/spdlog/include/spdlog/spdlog.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/stopwatch.h (renamed from deps/spdlog/include/spdlog/stopwatch.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/tweakme.h (renamed from deps/spdlog/include/spdlog/tweakme.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/include/spdlog/version.h (renamed from deps/spdlog/include/spdlog/version.h) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/async.cpp (renamed from deps/spdlog/src/async.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/bundled_fmtlib_format.cpp (renamed from deps/spdlog/src/bundled_fmtlib_format.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/cfg.cpp (renamed from deps/spdlog/src/cfg.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/color_sinks.cpp (renamed from deps/spdlog/src/color_sinks.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/file_sinks.cpp (renamed from deps/spdlog/src/file_sinks.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/spdlog.cpp (renamed from deps/spdlog/src/spdlog.cpp) | 0 | ||||
| -rw-r--r-- | external/spdlog/src/stdout_sinks.cpp (renamed from deps/spdlog/src/stdout_sinks.cpp) | 0 | ||||
| -rw-r--r-- | external/stb/CMakeLists.txt (renamed from deps/stb/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/stb/DESCRIPTION (renamed from deps/stb/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/stb/LICENSE (renamed from deps/stb/LICENSE) | 0 | ||||
| -rw-r--r-- | external/stb/include/stb_image.h (renamed from deps/stb/include/stb_image.h) | 0 | ||||
| -rw-r--r-- | external/stb/include/stb_image_write.h (renamed from deps/stb/include/stb_image_write.h) | 0 | ||||
| -rw-r--r-- | external/stb/src/stb_impl.c (renamed from deps/stb/src/stb_impl.c) | 0 | ||||
| -rw-r--r-- | external/thread_pool/CMakeLists.txt (renamed from deps/thread_pool/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | external/thread_pool/DESCRIPTION (renamed from deps/thread_pool/DESCRIPTION) | 0 | ||||
| -rw-r--r-- | external/thread_pool/LICENSE (renamed from deps/thread_pool/LICENSE) | 0 | ||||
| -rw-r--r-- | external/thread_pool/include/BS_thread_pool.hpp (renamed from deps/thread_pool/include/BS_thread_pool.hpp) | 0 | ||||
| -rw-r--r-- | media/client_splash.xcf (renamed from misc/client_splash.xcf) | bin | 19871 -> 19871 bytes | |||
| -rw-r--r-- | media/historic/2022_crc64_randomness.png | bin | 0 -> 175233 bytes | |||
| -rw-r--r-- | media/historic/renderdoc_screenshot_01.png | bin | 0 -> 467871 bytes | |||
| -rw-r--r-- | media/nsis-header.bmp | bin | 0 -> 25818 bytes | |||
| -rw-r--r-- | media/nsis-installer.ico (renamed from game/server/vserver.ico) | bin | 60201 -> 60201 bytes | |||
| -rw-r--r-- | media/nsis-splash.bmp | bin | 0 -> 154542 bytes | |||
| -rw-r--r-- | media/vclient.bbmodel (renamed from misc/vclient.bbmodel) | 0 | ||||
| -rw-r--r-- | media/vclient.png (renamed from misc/vclient.png) | bin | 174182 -> 174182 bytes | |||
| -rw-r--r-- | media/vserver.bbmodel (renamed from misc/vserver.bbmodel) | 0 | ||||
| -rw-r--r-- | media/vserver.png (renamed from misc/vserver.png) | bin | 138598 -> 138598 bytes | |||
| -rw-r--r-- | scripts/build-unix-debug.sh | 5 | ||||
| -rw-r--r-- | scripts/build-unix-release.sh | 5 | ||||
| -rw-r--r-- | scripts/build-win32-debug.bat | 7 | ||||
| -rw-r--r-- | scripts/build-win32-release.bat | 7 | ||||
| -rw-r--r-- | scripts/build-win64-debug.bat | 7 | ||||
| -rw-r--r-- | scripts/build-win64-release.bat | 7 | ||||
| -rw-r--r-- | scripts/generate-thirdparty.py (renamed from deps/thirdparty.py) | 4 | ||||
| -rw-r--r-- | scripts/package-unix.sh | 5 | ||||
| -rw-r--r-- | scripts/package-win32-nsis.bat | 7 | ||||
| -rw-r--r-- | scripts/package-win32-zip.bat | 7 | ||||
| -rw-r--r-- | scripts/package-win64-nsis.bat | 7 | ||||
| -rw-r--r-- | scripts/package-win64-zip.bat | 7 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt (renamed from core/CMakeLists.txt) | 2 | ||||
| -rw-r--r-- | src/core/config/CMakeLists.txt (renamed from core/config/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/core/config/boolean.cc (renamed from core/config/boolean.cc) | 86 | ||||
| -rw-r--r-- | src/core/config/boolean.hh (renamed from core/config/boolean.hh) | 50 | ||||
| -rw-r--r-- | src/core/config/ivalue.hh (renamed from core/config/ivalue.hh) | 22 | ||||
| -rw-r--r-- | src/core/config/number.hh (renamed from core/config/number.hh) | 260 | ||||
| -rw-r--r-- | src/core/config/string.cc (renamed from core/config/string.cc) | 36 | ||||
| -rw-r--r-- | src/core/config/string.hh (renamed from core/config/string.hh) | 62 | ||||
| -rw-r--r-- | src/core/io/CMakeLists.txt (renamed from core/io/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/core/io/buffer.cc (renamed from core/io/buffer.cc) | 690 | ||||
| -rw-r--r-- | src/core/io/buffer.hh (renamed from core/io/buffer.hh) | 176 | ||||
| -rw-r--r-- | src/core/io/cmdline.cc (renamed from core/io/cmdline.cc) | 190 | ||||
| -rw-r--r-- | src/core/io/cmdline.hh (renamed from core/io/cmdline.hh) | 22 | ||||
| -rw-r--r-- | src/core/io/config_map.cc (renamed from core/io/config_map.cc) | 272 | ||||
| -rw-r--r-- | src/core/io/config_map.hh (renamed from core/io/config_map.hh) | 58 | ||||
| -rw-r--r-- | src/core/io/physfs.cc (renamed from core/io/physfs.cc) | 0 | ||||
| -rw-r--r-- | src/core/io/physfs.hh (renamed from core/io/physfs.hh) | 0 | ||||
| -rw-r--r-- | src/core/math/CMakeLists.txt (renamed from core/math/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/core/math/aabb.hh (renamed from core/math/aabb.hh) | 222 | ||||
| -rw-r--r-- | src/core/math/angles.hh (renamed from core/math/angles.hh) | 206 | ||||
| -rw-r--r-- | src/core/math/concepts.hh (renamed from core/math/concepts.hh) | 22 | ||||
| -rw-r--r-- | src/core/math/constexpr.hh (renamed from core/math/constexpr.hh) | 144 | ||||
| -rw-r--r-- | src/core/math/crc64.cc (renamed from core/math/crc64.cc) | 152 | ||||
| -rw-r--r-- | src/core/math/crc64.hh (renamed from core/math/crc64.hh) | 18 | ||||
| -rw-r--r-- | src/core/math/vectors.hh (renamed from core/math/vectors.hh) | 86 | ||||
| -rw-r--r-- | src/core/pch.hh (renamed from core/pch.hh) | 98 | ||||
| -rw-r--r-- | src/core/resource/CMakeLists.txt (renamed from core/resource/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/core/resource/image.cc (renamed from core/resource/image.cc) | 162 | ||||
| -rw-r--r-- | src/core/resource/image.hh (renamed from core/resource/image.hh) | 22 | ||||
| -rw-r--r-- | src/core/resource/resource.cc (renamed from core/resource/resource.cc) | 252 | ||||
| -rw-r--r-- | src/core/resource/resource.hh (renamed from core/resource/resource.hh) | 106 | ||||
| -rw-r--r-- | src/core/threading.cc (renamed from core/threading.cc) | 256 | ||||
| -rw-r--r-- | src/core/threading.hh (renamed from core/threading.hh) | 92 | ||||
| -rw-r--r-- | src/core/utils/CMakeLists.txt (renamed from core/utils/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/core/utils/epoch.cc (renamed from core/utils/epoch.cc) | 78 | ||||
| -rw-r--r-- | src/core/utils/epoch.hh (renamed from core/utils/epoch.hh) | 30 | ||||
| -rw-r--r-- | src/core/utils/string.cc (renamed from core/utils/string.cc) | 114 | ||||
| -rw-r--r-- | src/core/utils/string.hh (renamed from core/utils/string.hh) | 34 | ||||
| -rw-r--r-- | src/core/version.cc | 15 | ||||
| -rw-r--r-- | src/core/version.cc.in | 15 | ||||
| -rw-r--r-- | src/core/version.hh | 20 | ||||
| -rw-r--r-- | src/game/CMakeLists.txt (renamed from game/CMakeLists.txt) | 4 | ||||
| -rw-r--r-- | src/game/client/CMakeLists.txt (renamed from game/client/CMakeLists.txt) | 4 | ||||
| -rw-r--r-- | src/game/client/config/CMakeLists.txt (renamed from game/client/config/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/config/gamepad_axis.cc (renamed from game/client/config/gamepad_axis.cc) | 230 | ||||
| -rw-r--r-- | src/game/client/config/gamepad_axis.hh (renamed from game/client/config/gamepad_axis.hh) | 76 | ||||
| -rw-r--r-- | src/game/client/config/gamepad_button.cc (renamed from game/client/config/gamepad_button.cc) | 180 | ||||
| -rw-r--r-- | src/game/client/config/gamepad_button.hh (renamed from game/client/config/gamepad_button.hh) | 56 | ||||
| -rw-r--r-- | src/game/client/config/keybind.cc (renamed from game/client/config/keybind.cc) | 404 | ||||
| -rw-r--r-- | src/game/client/config/keybind.hh (renamed from game/client/config/keybind.hh) | 50 | ||||
| -rw-r--r-- | src/game/client/const.hh (renamed from game/client/const.hh) | 46 | ||||
| -rw-r--r-- | src/game/client/entity/CMakeLists.txt (renamed from game/client/entity/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/entity/camera.cc (renamed from game/client/entity/camera.cc) | 228 | ||||
| -rw-r--r-- | src/game/client/entity/camera.hh (renamed from game/client/entity/camera.hh) | 62 | ||||
| -rw-r--r-- | src/game/client/entity/factory.cc (renamed from game/client/entity/factory.cc) | 60 | ||||
| -rw-r--r-- | src/game/client/entity/factory.hh (renamed from game/client/entity/factory.hh) | 22 | ||||
| -rw-r--r-- | src/game/client/entity/interpolation.cc (renamed from game/client/entity/interpolation.cc) | 126 | ||||
| -rw-r--r-- | src/game/client/entity/interpolation.hh (renamed from game/client/entity/interpolation.hh) | 12 | ||||
| -rw-r--r-- | src/game/client/entity/listener.cc (renamed from game/client/entity/listener.cc) | 84 | ||||
| -rw-r--r-- | src/game/client/entity/listener.hh (renamed from game/client/entity/listener.hh) | 12 | ||||
| -rw-r--r-- | src/game/client/entity/player_look.cc (renamed from game/client/entity/player_look.cc) | 310 | ||||
| -rw-r--r-- | src/game/client/entity/player_look.hh (renamed from game/client/entity/player_look.hh) | 14 | ||||
| -rw-r--r-- | src/game/client/entity/player_move.cc (renamed from game/client/entity/player_move.cc) | 596 | ||||
| -rw-r--r-- | src/game/client/entity/player_move.hh (renamed from game/client/entity/player_move.hh) | 30 | ||||
| -rw-r--r-- | src/game/client/entity/sound_emitter.cc (renamed from game/client/entity/sound_emitter.cc) | 126 | ||||
| -rw-r--r-- | src/game/client/entity/sound_emitter.hh (renamed from game/client/entity/sound_emitter.hh) | 40 | ||||
| -rw-r--r-- | src/game/client/experiments.cc (renamed from game/client/experiments.cc) | 168 | ||||
| -rw-r--r-- | src/game/client/experiments.hh (renamed from game/client/experiments.hh) | 32 | ||||
| -rw-r--r-- | src/game/client/game.cc (renamed from game/client/game.cc) | 1417 | ||||
| -rw-r--r-- | src/game/client/game.hh (renamed from game/client/game.hh) | 70 | ||||
| -rw-r--r-- | src/game/client/globals.cc (renamed from game/client/globals.cc) | 94 | ||||
| -rw-r--r-- | src/game/client/globals.hh (renamed from game/client/globals.hh) | 142 | ||||
| -rw-r--r-- | src/game/client/gui/CMakeLists.txt (renamed from game/client/gui/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/gui/background.cc (renamed from game/client/gui/background.cc) | 78 | ||||
| -rw-r--r-- | src/game/client/gui/background.hh (renamed from game/client/gui/background.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/gui/bother.cc (renamed from game/client/gui/bother.cc) | 334 | ||||
| -rw-r--r-- | src/game/client/gui/bother.hh (renamed from game/client/gui/bother.hh) | 48 | ||||
| -rw-r--r-- | src/game/client/gui/chat.cc (renamed from game/client/gui/chat.cc) | 546 | ||||
| -rw-r--r-- | src/game/client/gui/chat.hh (renamed from game/client/gui/chat.hh) | 34 | ||||
| -rw-r--r-- | src/game/client/gui/crosshair.cc (renamed from game/client/gui/crosshair.cc) | 86 | ||||
| -rw-r--r-- | src/game/client/gui/crosshair.hh (renamed from game/client/gui/crosshair.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/gui/direct_connection.cc (renamed from game/client/gui/direct_connection.cc) | 290 | ||||
| -rw-r--r-- | src/game/client/gui/direct_connection.hh (renamed from game/client/gui/direct_connection.hh) | 14 | ||||
| -rw-r--r-- | src/game/client/gui/gui_screen.hh (renamed from game/client/gui/gui_screen.hh) | 20 | ||||
| -rw-r--r-- | src/game/client/gui/hotbar.cc (renamed from game/client/gui/hotbar.cc) | 364 | ||||
| -rw-r--r-- | src/game/client/gui/hotbar.hh (renamed from game/client/gui/hotbar.hh) | 60 | ||||
| -rw-r--r-- | src/game/client/gui/imdraw_ext.cc (renamed from game/client/gui/imdraw_ext.cc) | 68 | ||||
| -rw-r--r-- | src/game/client/gui/imdraw_ext.hh (renamed from game/client/gui/imdraw_ext.hh) | 34 | ||||
| -rw-r--r-- | src/game/client/gui/language.cc (renamed from game/client/gui/language.cc) | 404 | ||||
| -rw-r--r-- | src/game/client/gui/language.hh (renamed from game/client/gui/language.hh) | 84 | ||||
| -rw-r--r-- | src/game/client/gui/main_menu.cc (renamed from game/client/gui/main_menu.cc) | 344 | ||||
| -rw-r--r-- | src/game/client/gui/main_menu.hh (renamed from game/client/gui/main_menu.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/gui/message_box.cc (renamed from game/client/gui/message_box.cc) | 190 | ||||
| -rw-r--r-- | src/game/client/gui/message_box.hh (renamed from game/client/gui/message_box.hh) | 40 | ||||
| -rw-r--r-- | src/game/client/gui/metrics.cc (renamed from game/client/gui/metrics.cc) | 206 | ||||
| -rw-r--r-- | src/game/client/gui/metrics.hh (renamed from game/client/gui/metrics.hh) | 14 | ||||
| -rw-r--r-- | src/game/client/gui/play_menu.cc (renamed from game/client/gui/play_menu.cc) | 1188 | ||||
| -rw-r--r-- | src/game/client/gui/play_menu.hh (renamed from game/client/gui/play_menu.hh) | 18 | ||||
| -rw-r--r-- | src/game/client/gui/progress_bar.cc (renamed from game/client/gui/progress_bar.cc) | 222 | ||||
| -rw-r--r-- | src/game/client/gui/progress_bar.hh (renamed from game/client/gui/progress_bar.hh) | 38 | ||||
| -rw-r--r-- | src/game/client/gui/scoreboard.cc (renamed from game/client/gui/scoreboard.cc) | 206 | ||||
| -rw-r--r-- | src/game/client/gui/scoreboard.hh (renamed from game/client/gui/scoreboard.hh) | 14 | ||||
| -rw-r--r-- | src/game/client/gui/settings.cc (renamed from game/client/gui/settings.cc) | 2138 | ||||
| -rw-r--r-- | src/game/client/gui/settings.hh (renamed from game/client/gui/settings.hh) | 180 | ||||
| -rw-r--r-- | src/game/client/gui/splash.cc (renamed from game/client/gui/splash.cc) | 355 | ||||
| -rw-r--r-- | src/game/client/gui/splash.hh (renamed from game/client/gui/splash.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/gui/status_lines.cc (renamed from game/client/gui/status_lines.cc) | 168 | ||||
| -rw-r--r-- | src/game/client/gui/status_lines.hh (renamed from game/client/gui/status_lines.hh) | 42 | ||||
| -rw-r--r-- | src/game/client/gui/window_title.cc (renamed from game/client/gui/window_title.cc) | 28 | ||||
| -rw-r--r-- | src/game/client/gui/window_title.hh (renamed from game/client/gui/window_title.hh) | 12 | ||||
| -rw-r--r-- | src/game/client/io/CMakeLists.txt (renamed from game/client/io/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/io/gamepad.cc (renamed from game/client/io/gamepad.cc) | 366 | ||||
| -rw-r--r-- | src/game/client/io/gamepad.hh (renamed from game/client/io/gamepad.hh) | 100 | ||||
| -rw-r--r-- | src/game/client/io/glfw.hh (renamed from game/client/io/glfw.hh) | 72 | ||||
| -rw-r--r-- | src/game/client/main.cc (renamed from game/client/main.cc) | 898 | ||||
| -rw-r--r-- | src/game/client/pch.hh (renamed from game/client/pch.hh) | 56 | ||||
| -rw-r--r-- | src/game/client/program.cc (renamed from game/client/program.cc) | 452 | ||||
| -rw-r--r-- | src/game/client/program.hh (renamed from game/client/program.hh) | 68 | ||||
| -rw-r--r-- | src/game/client/receive.cc (renamed from game/client/receive.cc) | 384 | ||||
| -rw-r--r-- | src/game/client/receive.hh (renamed from game/client/receive.hh) | 12 | ||||
| -rw-r--r-- | src/game/client/resource/CMakeLists.txt (renamed from game/client/resource/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/resource/sound_effect.cc (renamed from game/client/resource/sound_effect.cc) | 180 | ||||
| -rw-r--r-- | src/game/client/resource/sound_effect.hh (renamed from game/client/resource/sound_effect.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/resource/texture_gui.cc (renamed from game/client/resource/texture_gui.cc) | 166 | ||||
| -rw-r--r-- | src/game/client/resource/texture_gui.hh (renamed from game/client/resource/texture_gui.hh) | 30 | ||||
| -rw-r--r-- | src/game/client/screenshot.cc (renamed from game/client/screenshot.cc) | 172 | ||||
| -rw-r--r-- | src/game/client/screenshot.hh (renamed from game/client/screenshot.hh) | 14 | ||||
| -rw-r--r-- | src/game/client/session.cc (renamed from game/client/session.cc) | 626 | ||||
| -rw-r--r-- | src/game/client/session.hh (renamed from game/client/session.hh) | 54 | ||||
| -rw-r--r-- | src/game/client/sound/CMakeLists.txt (renamed from game/client/sound/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/sound/sound.cc (renamed from game/client/sound/sound.cc) | 422 | ||||
| -rw-r--r-- | src/game/client/sound/sound.hh (renamed from game/client/sound/sound.hh) | 86 | ||||
| -rw-r--r-- | src/game/client/toggles.cc (renamed from game/client/toggles.cc) | 314 | ||||
| -rw-r--r-- | src/game/client/toggles.hh (renamed from game/client/toggles.hh) | 70 | ||||
| -rw-r--r-- | src/game/client/vclient.ico (renamed from game/client/vclient.ico) | bin | 54361 -> 54361 bytes | |||
| -rw-r--r-- | src/game/client/vclient.rc (renamed from game/client/vclient.rc) | 0 | ||||
| -rw-r--r-- | src/game/client/world/CMakeLists.txt (renamed from game/client/world/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/client/world/chunk_mesher.cc (renamed from game/client/world/chunk_mesher.cc) | 900 | ||||
| -rw-r--r-- | src/game/client/world/chunk_mesher.hh (renamed from game/client/world/chunk_mesher.hh) | 36 | ||||
| -rw-r--r-- | src/game/client/world/chunk_quad.hh (renamed from game/client/world/chunk_quad.hh) | 82 | ||||
| -rw-r--r-- | src/game/client/world/chunk_renderer.cc (renamed from game/client/world/chunk_renderer.cc) | 409 | ||||
| -rw-r--r-- | src/game/client/world/chunk_renderer.hh (renamed from game/client/world/chunk_renderer.hh) | 16 | ||||
| -rw-r--r-- | src/game/client/world/chunk_vbo.hh (renamed from game/client/world/chunk_vbo.hh) | 44 | ||||
| -rw-r--r-- | src/game/client/world/chunk_visibility.cc (renamed from game/client/world/chunk_visibility.cc) | 180 | ||||
| -rw-r--r-- | src/game/client/world/chunk_visibility.hh (renamed from game/client/world/chunk_visibility.hh) | 12 | ||||
| -rw-r--r-- | src/game/client/world/outline.cc (renamed from game/client/world/outline.cc) | 300 | ||||
| -rw-r--r-- | src/game/client/world/outline.hh (renamed from game/client/world/outline.hh) | 32 | ||||
| -rw-r--r-- | src/game/client/world/player_target.cc (renamed from game/client/world/player_target.cc) | 128 | ||||
| -rw-r--r-- | src/game/client/world/player_target.hh (renamed from game/client/world/player_target.hh) | 34 | ||||
| -rw-r--r-- | src/game/client/world/skybox.cc (renamed from game/client/world/skybox.cc) | 22 | ||||
| -rw-r--r-- | src/game/client/world/skybox.hh (renamed from game/client/world/skybox.hh) | 22 | ||||
| -rw-r--r-- | src/game/client/world/voxel_anims.cc (renamed from game/client/world/voxel_anims.cc) | 66 | ||||
| -rw-r--r-- | src/game/client/world/voxel_anims.hh (renamed from game/client/world/voxel_anims.hh) | 26 | ||||
| -rw-r--r-- | src/game/client/world/voxel_atlas.cc (renamed from game/client/world/voxel_atlas.cc) | 371 | ||||
| -rw-r--r-- | src/game/client/world/voxel_atlas.hh (renamed from game/client/world/voxel_atlas.hh) | 56 | ||||
| -rw-r--r-- | src/game/client/world/voxel_sounds.cc (renamed from game/client/world/voxel_sounds.cc) | 166 | ||||
| -rw-r--r-- | src/game/client/world/voxel_sounds.hh (renamed from game/client/world/voxel_sounds.hh) | 38 | ||||
| -rw-r--r-- | src/game/server/CMakeLists.txt (renamed from game/server/CMakeLists.txt) | 4 | ||||
| -rw-r--r-- | src/game/server/chat.cc (renamed from game/server/chat.cc) | 110 | ||||
| -rw-r--r-- | src/game/server/chat.hh (renamed from game/server/chat.hh) | 24 | ||||
| -rw-r--r-- | src/game/server/game.cc (renamed from game/server/game.cc) | 326 | ||||
| -rw-r--r-- | src/game/server/game.hh (renamed from game/server/game.hh) | 50 | ||||
| -rw-r--r-- | src/game/server/globals.cc (renamed from game/server/globals.cc) | 36 | ||||
| -rw-r--r-- | src/game/server/globals.hh (renamed from game/server/globals.hh) | 54 | ||||
| -rw-r--r-- | src/game/server/main.cc (renamed from game/server/main.cc) | 216 | ||||
| -rw-r--r-- | src/game/server/pch.hh (renamed from game/server/pch.hh) | 6 | ||||
| -rw-r--r-- | src/game/server/receive.cc (renamed from game/server/receive.cc) | 350 | ||||
| -rw-r--r-- | src/game/server/receive.hh (renamed from game/server/receive.hh) | 12 | ||||
| -rw-r--r-- | src/game/server/sessions.cc (renamed from game/server/sessions.cc) | 904 | ||||
| -rw-r--r-- | src/game/server/sessions.hh (renamed from game/server/sessions.hh) | 110 | ||||
| -rw-r--r-- | src/game/server/status.cc (renamed from game/server/status.cc) | 60 | ||||
| -rw-r--r-- | src/game/server/status.hh (renamed from game/server/status.hh) | 12 | ||||
| -rw-r--r-- | src/game/server/vserver.ico | bin | 0 -> 60201 bytes | |||
| -rw-r--r-- | src/game/server/vserver.rc (renamed from game/server/vserver.rc) | 0 | ||||
| -rw-r--r-- | src/game/server/whitelist.cc (renamed from game/server/whitelist.cc) | 204 | ||||
| -rw-r--r-- | src/game/server/whitelist.hh (renamed from game/server/whitelist.hh) | 52 | ||||
| -rw-r--r-- | src/game/server/world/CMakeLists.txt (renamed from game/server/world/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/server/world/inhabited.hh (renamed from game/server/world/inhabited.hh) | 12 | ||||
| -rw-r--r-- | src/game/server/world/overworld.cc (renamed from game/server/world/overworld.cc) | 781 | ||||
| -rw-r--r-- | src/game/server/world/overworld.hh (renamed from game/server/world/overworld.hh) | 136 | ||||
| -rw-r--r-- | src/game/server/world/random_tick.cc (renamed from game/server/world/random_tick.cc) | 0 | ||||
| -rw-r--r-- | src/game/server/world/random_tick.hh (renamed from game/server/world/random_tick.hh) | 0 | ||||
| -rw-r--r-- | src/game/server/world/universe.cc (renamed from game/server/world/universe.cc) | 444 | ||||
| -rw-r--r-- | src/game/server/world/universe.hh (renamed from game/server/world/universe.hh) | 50 | ||||
| -rw-r--r-- | src/game/server/world/unloader.cc (renamed from game/server/world/unloader.cc) | 156 | ||||
| -rw-r--r-- | src/game/server/world/unloader.hh (renamed from game/server/world/unloader.hh) | 26 | ||||
| -rw-r--r-- | src/game/server/world/worldgen.cc (renamed from game/server/world/worldgen.cc) | 302 | ||||
| -rw-r--r-- | src/game/server/world/worldgen.hh (renamed from game/server/world/worldgen.hh) | 42 | ||||
| -rw-r--r-- | src/game/shared/CMakeLists.txt (renamed from game/shared/CMakeLists.txt) | 4 | ||||
| -rw-r--r-- | src/game/shared/const.hh (renamed from game/shared/const.hh) | 86 | ||||
| -rw-r--r-- | src/game/shared/coord.hh (renamed from game/shared/coord.hh) | 290 | ||||
| -rw-r--r-- | src/game/shared/entity/CMakeLists.txt (renamed from game/shared/entity/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/shared/entity/collision.cc (renamed from game/shared/entity/collision.cc) | 346 | ||||
| -rw-r--r-- | src/game/shared/entity/collision.hh (renamed from game/shared/entity/collision.hh) | 42 | ||||
| -rw-r--r-- | src/game/shared/entity/factory.cc (renamed from game/shared/entity/factory.cc) | 74 | ||||
| -rw-r--r-- | src/game/shared/entity/factory.hh (renamed from game/shared/entity/factory.hh) | 22 | ||||
| -rw-r--r-- | src/game/shared/entity/gravity.cc (renamed from game/shared/entity/gravity.cc) | 40 | ||||
| -rw-r--r-- | src/game/shared/entity/gravity.hh (renamed from game/shared/entity/gravity.hh) | 28 | ||||
| -rw-r--r-- | src/game/shared/entity/grounded.hh (renamed from game/shared/entity/grounded.hh) | 24 | ||||
| -rw-r--r-- | src/game/shared/entity/head.hh (renamed from game/shared/entity/head.hh) | 32 | ||||
| -rw-r--r-- | src/game/shared/entity/player.hh (renamed from game/shared/entity/player.hh) | 12 | ||||
| -rw-r--r-- | src/game/shared/entity/stasis.cc (renamed from game/shared/entity/stasis.cc) | 42 | ||||
| -rw-r--r-- | src/game/shared/entity/stasis.hh (renamed from game/shared/entity/stasis.hh) | 32 | ||||
| -rw-r--r-- | src/game/shared/entity/transform.cc (renamed from game/shared/entity/transform.cc) | 66 | ||||
| -rw-r--r-- | src/game/shared/entity/transform.hh (renamed from game/shared/entity/transform.hh) | 60 | ||||
| -rw-r--r-- | src/game/shared/entity/velocity.cc (renamed from game/shared/entity/velocity.cc) | 38 | ||||
| -rw-r--r-- | src/game/shared/entity/velocity.hh (renamed from game/shared/entity/velocity.hh) | 38 | ||||
| -rw-r--r-- | src/game/shared/game.cc (renamed from game/shared/game.cc) | 251 | ||||
| -rw-r--r-- | src/game/shared/game.hh (renamed from game/shared/game.hh) | 14 | ||||
| -rw-r--r-- | src/game/shared/game_items.cc (renamed from game/shared/game_items.cc) | 130 | ||||
| -rw-r--r-- | src/game/shared/game_items.hh (renamed from game/shared/game_items.hh) | 48 | ||||
| -rw-r--r-- | src/game/shared/game_voxels.cc (renamed from game/shared/game_voxels.cc) | 304 | ||||
| -rw-r--r-- | src/game/shared/game_voxels.hh (renamed from game/shared/game_voxels.hh) | 52 | ||||
| -rw-r--r-- | src/game/shared/globals.cc (renamed from game/shared/globals.cc) | 24 | ||||
| -rw-r--r-- | src/game/shared/globals.hh (renamed from game/shared/globals.hh) | 38 | ||||
| -rw-r--r-- | src/game/shared/pch.hh (renamed from game/shared/pch.hh) | 38 | ||||
| -rw-r--r-- | src/game/shared/protocol.cc (renamed from game/shared/protocol.cc) | 1036 | ||||
| -rw-r--r-- | src/game/shared/protocol.hh (renamed from game/shared/protocol.hh) | 430 | ||||
| -rw-r--r-- | src/game/shared/splash.cc (renamed from game/shared/splash.cc) | 134 | ||||
| -rw-r--r-- | src/game/shared/splash.hh (renamed from game/shared/splash.hh) | 16 | ||||
| -rw-r--r-- | src/game/shared/types.hh (renamed from game/shared/types.hh) | 80 | ||||
| -rw-r--r-- | src/game/shared/world/CMakeLists.txt (renamed from game/shared/world/CMakeLists.txt) | 0 | ||||
| -rw-r--r-- | src/game/shared/world/chunk.cc (renamed from game/shared/world/chunk.cc) | 144 | ||||
| -rw-r--r-- | src/game/shared/world/chunk.hh (renamed from game/shared/world/chunk.hh) | 86 | ||||
| -rw-r--r-- | src/game/shared/world/chunk_aabb.hh (renamed from game/shared/world/chunk_aabb.hh) | 20 | ||||
| -rw-r--r-- | src/game/shared/world/dimension.cc (renamed from game/shared/world/dimension.cc) | 374 | ||||
| -rw-r--r-- | src/game/shared/world/dimension.hh (renamed from game/shared/world/dimension.hh) | 202 | ||||
| -rw-r--r-- | src/game/shared/world/feature.cc (renamed from game/shared/world/feature.cc) | 150 | ||||
| -rw-r--r-- | src/game/shared/world/feature.hh (renamed from game/shared/world/feature.hh) | 50 | ||||
| -rw-r--r-- | src/game/shared/world/item.cc (renamed from game/shared/world/item.cc) | 0 | ||||
| -rw-r--r-- | src/game/shared/world/item.hh (renamed from game/shared/world/item.hh) | 0 | ||||
| -rw-r--r-- | src/game/shared/world/item_registry.cc (renamed from game/shared/world/item_registry.cc) | 136 | ||||
| -rw-r--r-- | src/game/shared/world/item_registry.hh (renamed from game/shared/world/item_registry.hh) | 52 | ||||
| -rw-r--r-- | src/game/shared/world/ray_dda.cc (renamed from game/shared/world/ray_dda.cc) | 214 | ||||
| -rw-r--r-- | src/game/shared/world/ray_dda.hh (renamed from game/shared/world/ray_dda.hh) | 76 | ||||
| -rw-r--r-- | src/game/shared/world/voxel.cc (renamed from game/shared/world/voxel.cc) | 0 | ||||
| -rw-r--r-- | src/game/shared/world/voxel.hh (renamed from game/shared/world/voxel.hh) | 0 | ||||
| -rw-r--r-- | src/game/shared/world/voxel_registry.cc (renamed from game/shared/world/voxel_registry.cc) | 128 | ||||
| -rw-r--r-- | src/game/shared/world/voxel_registry.hh (renamed from game/shared/world/voxel_registry.hh) | 52 | ||||
| -rw-r--r-- | src/game/shared/world/voxel_storage.cc (renamed from game/shared/world/voxel_storage.cc) | 96 | ||||
| -rw-r--r-- | src/game/shared/world/voxel_storage.hh (renamed from game/shared/world/voxel_storage.hh) | 40 | ||||
| -rwxr-xr-x | tools/build-unix.sh | 5 | ||||
| -rw-r--r-- | tools/build-win32.sh | 5 | ||||
| -rw-r--r-- | tools/build-win64.sh | 5 | ||||
| -rw-r--r-- | tools/pack-unix.sh | 5 | ||||
| -rw-r--r-- | tools/pack-win32.sh | 5 | ||||
| -rw-r--r-- | tools/pack-win64.sh | 5 |
1097 files changed, 17438 insertions, 17308 deletions
diff --git a/.clang-format b/.clang-format index bcb9014..8051ec6 100644 --- a/.clang-format +++ b/.clang-format @@ -32,8 +32,8 @@ AlignConsecutiveMacros: AlignEscapedNewlines: Left AlignOperands: false PenaltyBreakAssignment: 50 -PenaltyBreakBeforeFirstCallParameter: 21 -PenaltyBreakOpenParenthesis: 21 +PenaltyBreakBeforeFirstCallParameter: 90 +PenaltyBreakOpenParenthesis: 90 PenaltyIndentedWhitespace: 1 AlignTrailingComments: Kind: Always diff --git a/.gitattributes b/.gitattributes index 7123ceb..2fc9e29 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ -/core/version.cc.in linguist-language=C
-/deps/* linguist-vendored
+/src/core/version.cc.in linguist-language=C
+/external/* linguist-vendored
@@ -1,10 +1,14 @@ +/.vs/*
/.vscode/*
!/.vscode/c_cpp_properties.json
-/core/version.cc
/build/
+/dist/
+/out/
/*.log
/*.ini
/*.dll
/*.exe
/*.lib
/*.so
+/CMakePresets.json
+/CMakeUserPresets.json
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index d50221c..0abd9f9 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -17,23 +17,23 @@ "${workspaceFolder}/build/unix/**/_deps/glfw-src/include",
"${workspaceFolder}/build/win32/_deps/glfw-src/include",
"${workspaceFolder}/build/win64/_deps/glfw-src/include",
- "${workspaceFolder}/deps/dr_libs/include",
- "${workspaceFolder}/deps/emhash/include",
- "${workspaceFolder}/deps/enet/include",
- "${workspaceFolder}/deps/entt/include",
- "${workspaceFolder}/deps/fastnoiselite/include",
- "${workspaceFolder}/deps/glad/include",
- "${workspaceFolder}/deps/glm/include",
- "${workspaceFolder}/deps/imgui/include",
- "${workspaceFolder}/deps/miniz/include",
- "${workspaceFolder}/deps/parson/include",
- "${workspaceFolder}/deps/physfs/include",
- "${workspaceFolder}/deps/salad/include",
- "${workspaceFolder}/deps/spdlog/include",
- "${workspaceFolder}/deps/stb/include",
- "${workspaceFolder}/deps/thread_pool/include",
- "${workspaceFolder}/game/",
- "${workspaceFolder}",
+ "${workspaceFolder}/external/dr_libs/include",
+ "${workspaceFolder}/external/emhash/include",
+ "${workspaceFolder}/external/enet/include",
+ "${workspaceFolder}/external/entt/include",
+ "${workspaceFolder}/external/fastnoiselite/include",
+ "${workspaceFolder}/external/glad/include",
+ "${workspaceFolder}/external/glm/include",
+ "${workspaceFolder}/external/imgui/include",
+ "${workspaceFolder}/external/miniz/include",
+ "${workspaceFolder}/external/parson/include",
+ "${workspaceFolder}/external/physfs/include",
+ "${workspaceFolder}/external/salad/include",
+ "${workspaceFolder}/external/spdlog/include",
+ "${workspaceFolder}/external/stb/include",
+ "${workspaceFolder}/external/thread_pool/include",
+ "${workspaceFolder}/src/game/",
+ "${workspaceFolder}/src",
"${default}"
]
}
diff --git a/CMakeLists.txt b/CMakeLists.txt index ba2db83..81d15f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,51 +1,53 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
project(Voxelius LANGUAGES C CXX VERSION 16.0.1)
-## Declare build options
option(BUILD_VCLIENT "Build Voxelius client" ON)
option(BUILD_VSERVER "Build Voxelius server" ON)
-## If possible, enable solution directories; this allows
-## built-in pseudotargets like ALL_BUILD and ZERO_CHECK to
-## be moved out of sight into a separate directory
-set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+if(NOT BUILD_VCLIENT AND NOT BUILD_VSERVER)
+ message(FATAL_ERROR "Neither client or server is enabled; nothing to build")
+endif()
-## Ensure we are never building dependencies as dynamic
-## libraries; we only use dynamic libraries for non-compiled
-## third-party dependencies (such as SDL3 and maybe Discord-RPC);
-set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
-## Microsoft-vendored STL has been permissively licensed for quite
-## a while, so it makes all the sense to statically link with it to
-## avoid pulling redistributable installers alongside the game package
+set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-
-## Output binaries into build root
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-## Set C++ standard to C++20
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
+if(MSVC)
+ add_compile_options(/MP)
+ add_compile_options(/W3)
+endif()
+
+execute_process(COMMAND git rev-parse --short=8 HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+execute_process(COMMAND git rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
-add_subdirectory(core)
-add_subdirectory(deps)
-add_subdirectory(game)
+add_subdirectory(assets)
+add_subdirectory(external)
+add_subdirectory(src)
-install(FILES "${CMAKE_CURRENT_LIST_DIR}/LICENSE" DESTINATION ".")
-install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/data" DESTINATION ".")
+install(FILES "${PROJECT_SOURCE_DIR}/LICENSE.txt" DESTINATION "doc/voxelius")
set(CPACK_PACKAGE_NAME "Voxelius")
set(CPACK_PACKAGE_VENDOR "untodesu")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Block game on steroids")
-set(CPACK_PACKAGE_CONTACT "https://github.com/untodesu/voxelius/issues")
+set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt")
+set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}-${GIT_BRANCH}-${GIT_COMMIT}")
+set(CPACK_PACKAGE_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/packages")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
-set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
-set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
-set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
-set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
-set(CPACK_PACKAGE_VERSION_TWEAK ${PROJECT_VERSION_TWEAK})
+set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
+set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}\\\\media\\\\nsis-installer.ico")
+set(CPACK_NSIS_MUI_HEADERIMAGE "${PROJECT_SOURCE_DIR}\\\\media\\\\nsis-header.bmp")
+set(CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP "${PROJECT_SOURCE_DIR}\\\\media\\\\nsis-splash.bmp")
+unset(CPACK_NSIS_MENU_LINKS)
-set(CPACK_PACKAGE_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
+if(BUILD_CLIENT)
+ list(APPEND CPACK_NSIS_MENU_LINKS "bin/vclient.exe" "Voxelius Client")
+endif()
+
+if(BUILD_SERVER)
+ list(APPEND CPACK_NSIS_MENU_LINKS "bin/vserver.exe" "Voxelius Server")
+endif()
include(CPack)
diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000..d90280c --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,36 @@ +{ + "configurations": [ + { + "name": "win32-debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x86_x86" ], + "buildRoot": "${projectDir}/build/vs2022-${name}", + "installRoot": "${projectDir}/build/out-vs2022-${name}" + }, + { + "name": "win32-release", + "generator": "Ninja", + "configurationType": "Release", + "inheritEnvironments": [ "msvc_x86_x86" ], + "buildRoot": "${projectDir}/build/vs2022-${name}", + "installRoot": "${projectDir}/build/out-vs2022-${name}" + }, + { + "name": "win64-debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}/build/vs2022-${name}", + "installRoot": "${projectDir}/build/out-vs2022-${name}" + }, + { + "name": "win64-release", + "generator": "Ninja", + "configurationType": "Release", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}/build/vs2022-${name}", + "installRoot": "${projectDir}/build/out-vs2022-${name}" + } + ] +} @@ -1,22 +1,22 @@ -Copyright (c) 2021-2025, Kirill Dmitrievich <https://github.com/untodesu>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2021-2025, Kirill Dmitrievich <https://github.com/untodesu> + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt new file mode 100644 index 0000000..a851c4c --- /dev/null +++ b/assets/CMakeLists.txt @@ -0,0 +1,6 @@ +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/fonts" DESTINATION "assets") +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/lang" DESTINATION "assets") +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/misc" DESTINATION "assets") +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/shaders" DESTINATION "assets") +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/sounds" DESTINATION "assets") +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/textures" DESTINATION "assets") diff --git a/data/fonts/unscii-16.ttf b/assets/fonts/unscii-16.ttf Binary files differindex 6d3c740..6d3c740 100644 --- a/data/fonts/unscii-16.ttf +++ b/assets/fonts/unscii-16.ttf diff --git a/data/fonts/unscii-8.ttf b/assets/fonts/unscii-8.ttf Binary files differindex 7fe801e..7fe801e 100644 --- a/data/fonts/unscii-8.ttf +++ b/assets/fonts/unscii-8.ttf diff --git a/data/lang/lang.en_US.json b/assets/lang/lang.en_US.json index c80061b..c80061b 100644 --- a/data/lang/lang.en_US.json +++ b/assets/lang/lang.en_US.json diff --git a/data/lang/manifest.json b/assets/lang/manifest.json index 4f19b1f..4f19b1f 100644 --- a/data/lang/manifest.json +++ b/assets/lang/manifest.json diff --git a/data/misc/gamecontrollerdb.txt b/assets/misc/gamecontrollerdb.txt index 4cd9e5a..4cd9e5a 100644 --- a/data/misc/gamecontrollerdb.txt +++ b/assets/misc/gamecontrollerdb.txt diff --git a/data/misc/splashes_client.txt b/assets/misc/splashes_client.txt index 581c47f..581c47f 100644 --- a/data/misc/splashes_client.txt +++ b/assets/misc/splashes_client.txt diff --git a/data/misc/splashes_server.txt b/assets/misc/splashes_server.txt index fab2330..fab2330 100644 --- a/data/misc/splashes_server.txt +++ b/assets/misc/splashes_server.txt diff --git a/data/shaders/chunk_quad.frag b/assets/shaders/chunk_quad.frag index 5a08099..5a08099 100644 --- a/data/shaders/chunk_quad.frag +++ b/assets/shaders/chunk_quad.frag diff --git a/data/shaders/chunk_quad.vert b/assets/shaders/chunk_quad.vert index 50b343a..50b343a 100644 --- a/data/shaders/chunk_quad.vert +++ b/assets/shaders/chunk_quad.vert diff --git a/data/shaders/outline.frag b/assets/shaders/outline.frag index d8cae02..d8cae02 100644 --- a/data/shaders/outline.frag +++ b/assets/shaders/outline.frag diff --git a/data/shaders/outline.vert b/assets/shaders/outline.vert index 07626af..07626af 100644 --- a/data/shaders/outline.vert +++ b/assets/shaders/outline.vert diff --git a/data/sounds/surface/default1.wav b/assets/sounds/surface/default1.wav Binary files differindex 0100f24..0100f24 100644 --- a/data/sounds/surface/default1.wav +++ b/assets/sounds/surface/default1.wav diff --git a/data/sounds/surface/default2.wav b/assets/sounds/surface/default2.wav Binary files differindex 42a1377..42a1377 100644 --- a/data/sounds/surface/default2.wav +++ b/assets/sounds/surface/default2.wav diff --git a/data/sounds/surface/default3.wav b/assets/sounds/surface/default3.wav Binary files differindex 70910ab..70910ab 100644 --- a/data/sounds/surface/default3.wav +++ b/assets/sounds/surface/default3.wav diff --git a/data/sounds/surface/default4.wav b/assets/sounds/surface/default4.wav Binary files differindex b8f66fe..b8f66fe 100644 --- a/data/sounds/surface/default4.wav +++ b/assets/sounds/surface/default4.wav diff --git a/data/sounds/surface/dirt1.wav b/assets/sounds/surface/dirt1.wav Binary files differindex fe88d5f..fe88d5f 100644 --- a/data/sounds/surface/dirt1.wav +++ b/assets/sounds/surface/dirt1.wav diff --git a/data/sounds/surface/grass1.wav b/assets/sounds/surface/grass1.wav Binary files differindex 56630d7..56630d7 100644 --- a/data/sounds/surface/grass1.wav +++ b/assets/sounds/surface/grass1.wav diff --git a/data/sounds/surface/grass2.wav b/assets/sounds/surface/grass2.wav Binary files differindex 2a55b9c..2a55b9c 100644 --- a/data/sounds/surface/grass2.wav +++ b/assets/sounds/surface/grass2.wav diff --git a/data/sounds/surface/grass3.wav b/assets/sounds/surface/grass3.wav Binary files differindex 5198d77..5198d77 100644 --- a/data/sounds/surface/grass3.wav +++ b/assets/sounds/surface/grass3.wav diff --git a/data/sounds/surface/gravel1.wav b/assets/sounds/surface/gravel1.wav Binary files differindex de43266..de43266 100644 --- a/data/sounds/surface/gravel1.wav +++ b/assets/sounds/surface/gravel1.wav diff --git a/data/sounds/surface/sand1.wav b/assets/sounds/surface/sand1.wav Binary files differindex 6e3ea71..6e3ea71 100644 --- a/data/sounds/surface/sand1.wav +++ b/assets/sounds/surface/sand1.wav diff --git a/data/sounds/surface/sand2.wav b/assets/sounds/surface/sand2.wav Binary files differindex 88e9fae..88e9fae 100644 --- a/data/sounds/surface/sand2.wav +++ b/assets/sounds/surface/sand2.wav diff --git a/data/sounds/surface/wood1.wav b/assets/sounds/surface/wood1.wav Binary files differindex 89f9035..89f9035 100644 --- a/data/sounds/surface/wood1.wav +++ b/assets/sounds/surface/wood1.wav diff --git a/data/sounds/surface/wood2.wav b/assets/sounds/surface/wood2.wav Binary files differindex f892165..f892165 100644 --- a/data/sounds/surface/wood2.wav +++ b/assets/sounds/surface/wood2.wav diff --git a/data/sounds/surface/wood3.wav b/assets/sounds/surface/wood3.wav Binary files differindex a565b1a..a565b1a 100644 --- a/data/sounds/surface/wood3.wav +++ b/assets/sounds/surface/wood3.wav diff --git a/data/sounds/ui/chat_message.wav b/assets/sounds/ui/chat_message.wav Binary files differindex e3fa3c9..e3fa3c9 100644 --- a/data/sounds/ui/chat_message.wav +++ b/assets/sounds/ui/chat_message.wav diff --git a/data/textures/gui/background.png b/assets/textures/gui/background.png Binary files differindex 1aba254..1aba254 100644 --- a/data/textures/gui/background.png +++ b/assets/textures/gui/background.png diff --git a/data/textures/gui/client_splash.png b/assets/textures/gui/client_splash.png Binary files differindex 86effc9..86effc9 100644 --- a/data/textures/gui/client_splash.png +++ b/assets/textures/gui/client_splash.png diff --git a/data/textures/gui/hud_crosshair.png b/assets/textures/gui/hud_crosshair.png Binary files differindex db8a122..db8a122 100644 --- a/data/textures/gui/hud_crosshair.png +++ b/assets/textures/gui/hud_crosshair.png diff --git a/data/textures/gui/hud_hotbar.png b/assets/textures/gui/hud_hotbar.png Binary files differindex 4cc59ac..4cc59ac 100644 --- a/data/textures/gui/hud_hotbar.png +++ b/assets/textures/gui/hud_hotbar.png diff --git a/data/textures/gui/hud_selector.png b/assets/textures/gui/hud_selector.png Binary files differindex 00a0cbb..00a0cbb 100644 --- a/data/textures/gui/hud_selector.png +++ b/assets/textures/gui/hud_selector.png diff --git a/data/textures/gui/menu_title.png b/assets/textures/gui/menu_title.png Binary files differindex 401ee76..401ee76 100644 --- a/data/textures/gui/menu_title.png +++ b/assets/textures/gui/menu_title.png diff --git a/data/textures/gui/window_icon.png b/assets/textures/gui/window_icon.png Binary files differindex d0bfff6..d0bfff6 100644 --- a/data/textures/gui/window_icon.png +++ b/assets/textures/gui/window_icon.png diff --git a/data/textures/item/cobblestone.png b/assets/textures/item/cobblestone.png Binary files differindex 62573f4..62573f4 100644 --- a/data/textures/item/cobblestone.png +++ b/assets/textures/item/cobblestone.png diff --git a/data/textures/item/dirt.png b/assets/textures/item/dirt.png Binary files differindex 4c6cd40..4c6cd40 100644 --- a/data/textures/item/dirt.png +++ b/assets/textures/item/dirt.png diff --git a/data/textures/item/glass.png b/assets/textures/item/glass.png Binary files differindex 04d2334..04d2334 100644 --- a/data/textures/item/glass.png +++ b/assets/textures/item/glass.png diff --git a/data/textures/item/grass.png b/assets/textures/item/grass.png Binary files differindex 57709c7..57709c7 100644 --- a/data/textures/item/grass.png +++ b/assets/textures/item/grass.png diff --git a/data/textures/item/oak_leaves.png b/assets/textures/item/oak_leaves.png Binary files differindex a8f05c5..a8f05c5 100644 --- a/data/textures/item/oak_leaves.png +++ b/assets/textures/item/oak_leaves.png diff --git a/data/textures/item/oak_log.png b/assets/textures/item/oak_log.png Binary files differindex 36dd53d..36dd53d 100644 --- a/data/textures/item/oak_log.png +++ b/assets/textures/item/oak_log.png diff --git a/data/textures/item/oak_planks.png b/assets/textures/item/oak_planks.png Binary files differindex b8e1e75..b8e1e75 100644 --- a/data/textures/item/oak_planks.png +++ b/assets/textures/item/oak_planks.png diff --git a/data/textures/item/slime.png b/assets/textures/item/slime.png Binary files differindex 084af74..084af74 100644 --- a/data/textures/item/slime.png +++ b/assets/textures/item/slime.png diff --git a/data/textures/item/stone.png b/assets/textures/item/stone.png Binary files differindex bb0d932..bb0d932 100644 --- a/data/textures/item/stone.png +++ b/assets/textures/item/stone.png diff --git a/data/textures/item/template.png b/assets/textures/item/template.png Binary files differindex 111f7ce..111f7ce 100644 --- a/data/textures/item/template.png +++ b/assets/textures/item/template.png diff --git a/data/textures/voxel/chromakey.png b/assets/textures/voxel/chromakey.png Binary files differindex 7570d6c..7570d6c 100644 --- a/data/textures/voxel/chromakey.png +++ b/assets/textures/voxel/chromakey.png diff --git a/data/textures/voxel/cobblestone_01.png b/assets/textures/voxel/cobblestone_01.png Binary files differindex e465abb..e465abb 100644 --- a/data/textures/voxel/cobblestone_01.png +++ b/assets/textures/voxel/cobblestone_01.png diff --git a/data/textures/voxel/cobblestone_02.png b/assets/textures/voxel/cobblestone_02.png Binary files differindex cb0de08..cb0de08 100644 --- a/data/textures/voxel/cobblestone_02.png +++ b/assets/textures/voxel/cobblestone_02.png diff --git a/data/textures/voxel/dirt_01.png b/assets/textures/voxel/dirt_01.png Binary files differindex 695d337..695d337 100644 --- a/data/textures/voxel/dirt_01.png +++ b/assets/textures/voxel/dirt_01.png diff --git a/data/textures/voxel/dirt_02.png b/assets/textures/voxel/dirt_02.png Binary files differindex 7cd6c6b..7cd6c6b 100644 --- a/data/textures/voxel/dirt_02.png +++ b/assets/textures/voxel/dirt_02.png diff --git a/data/textures/voxel/dirt_03.png b/assets/textures/voxel/dirt_03.png Binary files differindex f830ffa..f830ffa 100644 --- a/data/textures/voxel/dirt_03.png +++ b/assets/textures/voxel/dirt_03.png diff --git a/data/textures/voxel/dirt_04.png b/assets/textures/voxel/dirt_04.png Binary files differindex 00314df..00314df 100644 --- a/data/textures/voxel/dirt_04.png +++ b/assets/textures/voxel/dirt_04.png diff --git a/data/textures/voxel/glass_01.png b/assets/textures/voxel/glass_01.png Binary files differindex 428c7d5..428c7d5 100644 --- a/data/textures/voxel/glass_01.png +++ b/assets/textures/voxel/glass_01.png diff --git a/data/textures/voxel/grass_01.png b/assets/textures/voxel/grass_01.png Binary files differindex b08b597..b08b597 100644 --- a/data/textures/voxel/grass_01.png +++ b/assets/textures/voxel/grass_01.png diff --git a/data/textures/voxel/grass_02.png b/assets/textures/voxel/grass_02.png Binary files differindex a492947..a492947 100644 --- a/data/textures/voxel/grass_02.png +++ b/assets/textures/voxel/grass_02.png diff --git a/data/textures/voxel/grass_side_01.png b/assets/textures/voxel/grass_side_01.png Binary files differindex 0d6fe64..0d6fe64 100644 --- a/data/textures/voxel/grass_side_01.png +++ b/assets/textures/voxel/grass_side_01.png diff --git a/data/textures/voxel/grass_side_02.png b/assets/textures/voxel/grass_side_02.png Binary files differindex 68e3bed..68e3bed 100644 --- a/data/textures/voxel/grass_side_02.png +++ b/assets/textures/voxel/grass_side_02.png diff --git a/data/textures/voxel/mud_01.png b/assets/textures/voxel/mud_01.png Binary files differindex daf4af2..daf4af2 100644 --- a/data/textures/voxel/mud_01.png +++ b/assets/textures/voxel/mud_01.png diff --git a/data/textures/voxel/mud_02.png b/assets/textures/voxel/mud_02.png Binary files differindex 2350b7e..2350b7e 100644 --- a/data/textures/voxel/mud_02.png +++ b/assets/textures/voxel/mud_02.png diff --git a/data/textures/voxel/oak_leaves.png b/assets/textures/voxel/oak_leaves.png Binary files differindex 80faf7e..80faf7e 100644 --- a/data/textures/voxel/oak_leaves.png +++ b/assets/textures/voxel/oak_leaves.png diff --git a/data/textures/voxel/oak_planks_01.png b/assets/textures/voxel/oak_planks_01.png Binary files differindex 837c659..837c659 100644 --- a/data/textures/voxel/oak_planks_01.png +++ b/assets/textures/voxel/oak_planks_01.png diff --git a/data/textures/voxel/oak_planks_02.png b/assets/textures/voxel/oak_planks_02.png Binary files differindex 9d183b7..9d183b7 100644 --- a/data/textures/voxel/oak_planks_02.png +++ b/assets/textures/voxel/oak_planks_02.png diff --git a/data/textures/voxel/oak_wood_01.png b/assets/textures/voxel/oak_wood_01.png Binary files differindex 24f53f8..24f53f8 100644 --- a/data/textures/voxel/oak_wood_01.png +++ b/assets/textures/voxel/oak_wood_01.png diff --git a/data/textures/voxel/oak_wood_02.png b/assets/textures/voxel/oak_wood_02.png Binary files differindex 9b67717..9b67717 100644 --- a/data/textures/voxel/oak_wood_02.png +++ b/assets/textures/voxel/oak_wood_02.png diff --git a/data/textures/voxel/oak_wood_top.png b/assets/textures/voxel/oak_wood_top.png Binary files differindex 9e92612..9e92612 100644 --- a/data/textures/voxel/oak_wood_top.png +++ b/assets/textures/voxel/oak_wood_top.png diff --git a/data/textures/voxel/slate_01.png b/assets/textures/voxel/slate_01.png Binary files differindex fb3697b..fb3697b 100644 --- a/data/textures/voxel/slate_01.png +++ b/assets/textures/voxel/slate_01.png diff --git a/data/textures/voxel/slate_02.png b/assets/textures/voxel/slate_02.png Binary files differindex 7244253..7244253 100644 --- a/data/textures/voxel/slate_02.png +++ b/assets/textures/voxel/slate_02.png diff --git a/data/textures/voxel/slime_01.png b/assets/textures/voxel/slime_01.png Binary files differindex 3560c94..3560c94 100644 --- a/data/textures/voxel/slime_01.png +++ b/assets/textures/voxel/slime_01.png diff --git a/data/textures/voxel/stone_01.png b/assets/textures/voxel/stone_01.png Binary files differindex 67878d7..67878d7 100644 --- a/data/textures/voxel/stone_01.png +++ b/assets/textures/voxel/stone_01.png diff --git a/data/textures/voxel/stone_02.png b/assets/textures/voxel/stone_02.png Binary files differindex f40a98d..f40a98d 100644 --- a/data/textures/voxel/stone_02.png +++ b/assets/textures/voxel/stone_02.png diff --git a/data/textures/voxel/stone_03.png b/assets/textures/voxel/stone_03.png Binary files differindex d8c795b..d8c795b 100644 --- a/data/textures/voxel/stone_03.png +++ b/assets/textures/voxel/stone_03.png diff --git a/data/textures/voxel/stone_04.png b/assets/textures/voxel/stone_04.png Binary files differindex 72aed34..72aed34 100644 --- a/data/textures/voxel/stone_04.png +++ b/assets/textures/voxel/stone_04.png diff --git a/data/textures/voxel/vtest_F1.png b/assets/textures/voxel/vtest_F1.png Binary files differindex 1fcffff..1fcffff 100644 --- a/data/textures/voxel/vtest_F1.png +++ b/assets/textures/voxel/vtest_F1.png diff --git a/data/textures/voxel/vtest_F2.png b/assets/textures/voxel/vtest_F2.png Binary files differindex 5a8de72..5a8de72 100644 --- a/data/textures/voxel/vtest_F2.png +++ b/assets/textures/voxel/vtest_F2.png diff --git a/data/textures/voxel/vtest_F3.png b/assets/textures/voxel/vtest_F3.png Binary files differindex ef1dc61..ef1dc61 100644 --- a/data/textures/voxel/vtest_F3.png +++ b/assets/textures/voxel/vtest_F3.png diff --git a/data/textures/voxel/vtest_F4.png b/assets/textures/voxel/vtest_F4.png Binary files differindex 299141e..299141e 100644 --- a/data/textures/voxel/vtest_F4.png +++ b/assets/textures/voxel/vtest_F4.png diff --git a/core/version.cc.in b/core/version.cc.in deleted file mode 100644 index a4689d7..0000000 --- a/core/version.cc.in +++ /dev/null @@ -1,12 +0,0 @@ -#include "core/pch.hh" - -#include "core/version.hh" - -// clang-format off -const unsigned long version::major = ${PROJECT_VERSION_MAJOR}; -const unsigned long version::minor = ${PROJECT_VERSION_MINOR}; -const unsigned long version::patch = ${PROJECT_VERSION_PATCH}; -// clang-format on - -const std::string_view version::commit = "${GIT_COMMIT_HASH}"; -const std::string_view version::semver = "${PROJECT_VERSION}"; diff --git a/core/version.hh b/core/version.hh deleted file mode 100644 index 50f128a..0000000 --- a/core/version.hh +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once
-
-namespace version
-{
-extern const unsigned long major;
-extern const unsigned long minor;
-extern const unsigned long patch;
-} // namespace version
-
-namespace version
-{
-extern const std::string_view commit;
-extern const std::string_view semver;
-} // namespace version
diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt deleted file mode 100644 index 7d94219..0000000 --- a/deps/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -add_subdirectory(dr_libs)
-add_subdirectory(emhash)
-add_subdirectory(enet)
-add_subdirectory(entt)
-add_subdirectory(fastnoiselite)
-add_subdirectory(glad)
-add_subdirectory(glfw)
-add_subdirectory(glm)
-add_subdirectory(imgui)
-add_subdirectory(miniz)
-add_subdirectory(parson)
-add_subdirectory(physfs)
-add_subdirectory(salad)
-add_subdirectory(spdlog)
-add_subdirectory(stb)
-add_subdirectory(thread_pool)
-
-find_package(Python3 REQUIRED COMPONENTS Interpreter)
-add_custom_target(thirdparty_txt ALL
- COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/thirdparty.py" "${CMAKE_CURRENT_LIST_DIR}"
- BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/thirdparty.txt"
- DEPENDS "${CMAKE_CURRENT_LIST_DIR}/thirdparty.py"
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/thirdparty.txt" DESTINATION ".")
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 0000000..b84c1ba --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,27 @@ +add_subdirectory(dr_libs) +add_subdirectory(emhash) +add_subdirectory(enet) +add_subdirectory(entt) +add_subdirectory(fastnoiselite) +add_subdirectory(glad) +add_subdirectory(glfw) +add_subdirectory(glm) +add_subdirectory(imgui) +add_subdirectory(miniz) +add_subdirectory(parson) +add_subdirectory(physfs) +add_subdirectory(salad) +add_subdirectory(spdlog) +add_subdirectory(stb) +add_subdirectory(thread_pool) + +# Generate thirdparty.txt; I find it annoying to manually aggregate +# all the third-party libraries licenses from all over the place so +# this convenient script is going to do that for me automatically +find_package(Python3 COMPONENTS Interpreter REQUIRED) +add_custom_target(thirdparty_txt ALL + COMMAND ${Python3_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/generate-thirdparty.py" "${PROJECT_SOURCE_DIR}/external" + BYPRODUCTS "${PROJECT_BINARY_DIR}/thirdparty.txt" + DEPENDS "${PROJECT_SOURCE_DIR}/scripts/generate-thirdparty.py" + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}") +install(FILES "${PROJECT_BINARY_DIR}/thirdparty.txt" DESTINATION "doc/voxelius") diff --git a/deps/dr_libs/CMakeLists.txt b/external/dr_libs/CMakeLists.txt index 7162cbb..7162cbb 100644 --- a/deps/dr_libs/CMakeLists.txt +++ b/external/dr_libs/CMakeLists.txt diff --git a/deps/dr_libs/DESCRIPTION b/external/dr_libs/DESCRIPTION index 16a8d4f..16a8d4f 100644 --- a/deps/dr_libs/DESCRIPTION +++ b/external/dr_libs/DESCRIPTION diff --git a/deps/dr_libs/LICENSE b/external/dr_libs/LICENSE index 0db8ff1..0db8ff1 100644 --- a/deps/dr_libs/LICENSE +++ b/external/dr_libs/LICENSE diff --git a/deps/dr_libs/include/dr_flac.h b/external/dr_libs/include/dr_flac.h index 4f0f6c9..4f0f6c9 100644 --- a/deps/dr_libs/include/dr_flac.h +++ b/external/dr_libs/include/dr_flac.h diff --git a/deps/dr_libs/include/dr_mp3.h b/external/dr_libs/include/dr_mp3.h index aee3cef..aee3cef 100644 --- a/deps/dr_libs/include/dr_mp3.h +++ b/external/dr_libs/include/dr_mp3.h diff --git a/deps/dr_libs/include/dr_wav.h b/external/dr_libs/include/dr_wav.h index f9f69a7..f9f69a7 100644 --- a/deps/dr_libs/include/dr_wav.h +++ b/external/dr_libs/include/dr_wav.h diff --git a/deps/dr_libs/src/dr_impl.c b/external/dr_libs/src/dr_impl.c index e73b028..e73b028 100644 --- a/deps/dr_libs/src/dr_impl.c +++ b/external/dr_libs/src/dr_impl.c diff --git a/deps/emhash/CMakeLists.txt b/external/emhash/CMakeLists.txt index c6647fa..c6647fa 100644 --- a/deps/emhash/CMakeLists.txt +++ b/external/emhash/CMakeLists.txt diff --git a/deps/emhash/DESCRIPTION b/external/emhash/DESCRIPTION index ace9662..ace9662 100644 --- a/deps/emhash/DESCRIPTION +++ b/external/emhash/DESCRIPTION diff --git a/deps/emhash/LICENSE b/external/emhash/LICENSE index 4abcb49..4abcb49 100644 --- a/deps/emhash/LICENSE +++ b/external/emhash/LICENSE diff --git a/deps/emhash/include/emhash/hash_set8.hpp b/external/emhash/include/emhash/hash_set8.hpp index 3b6454e..3b6454e 100644 --- a/deps/emhash/include/emhash/hash_set8.hpp +++ b/external/emhash/include/emhash/hash_set8.hpp diff --git a/deps/emhash/include/emhash/hash_table8.hpp b/external/emhash/include/emhash/hash_table8.hpp index b14d64b..b14d64b 100644 --- a/deps/emhash/include/emhash/hash_table8.hpp +++ b/external/emhash/include/emhash/hash_table8.hpp diff --git a/deps/enet/CMakeLists.txt b/external/enet/CMakeLists.txt index e997858..e997858 100644 --- a/deps/enet/CMakeLists.txt +++ b/external/enet/CMakeLists.txt diff --git a/deps/enet/DESCRIPTION b/external/enet/DESCRIPTION index 65266bb..65266bb 100644 --- a/deps/enet/DESCRIPTION +++ b/external/enet/DESCRIPTION diff --git a/deps/enet/LICENSE b/external/enet/LICENSE index 4647733..4647733 100644 --- a/deps/enet/LICENSE +++ b/external/enet/LICENSE diff --git a/deps/enet/include/enet/callbacks.h b/external/enet/include/enet/callbacks.h index 78a85d3..78a85d3 100644 --- a/deps/enet/include/enet/callbacks.h +++ b/external/enet/include/enet/callbacks.h diff --git a/deps/enet/include/enet/enet.h b/external/enet/include/enet/enet.h index dfa2c70..dfa2c70 100644 --- a/deps/enet/include/enet/enet.h +++ b/external/enet/include/enet/enet.h diff --git a/deps/enet/include/enet/list.h b/external/enet/include/enet/list.h index 076e886..076e886 100644 --- a/deps/enet/include/enet/list.h +++ b/external/enet/include/enet/list.h diff --git a/deps/enet/include/enet/protocol.h b/external/enet/include/enet/protocol.h index f8c73d8..f8c73d8 100644 --- a/deps/enet/include/enet/protocol.h +++ b/external/enet/include/enet/protocol.h diff --git a/deps/enet/include/enet/time.h b/external/enet/include/enet/time.h index c82a546..c82a546 100644 --- a/deps/enet/include/enet/time.h +++ b/external/enet/include/enet/time.h diff --git a/deps/enet/include/enet/types.h b/external/enet/include/enet/types.h index ab010a4..ab010a4 100644 --- a/deps/enet/include/enet/types.h +++ b/external/enet/include/enet/types.h diff --git a/deps/enet/include/enet/unix.h b/external/enet/include/enet/unix.h index b55be33..b55be33 100644 --- a/deps/enet/include/enet/unix.h +++ b/external/enet/include/enet/unix.h diff --git a/deps/enet/include/enet/utility.h b/external/enet/include/enet/utility.h index b04bb7a..b04bb7a 100644 --- a/deps/enet/include/enet/utility.h +++ b/external/enet/include/enet/utility.h diff --git a/deps/enet/include/enet/win32.h b/external/enet/include/enet/win32.h index 1ba5790..1ba5790 100644 --- a/deps/enet/include/enet/win32.h +++ b/external/enet/include/enet/win32.h diff --git a/deps/enet/src/callbacks.c b/external/enet/src/callbacks.c index b3990af..b3990af 100644 --- a/deps/enet/src/callbacks.c +++ b/external/enet/src/callbacks.c diff --git a/deps/enet/src/compress.c b/external/enet/src/compress.c index 784489a..784489a 100644 --- a/deps/enet/src/compress.c +++ b/external/enet/src/compress.c diff --git a/deps/enet/src/host.c b/external/enet/src/host.c index fff946a..fff946a 100644 --- a/deps/enet/src/host.c +++ b/external/enet/src/host.c diff --git a/deps/enet/src/list.c b/external/enet/src/list.c index 1c1a8df..1c1a8df 100644 --- a/deps/enet/src/list.c +++ b/external/enet/src/list.c diff --git a/deps/enet/src/packet.c b/external/enet/src/packet.c index 832cff9..832cff9 100644 --- a/deps/enet/src/packet.c +++ b/external/enet/src/packet.c diff --git a/deps/enet/src/peer.c b/external/enet/src/peer.c index df8f40f..df8f40f 100644 --- a/deps/enet/src/peer.c +++ b/external/enet/src/peer.c diff --git a/deps/enet/src/protocol.c b/external/enet/src/protocol.c index 6f18efa..6f18efa 100644 --- a/deps/enet/src/protocol.c +++ b/external/enet/src/protocol.c diff --git a/deps/enet/src/unix.c b/external/enet/src/unix.c index a66bc33..a66bc33 100644 --- a/deps/enet/src/unix.c +++ b/external/enet/src/unix.c diff --git a/deps/enet/src/win32.c b/external/enet/src/win32.c index 578a322..578a322 100644 --- a/deps/enet/src/win32.c +++ b/external/enet/src/win32.c diff --git a/deps/entt/CMakeLists.txt b/external/entt/CMakeLists.txt index 8e4e5c1..8e4e5c1 100644 --- a/deps/entt/CMakeLists.txt +++ b/external/entt/CMakeLists.txt diff --git a/deps/entt/DESCRIPTION b/external/entt/DESCRIPTION index a3a91eb..a3a91eb 100644 --- a/deps/entt/DESCRIPTION +++ b/external/entt/DESCRIPTION diff --git a/deps/entt/LICENSE b/external/entt/LICENSE index 770161e..770161e 100644 --- a/deps/entt/LICENSE +++ b/external/entt/LICENSE diff --git a/deps/entt/include/entt/config/config.h b/external/entt/include/entt/config/config.h index 80a3305..80a3305 100644 --- a/deps/entt/include/entt/config/config.h +++ b/external/entt/include/entt/config/config.h diff --git a/deps/entt/include/entt/config/macro.h b/external/entt/include/entt/config/macro.h index b7b2323..b7b2323 100644 --- a/deps/entt/include/entt/config/macro.h +++ b/external/entt/include/entt/config/macro.h diff --git a/deps/entt/include/entt/config/version.h b/external/entt/include/entt/config/version.h index 843443f..843443f 100644 --- a/deps/entt/include/entt/config/version.h +++ b/external/entt/include/entt/config/version.h diff --git a/deps/entt/include/entt/container/dense_map.hpp b/external/entt/include/entt/container/dense_map.hpp index 6bf7238..6bf7238 100644 --- a/deps/entt/include/entt/container/dense_map.hpp +++ b/external/entt/include/entt/container/dense_map.hpp diff --git a/deps/entt/include/entt/container/dense_set.hpp b/external/entt/include/entt/container/dense_set.hpp index 1ad5057..1ad5057 100644 --- a/deps/entt/include/entt/container/dense_set.hpp +++ b/external/entt/include/entt/container/dense_set.hpp diff --git a/deps/entt/include/entt/container/fwd.hpp b/external/entt/include/entt/container/fwd.hpp index 4622263..4622263 100644 --- a/deps/entt/include/entt/container/fwd.hpp +++ b/external/entt/include/entt/container/fwd.hpp diff --git a/deps/entt/include/entt/container/table.hpp b/external/entt/include/entt/container/table.hpp index f69e221..f69e221 100644 --- a/deps/entt/include/entt/container/table.hpp +++ b/external/entt/include/entt/container/table.hpp diff --git a/deps/entt/include/entt/core/algorithm.hpp b/external/entt/include/entt/core/algorithm.hpp index c3c6354..c3c6354 100644 --- a/deps/entt/include/entt/core/algorithm.hpp +++ b/external/entt/include/entt/core/algorithm.hpp diff --git a/deps/entt/include/entt/core/any.hpp b/external/entt/include/entt/core/any.hpp index 65d8736..65d8736 100644 --- a/deps/entt/include/entt/core/any.hpp +++ b/external/entt/include/entt/core/any.hpp diff --git a/deps/entt/include/entt/core/attribute.h b/external/entt/include/entt/core/attribute.h index b1d0503..b1d0503 100644 --- a/deps/entt/include/entt/core/attribute.h +++ b/external/entt/include/entt/core/attribute.h diff --git a/deps/entt/include/entt/core/bit.hpp b/external/entt/include/entt/core/bit.hpp index 6622bd6..6622bd6 100644 --- a/deps/entt/include/entt/core/bit.hpp +++ b/external/entt/include/entt/core/bit.hpp diff --git a/deps/entt/include/entt/core/compressed_pair.hpp b/external/entt/include/entt/core/compressed_pair.hpp index f1bea5a..f1bea5a 100644 --- a/deps/entt/include/entt/core/compressed_pair.hpp +++ b/external/entt/include/entt/core/compressed_pair.hpp diff --git a/deps/entt/include/entt/core/enum.hpp b/external/entt/include/entt/core/enum.hpp index 5922c2f..5922c2f 100644 --- a/deps/entt/include/entt/core/enum.hpp +++ b/external/entt/include/entt/core/enum.hpp diff --git a/deps/entt/include/entt/core/family.hpp b/external/entt/include/entt/core/family.hpp index 3a83b88..3a83b88 100644 --- a/deps/entt/include/entt/core/family.hpp +++ b/external/entt/include/entt/core/family.hpp diff --git a/deps/entt/include/entt/core/fwd.hpp b/external/entt/include/entt/core/fwd.hpp index bdd0b23..bdd0b23 100644 --- a/deps/entt/include/entt/core/fwd.hpp +++ b/external/entt/include/entt/core/fwd.hpp diff --git a/deps/entt/include/entt/core/hashed_string.hpp b/external/entt/include/entt/core/hashed_string.hpp index df3e964..df3e964 100644 --- a/deps/entt/include/entt/core/hashed_string.hpp +++ b/external/entt/include/entt/core/hashed_string.hpp diff --git a/deps/entt/include/entt/core/ident.hpp b/external/entt/include/entt/core/ident.hpp index 2ff6026..2ff6026 100644 --- a/deps/entt/include/entt/core/ident.hpp +++ b/external/entt/include/entt/core/ident.hpp diff --git a/deps/entt/include/entt/core/iterator.hpp b/external/entt/include/entt/core/iterator.hpp index 42db97e..42db97e 100644 --- a/deps/entt/include/entt/core/iterator.hpp +++ b/external/entt/include/entt/core/iterator.hpp diff --git a/deps/entt/include/entt/core/memory.hpp b/external/entt/include/entt/core/memory.hpp index 8f6f34b..8f6f34b 100644 --- a/deps/entt/include/entt/core/memory.hpp +++ b/external/entt/include/entt/core/memory.hpp diff --git a/deps/entt/include/entt/core/monostate.hpp b/external/entt/include/entt/core/monostate.hpp index 4116bda..4116bda 100644 --- a/deps/entt/include/entt/core/monostate.hpp +++ b/external/entt/include/entt/core/monostate.hpp diff --git a/deps/entt/include/entt/core/ranges.hpp b/external/entt/include/entt/core/ranges.hpp index c1d062c..c1d062c 100644 --- a/deps/entt/include/entt/core/ranges.hpp +++ b/external/entt/include/entt/core/ranges.hpp diff --git a/deps/entt/include/entt/core/tuple.hpp b/external/entt/include/entt/core/tuple.hpp index 1a2dc4e..1a2dc4e 100644 --- a/deps/entt/include/entt/core/tuple.hpp +++ b/external/entt/include/entt/core/tuple.hpp diff --git a/deps/entt/include/entt/core/type_info.hpp b/external/entt/include/entt/core/type_info.hpp index 1937506..1937506 100644 --- a/deps/entt/include/entt/core/type_info.hpp +++ b/external/entt/include/entt/core/type_info.hpp diff --git a/deps/entt/include/entt/core/type_traits.hpp b/external/entt/include/entt/core/type_traits.hpp index f6a9ea9..f6a9ea9 100644 --- a/deps/entt/include/entt/core/type_traits.hpp +++ b/external/entt/include/entt/core/type_traits.hpp diff --git a/deps/entt/include/entt/core/utility.hpp b/external/entt/include/entt/core/utility.hpp index af8b5bd..af8b5bd 100644 --- a/deps/entt/include/entt/core/utility.hpp +++ b/external/entt/include/entt/core/utility.hpp diff --git a/deps/entt/include/entt/entity/component.hpp b/external/entt/include/entt/entity/component.hpp index 2e8a02b..2e8a02b 100644 --- a/deps/entt/include/entt/entity/component.hpp +++ b/external/entt/include/entt/entity/component.hpp diff --git a/deps/entt/include/entt/entity/entity.hpp b/external/entt/include/entt/entity/entity.hpp index 3c3dae6..3c3dae6 100644 --- a/deps/entt/include/entt/entity/entity.hpp +++ b/external/entt/include/entt/entity/entity.hpp diff --git a/deps/entt/include/entt/entity/fwd.hpp b/external/entt/include/entt/entity/fwd.hpp index 17d23f6..17d23f6 100644 --- a/deps/entt/include/entt/entity/fwd.hpp +++ b/external/entt/include/entt/entity/fwd.hpp diff --git a/deps/entt/include/entt/entity/group.hpp b/external/entt/include/entt/entity/group.hpp index 32abb3a..32abb3a 100644 --- a/deps/entt/include/entt/entity/group.hpp +++ b/external/entt/include/entt/entity/group.hpp diff --git a/deps/entt/include/entt/entity/handle.hpp b/external/entt/include/entt/entity/handle.hpp index 15e82fd..15e82fd 100644 --- a/deps/entt/include/entt/entity/handle.hpp +++ b/external/entt/include/entt/entity/handle.hpp diff --git a/deps/entt/include/entt/entity/helper.hpp b/external/entt/include/entt/entity/helper.hpp index 4ad2e27..4ad2e27 100644 --- a/deps/entt/include/entt/entity/helper.hpp +++ b/external/entt/include/entt/entity/helper.hpp diff --git a/deps/entt/include/entt/entity/mixin.hpp b/external/entt/include/entt/entity/mixin.hpp index c8ebd57..c8ebd57 100644 --- a/deps/entt/include/entt/entity/mixin.hpp +++ b/external/entt/include/entt/entity/mixin.hpp diff --git a/deps/entt/include/entt/entity/observer.hpp b/external/entt/include/entt/entity/observer.hpp index c280e4d..c280e4d 100644 --- a/deps/entt/include/entt/entity/observer.hpp +++ b/external/entt/include/entt/entity/observer.hpp diff --git a/deps/entt/include/entt/entity/organizer.hpp b/external/entt/include/entt/entity/organizer.hpp index a73fea4..a73fea4 100644 --- a/deps/entt/include/entt/entity/organizer.hpp +++ b/external/entt/include/entt/entity/organizer.hpp diff --git a/deps/entt/include/entt/entity/ranges.hpp b/external/entt/include/entt/entity/ranges.hpp index a80c84e..a80c84e 100644 --- a/deps/entt/include/entt/entity/ranges.hpp +++ b/external/entt/include/entt/entity/ranges.hpp diff --git a/deps/entt/include/entt/entity/registry.hpp b/external/entt/include/entt/entity/registry.hpp index c4c0098..c4c0098 100644 --- a/deps/entt/include/entt/entity/registry.hpp +++ b/external/entt/include/entt/entity/registry.hpp diff --git a/deps/entt/include/entt/entity/runtime_view.hpp b/external/entt/include/entt/entity/runtime_view.hpp index c0dfa01..c0dfa01 100644 --- a/deps/entt/include/entt/entity/runtime_view.hpp +++ b/external/entt/include/entt/entity/runtime_view.hpp diff --git a/deps/entt/include/entt/entity/snapshot.hpp b/external/entt/include/entt/entity/snapshot.hpp index 970efba..970efba 100644 --- a/deps/entt/include/entt/entity/snapshot.hpp +++ b/external/entt/include/entt/entity/snapshot.hpp diff --git a/deps/entt/include/entt/entity/sparse_set.hpp b/external/entt/include/entt/entity/sparse_set.hpp index b0c251b..b0c251b 100644 --- a/deps/entt/include/entt/entity/sparse_set.hpp +++ b/external/entt/include/entt/entity/sparse_set.hpp diff --git a/deps/entt/include/entt/entity/storage.hpp b/external/entt/include/entt/entity/storage.hpp index 6c1c570..6c1c570 100644 --- a/deps/entt/include/entt/entity/storage.hpp +++ b/external/entt/include/entt/entity/storage.hpp diff --git a/deps/entt/include/entt/entity/storage_mixin.hpp b/external/entt/include/entt/entity/storage_mixin.hpp index 0686e4e..0686e4e 100644 --- a/deps/entt/include/entt/entity/storage_mixin.hpp +++ b/external/entt/include/entt/entity/storage_mixin.hpp diff --git a/deps/entt/include/entt/entity/view.hpp b/external/entt/include/entt/entity/view.hpp index f59bff4..f59bff4 100644 --- a/deps/entt/include/entt/entity/view.hpp +++ b/external/entt/include/entt/entity/view.hpp diff --git a/deps/entt/include/entt/entt.hpp b/external/entt/include/entt/entt.hpp index a00fed5..a00fed5 100644 --- a/deps/entt/include/entt/entt.hpp +++ b/external/entt/include/entt/entt.hpp diff --git a/deps/entt/include/entt/fwd.hpp b/external/entt/include/entt/fwd.hpp index 4b6e60c..4b6e60c 100644 --- a/deps/entt/include/entt/fwd.hpp +++ b/external/entt/include/entt/fwd.hpp diff --git a/deps/entt/include/entt/graph/adjacency_matrix.hpp b/external/entt/include/entt/graph/adjacency_matrix.hpp index 85025be..85025be 100644 --- a/deps/entt/include/entt/graph/adjacency_matrix.hpp +++ b/external/entt/include/entt/graph/adjacency_matrix.hpp diff --git a/deps/entt/include/entt/graph/dot.hpp b/external/entt/include/entt/graph/dot.hpp index 1da13e8..1da13e8 100644 --- a/deps/entt/include/entt/graph/dot.hpp +++ b/external/entt/include/entt/graph/dot.hpp diff --git a/deps/entt/include/entt/graph/flow.hpp b/external/entt/include/entt/graph/flow.hpp index 0e3721e..0e3721e 100644 --- a/deps/entt/include/entt/graph/flow.hpp +++ b/external/entt/include/entt/graph/flow.hpp diff --git a/deps/entt/include/entt/graph/fwd.hpp b/external/entt/include/entt/graph/fwd.hpp index 963082f..963082f 100644 --- a/deps/entt/include/entt/graph/fwd.hpp +++ b/external/entt/include/entt/graph/fwd.hpp diff --git a/deps/entt/include/entt/locator/locator.hpp b/external/entt/include/entt/locator/locator.hpp index dd80b5b..dd80b5b 100644 --- a/deps/entt/include/entt/locator/locator.hpp +++ b/external/entt/include/entt/locator/locator.hpp diff --git a/deps/entt/include/entt/meta/adl_pointer.hpp b/external/entt/include/entt/meta/adl_pointer.hpp index 5bb768a..5bb768a 100644 --- a/deps/entt/include/entt/meta/adl_pointer.hpp +++ b/external/entt/include/entt/meta/adl_pointer.hpp diff --git a/deps/entt/include/entt/meta/container.hpp b/external/entt/include/entt/meta/container.hpp index ca645a9..ca645a9 100644 --- a/deps/entt/include/entt/meta/container.hpp +++ b/external/entt/include/entt/meta/container.hpp diff --git a/deps/entt/include/entt/meta/context.hpp b/external/entt/include/entt/meta/context.hpp index cb26a72..cb26a72 100644 --- a/deps/entt/include/entt/meta/context.hpp +++ b/external/entt/include/entt/meta/context.hpp diff --git a/deps/entt/include/entt/meta/factory.hpp b/external/entt/include/entt/meta/factory.hpp index 1732d25..1732d25 100644 --- a/deps/entt/include/entt/meta/factory.hpp +++ b/external/entt/include/entt/meta/factory.hpp diff --git a/deps/entt/include/entt/meta/fwd.hpp b/external/entt/include/entt/meta/fwd.hpp index 09d1051..09d1051 100644 --- a/deps/entt/include/entt/meta/fwd.hpp +++ b/external/entt/include/entt/meta/fwd.hpp diff --git a/deps/entt/include/entt/meta/meta.hpp b/external/entt/include/entt/meta/meta.hpp index b7b120a..b7b120a 100644 --- a/deps/entt/include/entt/meta/meta.hpp +++ b/external/entt/include/entt/meta/meta.hpp diff --git a/deps/entt/include/entt/meta/node.hpp b/external/entt/include/entt/meta/node.hpp index 5c4e25c..5c4e25c 100644 --- a/deps/entt/include/entt/meta/node.hpp +++ b/external/entt/include/entt/meta/node.hpp diff --git a/deps/entt/include/entt/meta/pointer.hpp b/external/entt/include/entt/meta/pointer.hpp index e90b0a1..e90b0a1 100644 --- a/deps/entt/include/entt/meta/pointer.hpp +++ b/external/entt/include/entt/meta/pointer.hpp diff --git a/deps/entt/include/entt/meta/policy.hpp b/external/entt/include/entt/meta/policy.hpp index b939599..b939599 100644 --- a/deps/entt/include/entt/meta/policy.hpp +++ b/external/entt/include/entt/meta/policy.hpp diff --git a/deps/entt/include/entt/meta/range.hpp b/external/entt/include/entt/meta/range.hpp index f53b572..f53b572 100644 --- a/deps/entt/include/entt/meta/range.hpp +++ b/external/entt/include/entt/meta/range.hpp diff --git a/deps/entt/include/entt/meta/resolve.hpp b/external/entt/include/entt/meta/resolve.hpp index 9360db5..9360db5 100644 --- a/deps/entt/include/entt/meta/resolve.hpp +++ b/external/entt/include/entt/meta/resolve.hpp diff --git a/deps/entt/include/entt/meta/template.hpp b/external/entt/include/entt/meta/template.hpp index 5eab2af..5eab2af 100644 --- a/deps/entt/include/entt/meta/template.hpp +++ b/external/entt/include/entt/meta/template.hpp diff --git a/deps/entt/include/entt/meta/type_traits.hpp b/external/entt/include/entt/meta/type_traits.hpp index 9ba167f..9ba167f 100644 --- a/deps/entt/include/entt/meta/type_traits.hpp +++ b/external/entt/include/entt/meta/type_traits.hpp diff --git a/deps/entt/include/entt/meta/utility.hpp b/external/entt/include/entt/meta/utility.hpp index b2e45c6..b2e45c6 100644 --- a/deps/entt/include/entt/meta/utility.hpp +++ b/external/entt/include/entt/meta/utility.hpp diff --git a/deps/entt/include/entt/platform/android-ndk-r17.hpp b/external/entt/include/entt/platform/android-ndk-r17.hpp index 5696123..5696123 100644 --- a/deps/entt/include/entt/platform/android-ndk-r17.hpp +++ b/external/entt/include/entt/platform/android-ndk-r17.hpp diff --git a/deps/entt/include/entt/poly/fwd.hpp b/external/entt/include/entt/poly/fwd.hpp index 34b096d..34b096d 100644 --- a/deps/entt/include/entt/poly/fwd.hpp +++ b/external/entt/include/entt/poly/fwd.hpp diff --git a/deps/entt/include/entt/poly/poly.hpp b/external/entt/include/entt/poly/poly.hpp index 977148a..977148a 100644 --- a/deps/entt/include/entt/poly/poly.hpp +++ b/external/entt/include/entt/poly/poly.hpp diff --git a/deps/entt/include/entt/process/fwd.hpp b/external/entt/include/entt/process/fwd.hpp index 6d033a3..6d033a3 100644 --- a/deps/entt/include/entt/process/fwd.hpp +++ b/external/entt/include/entt/process/fwd.hpp diff --git a/deps/entt/include/entt/process/process.hpp b/external/entt/include/entt/process/process.hpp index e95ad0c..e95ad0c 100644 --- a/deps/entt/include/entt/process/process.hpp +++ b/external/entt/include/entt/process/process.hpp diff --git a/deps/entt/include/entt/process/scheduler.hpp b/external/entt/include/entt/process/scheduler.hpp index 770059d..770059d 100644 --- a/deps/entt/include/entt/process/scheduler.hpp +++ b/external/entt/include/entt/process/scheduler.hpp diff --git a/deps/entt/include/entt/resource/cache.hpp b/external/entt/include/entt/resource/cache.hpp index 4650c63..4650c63 100644 --- a/deps/entt/include/entt/resource/cache.hpp +++ b/external/entt/include/entt/resource/cache.hpp diff --git a/deps/entt/include/entt/resource/fwd.hpp b/external/entt/include/entt/resource/fwd.hpp index ed63da5..ed63da5 100644 --- a/deps/entt/include/entt/resource/fwd.hpp +++ b/external/entt/include/entt/resource/fwd.hpp diff --git a/deps/entt/include/entt/resource/loader.hpp b/external/entt/include/entt/resource/loader.hpp index f59d748..f59d748 100644 --- a/deps/entt/include/entt/resource/loader.hpp +++ b/external/entt/include/entt/resource/loader.hpp diff --git a/deps/entt/include/entt/resource/resource.hpp b/external/entt/include/entt/resource/resource.hpp index 323d738..323d738 100644 --- a/deps/entt/include/entt/resource/resource.hpp +++ b/external/entt/include/entt/resource/resource.hpp diff --git a/deps/entt/include/entt/signal/delegate.hpp b/external/entt/include/entt/signal/delegate.hpp index 0060649..0060649 100644 --- a/deps/entt/include/entt/signal/delegate.hpp +++ b/external/entt/include/entt/signal/delegate.hpp diff --git a/deps/entt/include/entt/signal/dispatcher.hpp b/external/entt/include/entt/signal/dispatcher.hpp index fbd758e..fbd758e 100644 --- a/deps/entt/include/entt/signal/dispatcher.hpp +++ b/external/entt/include/entt/signal/dispatcher.hpp diff --git a/deps/entt/include/entt/signal/emitter.hpp b/external/entt/include/entt/signal/emitter.hpp index de69ed4..de69ed4 100644 --- a/deps/entt/include/entt/signal/emitter.hpp +++ b/external/entt/include/entt/signal/emitter.hpp diff --git a/deps/entt/include/entt/signal/fwd.hpp b/external/entt/include/entt/signal/fwd.hpp index b0964b6..b0964b6 100644 --- a/deps/entt/include/entt/signal/fwd.hpp +++ b/external/entt/include/entt/signal/fwd.hpp diff --git a/deps/entt/include/entt/signal/sigh.hpp b/external/entt/include/entt/signal/sigh.hpp index 38da4a2..38da4a2 100644 --- a/deps/entt/include/entt/signal/sigh.hpp +++ b/external/entt/include/entt/signal/sigh.hpp diff --git a/deps/fastnoiselite/CMakeLists.txt b/external/fastnoiselite/CMakeLists.txt index 6e0d071..6e0d071 100644 --- a/deps/fastnoiselite/CMakeLists.txt +++ b/external/fastnoiselite/CMakeLists.txt diff --git a/deps/fastnoiselite/DESCRIPTION b/external/fastnoiselite/DESCRIPTION index 5cd471c..5cd471c 100644 --- a/deps/fastnoiselite/DESCRIPTION +++ b/external/fastnoiselite/DESCRIPTION diff --git a/deps/fastnoiselite/LICENSE b/external/fastnoiselite/LICENSE index 0689a21..0689a21 100644 --- a/deps/fastnoiselite/LICENSE +++ b/external/fastnoiselite/LICENSE diff --git a/deps/fastnoiselite/include/fastnoiselite.h b/external/fastnoiselite/include/fastnoiselite.h index f3e645e..f3e645e 100644 --- a/deps/fastnoiselite/include/fastnoiselite.h +++ b/external/fastnoiselite/include/fastnoiselite.h diff --git a/deps/fastnoiselite/src/fastnoiselite.c b/external/fastnoiselite/src/fastnoiselite.c index 383da41..383da41 100644 --- a/deps/fastnoiselite/src/fastnoiselite.c +++ b/external/fastnoiselite/src/fastnoiselite.c diff --git a/deps/gamecontrollerdb/DESCRIPTION b/external/gamecontrollerdb/DESCRIPTION index e0fee76..e0fee76 100644 --- a/deps/gamecontrollerdb/DESCRIPTION +++ b/external/gamecontrollerdb/DESCRIPTION diff --git a/deps/gamecontrollerdb/LICENSE b/external/gamecontrollerdb/LICENSE index 8316012..8316012 100644 --- a/deps/gamecontrollerdb/LICENSE +++ b/external/gamecontrollerdb/LICENSE diff --git a/deps/glad/CMakeLists.txt b/external/glad/CMakeLists.txt index 66d30d6..66d30d6 100644 --- a/deps/glad/CMakeLists.txt +++ b/external/glad/CMakeLists.txt diff --git a/deps/glad/include/KHR/khrplatform.h b/external/glad/include/KHR/khrplatform.h index 0164644..0164644 100644 --- a/deps/glad/include/KHR/khrplatform.h +++ b/external/glad/include/KHR/khrplatform.h diff --git a/deps/glad/include/glad/gl.h b/external/glad/include/glad/gl.h index 9af9dd0..9af9dd0 100644 --- a/deps/glad/include/glad/gl.h +++ b/external/glad/include/glad/gl.h diff --git a/deps/glad/src/gl.c b/external/glad/src/gl.c index c5f5b2b..c5f5b2b 100644 --- a/deps/glad/src/gl.c +++ b/external/glad/src/gl.c diff --git a/deps/glfw/CMakeLists.txt b/external/glfw/CMakeLists.txt index d982998..d982998 100644 --- a/deps/glfw/CMakeLists.txt +++ b/external/glfw/CMakeLists.txt diff --git a/deps/glfw/DESCRIPTION b/external/glfw/DESCRIPTION index b556778..b556778 100644 --- a/deps/glfw/DESCRIPTION +++ b/external/glfw/DESCRIPTION diff --git a/deps/glfw/LICENSE b/external/glfw/LICENSE index b8c0968..b8c0968 100644 --- a/deps/glfw/LICENSE +++ b/external/glfw/LICENSE diff --git a/deps/glm/CMakeLists.txt b/external/glm/CMakeLists.txt index 49a8d8e..49a8d8e 100644 --- a/deps/glm/CMakeLists.txt +++ b/external/glm/CMakeLists.txt diff --git a/deps/glm/DESCRIPTION b/external/glm/DESCRIPTION index 6514da5..6514da5 100644 --- a/deps/glm/DESCRIPTION +++ b/external/glm/DESCRIPTION diff --git a/deps/glm/LICENSE b/external/glm/LICENSE index 8c28a35..8c28a35 100644 --- a/deps/glm/LICENSE +++ b/external/glm/LICENSE diff --git a/deps/glm/include/glm/CMakeLists.txt b/external/glm/include/glm/CMakeLists.txt index 178d23a..178d23a 100644 --- a/deps/glm/include/glm/CMakeLists.txt +++ b/external/glm/include/glm/CMakeLists.txt diff --git a/deps/glm/include/glm/common.hpp b/external/glm/include/glm/common.hpp index b59657d..b59657d 100644 --- a/deps/glm/include/glm/common.hpp +++ b/external/glm/include/glm/common.hpp diff --git a/deps/glm/include/glm/detail/_features.hpp b/external/glm/include/glm/detail/_features.hpp index b0cbe9f..b0cbe9f 100644 --- a/deps/glm/include/glm/detail/_features.hpp +++ b/external/glm/include/glm/detail/_features.hpp diff --git a/deps/glm/include/glm/detail/_fixes.hpp b/external/glm/include/glm/detail/_fixes.hpp index a503c7c..a503c7c 100644 --- a/deps/glm/include/glm/detail/_fixes.hpp +++ b/external/glm/include/glm/detail/_fixes.hpp diff --git a/deps/glm/include/glm/detail/_noise.hpp b/external/glm/include/glm/detail/_noise.hpp index 5a874a0..5a874a0 100644 --- a/deps/glm/include/glm/detail/_noise.hpp +++ b/external/glm/include/glm/detail/_noise.hpp diff --git a/deps/glm/include/glm/detail/_swizzle.hpp b/external/glm/include/glm/detail/_swizzle.hpp index e1f57cc..e1f57cc 100644 --- a/deps/glm/include/glm/detail/_swizzle.hpp +++ b/external/glm/include/glm/detail/_swizzle.hpp diff --git a/deps/glm/include/glm/detail/_swizzle_func.hpp b/external/glm/include/glm/detail/_swizzle_func.hpp index a264ae9..a264ae9 100644 --- a/deps/glm/include/glm/detail/_swizzle_func.hpp +++ b/external/glm/include/glm/detail/_swizzle_func.hpp diff --git a/deps/glm/include/glm/detail/_vectorize.hpp b/external/glm/include/glm/detail/_vectorize.hpp index 1fcaec3..1fcaec3 100644 --- a/deps/glm/include/glm/detail/_vectorize.hpp +++ b/external/glm/include/glm/detail/_vectorize.hpp diff --git a/deps/glm/include/glm/detail/compute_common.hpp b/external/glm/include/glm/detail/compute_common.hpp index 83362bc..83362bc 100644 --- a/deps/glm/include/glm/detail/compute_common.hpp +++ b/external/glm/include/glm/detail/compute_common.hpp diff --git a/deps/glm/include/glm/detail/compute_vector_decl.hpp b/external/glm/include/glm/detail/compute_vector_decl.hpp index 00d7de5..00d7de5 100644 --- a/deps/glm/include/glm/detail/compute_vector_decl.hpp +++ b/external/glm/include/glm/detail/compute_vector_decl.hpp diff --git a/deps/glm/include/glm/detail/compute_vector_relational.hpp b/external/glm/include/glm/detail/compute_vector_relational.hpp index 167b634..167b634 100644 --- a/deps/glm/include/glm/detail/compute_vector_relational.hpp +++ b/external/glm/include/glm/detail/compute_vector_relational.hpp diff --git a/deps/glm/include/glm/detail/func_common.inl b/external/glm/include/glm/detail/func_common.inl index f8584c9..f8584c9 100644 --- a/deps/glm/include/glm/detail/func_common.inl +++ b/external/glm/include/glm/detail/func_common.inl diff --git a/deps/glm/include/glm/detail/func_common_simd.inl b/external/glm/include/glm/detail/func_common_simd.inl index ce0032d..ce0032d 100644 --- a/deps/glm/include/glm/detail/func_common_simd.inl +++ b/external/glm/include/glm/detail/func_common_simd.inl diff --git a/deps/glm/include/glm/detail/func_exponential.inl b/external/glm/include/glm/detail/func_exponential.inl index 2efcdc6..2efcdc6 100644 --- a/deps/glm/include/glm/detail/func_exponential.inl +++ b/external/glm/include/glm/detail/func_exponential.inl diff --git a/deps/glm/include/glm/detail/func_exponential_simd.inl b/external/glm/include/glm/detail/func_exponential_simd.inl index fb78951..fb78951 100644 --- a/deps/glm/include/glm/detail/func_exponential_simd.inl +++ b/external/glm/include/glm/detail/func_exponential_simd.inl diff --git a/deps/glm/include/glm/detail/func_geometric.inl b/external/glm/include/glm/detail/func_geometric.inl index 404c990..404c990 100644 --- a/deps/glm/include/glm/detail/func_geometric.inl +++ b/external/glm/include/glm/detail/func_geometric.inl diff --git a/deps/glm/include/glm/detail/func_geometric_simd.inl b/external/glm/include/glm/detail/func_geometric_simd.inl index 2076dae..2076dae 100644 --- a/deps/glm/include/glm/detail/func_geometric_simd.inl +++ b/external/glm/include/glm/detail/func_geometric_simd.inl diff --git a/deps/glm/include/glm/detail/func_integer.inl b/external/glm/include/glm/detail/func_integer.inl index 67177a0..67177a0 100644 --- a/deps/glm/include/glm/detail/func_integer.inl +++ b/external/glm/include/glm/detail/func_integer.inl diff --git a/deps/glm/include/glm/detail/func_integer_simd.inl b/external/glm/include/glm/detail/func_integer_simd.inl index 5600c84..5600c84 100644 --- a/deps/glm/include/glm/detail/func_integer_simd.inl +++ b/external/glm/include/glm/detail/func_integer_simd.inl diff --git a/deps/glm/include/glm/detail/func_matrix.inl b/external/glm/include/glm/detail/func_matrix.inl index 081761f..081761f 100644 --- a/deps/glm/include/glm/detail/func_matrix.inl +++ b/external/glm/include/glm/detail/func_matrix.inl diff --git a/deps/glm/include/glm/detail/func_matrix_simd.inl b/external/glm/include/glm/detail/func_matrix_simd.inl index b9bb461..b9bb461 100644 --- a/deps/glm/include/glm/detail/func_matrix_simd.inl +++ b/external/glm/include/glm/detail/func_matrix_simd.inl diff --git a/deps/glm/include/glm/detail/func_packing.inl b/external/glm/include/glm/detail/func_packing.inl index 234b093..234b093 100644 --- a/deps/glm/include/glm/detail/func_packing.inl +++ b/external/glm/include/glm/detail/func_packing.inl diff --git a/deps/glm/include/glm/detail/func_packing_simd.inl b/external/glm/include/glm/detail/func_packing_simd.inl index fd0fe8b..fd0fe8b 100644 --- a/deps/glm/include/glm/detail/func_packing_simd.inl +++ b/external/glm/include/glm/detail/func_packing_simd.inl diff --git a/deps/glm/include/glm/detail/func_trigonometric.inl b/external/glm/include/glm/detail/func_trigonometric.inl index 9e6d9cf..9e6d9cf 100644 --- a/deps/glm/include/glm/detail/func_trigonometric.inl +++ b/external/glm/include/glm/detail/func_trigonometric.inl diff --git a/deps/glm/include/glm/detail/func_trigonometric_simd.inl b/external/glm/include/glm/detail/func_trigonometric_simd.inl index e69de29..e69de29 100644 --- a/deps/glm/include/glm/detail/func_trigonometric_simd.inl +++ b/external/glm/include/glm/detail/func_trigonometric_simd.inl diff --git a/deps/glm/include/glm/detail/func_vector_relational.inl b/external/glm/include/glm/detail/func_vector_relational.inl index 80c9e87..80c9e87 100644 --- a/deps/glm/include/glm/detail/func_vector_relational.inl +++ b/external/glm/include/glm/detail/func_vector_relational.inl diff --git a/deps/glm/include/glm/detail/func_vector_relational_simd.inl b/external/glm/include/glm/detail/func_vector_relational_simd.inl index fd0fe8b..fd0fe8b 100644 --- a/deps/glm/include/glm/detail/func_vector_relational_simd.inl +++ b/external/glm/include/glm/detail/func_vector_relational_simd.inl diff --git a/deps/glm/include/glm/detail/glm.cpp b/external/glm/include/glm/detail/glm.cpp index e0755bd..e0755bd 100644 --- a/deps/glm/include/glm/detail/glm.cpp +++ b/external/glm/include/glm/detail/glm.cpp diff --git a/deps/glm/include/glm/detail/qualifier.hpp b/external/glm/include/glm/detail/qualifier.hpp index a6c96cc..a6c96cc 100644 --- a/deps/glm/include/glm/detail/qualifier.hpp +++ b/external/glm/include/glm/detail/qualifier.hpp diff --git a/deps/glm/include/glm/detail/setup.hpp b/external/glm/include/glm/detail/setup.hpp index 1664c89..1664c89 100644 --- a/deps/glm/include/glm/detail/setup.hpp +++ b/external/glm/include/glm/detail/setup.hpp diff --git a/deps/glm/include/glm/detail/type_float.hpp b/external/glm/include/glm/detail/type_float.hpp index c8037eb..c8037eb 100644 --- a/deps/glm/include/glm/detail/type_float.hpp +++ b/external/glm/include/glm/detail/type_float.hpp diff --git a/deps/glm/include/glm/detail/type_half.hpp b/external/glm/include/glm/detail/type_half.hpp index 40b8bec..40b8bec 100644 --- a/deps/glm/include/glm/detail/type_half.hpp +++ b/external/glm/include/glm/detail/type_half.hpp diff --git a/deps/glm/include/glm/detail/type_half.inl b/external/glm/include/glm/detail/type_half.inl index 5d239cf..5d239cf 100644 --- a/deps/glm/include/glm/detail/type_half.inl +++ b/external/glm/include/glm/detail/type_half.inl diff --git a/deps/glm/include/glm/detail/type_mat2x2.hpp b/external/glm/include/glm/detail/type_mat2x2.hpp index 82e9f66..82e9f66 100644 --- a/deps/glm/include/glm/detail/type_mat2x2.hpp +++ b/external/glm/include/glm/detail/type_mat2x2.hpp diff --git a/deps/glm/include/glm/detail/type_mat2x2.inl b/external/glm/include/glm/detail/type_mat2x2.inl index afb2b31..afb2b31 100644 --- a/deps/glm/include/glm/detail/type_mat2x2.inl +++ b/external/glm/include/glm/detail/type_mat2x2.inl diff --git a/deps/glm/include/glm/detail/type_mat2x3.hpp b/external/glm/include/glm/detail/type_mat2x3.hpp index b65d1c5..b65d1c5 100644 --- a/deps/glm/include/glm/detail/type_mat2x3.hpp +++ b/external/glm/include/glm/detail/type_mat2x3.hpp diff --git a/deps/glm/include/glm/detail/type_mat2x3.inl b/external/glm/include/glm/detail/type_mat2x3.inl index 345ac8a..345ac8a 100644 --- a/deps/glm/include/glm/detail/type_mat2x3.inl +++ b/external/glm/include/glm/detail/type_mat2x3.inl diff --git a/deps/glm/include/glm/detail/type_mat2x4.hpp b/external/glm/include/glm/detail/type_mat2x4.hpp index 7ca43e5..7ca43e5 100644 --- a/deps/glm/include/glm/detail/type_mat2x4.hpp +++ b/external/glm/include/glm/detail/type_mat2x4.hpp diff --git a/deps/glm/include/glm/detail/type_mat2x4.inl b/external/glm/include/glm/detail/type_mat2x4.inl index 1c182c9..1c182c9 100644 --- a/deps/glm/include/glm/detail/type_mat2x4.inl +++ b/external/glm/include/glm/detail/type_mat2x4.inl diff --git a/deps/glm/include/glm/detail/type_mat3x2.hpp b/external/glm/include/glm/detail/type_mat3x2.hpp index 0249bef..0249bef 100644 --- a/deps/glm/include/glm/detail/type_mat3x2.hpp +++ b/external/glm/include/glm/detail/type_mat3x2.hpp diff --git a/deps/glm/include/glm/detail/type_mat3x2.inl b/external/glm/include/glm/detail/type_mat3x2.inl index cd9f46c..cd9f46c 100644 --- a/deps/glm/include/glm/detail/type_mat3x2.inl +++ b/external/glm/include/glm/detail/type_mat3x2.inl diff --git a/deps/glm/include/glm/detail/type_mat3x3.hpp b/external/glm/include/glm/detail/type_mat3x3.hpp index e4cbbdc..e4cbbdc 100644 --- a/deps/glm/include/glm/detail/type_mat3x3.hpp +++ b/external/glm/include/glm/detail/type_mat3x3.hpp diff --git a/deps/glm/include/glm/detail/type_mat3x3.inl b/external/glm/include/glm/detail/type_mat3x3.inl index a9b633a..a9b633a 100644 --- a/deps/glm/include/glm/detail/type_mat3x3.inl +++ b/external/glm/include/glm/detail/type_mat3x3.inl diff --git a/deps/glm/include/glm/detail/type_mat3x4.hpp b/external/glm/include/glm/detail/type_mat3x4.hpp index f9913d2..f9913d2 100644 --- a/deps/glm/include/glm/detail/type_mat3x4.hpp +++ b/external/glm/include/glm/detail/type_mat3x4.hpp diff --git a/deps/glm/include/glm/detail/type_mat3x4.inl b/external/glm/include/glm/detail/type_mat3x4.inl index 209e9d9..209e9d9 100644 --- a/deps/glm/include/glm/detail/type_mat3x4.inl +++ b/external/glm/include/glm/detail/type_mat3x4.inl diff --git a/deps/glm/include/glm/detail/type_mat4x2.hpp b/external/glm/include/glm/detail/type_mat4x2.hpp index 7057d4c..7057d4c 100644 --- a/deps/glm/include/glm/detail/type_mat4x2.hpp +++ b/external/glm/include/glm/detail/type_mat4x2.hpp diff --git a/deps/glm/include/glm/detail/type_mat4x2.inl b/external/glm/include/glm/detail/type_mat4x2.inl index 2b9b617..2b9b617 100644 --- a/deps/glm/include/glm/detail/type_mat4x2.inl +++ b/external/glm/include/glm/detail/type_mat4x2.inl diff --git a/deps/glm/include/glm/detail/type_mat4x3.hpp b/external/glm/include/glm/detail/type_mat4x3.hpp index 52a38d8..52a38d8 100644 --- a/deps/glm/include/glm/detail/type_mat4x3.hpp +++ b/external/glm/include/glm/detail/type_mat4x3.hpp diff --git a/deps/glm/include/glm/detail/type_mat4x3.inl b/external/glm/include/glm/detail/type_mat4x3.inl index 8430bc0..8430bc0 100644 --- a/deps/glm/include/glm/detail/type_mat4x3.inl +++ b/external/glm/include/glm/detail/type_mat4x3.inl diff --git a/deps/glm/include/glm/detail/type_mat4x4.hpp b/external/glm/include/glm/detail/type_mat4x4.hpp index ad7597b..ad7597b 100644 --- a/deps/glm/include/glm/detail/type_mat4x4.hpp +++ b/external/glm/include/glm/detail/type_mat4x4.hpp diff --git a/deps/glm/include/glm/detail/type_mat4x4.inl b/external/glm/include/glm/detail/type_mat4x4.inl index 116731d..116731d 100644 --- a/deps/glm/include/glm/detail/type_mat4x4.inl +++ b/external/glm/include/glm/detail/type_mat4x4.inl diff --git a/deps/glm/include/glm/detail/type_mat4x4_simd.inl b/external/glm/include/glm/detail/type_mat4x4_simd.inl index fb3a16f..fb3a16f 100644 --- a/deps/glm/include/glm/detail/type_mat4x4_simd.inl +++ b/external/glm/include/glm/detail/type_mat4x4_simd.inl diff --git a/deps/glm/include/glm/detail/type_quat.hpp b/external/glm/include/glm/detail/type_quat.hpp index 1b41e15..1b41e15 100644 --- a/deps/glm/include/glm/detail/type_quat.hpp +++ b/external/glm/include/glm/detail/type_quat.hpp diff --git a/deps/glm/include/glm/detail/type_quat.inl b/external/glm/include/glm/detail/type_quat.inl index 6a8f987..6a8f987 100644 --- a/deps/glm/include/glm/detail/type_quat.inl +++ b/external/glm/include/glm/detail/type_quat.inl diff --git a/deps/glm/include/glm/detail/type_quat_simd.inl b/external/glm/include/glm/detail/type_quat_simd.inl index fa6da19..fa6da19 100644 --- a/deps/glm/include/glm/detail/type_quat_simd.inl +++ b/external/glm/include/glm/detail/type_quat_simd.inl diff --git a/deps/glm/include/glm/detail/type_vec1.hpp b/external/glm/include/glm/detail/type_vec1.hpp index 0cc7b5d..0cc7b5d 100644 --- a/deps/glm/include/glm/detail/type_vec1.hpp +++ b/external/glm/include/glm/detail/type_vec1.hpp diff --git a/deps/glm/include/glm/detail/type_vec1.inl b/external/glm/include/glm/detail/type_vec1.inl index 18411e7..18411e7 100644 --- a/deps/glm/include/glm/detail/type_vec1.inl +++ b/external/glm/include/glm/detail/type_vec1.inl diff --git a/deps/glm/include/glm/detail/type_vec2.hpp b/external/glm/include/glm/detail/type_vec2.hpp index 2ddfb43..2ddfb43 100644 --- a/deps/glm/include/glm/detail/type_vec2.hpp +++ b/external/glm/include/glm/detail/type_vec2.hpp diff --git a/deps/glm/include/glm/detail/type_vec2.inl b/external/glm/include/glm/detail/type_vec2.inl index e840899..e840899 100644 --- a/deps/glm/include/glm/detail/type_vec2.inl +++ b/external/glm/include/glm/detail/type_vec2.inl diff --git a/deps/glm/include/glm/detail/type_vec3.hpp b/external/glm/include/glm/detail/type_vec3.hpp index 4bf8395..4bf8395 100644 --- a/deps/glm/include/glm/detail/type_vec3.hpp +++ b/external/glm/include/glm/detail/type_vec3.hpp diff --git a/deps/glm/include/glm/detail/type_vec3.inl b/external/glm/include/glm/detail/type_vec3.inl index 4e44047..4e44047 100644 --- a/deps/glm/include/glm/detail/type_vec3.inl +++ b/external/glm/include/glm/detail/type_vec3.inl diff --git a/deps/glm/include/glm/detail/type_vec4.hpp b/external/glm/include/glm/detail/type_vec4.hpp index 15f122f..15f122f 100644 --- a/deps/glm/include/glm/detail/type_vec4.hpp +++ b/external/glm/include/glm/detail/type_vec4.hpp diff --git a/deps/glm/include/glm/detail/type_vec4.inl b/external/glm/include/glm/detail/type_vec4.inl index d48fae7..d48fae7 100644 --- a/deps/glm/include/glm/detail/type_vec4.inl +++ b/external/glm/include/glm/detail/type_vec4.inl diff --git a/deps/glm/include/glm/detail/type_vec4_simd.inl b/external/glm/include/glm/detail/type_vec4_simd.inl index 816ef45..816ef45 100644 --- a/deps/glm/include/glm/detail/type_vec4_simd.inl +++ b/external/glm/include/glm/detail/type_vec4_simd.inl diff --git a/deps/glm/include/glm/exponential.hpp b/external/glm/include/glm/exponential.hpp index 1614f76..1614f76 100644 --- a/deps/glm/include/glm/exponential.hpp +++ b/external/glm/include/glm/exponential.hpp diff --git a/deps/glm/include/glm/ext.hpp b/external/glm/include/glm/ext.hpp index f9ac369..f9ac369 100644 --- a/deps/glm/include/glm/ext.hpp +++ b/external/glm/include/glm/ext.hpp diff --git a/deps/glm/include/glm/ext/_matrix_vectorize.hpp b/external/glm/include/glm/ext/_matrix_vectorize.hpp index 0d08117..0d08117 100644 --- a/deps/glm/include/glm/ext/_matrix_vectorize.hpp +++ b/external/glm/include/glm/ext/_matrix_vectorize.hpp diff --git a/deps/glm/include/glm/ext/matrix_clip_space.hpp b/external/glm/include/glm/ext/matrix_clip_space.hpp index 43579b8..43579b8 100644 --- a/deps/glm/include/glm/ext/matrix_clip_space.hpp +++ b/external/glm/include/glm/ext/matrix_clip_space.hpp diff --git a/deps/glm/include/glm/ext/matrix_clip_space.inl b/external/glm/include/glm/ext/matrix_clip_space.inl index 27fb6a1..27fb6a1 100644 --- a/deps/glm/include/glm/ext/matrix_clip_space.inl +++ b/external/glm/include/glm/ext/matrix_clip_space.inl diff --git a/deps/glm/include/glm/ext/matrix_common.hpp b/external/glm/include/glm/ext/matrix_common.hpp index 6bb3d06..6bb3d06 100644 --- a/deps/glm/include/glm/ext/matrix_common.hpp +++ b/external/glm/include/glm/ext/matrix_common.hpp diff --git a/deps/glm/include/glm/ext/matrix_common.inl b/external/glm/include/glm/ext/matrix_common.inl index 1be4222..1be4222 100644 --- a/deps/glm/include/glm/ext/matrix_common.inl +++ b/external/glm/include/glm/ext/matrix_common.inl diff --git a/deps/glm/include/glm/ext/matrix_double2x2.hpp b/external/glm/include/glm/ext/matrix_double2x2.hpp index 94dca54..94dca54 100644 --- a/deps/glm/include/glm/ext/matrix_double2x2.hpp +++ b/external/glm/include/glm/ext/matrix_double2x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_double2x2_precision.hpp b/external/glm/include/glm/ext/matrix_double2x2_precision.hpp index 9e2c174..9e2c174 100644 --- a/deps/glm/include/glm/ext/matrix_double2x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double2x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double2x3.hpp b/external/glm/include/glm/ext/matrix_double2x3.hpp index bfef87a..bfef87a 100644 --- a/deps/glm/include/glm/ext/matrix_double2x3.hpp +++ b/external/glm/include/glm/ext/matrix_double2x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_double2x3_precision.hpp b/external/glm/include/glm/ext/matrix_double2x3_precision.hpp index 098fb60..098fb60 100644 --- a/deps/glm/include/glm/ext/matrix_double2x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double2x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double2x4.hpp b/external/glm/include/glm/ext/matrix_double2x4.hpp index 499284b..499284b 100644 --- a/deps/glm/include/glm/ext/matrix_double2x4.hpp +++ b/external/glm/include/glm/ext/matrix_double2x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_double2x4_precision.hpp b/external/glm/include/glm/ext/matrix_double2x4_precision.hpp index 9b61ebc..9b61ebc 100644 --- a/deps/glm/include/glm/ext/matrix_double2x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double2x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x2.hpp b/external/glm/include/glm/ext/matrix_double3x2.hpp index dd23f36..dd23f36 100644 --- a/deps/glm/include/glm/ext/matrix_double3x2.hpp +++ b/external/glm/include/glm/ext/matrix_double3x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x2_precision.hpp b/external/glm/include/glm/ext/matrix_double3x2_precision.hpp index 068d9e9..068d9e9 100644 --- a/deps/glm/include/glm/ext/matrix_double3x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double3x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x3.hpp b/external/glm/include/glm/ext/matrix_double3x3.hpp index 53572b7..53572b7 100644 --- a/deps/glm/include/glm/ext/matrix_double3x3.hpp +++ b/external/glm/include/glm/ext/matrix_double3x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x3_precision.hpp b/external/glm/include/glm/ext/matrix_double3x3_precision.hpp index 8691e78..8691e78 100644 --- a/deps/glm/include/glm/ext/matrix_double3x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double3x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x4.hpp b/external/glm/include/glm/ext/matrix_double3x4.hpp index c572d63..c572d63 100644 --- a/deps/glm/include/glm/ext/matrix_double3x4.hpp +++ b/external/glm/include/glm/ext/matrix_double3x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_double3x4_precision.hpp b/external/glm/include/glm/ext/matrix_double3x4_precision.hpp index f040217..f040217 100644 --- a/deps/glm/include/glm/ext/matrix_double3x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double3x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x2.hpp b/external/glm/include/glm/ext/matrix_double4x2.hpp index 9b229f4..9b229f4 100644 --- a/deps/glm/include/glm/ext/matrix_double4x2.hpp +++ b/external/glm/include/glm/ext/matrix_double4x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x2_precision.hpp b/external/glm/include/glm/ext/matrix_double4x2_precision.hpp index 6ad18ba..6ad18ba 100644 --- a/deps/glm/include/glm/ext/matrix_double4x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double4x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x3.hpp b/external/glm/include/glm/ext/matrix_double4x3.hpp index dca4cf9..dca4cf9 100644 --- a/deps/glm/include/glm/ext/matrix_double4x3.hpp +++ b/external/glm/include/glm/ext/matrix_double4x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x3_precision.hpp b/external/glm/include/glm/ext/matrix_double4x3_precision.hpp index f7371de..f7371de 100644 --- a/deps/glm/include/glm/ext/matrix_double4x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double4x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x4.hpp b/external/glm/include/glm/ext/matrix_double4x4.hpp index 81e1bf6..81e1bf6 100644 --- a/deps/glm/include/glm/ext/matrix_double4x4.hpp +++ b/external/glm/include/glm/ext/matrix_double4x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_double4x4_precision.hpp b/external/glm/include/glm/ext/matrix_double4x4_precision.hpp index 4c36a84..4c36a84 100644 --- a/deps/glm/include/glm/ext/matrix_double4x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_double4x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x2.hpp b/external/glm/include/glm/ext/matrix_float2x2.hpp index 53df921..53df921 100644 --- a/deps/glm/include/glm/ext/matrix_float2x2.hpp +++ b/external/glm/include/glm/ext/matrix_float2x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x2_precision.hpp b/external/glm/include/glm/ext/matrix_float2x2_precision.hpp index 898b6db..898b6db 100644 --- a/deps/glm/include/glm/ext/matrix_float2x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float2x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x3.hpp b/external/glm/include/glm/ext/matrix_float2x3.hpp index 6f68822..6f68822 100644 --- a/deps/glm/include/glm/ext/matrix_float2x3.hpp +++ b/external/glm/include/glm/ext/matrix_float2x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x3_precision.hpp b/external/glm/include/glm/ext/matrix_float2x3_precision.hpp index 50c1032..50c1032 100644 --- a/deps/glm/include/glm/ext/matrix_float2x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float2x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x4.hpp b/external/glm/include/glm/ext/matrix_float2x4.hpp index 30f30de..30f30de 100644 --- a/deps/glm/include/glm/ext/matrix_float2x4.hpp +++ b/external/glm/include/glm/ext/matrix_float2x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_float2x4_precision.hpp b/external/glm/include/glm/ext/matrix_float2x4_precision.hpp index 079d638..079d638 100644 --- a/deps/glm/include/glm/ext/matrix_float2x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float2x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x2.hpp b/external/glm/include/glm/ext/matrix_float3x2.hpp index 280d0a3..280d0a3 100644 --- a/deps/glm/include/glm/ext/matrix_float3x2.hpp +++ b/external/glm/include/glm/ext/matrix_float3x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x2_precision.hpp b/external/glm/include/glm/ext/matrix_float3x2_precision.hpp index 8572c2a..8572c2a 100644 --- a/deps/glm/include/glm/ext/matrix_float3x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float3x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x3.hpp b/external/glm/include/glm/ext/matrix_float3x3.hpp index 177d809..177d809 100644 --- a/deps/glm/include/glm/ext/matrix_float3x3.hpp +++ b/external/glm/include/glm/ext/matrix_float3x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x3_precision.hpp b/external/glm/include/glm/ext/matrix_float3x3_precision.hpp index 8a900c1..8a900c1 100644 --- a/deps/glm/include/glm/ext/matrix_float3x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float3x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x4.hpp b/external/glm/include/glm/ext/matrix_float3x4.hpp index 64b8459..64b8459 100644 --- a/deps/glm/include/glm/ext/matrix_float3x4.hpp +++ b/external/glm/include/glm/ext/matrix_float3x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_float3x4_precision.hpp b/external/glm/include/glm/ext/matrix_float3x4_precision.hpp index bc36bf1..bc36bf1 100644 --- a/deps/glm/include/glm/ext/matrix_float3x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float3x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x2.hpp b/external/glm/include/glm/ext/matrix_float4x2.hpp index 1ed5227..1ed5227 100644 --- a/deps/glm/include/glm/ext/matrix_float4x2.hpp +++ b/external/glm/include/glm/ext/matrix_float4x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x2_precision.hpp b/external/glm/include/glm/ext/matrix_float4x2_precision.hpp index 88fd069..88fd069 100644 --- a/deps/glm/include/glm/ext/matrix_float4x2_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float4x2_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x3.hpp b/external/glm/include/glm/ext/matrix_float4x3.hpp index 5dbe765..5dbe765 100644 --- a/deps/glm/include/glm/ext/matrix_float4x3.hpp +++ b/external/glm/include/glm/ext/matrix_float4x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x3_precision.hpp b/external/glm/include/glm/ext/matrix_float4x3_precision.hpp index 846ed4f..846ed4f 100644 --- a/deps/glm/include/glm/ext/matrix_float4x3_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float4x3_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x4.hpp b/external/glm/include/glm/ext/matrix_float4x4.hpp index 5ba111d..5ba111d 100644 --- a/deps/glm/include/glm/ext/matrix_float4x4.hpp +++ b/external/glm/include/glm/ext/matrix_float4x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_float4x4_precision.hpp b/external/glm/include/glm/ext/matrix_float4x4_precision.hpp index 597149b..597149b 100644 --- a/deps/glm/include/glm/ext/matrix_float4x4_precision.hpp +++ b/external/glm/include/glm/ext/matrix_float4x4_precision.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x2.hpp b/external/glm/include/glm/ext/matrix_int2x2.hpp index c6aa068..c6aa068 100644 --- a/deps/glm/include/glm/ext/matrix_int2x2.hpp +++ b/external/glm/include/glm/ext/matrix_int2x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x2_sized.hpp b/external/glm/include/glm/ext/matrix_int2x2_sized.hpp index 70c0c21..70c0c21 100644 --- a/deps/glm/include/glm/ext/matrix_int2x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int2x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x3.hpp b/external/glm/include/glm/ext/matrix_int2x3.hpp index aee415c..aee415c 100644 --- a/deps/glm/include/glm/ext/matrix_int2x3.hpp +++ b/external/glm/include/glm/ext/matrix_int2x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x3_sized.hpp b/external/glm/include/glm/ext/matrix_int2x3_sized.hpp index b5526fe..b5526fe 100644 --- a/deps/glm/include/glm/ext/matrix_int2x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int2x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x4.hpp b/external/glm/include/glm/ext/matrix_int2x4.hpp index 4f36331..4f36331 100644 --- a/deps/glm/include/glm/ext/matrix_int2x4.hpp +++ b/external/glm/include/glm/ext/matrix_int2x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_int2x4_sized.hpp b/external/glm/include/glm/ext/matrix_int2x4_sized.hpp index a66a5e7..a66a5e7 100644 --- a/deps/glm/include/glm/ext/matrix_int2x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int2x4_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x2.hpp b/external/glm/include/glm/ext/matrix_int3x2.hpp index 3bd563b..3bd563b 100644 --- a/deps/glm/include/glm/ext/matrix_int3x2.hpp +++ b/external/glm/include/glm/ext/matrix_int3x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x2_sized.hpp b/external/glm/include/glm/ext/matrix_int3x2_sized.hpp index 7e34c52..7e34c52 100644 --- a/deps/glm/include/glm/ext/matrix_int3x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int3x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x3.hpp b/external/glm/include/glm/ext/matrix_int3x3.hpp index 287488d..287488d 100644 --- a/deps/glm/include/glm/ext/matrix_int3x3.hpp +++ b/external/glm/include/glm/ext/matrix_int3x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x3_sized.hpp b/external/glm/include/glm/ext/matrix_int3x3_sized.hpp index 577e305..577e305 100644 --- a/deps/glm/include/glm/ext/matrix_int3x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int3x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x4.hpp b/external/glm/include/glm/ext/matrix_int3x4.hpp index 08e534d..08e534d 100644 --- a/deps/glm/include/glm/ext/matrix_int3x4.hpp +++ b/external/glm/include/glm/ext/matrix_int3x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_int3x4_sized.hpp b/external/glm/include/glm/ext/matrix_int3x4_sized.hpp index 692c48c..692c48c 100644 --- a/deps/glm/include/glm/ext/matrix_int3x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int3x4_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x2.hpp b/external/glm/include/glm/ext/matrix_int4x2.hpp index f756ef2..f756ef2 100644 --- a/deps/glm/include/glm/ext/matrix_int4x2.hpp +++ b/external/glm/include/glm/ext/matrix_int4x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x2_sized.hpp b/external/glm/include/glm/ext/matrix_int4x2_sized.hpp index 63a99d6..63a99d6 100644 --- a/deps/glm/include/glm/ext/matrix_int4x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int4x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x3.hpp b/external/glm/include/glm/ext/matrix_int4x3.hpp index d5d97a7..d5d97a7 100644 --- a/deps/glm/include/glm/ext/matrix_int4x3.hpp +++ b/external/glm/include/glm/ext/matrix_int4x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x3_sized.hpp b/external/glm/include/glm/ext/matrix_int4x3_sized.hpp index 55078fa..55078fa 100644 --- a/deps/glm/include/glm/ext/matrix_int4x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int4x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x4.hpp b/external/glm/include/glm/ext/matrix_int4x4.hpp index e17cff1..e17cff1 100644 --- a/deps/glm/include/glm/ext/matrix_int4x4.hpp +++ b/external/glm/include/glm/ext/matrix_int4x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_int4x4_sized.hpp b/external/glm/include/glm/ext/matrix_int4x4_sized.hpp index 4a11203..4a11203 100644 --- a/deps/glm/include/glm/ext/matrix_int4x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_int4x4_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_integer.hpp b/external/glm/include/glm/ext/matrix_integer.hpp index 7d7dfc5..7d7dfc5 100644 --- a/deps/glm/include/glm/ext/matrix_integer.hpp +++ b/external/glm/include/glm/ext/matrix_integer.hpp diff --git a/deps/glm/include/glm/ext/matrix_integer.inl b/external/glm/include/glm/ext/matrix_integer.inl index 8b377ce..8b377ce 100644 --- a/deps/glm/include/glm/ext/matrix_integer.inl +++ b/external/glm/include/glm/ext/matrix_integer.inl diff --git a/deps/glm/include/glm/ext/matrix_projection.hpp b/external/glm/include/glm/ext/matrix_projection.hpp index 51fd01b..51fd01b 100644 --- a/deps/glm/include/glm/ext/matrix_projection.hpp +++ b/external/glm/include/glm/ext/matrix_projection.hpp diff --git a/deps/glm/include/glm/ext/matrix_projection.inl b/external/glm/include/glm/ext/matrix_projection.inl index 2f2c196..2f2c196 100644 --- a/deps/glm/include/glm/ext/matrix_projection.inl +++ b/external/glm/include/glm/ext/matrix_projection.inl diff --git a/deps/glm/include/glm/ext/matrix_relational.hpp b/external/glm/include/glm/ext/matrix_relational.hpp index 20023ad..20023ad 100644 --- a/deps/glm/include/glm/ext/matrix_relational.hpp +++ b/external/glm/include/glm/ext/matrix_relational.hpp diff --git a/deps/glm/include/glm/ext/matrix_relational.inl b/external/glm/include/glm/ext/matrix_relational.inl index 9cd42b7..9cd42b7 100644 --- a/deps/glm/include/glm/ext/matrix_relational.inl +++ b/external/glm/include/glm/ext/matrix_relational.inl diff --git a/deps/glm/include/glm/ext/matrix_transform.hpp b/external/glm/include/glm/ext/matrix_transform.hpp index 52695b8..52695b8 100644 --- a/deps/glm/include/glm/ext/matrix_transform.hpp +++ b/external/glm/include/glm/ext/matrix_transform.hpp diff --git a/deps/glm/include/glm/ext/matrix_transform.inl b/external/glm/include/glm/ext/matrix_transform.inl index 029ef0f..029ef0f 100644 --- a/deps/glm/include/glm/ext/matrix_transform.inl +++ b/external/glm/include/glm/ext/matrix_transform.inl diff --git a/deps/glm/include/glm/ext/matrix_uint2x2.hpp b/external/glm/include/glm/ext/matrix_uint2x2.hpp index 034771a..034771a 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x2.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint2x2_sized.hpp b/external/glm/include/glm/ext/matrix_uint2x2_sized.hpp index 4555324..4555324 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint2x3.hpp b/external/glm/include/glm/ext/matrix_uint2x3.hpp index f496c53..f496c53 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x3.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint2x3_sized.hpp b/external/glm/include/glm/ext/matrix_uint2x3_sized.hpp index db7939c..db7939c 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint2x4.hpp b/external/glm/include/glm/ext/matrix_uint2x4.hpp index 0f99350..0f99350 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x4.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint2x4_sized.hpp b/external/glm/include/glm/ext/matrix_uint2x4_sized.hpp index 5c55547..5c55547 100644 --- a/deps/glm/include/glm/ext/matrix_uint2x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint2x4_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x2.hpp b/external/glm/include/glm/ext/matrix_uint3x2.hpp index 55a9bed..55a9bed 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x2.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x2_sized.hpp b/external/glm/include/glm/ext/matrix_uint3x2_sized.hpp index c81af8f..c81af8f 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x3.hpp b/external/glm/include/glm/ext/matrix_uint3x3.hpp index 1004c0d..1004c0d 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x3.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x3_sized.hpp b/external/glm/include/glm/ext/matrix_uint3x3_sized.hpp index 41a8be7..41a8be7 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x4.hpp b/external/glm/include/glm/ext/matrix_uint3x4.hpp index c6dd78c..c6dd78c 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x4.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint3x4_sized.hpp b/external/glm/include/glm/ext/matrix_uint3x4_sized.hpp index 2ce28ad..2ce28ad 100644 --- a/deps/glm/include/glm/ext/matrix_uint3x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint3x4_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x2.hpp b/external/glm/include/glm/ext/matrix_uint4x2.hpp index 0446f57..0446f57 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x2.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x2.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x2_sized.hpp b/external/glm/include/glm/ext/matrix_uint4x2_sized.hpp index 57a66bf..57a66bf 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x2_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x2_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x3.hpp b/external/glm/include/glm/ext/matrix_uint4x3.hpp index 54c24e4..54c24e4 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x3.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x3.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x3_sized.hpp b/external/glm/include/glm/ext/matrix_uint4x3_sized.hpp index 2e61124..2e61124 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x3_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x3_sized.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x4.hpp b/external/glm/include/glm/ext/matrix_uint4x4.hpp index 5cc8455..5cc8455 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x4.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x4.hpp diff --git a/deps/glm/include/glm/ext/matrix_uint4x4_sized.hpp b/external/glm/include/glm/ext/matrix_uint4x4_sized.hpp index bb10bd2..bb10bd2 100644 --- a/deps/glm/include/glm/ext/matrix_uint4x4_sized.hpp +++ b/external/glm/include/glm/ext/matrix_uint4x4_sized.hpp diff --git a/deps/glm/include/glm/ext/quaternion_common.hpp b/external/glm/include/glm/ext/quaternion_common.hpp index f738692..f738692 100644 --- a/deps/glm/include/glm/ext/quaternion_common.hpp +++ b/external/glm/include/glm/ext/quaternion_common.hpp diff --git a/deps/glm/include/glm/ext/quaternion_common.inl b/external/glm/include/glm/ext/quaternion_common.inl index ad171f9..ad171f9 100644 --- a/deps/glm/include/glm/ext/quaternion_common.inl +++ b/external/glm/include/glm/ext/quaternion_common.inl diff --git a/deps/glm/include/glm/ext/quaternion_common_simd.inl b/external/glm/include/glm/ext/quaternion_common_simd.inl index ddfc8a4..ddfc8a4 100644 --- a/deps/glm/include/glm/ext/quaternion_common_simd.inl +++ b/external/glm/include/glm/ext/quaternion_common_simd.inl diff --git a/deps/glm/include/glm/ext/quaternion_double.hpp b/external/glm/include/glm/ext/quaternion_double.hpp index 63b24de..63b24de 100644 --- a/deps/glm/include/glm/ext/quaternion_double.hpp +++ b/external/glm/include/glm/ext/quaternion_double.hpp diff --git a/deps/glm/include/glm/ext/quaternion_double_precision.hpp b/external/glm/include/glm/ext/quaternion_double_precision.hpp index 8aa24a1..8aa24a1 100644 --- a/deps/glm/include/glm/ext/quaternion_double_precision.hpp +++ b/external/glm/include/glm/ext/quaternion_double_precision.hpp diff --git a/deps/glm/include/glm/ext/quaternion_exponential.hpp b/external/glm/include/glm/ext/quaternion_exponential.hpp index affe297..affe297 100644 --- a/deps/glm/include/glm/ext/quaternion_exponential.hpp +++ b/external/glm/include/glm/ext/quaternion_exponential.hpp diff --git a/deps/glm/include/glm/ext/quaternion_exponential.inl b/external/glm/include/glm/ext/quaternion_exponential.inl index 8a9d774..8a9d774 100644 --- a/deps/glm/include/glm/ext/quaternion_exponential.inl +++ b/external/glm/include/glm/ext/quaternion_exponential.inl diff --git a/deps/glm/include/glm/ext/quaternion_float.hpp b/external/glm/include/glm/ext/quaternion_float.hpp index ca42a60..ca42a60 100644 --- a/deps/glm/include/glm/ext/quaternion_float.hpp +++ b/external/glm/include/glm/ext/quaternion_float.hpp diff --git a/deps/glm/include/glm/ext/quaternion_float_precision.hpp b/external/glm/include/glm/ext/quaternion_float_precision.hpp index f9e4f5c..f9e4f5c 100644 --- a/deps/glm/include/glm/ext/quaternion_float_precision.hpp +++ b/external/glm/include/glm/ext/quaternion_float_precision.hpp diff --git a/deps/glm/include/glm/ext/quaternion_geometric.hpp b/external/glm/include/glm/ext/quaternion_geometric.hpp index 6a2403f..6a2403f 100644 --- a/deps/glm/include/glm/ext/quaternion_geometric.hpp +++ b/external/glm/include/glm/ext/quaternion_geometric.hpp diff --git a/deps/glm/include/glm/ext/quaternion_geometric.inl b/external/glm/include/glm/ext/quaternion_geometric.inl index 88dc4d6..88dc4d6 100644 --- a/deps/glm/include/glm/ext/quaternion_geometric.inl +++ b/external/glm/include/glm/ext/quaternion_geometric.inl diff --git a/deps/glm/include/glm/ext/quaternion_relational.hpp b/external/glm/include/glm/ext/quaternion_relational.hpp index 7aa121d..7aa121d 100644 --- a/deps/glm/include/glm/ext/quaternion_relational.hpp +++ b/external/glm/include/glm/ext/quaternion_relational.hpp diff --git a/deps/glm/include/glm/ext/quaternion_relational.inl b/external/glm/include/glm/ext/quaternion_relational.inl index b1713e9..b1713e9 100644 --- a/deps/glm/include/glm/ext/quaternion_relational.inl +++ b/external/glm/include/glm/ext/quaternion_relational.inl diff --git a/deps/glm/include/glm/ext/quaternion_transform.hpp b/external/glm/include/glm/ext/quaternion_transform.hpp index a9cc5c2..a9cc5c2 100644 --- a/deps/glm/include/glm/ext/quaternion_transform.hpp +++ b/external/glm/include/glm/ext/quaternion_transform.hpp diff --git a/deps/glm/include/glm/ext/quaternion_transform.inl b/external/glm/include/glm/ext/quaternion_transform.inl index 7e773fb..7e773fb 100644 --- a/deps/glm/include/glm/ext/quaternion_transform.inl +++ b/external/glm/include/glm/ext/quaternion_transform.inl diff --git a/deps/glm/include/glm/ext/quaternion_trigonometric.hpp b/external/glm/include/glm/ext/quaternion_trigonometric.hpp index 574a704..574a704 100644 --- a/deps/glm/include/glm/ext/quaternion_trigonometric.hpp +++ b/external/glm/include/glm/ext/quaternion_trigonometric.hpp diff --git a/deps/glm/include/glm/ext/quaternion_trigonometric.inl b/external/glm/include/glm/ext/quaternion_trigonometric.inl index 896449a..896449a 100644 --- a/deps/glm/include/glm/ext/quaternion_trigonometric.inl +++ b/external/glm/include/glm/ext/quaternion_trigonometric.inl diff --git a/deps/glm/include/glm/ext/scalar_common.hpp b/external/glm/include/glm/ext/scalar_common.hpp index df04b6b..df04b6b 100644 --- a/deps/glm/include/glm/ext/scalar_common.hpp +++ b/external/glm/include/glm/ext/scalar_common.hpp diff --git a/deps/glm/include/glm/ext/scalar_common.inl b/external/glm/include/glm/ext/scalar_common.inl index 3d09fef..3d09fef 100644 --- a/deps/glm/include/glm/ext/scalar_common.inl +++ b/external/glm/include/glm/ext/scalar_common.inl diff --git a/deps/glm/include/glm/ext/scalar_constants.hpp b/external/glm/include/glm/ext/scalar_constants.hpp index 74e210d..74e210d 100644 --- a/deps/glm/include/glm/ext/scalar_constants.hpp +++ b/external/glm/include/glm/ext/scalar_constants.hpp diff --git a/deps/glm/include/glm/ext/scalar_constants.inl b/external/glm/include/glm/ext/scalar_constants.inl index b928e51..b928e51 100644 --- a/deps/glm/include/glm/ext/scalar_constants.inl +++ b/external/glm/include/glm/ext/scalar_constants.inl diff --git a/deps/glm/include/glm/ext/scalar_int_sized.hpp b/external/glm/include/glm/ext/scalar_int_sized.hpp index 8e9c511..8e9c511 100644 --- a/deps/glm/include/glm/ext/scalar_int_sized.hpp +++ b/external/glm/include/glm/ext/scalar_int_sized.hpp diff --git a/deps/glm/include/glm/ext/scalar_integer.hpp b/external/glm/include/glm/ext/scalar_integer.hpp index a2ca8a2..a2ca8a2 100644 --- a/deps/glm/include/glm/ext/scalar_integer.hpp +++ b/external/glm/include/glm/ext/scalar_integer.hpp diff --git a/deps/glm/include/glm/ext/scalar_integer.inl b/external/glm/include/glm/ext/scalar_integer.inl index d416197..d416197 100644 --- a/deps/glm/include/glm/ext/scalar_integer.inl +++ b/external/glm/include/glm/ext/scalar_integer.inl diff --git a/deps/glm/include/glm/ext/scalar_packing.hpp b/external/glm/include/glm/ext/scalar_packing.hpp index 18b85b7..18b85b7 100644 --- a/deps/glm/include/glm/ext/scalar_packing.hpp +++ b/external/glm/include/glm/ext/scalar_packing.hpp diff --git a/deps/glm/include/glm/ext/scalar_packing.inl b/external/glm/include/glm/ext/scalar_packing.inl index e69de29..e69de29 100644 --- a/deps/glm/include/glm/ext/scalar_packing.inl +++ b/external/glm/include/glm/ext/scalar_packing.inl diff --git a/deps/glm/include/glm/ext/scalar_reciprocal.hpp b/external/glm/include/glm/ext/scalar_reciprocal.hpp index 1c7b81d..1c7b81d 100644 --- a/deps/glm/include/glm/ext/scalar_reciprocal.hpp +++ b/external/glm/include/glm/ext/scalar_reciprocal.hpp diff --git a/deps/glm/include/glm/ext/scalar_reciprocal.inl b/external/glm/include/glm/ext/scalar_reciprocal.inl index 0cd5f87..0cd5f87 100644 --- a/deps/glm/include/glm/ext/scalar_reciprocal.inl +++ b/external/glm/include/glm/ext/scalar_reciprocal.inl diff --git a/deps/glm/include/glm/ext/scalar_relational.hpp b/external/glm/include/glm/ext/scalar_relational.hpp index e84df17..e84df17 100644 --- a/deps/glm/include/glm/ext/scalar_relational.hpp +++ b/external/glm/include/glm/ext/scalar_relational.hpp diff --git a/deps/glm/include/glm/ext/scalar_relational.inl b/external/glm/include/glm/ext/scalar_relational.inl index c85583e..c85583e 100644 --- a/deps/glm/include/glm/ext/scalar_relational.inl +++ b/external/glm/include/glm/ext/scalar_relational.inl diff --git a/deps/glm/include/glm/ext/scalar_uint_sized.hpp b/external/glm/include/glm/ext/scalar_uint_sized.hpp index fd5267f..fd5267f 100644 --- a/deps/glm/include/glm/ext/scalar_uint_sized.hpp +++ b/external/glm/include/glm/ext/scalar_uint_sized.hpp diff --git a/deps/glm/include/glm/ext/scalar_ulp.hpp b/external/glm/include/glm/ext/scalar_ulp.hpp index 6344d95..6344d95 100644 --- a/deps/glm/include/glm/ext/scalar_ulp.hpp +++ b/external/glm/include/glm/ext/scalar_ulp.hpp diff --git a/deps/glm/include/glm/ext/scalar_ulp.inl b/external/glm/include/glm/ext/scalar_ulp.inl index 716528d..716528d 100644 --- a/deps/glm/include/glm/ext/scalar_ulp.inl +++ b/external/glm/include/glm/ext/scalar_ulp.inl diff --git a/deps/glm/include/glm/ext/vector_bool1.hpp b/external/glm/include/glm/ext/vector_bool1.hpp index 002c320..002c320 100644 --- a/deps/glm/include/glm/ext/vector_bool1.hpp +++ b/external/glm/include/glm/ext/vector_bool1.hpp diff --git a/deps/glm/include/glm/ext/vector_bool1_precision.hpp b/external/glm/include/glm/ext/vector_bool1_precision.hpp index e62d3cf..e62d3cf 100644 --- a/deps/glm/include/glm/ext/vector_bool1_precision.hpp +++ b/external/glm/include/glm/ext/vector_bool1_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_bool2.hpp b/external/glm/include/glm/ext/vector_bool2.hpp index 52288b7..52288b7 100644 --- a/deps/glm/include/glm/ext/vector_bool2.hpp +++ b/external/glm/include/glm/ext/vector_bool2.hpp diff --git a/deps/glm/include/glm/ext/vector_bool2_precision.hpp b/external/glm/include/glm/ext/vector_bool2_precision.hpp index 4370933..4370933 100644 --- a/deps/glm/include/glm/ext/vector_bool2_precision.hpp +++ b/external/glm/include/glm/ext/vector_bool2_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_bool3.hpp b/external/glm/include/glm/ext/vector_bool3.hpp index 90a0b7e..90a0b7e 100644 --- a/deps/glm/include/glm/ext/vector_bool3.hpp +++ b/external/glm/include/glm/ext/vector_bool3.hpp diff --git a/deps/glm/include/glm/ext/vector_bool3_precision.hpp b/external/glm/include/glm/ext/vector_bool3_precision.hpp index 89cd2d3..89cd2d3 100644 --- a/deps/glm/include/glm/ext/vector_bool3_precision.hpp +++ b/external/glm/include/glm/ext/vector_bool3_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_bool4.hpp b/external/glm/include/glm/ext/vector_bool4.hpp index 18aa71b..18aa71b 100644 --- a/deps/glm/include/glm/ext/vector_bool4.hpp +++ b/external/glm/include/glm/ext/vector_bool4.hpp diff --git a/deps/glm/include/glm/ext/vector_bool4_precision.hpp b/external/glm/include/glm/ext/vector_bool4_precision.hpp index 79786e5..79786e5 100644 --- a/deps/glm/include/glm/ext/vector_bool4_precision.hpp +++ b/external/glm/include/glm/ext/vector_bool4_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_common.hpp b/external/glm/include/glm/ext/vector_common.hpp index c0a2858..c0a2858 100644 --- a/deps/glm/include/glm/ext/vector_common.hpp +++ b/external/glm/include/glm/ext/vector_common.hpp diff --git a/deps/glm/include/glm/ext/vector_common.inl b/external/glm/include/glm/ext/vector_common.inl index 67817fc..67817fc 100644 --- a/deps/glm/include/glm/ext/vector_common.inl +++ b/external/glm/include/glm/ext/vector_common.inl diff --git a/deps/glm/include/glm/ext/vector_double1.hpp b/external/glm/include/glm/ext/vector_double1.hpp index 3882667..3882667 100644 --- a/deps/glm/include/glm/ext/vector_double1.hpp +++ b/external/glm/include/glm/ext/vector_double1.hpp diff --git a/deps/glm/include/glm/ext/vector_double1_precision.hpp b/external/glm/include/glm/ext/vector_double1_precision.hpp index 1d47195..1d47195 100644 --- a/deps/glm/include/glm/ext/vector_double1_precision.hpp +++ b/external/glm/include/glm/ext/vector_double1_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_double2.hpp b/external/glm/include/glm/ext/vector_double2.hpp index 60e3577..60e3577 100644 --- a/deps/glm/include/glm/ext/vector_double2.hpp +++ b/external/glm/include/glm/ext/vector_double2.hpp diff --git a/deps/glm/include/glm/ext/vector_double2_precision.hpp b/external/glm/include/glm/ext/vector_double2_precision.hpp index fa53940..fa53940 100644 --- a/deps/glm/include/glm/ext/vector_double2_precision.hpp +++ b/external/glm/include/glm/ext/vector_double2_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_double3.hpp b/external/glm/include/glm/ext/vector_double3.hpp index 6dfe4c6..6dfe4c6 100644 --- a/deps/glm/include/glm/ext/vector_double3.hpp +++ b/external/glm/include/glm/ext/vector_double3.hpp diff --git a/deps/glm/include/glm/ext/vector_double3_precision.hpp b/external/glm/include/glm/ext/vector_double3_precision.hpp index a8cfa37..a8cfa37 100644 --- a/deps/glm/include/glm/ext/vector_double3_precision.hpp +++ b/external/glm/include/glm/ext/vector_double3_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_double4.hpp b/external/glm/include/glm/ext/vector_double4.hpp index 87f225f..87f225f 100644 --- a/deps/glm/include/glm/ext/vector_double4.hpp +++ b/external/glm/include/glm/ext/vector_double4.hpp diff --git a/deps/glm/include/glm/ext/vector_double4_precision.hpp b/external/glm/include/glm/ext/vector_double4_precision.hpp index 09cafa1..09cafa1 100644 --- a/deps/glm/include/glm/ext/vector_double4_precision.hpp +++ b/external/glm/include/glm/ext/vector_double4_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_float1.hpp b/external/glm/include/glm/ext/vector_float1.hpp index 28acc2c..28acc2c 100644 --- a/deps/glm/include/glm/ext/vector_float1.hpp +++ b/external/glm/include/glm/ext/vector_float1.hpp diff --git a/deps/glm/include/glm/ext/vector_float1_precision.hpp b/external/glm/include/glm/ext/vector_float1_precision.hpp index 6e8dad8..6e8dad8 100644 --- a/deps/glm/include/glm/ext/vector_float1_precision.hpp +++ b/external/glm/include/glm/ext/vector_float1_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_float2.hpp b/external/glm/include/glm/ext/vector_float2.hpp index d31545d..d31545d 100644 --- a/deps/glm/include/glm/ext/vector_float2.hpp +++ b/external/glm/include/glm/ext/vector_float2.hpp diff --git a/deps/glm/include/glm/ext/vector_float2_precision.hpp b/external/glm/include/glm/ext/vector_float2_precision.hpp index 23c0820..23c0820 100644 --- a/deps/glm/include/glm/ext/vector_float2_precision.hpp +++ b/external/glm/include/glm/ext/vector_float2_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_float3.hpp b/external/glm/include/glm/ext/vector_float3.hpp index cd79a62..cd79a62 100644 --- a/deps/glm/include/glm/ext/vector_float3.hpp +++ b/external/glm/include/glm/ext/vector_float3.hpp diff --git a/deps/glm/include/glm/ext/vector_float3_precision.hpp b/external/glm/include/glm/ext/vector_float3_precision.hpp index be640b5..be640b5 100644 --- a/deps/glm/include/glm/ext/vector_float3_precision.hpp +++ b/external/glm/include/glm/ext/vector_float3_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_float4.hpp b/external/glm/include/glm/ext/vector_float4.hpp index d84adcc..d84adcc 100644 --- a/deps/glm/include/glm/ext/vector_float4.hpp +++ b/external/glm/include/glm/ext/vector_float4.hpp diff --git a/deps/glm/include/glm/ext/vector_float4_precision.hpp b/external/glm/include/glm/ext/vector_float4_precision.hpp index aede838..aede838 100644 --- a/deps/glm/include/glm/ext/vector_float4_precision.hpp +++ b/external/glm/include/glm/ext/vector_float4_precision.hpp diff --git a/deps/glm/include/glm/ext/vector_int1.hpp b/external/glm/include/glm/ext/vector_int1.hpp index dc86038..dc86038 100644 --- a/deps/glm/include/glm/ext/vector_int1.hpp +++ b/external/glm/include/glm/ext/vector_int1.hpp diff --git a/deps/glm/include/glm/ext/vector_int1_sized.hpp b/external/glm/include/glm/ext/vector_int1_sized.hpp index de0d4cf..de0d4cf 100644 --- a/deps/glm/include/glm/ext/vector_int1_sized.hpp +++ b/external/glm/include/glm/ext/vector_int1_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_int2.hpp b/external/glm/include/glm/ext/vector_int2.hpp index aef803e..aef803e 100644 --- a/deps/glm/include/glm/ext/vector_int2.hpp +++ b/external/glm/include/glm/ext/vector_int2.hpp diff --git a/deps/glm/include/glm/ext/vector_int2_sized.hpp b/external/glm/include/glm/ext/vector_int2_sized.hpp index 1fd57ee..1fd57ee 100644 --- a/deps/glm/include/glm/ext/vector_int2_sized.hpp +++ b/external/glm/include/glm/ext/vector_int2_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_int3.hpp b/external/glm/include/glm/ext/vector_int3.hpp index 4767e61..4767e61 100644 --- a/deps/glm/include/glm/ext/vector_int3.hpp +++ b/external/glm/include/glm/ext/vector_int3.hpp diff --git a/deps/glm/include/glm/ext/vector_int3_sized.hpp b/external/glm/include/glm/ext/vector_int3_sized.hpp index 085a3fe..085a3fe 100644 --- a/deps/glm/include/glm/ext/vector_int3_sized.hpp +++ b/external/glm/include/glm/ext/vector_int3_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_int4.hpp b/external/glm/include/glm/ext/vector_int4.hpp index bb23adf..bb23adf 100644 --- a/deps/glm/include/glm/ext/vector_int4.hpp +++ b/external/glm/include/glm/ext/vector_int4.hpp diff --git a/deps/glm/include/glm/ext/vector_int4_sized.hpp b/external/glm/include/glm/ext/vector_int4_sized.hpp index c63d465..c63d465 100644 --- a/deps/glm/include/glm/ext/vector_int4_sized.hpp +++ b/external/glm/include/glm/ext/vector_int4_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_integer.hpp b/external/glm/include/glm/ext/vector_integer.hpp index 1304dd8..1304dd8 100644 --- a/deps/glm/include/glm/ext/vector_integer.hpp +++ b/external/glm/include/glm/ext/vector_integer.hpp diff --git a/deps/glm/include/glm/ext/vector_integer.inl b/external/glm/include/glm/ext/vector_integer.inl index cefb132..cefb132 100644 --- a/deps/glm/include/glm/ext/vector_integer.inl +++ b/external/glm/include/glm/ext/vector_integer.inl diff --git a/deps/glm/include/glm/ext/vector_packing.hpp b/external/glm/include/glm/ext/vector_packing.hpp index 76e5d0c..76e5d0c 100644 --- a/deps/glm/include/glm/ext/vector_packing.hpp +++ b/external/glm/include/glm/ext/vector_packing.hpp diff --git a/deps/glm/include/glm/ext/vector_packing.inl b/external/glm/include/glm/ext/vector_packing.inl index e69de29..e69de29 100644 --- a/deps/glm/include/glm/ext/vector_packing.inl +++ b/external/glm/include/glm/ext/vector_packing.inl diff --git a/deps/glm/include/glm/ext/vector_reciprocal.hpp b/external/glm/include/glm/ext/vector_reciprocal.hpp index 84d6766..84d6766 100644 --- a/deps/glm/include/glm/ext/vector_reciprocal.hpp +++ b/external/glm/include/glm/ext/vector_reciprocal.hpp diff --git a/deps/glm/include/glm/ext/vector_reciprocal.inl b/external/glm/include/glm/ext/vector_reciprocal.inl index b85102a..b85102a 100644 --- a/deps/glm/include/glm/ext/vector_reciprocal.inl +++ b/external/glm/include/glm/ext/vector_reciprocal.inl diff --git a/deps/glm/include/glm/ext/vector_relational.hpp b/external/glm/include/glm/ext/vector_relational.hpp index 1c2367d..1c2367d 100644 --- a/deps/glm/include/glm/ext/vector_relational.hpp +++ b/external/glm/include/glm/ext/vector_relational.hpp diff --git a/deps/glm/include/glm/ext/vector_relational.inl b/external/glm/include/glm/ext/vector_relational.inl index 7a39ab5..7a39ab5 100644 --- a/deps/glm/include/glm/ext/vector_relational.inl +++ b/external/glm/include/glm/ext/vector_relational.inl diff --git a/deps/glm/include/glm/ext/vector_uint1.hpp b/external/glm/include/glm/ext/vector_uint1.hpp index eb8a704..eb8a704 100644 --- a/deps/glm/include/glm/ext/vector_uint1.hpp +++ b/external/glm/include/glm/ext/vector_uint1.hpp diff --git a/deps/glm/include/glm/ext/vector_uint1_sized.hpp b/external/glm/include/glm/ext/vector_uint1_sized.hpp index 2a938bb..2a938bb 100644 --- a/deps/glm/include/glm/ext/vector_uint1_sized.hpp +++ b/external/glm/include/glm/ext/vector_uint1_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_uint2.hpp b/external/glm/include/glm/ext/vector_uint2.hpp index 03c00f5..03c00f5 100644 --- a/deps/glm/include/glm/ext/vector_uint2.hpp +++ b/external/glm/include/glm/ext/vector_uint2.hpp diff --git a/deps/glm/include/glm/ext/vector_uint2_sized.hpp b/external/glm/include/glm/ext/vector_uint2_sized.hpp index 620fdc6..620fdc6 100644 --- a/deps/glm/include/glm/ext/vector_uint2_sized.hpp +++ b/external/glm/include/glm/ext/vector_uint2_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_uint3.hpp b/external/glm/include/glm/ext/vector_uint3.hpp index f5b41c4..f5b41c4 100644 --- a/deps/glm/include/glm/ext/vector_uint3.hpp +++ b/external/glm/include/glm/ext/vector_uint3.hpp diff --git a/deps/glm/include/glm/ext/vector_uint3_sized.hpp b/external/glm/include/glm/ext/vector_uint3_sized.hpp index 6f96b98..6f96b98 100644 --- a/deps/glm/include/glm/ext/vector_uint3_sized.hpp +++ b/external/glm/include/glm/ext/vector_uint3_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_uint4.hpp b/external/glm/include/glm/ext/vector_uint4.hpp index 32ced58..32ced58 100644 --- a/deps/glm/include/glm/ext/vector_uint4.hpp +++ b/external/glm/include/glm/ext/vector_uint4.hpp diff --git a/deps/glm/include/glm/ext/vector_uint4_sized.hpp b/external/glm/include/glm/ext/vector_uint4_sized.hpp index da992ea..da992ea 100644 --- a/deps/glm/include/glm/ext/vector_uint4_sized.hpp +++ b/external/glm/include/glm/ext/vector_uint4_sized.hpp diff --git a/deps/glm/include/glm/ext/vector_ulp.hpp b/external/glm/include/glm/ext/vector_ulp.hpp index 7c539bb..7c539bb 100644 --- a/deps/glm/include/glm/ext/vector_ulp.hpp +++ b/external/glm/include/glm/ext/vector_ulp.hpp diff --git a/deps/glm/include/glm/ext/vector_ulp.inl b/external/glm/include/glm/ext/vector_ulp.inl index d3c7648..d3c7648 100644 --- a/deps/glm/include/glm/ext/vector_ulp.inl +++ b/external/glm/include/glm/ext/vector_ulp.inl diff --git a/deps/glm/include/glm/fwd.hpp b/external/glm/include/glm/fwd.hpp index 9c2e5ea..9c2e5ea 100644 --- a/deps/glm/include/glm/fwd.hpp +++ b/external/glm/include/glm/fwd.hpp diff --git a/deps/glm/include/glm/geometric.hpp b/external/glm/include/glm/geometric.hpp index ac857e6..ac857e6 100644 --- a/deps/glm/include/glm/geometric.hpp +++ b/external/glm/include/glm/geometric.hpp diff --git a/deps/glm/include/glm/glm.cppm b/external/glm/include/glm/glm.cppm index 85e946e..85e946e 100644 --- a/deps/glm/include/glm/glm.cppm +++ b/external/glm/include/glm/glm.cppm diff --git a/deps/glm/include/glm/glm.hpp b/external/glm/include/glm/glm.hpp index 8b37545..8b37545 100644 --- a/deps/glm/include/glm/glm.hpp +++ b/external/glm/include/glm/glm.hpp diff --git a/deps/glm/include/glm/gtc/bitfield.hpp b/external/glm/include/glm/gtc/bitfield.hpp index 084fbe7..084fbe7 100644 --- a/deps/glm/include/glm/gtc/bitfield.hpp +++ b/external/glm/include/glm/gtc/bitfield.hpp diff --git a/deps/glm/include/glm/gtc/bitfield.inl b/external/glm/include/glm/gtc/bitfield.inl index e7a0b4f..e7a0b4f 100644 --- a/deps/glm/include/glm/gtc/bitfield.inl +++ b/external/glm/include/glm/gtc/bitfield.inl diff --git a/deps/glm/include/glm/gtc/color_space.hpp b/external/glm/include/glm/gtc/color_space.hpp index cffd9f0..cffd9f0 100644 --- a/deps/glm/include/glm/gtc/color_space.hpp +++ b/external/glm/include/glm/gtc/color_space.hpp diff --git a/deps/glm/include/glm/gtc/color_space.inl b/external/glm/include/glm/gtc/color_space.inl index 2a90004..2a90004 100644 --- a/deps/glm/include/glm/gtc/color_space.inl +++ b/external/glm/include/glm/gtc/color_space.inl diff --git a/deps/glm/include/glm/gtc/constants.hpp b/external/glm/include/glm/gtc/constants.hpp index 6a1f37d..6a1f37d 100644 --- a/deps/glm/include/glm/gtc/constants.hpp +++ b/external/glm/include/glm/gtc/constants.hpp diff --git a/deps/glm/include/glm/gtc/constants.inl b/external/glm/include/glm/gtc/constants.inl index e9d3776..e9d3776 100644 --- a/deps/glm/include/glm/gtc/constants.inl +++ b/external/glm/include/glm/gtc/constants.inl diff --git a/deps/glm/include/glm/gtc/epsilon.hpp b/external/glm/include/glm/gtc/epsilon.hpp index 640439b..640439b 100644 --- a/deps/glm/include/glm/gtc/epsilon.hpp +++ b/external/glm/include/glm/gtc/epsilon.hpp diff --git a/deps/glm/include/glm/gtc/epsilon.inl b/external/glm/include/glm/gtc/epsilon.inl index 508b9f8..508b9f8 100644 --- a/deps/glm/include/glm/gtc/epsilon.inl +++ b/external/glm/include/glm/gtc/epsilon.inl diff --git a/deps/glm/include/glm/gtc/integer.hpp b/external/glm/include/glm/gtc/integer.hpp index cff08dc..cff08dc 100644 --- a/deps/glm/include/glm/gtc/integer.hpp +++ b/external/glm/include/glm/gtc/integer.hpp diff --git a/deps/glm/include/glm/gtc/integer.inl b/external/glm/include/glm/gtc/integer.inl index 5f66dfe..5f66dfe 100644 --- a/deps/glm/include/glm/gtc/integer.inl +++ b/external/glm/include/glm/gtc/integer.inl diff --git a/deps/glm/include/glm/gtc/matrix_access.hpp b/external/glm/include/glm/gtc/matrix_access.hpp index 4935ba7..4935ba7 100644 --- a/deps/glm/include/glm/gtc/matrix_access.hpp +++ b/external/glm/include/glm/gtc/matrix_access.hpp diff --git a/deps/glm/include/glm/gtc/matrix_access.inl b/external/glm/include/glm/gtc/matrix_access.inl index 09fcc10..09fcc10 100644 --- a/deps/glm/include/glm/gtc/matrix_access.inl +++ b/external/glm/include/glm/gtc/matrix_access.inl diff --git a/deps/glm/include/glm/gtc/matrix_integer.hpp b/external/glm/include/glm/gtc/matrix_integer.hpp index d7ebdc7..d7ebdc7 100644 --- a/deps/glm/include/glm/gtc/matrix_integer.hpp +++ b/external/glm/include/glm/gtc/matrix_integer.hpp diff --git a/deps/glm/include/glm/gtc/matrix_inverse.hpp b/external/glm/include/glm/gtc/matrix_inverse.hpp index 75d53f2..75d53f2 100644 --- a/deps/glm/include/glm/gtc/matrix_inverse.hpp +++ b/external/glm/include/glm/gtc/matrix_inverse.hpp diff --git a/deps/glm/include/glm/gtc/matrix_inverse.inl b/external/glm/include/glm/gtc/matrix_inverse.inl index c004b9e..c004b9e 100644 --- a/deps/glm/include/glm/gtc/matrix_inverse.inl +++ b/external/glm/include/glm/gtc/matrix_inverse.inl diff --git a/deps/glm/include/glm/gtc/matrix_transform.hpp b/external/glm/include/glm/gtc/matrix_transform.hpp index 612418f..612418f 100644 --- a/deps/glm/include/glm/gtc/matrix_transform.hpp +++ b/external/glm/include/glm/gtc/matrix_transform.hpp diff --git a/deps/glm/include/glm/gtc/matrix_transform.inl b/external/glm/include/glm/gtc/matrix_transform.inl index 15b46bc..15b46bc 100644 --- a/deps/glm/include/glm/gtc/matrix_transform.inl +++ b/external/glm/include/glm/gtc/matrix_transform.inl diff --git a/deps/glm/include/glm/gtc/noise.hpp b/external/glm/include/glm/gtc/noise.hpp index ab1772e..ab1772e 100644 --- a/deps/glm/include/glm/gtc/noise.hpp +++ b/external/glm/include/glm/gtc/noise.hpp diff --git a/deps/glm/include/glm/gtc/noise.inl b/external/glm/include/glm/gtc/noise.inl index a1cf399..a1cf399 100644 --- a/deps/glm/include/glm/gtc/noise.inl +++ b/external/glm/include/glm/gtc/noise.inl diff --git a/deps/glm/include/glm/gtc/packing.hpp b/external/glm/include/glm/gtc/packing.hpp index 8e416b3..8e416b3 100644 --- a/deps/glm/include/glm/gtc/packing.hpp +++ b/external/glm/include/glm/gtc/packing.hpp diff --git a/deps/glm/include/glm/gtc/packing.inl b/external/glm/include/glm/gtc/packing.inl index 1792760..1792760 100644 --- a/deps/glm/include/glm/gtc/packing.inl +++ b/external/glm/include/glm/gtc/packing.inl diff --git a/deps/glm/include/glm/gtc/quaternion.hpp b/external/glm/include/glm/gtc/quaternion.hpp index 314449e..314449e 100644 --- a/deps/glm/include/glm/gtc/quaternion.hpp +++ b/external/glm/include/glm/gtc/quaternion.hpp diff --git a/deps/glm/include/glm/gtc/quaternion.inl b/external/glm/include/glm/gtc/quaternion.inl index ea159f2..ea159f2 100644 --- a/deps/glm/include/glm/gtc/quaternion.inl +++ b/external/glm/include/glm/gtc/quaternion.inl diff --git a/deps/glm/include/glm/gtc/quaternion_simd.inl b/external/glm/include/glm/gtc/quaternion_simd.inl index e69de29..e69de29 100644 --- a/deps/glm/include/glm/gtc/quaternion_simd.inl +++ b/external/glm/include/glm/gtc/quaternion_simd.inl diff --git a/deps/glm/include/glm/gtc/random.hpp b/external/glm/include/glm/gtc/random.hpp index c6485bf..c6485bf 100644 --- a/deps/glm/include/glm/gtc/random.hpp +++ b/external/glm/include/glm/gtc/random.hpp diff --git a/deps/glm/include/glm/gtc/random.inl b/external/glm/include/glm/gtc/random.inl index 249ec9f..249ec9f 100644 --- a/deps/glm/include/glm/gtc/random.inl +++ b/external/glm/include/glm/gtc/random.inl diff --git a/deps/glm/include/glm/gtc/reciprocal.hpp b/external/glm/include/glm/gtc/reciprocal.hpp index 4d0fc91..4d0fc91 100644 --- a/deps/glm/include/glm/gtc/reciprocal.hpp +++ b/external/glm/include/glm/gtc/reciprocal.hpp diff --git a/deps/glm/include/glm/gtc/round.hpp b/external/glm/include/glm/gtc/round.hpp index 56edbbc..56edbbc 100644 --- a/deps/glm/include/glm/gtc/round.hpp +++ b/external/glm/include/glm/gtc/round.hpp diff --git a/deps/glm/include/glm/gtc/round.inl b/external/glm/include/glm/gtc/round.inl index 48411e4..48411e4 100644 --- a/deps/glm/include/glm/gtc/round.inl +++ b/external/glm/include/glm/gtc/round.inl diff --git a/deps/glm/include/glm/gtc/type_aligned.hpp b/external/glm/include/glm/gtc/type_aligned.hpp index 5403abf..5403abf 100644 --- a/deps/glm/include/glm/gtc/type_aligned.hpp +++ b/external/glm/include/glm/gtc/type_aligned.hpp diff --git a/deps/glm/include/glm/gtc/type_precision.hpp b/external/glm/include/glm/gtc/type_precision.hpp index 775e2f4..775e2f4 100644 --- a/deps/glm/include/glm/gtc/type_precision.hpp +++ b/external/glm/include/glm/gtc/type_precision.hpp diff --git a/deps/glm/include/glm/gtc/type_precision.inl b/external/glm/include/glm/gtc/type_precision.inl index ae80912..ae80912 100644 --- a/deps/glm/include/glm/gtc/type_precision.inl +++ b/external/glm/include/glm/gtc/type_precision.inl diff --git a/deps/glm/include/glm/gtc/type_ptr.hpp b/external/glm/include/glm/gtc/type_ptr.hpp index d7e625a..d7e625a 100644 --- a/deps/glm/include/glm/gtc/type_ptr.hpp +++ b/external/glm/include/glm/gtc/type_ptr.hpp diff --git a/deps/glm/include/glm/gtc/type_ptr.inl b/external/glm/include/glm/gtc/type_ptr.inl index 26b20b5..26b20b5 100644 --- a/deps/glm/include/glm/gtc/type_ptr.inl +++ b/external/glm/include/glm/gtc/type_ptr.inl diff --git a/deps/glm/include/glm/gtc/ulp.hpp b/external/glm/include/glm/gtc/ulp.hpp index 7b918f0..7b918f0 100644 --- a/deps/glm/include/glm/gtc/ulp.hpp +++ b/external/glm/include/glm/gtc/ulp.hpp diff --git a/deps/glm/include/glm/gtc/ulp.inl b/external/glm/include/glm/gtc/ulp.inl index 836c84b..836c84b 100644 --- a/deps/glm/include/glm/gtc/ulp.inl +++ b/external/glm/include/glm/gtc/ulp.inl diff --git a/deps/glm/include/glm/gtc/vec1.hpp b/external/glm/include/glm/gtc/vec1.hpp index 63697a2..63697a2 100644 --- a/deps/glm/include/glm/gtc/vec1.hpp +++ b/external/glm/include/glm/gtc/vec1.hpp diff --git a/deps/glm/include/glm/gtx/associated_min_max.hpp b/external/glm/include/glm/gtx/associated_min_max.hpp index 435230d..435230d 100644 --- a/deps/glm/include/glm/gtx/associated_min_max.hpp +++ b/external/glm/include/glm/gtx/associated_min_max.hpp diff --git a/deps/glm/include/glm/gtx/associated_min_max.inl b/external/glm/include/glm/gtx/associated_min_max.inl index f09f5bb..f09f5bb 100644 --- a/deps/glm/include/glm/gtx/associated_min_max.inl +++ b/external/glm/include/glm/gtx/associated_min_max.inl diff --git a/deps/glm/include/glm/gtx/bit.hpp b/external/glm/include/glm/gtx/bit.hpp index 2f6b3f6..2f6b3f6 100644 --- a/deps/glm/include/glm/gtx/bit.hpp +++ b/external/glm/include/glm/gtx/bit.hpp diff --git a/deps/glm/include/glm/gtx/bit.inl b/external/glm/include/glm/gtx/bit.inl index 621b626..621b626 100644 --- a/deps/glm/include/glm/gtx/bit.inl +++ b/external/glm/include/glm/gtx/bit.inl diff --git a/deps/glm/include/glm/gtx/closest_point.hpp b/external/glm/include/glm/gtx/closest_point.hpp index a248e4b..a248e4b 100644 --- a/deps/glm/include/glm/gtx/closest_point.hpp +++ b/external/glm/include/glm/gtx/closest_point.hpp diff --git a/deps/glm/include/glm/gtx/closest_point.inl b/external/glm/include/glm/gtx/closest_point.inl index 0a39b04..0a39b04 100644 --- a/deps/glm/include/glm/gtx/closest_point.inl +++ b/external/glm/include/glm/gtx/closest_point.inl diff --git a/deps/glm/include/glm/gtx/color_encoding.hpp b/external/glm/include/glm/gtx/color_encoding.hpp index 4769e0a..4769e0a 100644 --- a/deps/glm/include/glm/gtx/color_encoding.hpp +++ b/external/glm/include/glm/gtx/color_encoding.hpp diff --git a/deps/glm/include/glm/gtx/color_encoding.inl b/external/glm/include/glm/gtx/color_encoding.inl index e50fa3e..e50fa3e 100644 --- a/deps/glm/include/glm/gtx/color_encoding.inl +++ b/external/glm/include/glm/gtx/color_encoding.inl diff --git a/deps/glm/include/glm/gtx/color_space.hpp b/external/glm/include/glm/gtx/color_space.hpp index c39a1f4..c39a1f4 100644 --- a/deps/glm/include/glm/gtx/color_space.hpp +++ b/external/glm/include/glm/gtx/color_space.hpp diff --git a/deps/glm/include/glm/gtx/color_space.inl b/external/glm/include/glm/gtx/color_space.inl index b3183b9..b3183b9 100644 --- a/deps/glm/include/glm/gtx/color_space.inl +++ b/external/glm/include/glm/gtx/color_space.inl diff --git a/deps/glm/include/glm/gtx/color_space_YCoCg.hpp b/external/glm/include/glm/gtx/color_space_YCoCg.hpp index a418037..a418037 100644 --- a/deps/glm/include/glm/gtx/color_space_YCoCg.hpp +++ b/external/glm/include/glm/gtx/color_space_YCoCg.hpp diff --git a/deps/glm/include/glm/gtx/color_space_YCoCg.inl b/external/glm/include/glm/gtx/color_space_YCoCg.inl index 83ba857..83ba857 100644 --- a/deps/glm/include/glm/gtx/color_space_YCoCg.inl +++ b/external/glm/include/glm/gtx/color_space_YCoCg.inl diff --git a/deps/glm/include/glm/gtx/common.hpp b/external/glm/include/glm/gtx/common.hpp index 283f947..283f947 100644 --- a/deps/glm/include/glm/gtx/common.hpp +++ b/external/glm/include/glm/gtx/common.hpp diff --git a/deps/glm/include/glm/gtx/common.inl b/external/glm/include/glm/gtx/common.inl index 4575b20..4575b20 100644 --- a/deps/glm/include/glm/gtx/common.inl +++ b/external/glm/include/glm/gtx/common.inl diff --git a/deps/glm/include/glm/gtx/compatibility.hpp b/external/glm/include/glm/gtx/compatibility.hpp index 463f86f..463f86f 100644 --- a/deps/glm/include/glm/gtx/compatibility.hpp +++ b/external/glm/include/glm/gtx/compatibility.hpp diff --git a/deps/glm/include/glm/gtx/compatibility.inl b/external/glm/include/glm/gtx/compatibility.inl index 1d49496..1d49496 100644 --- a/deps/glm/include/glm/gtx/compatibility.inl +++ b/external/glm/include/glm/gtx/compatibility.inl diff --git a/deps/glm/include/glm/gtx/component_wise.hpp b/external/glm/include/glm/gtx/component_wise.hpp index b1caaa2..b1caaa2 100644 --- a/deps/glm/include/glm/gtx/component_wise.hpp +++ b/external/glm/include/glm/gtx/component_wise.hpp diff --git a/deps/glm/include/glm/gtx/component_wise.inl b/external/glm/include/glm/gtx/component_wise.inl index f8217b2..f8217b2 100644 --- a/deps/glm/include/glm/gtx/component_wise.inl +++ b/external/glm/include/glm/gtx/component_wise.inl diff --git a/deps/glm/include/glm/gtx/dual_quaternion.hpp b/external/glm/include/glm/gtx/dual_quaternion.hpp index 04a6070..04a6070 100644 --- a/deps/glm/include/glm/gtx/dual_quaternion.hpp +++ b/external/glm/include/glm/gtx/dual_quaternion.hpp diff --git a/deps/glm/include/glm/gtx/dual_quaternion.inl b/external/glm/include/glm/gtx/dual_quaternion.inl index 3a04160..3a04160 100644 --- a/deps/glm/include/glm/gtx/dual_quaternion.inl +++ b/external/glm/include/glm/gtx/dual_quaternion.inl diff --git a/deps/glm/include/glm/gtx/easing.hpp b/external/glm/include/glm/gtx/easing.hpp index 50ed903..50ed903 100644 --- a/deps/glm/include/glm/gtx/easing.hpp +++ b/external/glm/include/glm/gtx/easing.hpp diff --git a/deps/glm/include/glm/gtx/easing.inl b/external/glm/include/glm/gtx/easing.inl index b599c30..b599c30 100644 --- a/deps/glm/include/glm/gtx/easing.inl +++ b/external/glm/include/glm/gtx/easing.inl diff --git a/deps/glm/include/glm/gtx/euler_angles.hpp b/external/glm/include/glm/gtx/euler_angles.hpp index 5d67d8e..5d67d8e 100644 --- a/deps/glm/include/glm/gtx/euler_angles.hpp +++ b/external/glm/include/glm/gtx/euler_angles.hpp diff --git a/deps/glm/include/glm/gtx/euler_angles.inl b/external/glm/include/glm/gtx/euler_angles.inl index 85f22b9..85f22b9 100644 --- a/deps/glm/include/glm/gtx/euler_angles.inl +++ b/external/glm/include/glm/gtx/euler_angles.inl diff --git a/deps/glm/include/glm/gtx/extend.hpp b/external/glm/include/glm/gtx/extend.hpp index 46bf5e7..46bf5e7 100644 --- a/deps/glm/include/glm/gtx/extend.hpp +++ b/external/glm/include/glm/gtx/extend.hpp diff --git a/deps/glm/include/glm/gtx/extend.inl b/external/glm/include/glm/gtx/extend.inl index 32128eb..32128eb 100644 --- a/deps/glm/include/glm/gtx/extend.inl +++ b/external/glm/include/glm/gtx/extend.inl diff --git a/deps/glm/include/glm/gtx/extended_min_max.hpp b/external/glm/include/glm/gtx/extended_min_max.hpp index e1b722f..e1b722f 100644 --- a/deps/glm/include/glm/gtx/extended_min_max.hpp +++ b/external/glm/include/glm/gtx/extended_min_max.hpp diff --git a/deps/glm/include/glm/gtx/extended_min_max.inl b/external/glm/include/glm/gtx/extended_min_max.inl index de5998f..de5998f 100644 --- a/deps/glm/include/glm/gtx/extended_min_max.inl +++ b/external/glm/include/glm/gtx/extended_min_max.inl diff --git a/deps/glm/include/glm/gtx/exterior_product.hpp b/external/glm/include/glm/gtx/exterior_product.hpp index 1979acc..1979acc 100644 --- a/deps/glm/include/glm/gtx/exterior_product.hpp +++ b/external/glm/include/glm/gtx/exterior_product.hpp diff --git a/deps/glm/include/glm/gtx/exterior_product.inl b/external/glm/include/glm/gtx/exterior_product.inl index 690085d..690085d 100644 --- a/deps/glm/include/glm/gtx/exterior_product.inl +++ b/external/glm/include/glm/gtx/exterior_product.inl diff --git a/deps/glm/include/glm/gtx/fast_exponential.hpp b/external/glm/include/glm/gtx/fast_exponential.hpp index 9fae325..9fae325 100644 --- a/deps/glm/include/glm/gtx/fast_exponential.hpp +++ b/external/glm/include/glm/gtx/fast_exponential.hpp diff --git a/deps/glm/include/glm/gtx/fast_exponential.inl b/external/glm/include/glm/gtx/fast_exponential.inl index 5b11742..5b11742 100644 --- a/deps/glm/include/glm/gtx/fast_exponential.inl +++ b/external/glm/include/glm/gtx/fast_exponential.inl diff --git a/deps/glm/include/glm/gtx/fast_square_root.hpp b/external/glm/include/glm/gtx/fast_square_root.hpp index 80729db..80729db 100644 --- a/deps/glm/include/glm/gtx/fast_square_root.hpp +++ b/external/glm/include/glm/gtx/fast_square_root.hpp diff --git a/deps/glm/include/glm/gtx/fast_square_root.inl b/external/glm/include/glm/gtx/fast_square_root.inl index 60fdb7a..60fdb7a 100644 --- a/deps/glm/include/glm/gtx/fast_square_root.inl +++ b/external/glm/include/glm/gtx/fast_square_root.inl diff --git a/deps/glm/include/glm/gtx/fast_trigonometry.hpp b/external/glm/include/glm/gtx/fast_trigonometry.hpp index 93acab5..93acab5 100644 --- a/deps/glm/include/glm/gtx/fast_trigonometry.hpp +++ b/external/glm/include/glm/gtx/fast_trigonometry.hpp diff --git a/deps/glm/include/glm/gtx/fast_trigonometry.inl b/external/glm/include/glm/gtx/fast_trigonometry.inl index 1a710cb..1a710cb 100644 --- a/deps/glm/include/glm/gtx/fast_trigonometry.inl +++ b/external/glm/include/glm/gtx/fast_trigonometry.inl diff --git a/deps/glm/include/glm/gtx/float_notmalize.inl b/external/glm/include/glm/gtx/float_notmalize.inl index 8cdbc5a..8cdbc5a 100644 --- a/deps/glm/include/glm/gtx/float_notmalize.inl +++ b/external/glm/include/glm/gtx/float_notmalize.inl diff --git a/deps/glm/include/glm/gtx/functions.hpp b/external/glm/include/glm/gtx/functions.hpp index df68a0d..df68a0d 100644 --- a/deps/glm/include/glm/gtx/functions.hpp +++ b/external/glm/include/glm/gtx/functions.hpp diff --git a/deps/glm/include/glm/gtx/functions.inl b/external/glm/include/glm/gtx/functions.inl index 29cbb20..29cbb20 100644 --- a/deps/glm/include/glm/gtx/functions.inl +++ b/external/glm/include/glm/gtx/functions.inl diff --git a/deps/glm/include/glm/gtx/gradient_paint.hpp b/external/glm/include/glm/gtx/gradient_paint.hpp index 5656445..5656445 100644 --- a/deps/glm/include/glm/gtx/gradient_paint.hpp +++ b/external/glm/include/glm/gtx/gradient_paint.hpp diff --git a/deps/glm/include/glm/gtx/gradient_paint.inl b/external/glm/include/glm/gtx/gradient_paint.inl index 4c495e6..4c495e6 100644 --- a/deps/glm/include/glm/gtx/gradient_paint.inl +++ b/external/glm/include/glm/gtx/gradient_paint.inl diff --git a/deps/glm/include/glm/gtx/handed_coordinate_space.hpp b/external/glm/include/glm/gtx/handed_coordinate_space.hpp index 7c2aada..7c2aada 100644 --- a/deps/glm/include/glm/gtx/handed_coordinate_space.hpp +++ b/external/glm/include/glm/gtx/handed_coordinate_space.hpp diff --git a/deps/glm/include/glm/gtx/handed_coordinate_space.inl b/external/glm/include/glm/gtx/handed_coordinate_space.inl index e43c17b..e43c17b 100644 --- a/deps/glm/include/glm/gtx/handed_coordinate_space.inl +++ b/external/glm/include/glm/gtx/handed_coordinate_space.inl diff --git a/deps/glm/include/glm/gtx/hash.hpp b/external/glm/include/glm/gtx/hash.hpp index ef89290..ef89290 100644 --- a/deps/glm/include/glm/gtx/hash.hpp +++ b/external/glm/include/glm/gtx/hash.hpp diff --git a/deps/glm/include/glm/gtx/hash.inl b/external/glm/include/glm/gtx/hash.inl index bcadfe5..bcadfe5 100644 --- a/deps/glm/include/glm/gtx/hash.inl +++ b/external/glm/include/glm/gtx/hash.inl diff --git a/deps/glm/include/glm/gtx/integer.hpp b/external/glm/include/glm/gtx/integer.hpp index 2b16830..2b16830 100644 --- a/deps/glm/include/glm/gtx/integer.hpp +++ b/external/glm/include/glm/gtx/integer.hpp diff --git a/deps/glm/include/glm/gtx/integer.inl b/external/glm/include/glm/gtx/integer.inl index eb5df30..eb5df30 100644 --- a/deps/glm/include/glm/gtx/integer.inl +++ b/external/glm/include/glm/gtx/integer.inl diff --git a/deps/glm/include/glm/gtx/intersect.hpp b/external/glm/include/glm/gtx/intersect.hpp index c7aec6f..c7aec6f 100644 --- a/deps/glm/include/glm/gtx/intersect.hpp +++ b/external/glm/include/glm/gtx/intersect.hpp diff --git a/deps/glm/include/glm/gtx/intersect.inl b/external/glm/include/glm/gtx/intersect.inl index 925a903..925a903 100644 --- a/deps/glm/include/glm/gtx/intersect.inl +++ b/external/glm/include/glm/gtx/intersect.inl diff --git a/deps/glm/include/glm/gtx/io.hpp b/external/glm/include/glm/gtx/io.hpp index 5afc8cc..5afc8cc 100644 --- a/deps/glm/include/glm/gtx/io.hpp +++ b/external/glm/include/glm/gtx/io.hpp diff --git a/deps/glm/include/glm/gtx/io.inl b/external/glm/include/glm/gtx/io.inl index d4ef825..d4ef825 100644 --- a/deps/glm/include/glm/gtx/io.inl +++ b/external/glm/include/glm/gtx/io.inl diff --git a/deps/glm/include/glm/gtx/log_base.hpp b/external/glm/include/glm/gtx/log_base.hpp index 915c7a4..915c7a4 100644 --- a/deps/glm/include/glm/gtx/log_base.hpp +++ b/external/glm/include/glm/gtx/log_base.hpp diff --git a/deps/glm/include/glm/gtx/log_base.inl b/external/glm/include/glm/gtx/log_base.inl index 4bbb8e8..4bbb8e8 100644 --- a/deps/glm/include/glm/gtx/log_base.inl +++ b/external/glm/include/glm/gtx/log_base.inl diff --git a/deps/glm/include/glm/gtx/matrix_cross_product.hpp b/external/glm/include/glm/gtx/matrix_cross_product.hpp index 882a1d7..882a1d7 100644 --- a/deps/glm/include/glm/gtx/matrix_cross_product.hpp +++ b/external/glm/include/glm/gtx/matrix_cross_product.hpp diff --git a/deps/glm/include/glm/gtx/matrix_cross_product.inl b/external/glm/include/glm/gtx/matrix_cross_product.inl index 3a15397..3a15397 100644 --- a/deps/glm/include/glm/gtx/matrix_cross_product.inl +++ b/external/glm/include/glm/gtx/matrix_cross_product.inl diff --git a/deps/glm/include/glm/gtx/matrix_decompose.hpp b/external/glm/include/glm/gtx/matrix_decompose.hpp index 19ac8a8..19ac8a8 100644 --- a/deps/glm/include/glm/gtx/matrix_decompose.hpp +++ b/external/glm/include/glm/gtx/matrix_decompose.hpp diff --git a/deps/glm/include/glm/gtx/matrix_decompose.inl b/external/glm/include/glm/gtx/matrix_decompose.inl index 1b587e2..1b587e2 100644 --- a/deps/glm/include/glm/gtx/matrix_decompose.inl +++ b/external/glm/include/glm/gtx/matrix_decompose.inl diff --git a/deps/glm/include/glm/gtx/matrix_factorisation.hpp b/external/glm/include/glm/gtx/matrix_factorisation.hpp index dc32847..dc32847 100644 --- a/deps/glm/include/glm/gtx/matrix_factorisation.hpp +++ b/external/glm/include/glm/gtx/matrix_factorisation.hpp diff --git a/deps/glm/include/glm/gtx/matrix_factorisation.inl b/external/glm/include/glm/gtx/matrix_factorisation.inl index 6f1683c..6f1683c 100644 --- a/deps/glm/include/glm/gtx/matrix_factorisation.inl +++ b/external/glm/include/glm/gtx/matrix_factorisation.inl diff --git a/deps/glm/include/glm/gtx/matrix_interpolation.hpp b/external/glm/include/glm/gtx/matrix_interpolation.hpp index e2767c8..e2767c8 100644 --- a/deps/glm/include/glm/gtx/matrix_interpolation.hpp +++ b/external/glm/include/glm/gtx/matrix_interpolation.hpp diff --git a/deps/glm/include/glm/gtx/matrix_interpolation.inl b/external/glm/include/glm/gtx/matrix_interpolation.inl index f4ba3a6..f4ba3a6 100644 --- a/deps/glm/include/glm/gtx/matrix_interpolation.inl +++ b/external/glm/include/glm/gtx/matrix_interpolation.inl diff --git a/deps/glm/include/glm/gtx/matrix_major_storage.hpp b/external/glm/include/glm/gtx/matrix_major_storage.hpp index f518578..f518578 100644 --- a/deps/glm/include/glm/gtx/matrix_major_storage.hpp +++ b/external/glm/include/glm/gtx/matrix_major_storage.hpp diff --git a/deps/glm/include/glm/gtx/matrix_major_storage.inl b/external/glm/include/glm/gtx/matrix_major_storage.inl index 279dd34..279dd34 100644 --- a/deps/glm/include/glm/gtx/matrix_major_storage.inl +++ b/external/glm/include/glm/gtx/matrix_major_storage.inl diff --git a/deps/glm/include/glm/gtx/matrix_operation.hpp b/external/glm/include/glm/gtx/matrix_operation.hpp index 07ed8e8..07ed8e8 100644 --- a/deps/glm/include/glm/gtx/matrix_operation.hpp +++ b/external/glm/include/glm/gtx/matrix_operation.hpp diff --git a/deps/glm/include/glm/gtx/matrix_operation.inl b/external/glm/include/glm/gtx/matrix_operation.inl index a4f4a85..a4f4a85 100644 --- a/deps/glm/include/glm/gtx/matrix_operation.inl +++ b/external/glm/include/glm/gtx/matrix_operation.inl diff --git a/deps/glm/include/glm/gtx/matrix_query.hpp b/external/glm/include/glm/gtx/matrix_query.hpp index de8c655..de8c655 100644 --- a/deps/glm/include/glm/gtx/matrix_query.hpp +++ b/external/glm/include/glm/gtx/matrix_query.hpp diff --git a/deps/glm/include/glm/gtx/matrix_query.inl b/external/glm/include/glm/gtx/matrix_query.inl index dc3ec84..dc3ec84 100644 --- a/deps/glm/include/glm/gtx/matrix_query.inl +++ b/external/glm/include/glm/gtx/matrix_query.inl diff --git a/deps/glm/include/glm/gtx/matrix_transform_2d.hpp b/external/glm/include/glm/gtx/matrix_transform_2d.hpp index deb8da2..deb8da2 100644 --- a/deps/glm/include/glm/gtx/matrix_transform_2d.hpp +++ b/external/glm/include/glm/gtx/matrix_transform_2d.hpp diff --git a/deps/glm/include/glm/gtx/matrix_transform_2d.inl b/external/glm/include/glm/gtx/matrix_transform_2d.inl index a68d24d..a68d24d 100644 --- a/deps/glm/include/glm/gtx/matrix_transform_2d.inl +++ b/external/glm/include/glm/gtx/matrix_transform_2d.inl diff --git a/deps/glm/include/glm/gtx/mixed_product.hpp b/external/glm/include/glm/gtx/mixed_product.hpp index a091274..a091274 100644 --- a/deps/glm/include/glm/gtx/mixed_product.hpp +++ b/external/glm/include/glm/gtx/mixed_product.hpp diff --git a/deps/glm/include/glm/gtx/mixed_product.inl b/external/glm/include/glm/gtx/mixed_product.inl index e5cdbdb..e5cdbdb 100644 --- a/deps/glm/include/glm/gtx/mixed_product.inl +++ b/external/glm/include/glm/gtx/mixed_product.inl diff --git a/deps/glm/include/glm/gtx/norm.hpp b/external/glm/include/glm/gtx/norm.hpp index d6724a8..d6724a8 100644 --- a/deps/glm/include/glm/gtx/norm.hpp +++ b/external/glm/include/glm/gtx/norm.hpp diff --git a/deps/glm/include/glm/gtx/norm.inl b/external/glm/include/glm/gtx/norm.inl index 4a9f796..4a9f796 100644 --- a/deps/glm/include/glm/gtx/norm.inl +++ b/external/glm/include/glm/gtx/norm.inl diff --git a/deps/glm/include/glm/gtx/normal.hpp b/external/glm/include/glm/gtx/normal.hpp index 8b3a4b5..8b3a4b5 100644 --- a/deps/glm/include/glm/gtx/normal.hpp +++ b/external/glm/include/glm/gtx/normal.hpp diff --git a/deps/glm/include/glm/gtx/normal.inl b/external/glm/include/glm/gtx/normal.inl index 74f9fc9..74f9fc9 100644 --- a/deps/glm/include/glm/gtx/normal.inl +++ b/external/glm/include/glm/gtx/normal.inl diff --git a/deps/glm/include/glm/gtx/normalize_dot.hpp b/external/glm/include/glm/gtx/normalize_dot.hpp index 04a6b08..04a6b08 100644 --- a/deps/glm/include/glm/gtx/normalize_dot.hpp +++ b/external/glm/include/glm/gtx/normalize_dot.hpp diff --git a/deps/glm/include/glm/gtx/normalize_dot.inl b/external/glm/include/glm/gtx/normalize_dot.inl index 7bcd9a5..7bcd9a5 100644 --- a/deps/glm/include/glm/gtx/normalize_dot.inl +++ b/external/glm/include/glm/gtx/normalize_dot.inl diff --git a/deps/glm/include/glm/gtx/number_precision.hpp b/external/glm/include/glm/gtx/number_precision.hpp index 5b9663e..5b9663e 100644 --- a/deps/glm/include/glm/gtx/number_precision.hpp +++ b/external/glm/include/glm/gtx/number_precision.hpp diff --git a/deps/glm/include/glm/gtx/optimum_pow.hpp b/external/glm/include/glm/gtx/optimum_pow.hpp index ac34e7e..ac34e7e 100644 --- a/deps/glm/include/glm/gtx/optimum_pow.hpp +++ b/external/glm/include/glm/gtx/optimum_pow.hpp diff --git a/deps/glm/include/glm/gtx/optimum_pow.inl b/external/glm/include/glm/gtx/optimum_pow.inl index a26c19c..a26c19c 100644 --- a/deps/glm/include/glm/gtx/optimum_pow.inl +++ b/external/glm/include/glm/gtx/optimum_pow.inl diff --git a/deps/glm/include/glm/gtx/orthonormalize.hpp b/external/glm/include/glm/gtx/orthonormalize.hpp index 801b755..801b755 100644 --- a/deps/glm/include/glm/gtx/orthonormalize.hpp +++ b/external/glm/include/glm/gtx/orthonormalize.hpp diff --git a/deps/glm/include/glm/gtx/orthonormalize.inl b/external/glm/include/glm/gtx/orthonormalize.inl index cb553ba..cb553ba 100644 --- a/deps/glm/include/glm/gtx/orthonormalize.inl +++ b/external/glm/include/glm/gtx/orthonormalize.inl diff --git a/deps/glm/include/glm/gtx/pca.hpp b/external/glm/include/glm/gtx/pca.hpp index 26f9aec..26f9aec 100644 --- a/deps/glm/include/glm/gtx/pca.hpp +++ b/external/glm/include/glm/gtx/pca.hpp diff --git a/deps/glm/include/glm/gtx/pca.inl b/external/glm/include/glm/gtx/pca.inl index 94cae94..94cae94 100644 --- a/deps/glm/include/glm/gtx/pca.inl +++ b/external/glm/include/glm/gtx/pca.inl diff --git a/deps/glm/include/glm/gtx/perpendicular.hpp b/external/glm/include/glm/gtx/perpendicular.hpp index 4087ab0..4087ab0 100644 --- a/deps/glm/include/glm/gtx/perpendicular.hpp +++ b/external/glm/include/glm/gtx/perpendicular.hpp diff --git a/deps/glm/include/glm/gtx/perpendicular.inl b/external/glm/include/glm/gtx/perpendicular.inl index 1e72f33..1e72f33 100644 --- a/deps/glm/include/glm/gtx/perpendicular.inl +++ b/external/glm/include/glm/gtx/perpendicular.inl diff --git a/deps/glm/include/glm/gtx/polar_coordinates.hpp b/external/glm/include/glm/gtx/polar_coordinates.hpp index c27aacf..c27aacf 100644 --- a/deps/glm/include/glm/gtx/polar_coordinates.hpp +++ b/external/glm/include/glm/gtx/polar_coordinates.hpp diff --git a/deps/glm/include/glm/gtx/polar_coordinates.inl b/external/glm/include/glm/gtx/polar_coordinates.inl index 371c8dd..371c8dd 100644 --- a/deps/glm/include/glm/gtx/polar_coordinates.inl +++ b/external/glm/include/glm/gtx/polar_coordinates.inl diff --git a/deps/glm/include/glm/gtx/projection.hpp b/external/glm/include/glm/gtx/projection.hpp index a438f39..a438f39 100644 --- a/deps/glm/include/glm/gtx/projection.hpp +++ b/external/glm/include/glm/gtx/projection.hpp diff --git a/deps/glm/include/glm/gtx/projection.inl b/external/glm/include/glm/gtx/projection.inl index f23f884..f23f884 100644 --- a/deps/glm/include/glm/gtx/projection.inl +++ b/external/glm/include/glm/gtx/projection.inl diff --git a/deps/glm/include/glm/gtx/quaternion.hpp b/external/glm/include/glm/gtx/quaternion.hpp index f51c521..f51c521 100644 --- a/deps/glm/include/glm/gtx/quaternion.hpp +++ b/external/glm/include/glm/gtx/quaternion.hpp diff --git a/deps/glm/include/glm/gtx/quaternion.inl b/external/glm/include/glm/gtx/quaternion.inl index 5e18899..5e18899 100644 --- a/deps/glm/include/glm/gtx/quaternion.inl +++ b/external/glm/include/glm/gtx/quaternion.inl diff --git a/deps/glm/include/glm/gtx/range.hpp b/external/glm/include/glm/gtx/range.hpp index 50c5e57..50c5e57 100644 --- a/deps/glm/include/glm/gtx/range.hpp +++ b/external/glm/include/glm/gtx/range.hpp diff --git a/deps/glm/include/glm/gtx/raw_data.hpp b/external/glm/include/glm/gtx/raw_data.hpp index 3bc27b9..3bc27b9 100644 --- a/deps/glm/include/glm/gtx/raw_data.hpp +++ b/external/glm/include/glm/gtx/raw_data.hpp diff --git a/deps/glm/include/glm/gtx/raw_data.inl b/external/glm/include/glm/gtx/raw_data.inl index c740317..c740317 100644 --- a/deps/glm/include/glm/gtx/raw_data.inl +++ b/external/glm/include/glm/gtx/raw_data.inl diff --git a/deps/glm/include/glm/gtx/rotate_normalized_axis.hpp b/external/glm/include/glm/gtx/rotate_normalized_axis.hpp index 02c3f5c..02c3f5c 100644 --- a/deps/glm/include/glm/gtx/rotate_normalized_axis.hpp +++ b/external/glm/include/glm/gtx/rotate_normalized_axis.hpp diff --git a/deps/glm/include/glm/gtx/rotate_normalized_axis.inl b/external/glm/include/glm/gtx/rotate_normalized_axis.inl index 352a56c..352a56c 100644 --- a/deps/glm/include/glm/gtx/rotate_normalized_axis.inl +++ b/external/glm/include/glm/gtx/rotate_normalized_axis.inl diff --git a/deps/glm/include/glm/gtx/rotate_vector.hpp b/external/glm/include/glm/gtx/rotate_vector.hpp index b7345bf..b7345bf 100644 --- a/deps/glm/include/glm/gtx/rotate_vector.hpp +++ b/external/glm/include/glm/gtx/rotate_vector.hpp diff --git a/deps/glm/include/glm/gtx/rotate_vector.inl b/external/glm/include/glm/gtx/rotate_vector.inl index f8136e7..f8136e7 100644 --- a/deps/glm/include/glm/gtx/rotate_vector.inl +++ b/external/glm/include/glm/gtx/rotate_vector.inl diff --git a/deps/glm/include/glm/gtx/scalar_multiplication.hpp b/external/glm/include/glm/gtx/scalar_multiplication.hpp index 97df000..97df000 100644 --- a/deps/glm/include/glm/gtx/scalar_multiplication.hpp +++ b/external/glm/include/glm/gtx/scalar_multiplication.hpp diff --git a/deps/glm/include/glm/gtx/scalar_relational.hpp b/external/glm/include/glm/gtx/scalar_relational.hpp index e840932..e840932 100644 --- a/deps/glm/include/glm/gtx/scalar_relational.hpp +++ b/external/glm/include/glm/gtx/scalar_relational.hpp diff --git a/deps/glm/include/glm/gtx/scalar_relational.inl b/external/glm/include/glm/gtx/scalar_relational.inl index c2a121c..c2a121c 100644 --- a/deps/glm/include/glm/gtx/scalar_relational.inl +++ b/external/glm/include/glm/gtx/scalar_relational.inl diff --git a/deps/glm/include/glm/gtx/spline.hpp b/external/glm/include/glm/gtx/spline.hpp index 8df5584..8df5584 100644 --- a/deps/glm/include/glm/gtx/spline.hpp +++ b/external/glm/include/glm/gtx/spline.hpp diff --git a/deps/glm/include/glm/gtx/spline.inl b/external/glm/include/glm/gtx/spline.inl index c3fd056..c3fd056 100644 --- a/deps/glm/include/glm/gtx/spline.inl +++ b/external/glm/include/glm/gtx/spline.inl diff --git a/deps/glm/include/glm/gtx/std_based_type.hpp b/external/glm/include/glm/gtx/std_based_type.hpp index 864885d..864885d 100644 --- a/deps/glm/include/glm/gtx/std_based_type.hpp +++ b/external/glm/include/glm/gtx/std_based_type.hpp diff --git a/deps/glm/include/glm/gtx/std_based_type.inl b/external/glm/include/glm/gtx/std_based_type.inl index 9c34bdb..9c34bdb 100644 --- a/deps/glm/include/glm/gtx/std_based_type.inl +++ b/external/glm/include/glm/gtx/std_based_type.inl diff --git a/deps/glm/include/glm/gtx/string_cast.hpp b/external/glm/include/glm/gtx/string_cast.hpp index 2958edc..2958edc 100644 --- a/deps/glm/include/glm/gtx/string_cast.hpp +++ b/external/glm/include/glm/gtx/string_cast.hpp diff --git a/deps/glm/include/glm/gtx/string_cast.inl b/external/glm/include/glm/gtx/string_cast.inl index 875f2be..875f2be 100644 --- a/deps/glm/include/glm/gtx/string_cast.inl +++ b/external/glm/include/glm/gtx/string_cast.inl diff --git a/deps/glm/include/glm/gtx/texture.hpp b/external/glm/include/glm/gtx/texture.hpp index 608c6ad..608c6ad 100644 --- a/deps/glm/include/glm/gtx/texture.hpp +++ b/external/glm/include/glm/gtx/texture.hpp diff --git a/deps/glm/include/glm/gtx/texture.inl b/external/glm/include/glm/gtx/texture.inl index 593c826..593c826 100644 --- a/deps/glm/include/glm/gtx/texture.inl +++ b/external/glm/include/glm/gtx/texture.inl diff --git a/deps/glm/include/glm/gtx/transform.hpp b/external/glm/include/glm/gtx/transform.hpp index 9707b50..9707b50 100644 --- a/deps/glm/include/glm/gtx/transform.hpp +++ b/external/glm/include/glm/gtx/transform.hpp diff --git a/deps/glm/include/glm/gtx/transform.inl b/external/glm/include/glm/gtx/transform.inl index 48ee680..48ee680 100644 --- a/deps/glm/include/glm/gtx/transform.inl +++ b/external/glm/include/glm/gtx/transform.inl diff --git a/deps/glm/include/glm/gtx/transform2.hpp b/external/glm/include/glm/gtx/transform2.hpp index 9604a92..9604a92 100644 --- a/deps/glm/include/glm/gtx/transform2.hpp +++ b/external/glm/include/glm/gtx/transform2.hpp diff --git a/deps/glm/include/glm/gtx/transform2.inl b/external/glm/include/glm/gtx/transform2.inl index 0118ab0..0118ab0 100644 --- a/deps/glm/include/glm/gtx/transform2.inl +++ b/external/glm/include/glm/gtx/transform2.inl diff --git a/deps/glm/include/glm/gtx/type_aligned.hpp b/external/glm/include/glm/gtx/type_aligned.hpp index ec40935..ec40935 100644 --- a/deps/glm/include/glm/gtx/type_aligned.hpp +++ b/external/glm/include/glm/gtx/type_aligned.hpp diff --git a/deps/glm/include/glm/gtx/type_aligned.inl b/external/glm/include/glm/gtx/type_aligned.inl index 54c1b81..54c1b81 100644 --- a/deps/glm/include/glm/gtx/type_aligned.inl +++ b/external/glm/include/glm/gtx/type_aligned.inl diff --git a/deps/glm/include/glm/gtx/type_trait.hpp b/external/glm/include/glm/gtx/type_trait.hpp index 17ddbad..17ddbad 100644 --- a/deps/glm/include/glm/gtx/type_trait.hpp +++ b/external/glm/include/glm/gtx/type_trait.hpp diff --git a/deps/glm/include/glm/gtx/type_trait.inl b/external/glm/include/glm/gtx/type_trait.inl index 045de95..045de95 100644 --- a/deps/glm/include/glm/gtx/type_trait.inl +++ b/external/glm/include/glm/gtx/type_trait.inl diff --git a/deps/glm/include/glm/gtx/vec_swizzle.hpp b/external/glm/include/glm/gtx/vec_swizzle.hpp index 2dafa64..2dafa64 100644 --- a/deps/glm/include/glm/gtx/vec_swizzle.hpp +++ b/external/glm/include/glm/gtx/vec_swizzle.hpp diff --git a/deps/glm/include/glm/gtx/vector_angle.hpp b/external/glm/include/glm/gtx/vector_angle.hpp index 9ff4127..9ff4127 100644 --- a/deps/glm/include/glm/gtx/vector_angle.hpp +++ b/external/glm/include/glm/gtx/vector_angle.hpp diff --git a/deps/glm/include/glm/gtx/vector_angle.inl b/external/glm/include/glm/gtx/vector_angle.inl index 11e1a21..11e1a21 100644 --- a/deps/glm/include/glm/gtx/vector_angle.inl +++ b/external/glm/include/glm/gtx/vector_angle.inl diff --git a/deps/glm/include/glm/gtx/vector_query.hpp b/external/glm/include/glm/gtx/vector_query.hpp index ab52df0..ab52df0 100644 --- a/deps/glm/include/glm/gtx/vector_query.hpp +++ b/external/glm/include/glm/gtx/vector_query.hpp diff --git a/deps/glm/include/glm/gtx/vector_query.inl b/external/glm/include/glm/gtx/vector_query.inl index d1a5c9b..d1a5c9b 100644 --- a/deps/glm/include/glm/gtx/vector_query.inl +++ b/external/glm/include/glm/gtx/vector_query.inl diff --git a/deps/glm/include/glm/gtx/wrap.hpp b/external/glm/include/glm/gtx/wrap.hpp index b7ac5af..b7ac5af 100644 --- a/deps/glm/include/glm/gtx/wrap.hpp +++ b/external/glm/include/glm/gtx/wrap.hpp diff --git a/deps/glm/include/glm/gtx/wrap.inl b/external/glm/include/glm/gtx/wrap.inl index 4be3b4c..4be3b4c 100644 --- a/deps/glm/include/glm/gtx/wrap.inl +++ b/external/glm/include/glm/gtx/wrap.inl diff --git a/deps/glm/include/glm/integer.hpp b/external/glm/include/glm/integer.hpp index 36c67be..36c67be 100644 --- a/deps/glm/include/glm/integer.hpp +++ b/external/glm/include/glm/integer.hpp diff --git a/deps/glm/include/glm/mat2x2.hpp b/external/glm/include/glm/mat2x2.hpp index 96bec96..96bec96 100644 --- a/deps/glm/include/glm/mat2x2.hpp +++ b/external/glm/include/glm/mat2x2.hpp diff --git a/deps/glm/include/glm/mat2x3.hpp b/external/glm/include/glm/mat2x3.hpp index d68dc25..d68dc25 100644 --- a/deps/glm/include/glm/mat2x3.hpp +++ b/external/glm/include/glm/mat2x3.hpp diff --git a/deps/glm/include/glm/mat2x4.hpp b/external/glm/include/glm/mat2x4.hpp index b04b738..b04b738 100644 --- a/deps/glm/include/glm/mat2x4.hpp +++ b/external/glm/include/glm/mat2x4.hpp diff --git a/deps/glm/include/glm/mat3x2.hpp b/external/glm/include/glm/mat3x2.hpp index c853153..c853153 100644 --- a/deps/glm/include/glm/mat3x2.hpp +++ b/external/glm/include/glm/mat3x2.hpp diff --git a/deps/glm/include/glm/mat3x3.hpp b/external/glm/include/glm/mat3x3.hpp index fd4fa31..fd4fa31 100644 --- a/deps/glm/include/glm/mat3x3.hpp +++ b/external/glm/include/glm/mat3x3.hpp diff --git a/deps/glm/include/glm/mat3x4.hpp b/external/glm/include/glm/mat3x4.hpp index 6342bf5..6342bf5 100644 --- a/deps/glm/include/glm/mat3x4.hpp +++ b/external/glm/include/glm/mat3x4.hpp diff --git a/deps/glm/include/glm/mat4x2.hpp b/external/glm/include/glm/mat4x2.hpp index e013e46..e013e46 100644 --- a/deps/glm/include/glm/mat4x2.hpp +++ b/external/glm/include/glm/mat4x2.hpp diff --git a/deps/glm/include/glm/mat4x3.hpp b/external/glm/include/glm/mat4x3.hpp index 205725a..205725a 100644 --- a/deps/glm/include/glm/mat4x3.hpp +++ b/external/glm/include/glm/mat4x3.hpp diff --git a/deps/glm/include/glm/mat4x4.hpp b/external/glm/include/glm/mat4x4.hpp index 3515f7f..3515f7f 100644 --- a/deps/glm/include/glm/mat4x4.hpp +++ b/external/glm/include/glm/mat4x4.hpp diff --git a/deps/glm/include/glm/matrix.hpp b/external/glm/include/glm/matrix.hpp index 4584c92..4584c92 100644 --- a/deps/glm/include/glm/matrix.hpp +++ b/external/glm/include/glm/matrix.hpp diff --git a/deps/glm/include/glm/packing.hpp b/external/glm/include/glm/packing.hpp index ca83ac1..ca83ac1 100644 --- a/deps/glm/include/glm/packing.hpp +++ b/external/glm/include/glm/packing.hpp diff --git a/deps/glm/include/glm/simd/common.h b/external/glm/include/glm/simd/common.h index a580a1f..a580a1f 100644 --- a/deps/glm/include/glm/simd/common.h +++ b/external/glm/include/glm/simd/common.h diff --git a/deps/glm/include/glm/simd/exponential.h b/external/glm/include/glm/simd/exponential.h index bc351d0..bc351d0 100644 --- a/deps/glm/include/glm/simd/exponential.h +++ b/external/glm/include/glm/simd/exponential.h diff --git a/deps/glm/include/glm/simd/geometric.h b/external/glm/include/glm/simd/geometric.h index afbe590..afbe590 100644 --- a/deps/glm/include/glm/simd/geometric.h +++ b/external/glm/include/glm/simd/geometric.h diff --git a/deps/glm/include/glm/simd/integer.h b/external/glm/include/glm/simd/integer.h index 9381418..9381418 100644 --- a/deps/glm/include/glm/simd/integer.h +++ b/external/glm/include/glm/simd/integer.h diff --git a/deps/glm/include/glm/simd/matrix.h b/external/glm/include/glm/simd/matrix.h index b6c42ea..b6c42ea 100644 --- a/deps/glm/include/glm/simd/matrix.h +++ b/external/glm/include/glm/simd/matrix.h diff --git a/deps/glm/include/glm/simd/neon.h b/external/glm/include/glm/simd/neon.h index f85947f..f85947f 100644 --- a/deps/glm/include/glm/simd/neon.h +++ b/external/glm/include/glm/simd/neon.h diff --git a/deps/glm/include/glm/simd/packing.h b/external/glm/include/glm/simd/packing.h index 609163e..609163e 100644 --- a/deps/glm/include/glm/simd/packing.h +++ b/external/glm/include/glm/simd/packing.h diff --git a/deps/glm/include/glm/simd/platform.h b/external/glm/include/glm/simd/platform.h index a318b09..a318b09 100644 --- a/deps/glm/include/glm/simd/platform.h +++ b/external/glm/include/glm/simd/platform.h diff --git a/deps/glm/include/glm/simd/trigonometric.h b/external/glm/include/glm/simd/trigonometric.h index 739b796..739b796 100644 --- a/deps/glm/include/glm/simd/trigonometric.h +++ b/external/glm/include/glm/simd/trigonometric.h diff --git a/deps/glm/include/glm/simd/vector_relational.h b/external/glm/include/glm/simd/vector_relational.h index f7385e9..f7385e9 100644 --- a/deps/glm/include/glm/simd/vector_relational.h +++ b/external/glm/include/glm/simd/vector_relational.h diff --git a/deps/glm/include/glm/trigonometric.hpp b/external/glm/include/glm/trigonometric.hpp index 51d49c1..51d49c1 100644 --- a/deps/glm/include/glm/trigonometric.hpp +++ b/external/glm/include/glm/trigonometric.hpp diff --git a/deps/glm/include/glm/vec2.hpp b/external/glm/include/glm/vec2.hpp index cd4e070..cd4e070 100644 --- a/deps/glm/include/glm/vec2.hpp +++ b/external/glm/include/glm/vec2.hpp diff --git a/deps/glm/include/glm/vec3.hpp b/external/glm/include/glm/vec3.hpp index f5a927d..f5a927d 100644 --- a/deps/glm/include/glm/vec3.hpp +++ b/external/glm/include/glm/vec3.hpp diff --git a/deps/glm/include/glm/vec4.hpp b/external/glm/include/glm/vec4.hpp index c6ea9f1..c6ea9f1 100644 --- a/deps/glm/include/glm/vec4.hpp +++ b/external/glm/include/glm/vec4.hpp diff --git a/deps/glm/include/glm/vector_relational.hpp b/external/glm/include/glm/vector_relational.hpp index a0fe17e..a0fe17e 100644 --- a/deps/glm/include/glm/vector_relational.hpp +++ b/external/glm/include/glm/vector_relational.hpp diff --git a/deps/imgui/CMakeLists.txt b/external/imgui/CMakeLists.txt index 38ecb5e..38ecb5e 100644 --- a/deps/imgui/CMakeLists.txt +++ b/external/imgui/CMakeLists.txt diff --git a/deps/imgui/DESCRIPTION b/external/imgui/DESCRIPTION index f3366d0..f3366d0 100644 --- a/deps/imgui/DESCRIPTION +++ b/external/imgui/DESCRIPTION diff --git a/deps/imgui/LICENSE b/external/imgui/LICENSE index 3282f5b..3282f5b 100644 --- a/deps/imgui/LICENSE +++ b/external/imgui/LICENSE diff --git a/deps/imgui/include/imconfig.h b/external/imgui/include/imconfig.h index a1e29e8..a1e29e8 100644 --- a/deps/imgui/include/imconfig.h +++ b/external/imgui/include/imconfig.h diff --git a/deps/imgui/include/imgui.h b/external/imgui/include/imgui.h index 78baa1b..78baa1b 100644 --- a/deps/imgui/include/imgui.h +++ b/external/imgui/include/imgui.h diff --git a/deps/imgui/include/imgui_impl_glfw.h b/external/imgui/include/imgui_impl_glfw.h index 80e2b55..80e2b55 100644 --- a/deps/imgui/include/imgui_impl_glfw.h +++ b/external/imgui/include/imgui_impl_glfw.h diff --git a/deps/imgui/include/imgui_impl_opengl3.h b/external/imgui/include/imgui_impl_opengl3.h index b72b5c8..b72b5c8 100644 --- a/deps/imgui/include/imgui_impl_opengl3.h +++ b/external/imgui/include/imgui_impl_opengl3.h diff --git a/deps/imgui/include/imgui_impl_opengl3_loader.h b/external/imgui/include/imgui_impl_opengl3_loader.h index 4ca0536..4ca0536 100644 --- a/deps/imgui/include/imgui_impl_opengl3_loader.h +++ b/external/imgui/include/imgui_impl_opengl3_loader.h diff --git a/deps/imgui/include/imgui_stdlib.h b/external/imgui/include/imgui_stdlib.h index 697fc34..697fc34 100644 --- a/deps/imgui/include/imgui_stdlib.h +++ b/external/imgui/include/imgui_stdlib.h diff --git a/deps/imgui/include/imstb_rectpack.h b/external/imgui/include/imstb_rectpack.h index f6917e7..f6917e7 100644 --- a/deps/imgui/include/imstb_rectpack.h +++ b/external/imgui/include/imstb_rectpack.h diff --git a/deps/imgui/include/imstb_textedit.h b/external/imgui/include/imstb_textedit.h index 33eef70..33eef70 100644 --- a/deps/imgui/include/imstb_textedit.h +++ b/external/imgui/include/imstb_textedit.h diff --git a/deps/imgui/include/imstb_truetype.h b/external/imgui/include/imstb_truetype.h index cf33289..cf33289 100644 --- a/deps/imgui/include/imstb_truetype.h +++ b/external/imgui/include/imstb_truetype.h diff --git a/deps/imgui/src/imgui.cpp b/external/imgui/src/imgui.cpp index 21df133..21df133 100644 --- a/deps/imgui/src/imgui.cpp +++ b/external/imgui/src/imgui.cpp diff --git a/deps/imgui/src/imgui_demo.cpp b/external/imgui/src/imgui_demo.cpp index 9b71cea..9b71cea 100644 --- a/deps/imgui/src/imgui_demo.cpp +++ b/external/imgui/src/imgui_demo.cpp diff --git a/deps/imgui/src/imgui_draw.cpp b/external/imgui/src/imgui_draw.cpp index dc09445..dc09445 100644 --- a/deps/imgui/src/imgui_draw.cpp +++ b/external/imgui/src/imgui_draw.cpp diff --git a/deps/imgui/src/imgui_impl_glfw.cpp b/external/imgui/src/imgui_impl_glfw.cpp index d0a75ac..d0a75ac 100644 --- a/deps/imgui/src/imgui_impl_glfw.cpp +++ b/external/imgui/src/imgui_impl_glfw.cpp diff --git a/deps/imgui/src/imgui_impl_opengl3.cpp b/external/imgui/src/imgui_impl_opengl3.cpp index 40b3be6..40b3be6 100644 --- a/deps/imgui/src/imgui_impl_opengl3.cpp +++ b/external/imgui/src/imgui_impl_opengl3.cpp diff --git a/deps/imgui/src/imgui_internal.h b/external/imgui/src/imgui_internal.h index 40fe681..40fe681 100644 --- a/deps/imgui/src/imgui_internal.h +++ b/external/imgui/src/imgui_internal.h diff --git a/deps/imgui/src/imgui_stdlib.cpp b/external/imgui/src/imgui_stdlib.cpp index c04d487..c04d487 100644 --- a/deps/imgui/src/imgui_stdlib.cpp +++ b/external/imgui/src/imgui_stdlib.cpp diff --git a/deps/imgui/src/imgui_tables.cpp b/external/imgui/src/imgui_tables.cpp index 88b99d0..88b99d0 100644 --- a/deps/imgui/src/imgui_tables.cpp +++ b/external/imgui/src/imgui_tables.cpp diff --git a/deps/imgui/src/imgui_widgets.cpp b/external/imgui/src/imgui_widgets.cpp index 49bee84..49bee84 100644 --- a/deps/imgui/src/imgui_widgets.cpp +++ b/external/imgui/src/imgui_widgets.cpp diff --git a/deps/miniz/CMakeLists.txt b/external/miniz/CMakeLists.txt index 1eb9042..1eb9042 100644 --- a/deps/miniz/CMakeLists.txt +++ b/external/miniz/CMakeLists.txt diff --git a/deps/miniz/DESCRIPTION b/external/miniz/DESCRIPTION index e2a240f..e2a240f 100644 --- a/deps/miniz/DESCRIPTION +++ b/external/miniz/DESCRIPTION diff --git a/deps/miniz/LICENSE b/external/miniz/LICENSE index b6ff45a..b6ff45a 100644 --- a/deps/miniz/LICENSE +++ b/external/miniz/LICENSE diff --git a/deps/miniz/include/miniz.h b/external/miniz/include/miniz.h index 9fcfffc..9fcfffc 100644 --- a/deps/miniz/include/miniz.h +++ b/external/miniz/include/miniz.h diff --git a/deps/miniz/src/miniz.c b/external/miniz/src/miniz.c index 8d0032f..8d0032f 100644 --- a/deps/miniz/src/miniz.c +++ b/external/miniz/src/miniz.c diff --git a/deps/parson/CMakeLists.txt b/external/parson/CMakeLists.txt index 336d4ad..336d4ad 100644 --- a/deps/parson/CMakeLists.txt +++ b/external/parson/CMakeLists.txt diff --git a/deps/parson/DESCRIPTION b/external/parson/DESCRIPTION index b4db252..b4db252 100644 --- a/deps/parson/DESCRIPTION +++ b/external/parson/DESCRIPTION diff --git a/deps/parson/LICENSE b/external/parson/LICENSE index 4431a61..4431a61 100644 --- a/deps/parson/LICENSE +++ b/external/parson/LICENSE diff --git a/deps/parson/include/parson.h b/external/parson/include/parson.h index 40be490..40be490 100644 --- a/deps/parson/include/parson.h +++ b/external/parson/include/parson.h diff --git a/deps/parson/src/parson.c b/external/parson/src/parson.c index 526aab4..526aab4 100644 --- a/deps/parson/src/parson.c +++ b/external/parson/src/parson.c diff --git a/deps/physfs/CMakeLists.txt b/external/physfs/CMakeLists.txt index bce32de..bce32de 100644 --- a/deps/physfs/CMakeLists.txt +++ b/external/physfs/CMakeLists.txt diff --git a/deps/physfs/DESCRIPTION b/external/physfs/DESCRIPTION index dd7be5d..dd7be5d 100644 --- a/deps/physfs/DESCRIPTION +++ b/external/physfs/DESCRIPTION diff --git a/deps/physfs/LICENSE b/external/physfs/LICENSE index e8d37a1..e8d37a1 100644 --- a/deps/physfs/LICENSE +++ b/external/physfs/LICENSE diff --git a/deps/physfs/include/physfs.h b/external/physfs/include/physfs.h index 6e55ce4..6e55ce4 100644 --- a/deps/physfs/include/physfs.h +++ b/external/physfs/include/physfs.h diff --git a/deps/physfs/src/physfs.c b/external/physfs/src/physfs.c index 6476e0a..6476e0a 100644 --- a/deps/physfs/src/physfs.c +++ b/external/physfs/src/physfs.c diff --git a/deps/physfs/src/physfs_archiver_7z.c b/external/physfs/src/physfs_archiver_7z.c index 44be3c9..44be3c9 100644 --- a/deps/physfs/src/physfs_archiver_7z.c +++ b/external/physfs/src/physfs_archiver_7z.c diff --git a/deps/physfs/src/physfs_archiver_dir.c b/external/physfs/src/physfs_archiver_dir.c index 61c0da3..61c0da3 100644 --- a/deps/physfs/src/physfs_archiver_dir.c +++ b/external/physfs/src/physfs_archiver_dir.c diff --git a/deps/physfs/src/physfs_archiver_grp.c b/external/physfs/src/physfs_archiver_grp.c index 9a2978a..9a2978a 100644 --- a/deps/physfs/src/physfs_archiver_grp.c +++ b/external/physfs/src/physfs_archiver_grp.c diff --git a/deps/physfs/src/physfs_archiver_hog.c b/external/physfs/src/physfs_archiver_hog.c index a818478..a818478 100644 --- a/deps/physfs/src/physfs_archiver_hog.c +++ b/external/physfs/src/physfs_archiver_hog.c diff --git a/deps/physfs/src/physfs_archiver_iso9660.c b/external/physfs/src/physfs_archiver_iso9660.c index e92d677..e92d677 100644 --- a/deps/physfs/src/physfs_archiver_iso9660.c +++ b/external/physfs/src/physfs_archiver_iso9660.c diff --git a/deps/physfs/src/physfs_archiver_mvl.c b/external/physfs/src/physfs_archiver_mvl.c index 7a5c432..7a5c432 100644 --- a/deps/physfs/src/physfs_archiver_mvl.c +++ b/external/physfs/src/physfs_archiver_mvl.c diff --git a/deps/physfs/src/physfs_archiver_qpak.c b/external/physfs/src/physfs_archiver_qpak.c index ddca271..ddca271 100644 --- a/deps/physfs/src/physfs_archiver_qpak.c +++ b/external/physfs/src/physfs_archiver_qpak.c diff --git a/deps/physfs/src/physfs_archiver_slb.c b/external/physfs/src/physfs_archiver_slb.c index 58f3bc8..58f3bc8 100644 --- a/deps/physfs/src/physfs_archiver_slb.c +++ b/external/physfs/src/physfs_archiver_slb.c diff --git a/deps/physfs/src/physfs_archiver_unpacked.c b/external/physfs/src/physfs_archiver_unpacked.c index fbb12a0..fbb12a0 100644 --- a/deps/physfs/src/physfs_archiver_unpacked.c +++ b/external/physfs/src/physfs_archiver_unpacked.c diff --git a/deps/physfs/src/physfs_archiver_vdf.c b/external/physfs/src/physfs_archiver_vdf.c index 6d3a23f..6d3a23f 100644 --- a/deps/physfs/src/physfs_archiver_vdf.c +++ b/external/physfs/src/physfs_archiver_vdf.c diff --git a/deps/physfs/src/physfs_archiver_wad.c b/external/physfs/src/physfs_archiver_wad.c index d3ae045..d3ae045 100644 --- a/deps/physfs/src/physfs_archiver_wad.c +++ b/external/physfs/src/physfs_archiver_wad.c diff --git a/deps/physfs/src/physfs_archiver_zip.c b/external/physfs/src/physfs_archiver_zip.c index 7327a61..7327a61 100644 --- a/deps/physfs/src/physfs_archiver_zip.c +++ b/external/physfs/src/physfs_archiver_zip.c diff --git a/deps/physfs/src/physfs_byteorder.c b/external/physfs/src/physfs_byteorder.c index b2d3a2c..b2d3a2c 100644 --- a/deps/physfs/src/physfs_byteorder.c +++ b/external/physfs/src/physfs_byteorder.c diff --git a/deps/physfs/src/physfs_casefolding.h b/external/physfs/src/physfs_casefolding.h index bb6ac18..bb6ac18 100644 --- a/deps/physfs/src/physfs_casefolding.h +++ b/external/physfs/src/physfs_casefolding.h diff --git a/deps/physfs/src/physfs_internal.h b/external/physfs/src/physfs_internal.h index 2200d4d..2200d4d 100644 --- a/deps/physfs/src/physfs_internal.h +++ b/external/physfs/src/physfs_internal.h diff --git a/deps/physfs/src/physfs_lzmasdk.h b/external/physfs/src/physfs_lzmasdk.h index d2bbcc6..d2bbcc6 100644 --- a/deps/physfs/src/physfs_lzmasdk.h +++ b/external/physfs/src/physfs_lzmasdk.h diff --git a/deps/physfs/src/physfs_miniz.h b/external/physfs/src/physfs_miniz.h index e0fddb0..e0fddb0 100644 --- a/deps/physfs/src/physfs_miniz.h +++ b/external/physfs/src/physfs_miniz.h diff --git a/deps/physfs/src/physfs_platform_android.c b/external/physfs/src/physfs_platform_android.c index f892fed..f892fed 100644 --- a/deps/physfs/src/physfs_platform_android.c +++ b/external/physfs/src/physfs_platform_android.c diff --git a/deps/physfs/src/physfs_platform_apple.m b/external/physfs/src/physfs_platform_apple.m index f98f10d..f98f10d 100644 --- a/deps/physfs/src/physfs_platform_apple.m +++ b/external/physfs/src/physfs_platform_apple.m diff --git a/deps/physfs/src/physfs_platform_os2.c b/external/physfs/src/physfs_platform_os2.c index bf47a9d..bf47a9d 100644 --- a/deps/physfs/src/physfs_platform_os2.c +++ b/external/physfs/src/physfs_platform_os2.c diff --git a/deps/physfs/src/physfs_platform_posix.c b/external/physfs/src/physfs_platform_posix.c index 7ba5e10..7ba5e10 100644 --- a/deps/physfs/src/physfs_platform_posix.c +++ b/external/physfs/src/physfs_platform_posix.c diff --git a/deps/physfs/src/physfs_platform_qnx.c b/external/physfs/src/physfs_platform_qnx.c index 46f9aa7..46f9aa7 100644 --- a/deps/physfs/src/physfs_platform_qnx.c +++ b/external/physfs/src/physfs_platform_qnx.c diff --git a/deps/physfs/src/physfs_platform_unix.c b/external/physfs/src/physfs_platform_unix.c index 10d93a7..10d93a7 100644 --- a/deps/physfs/src/physfs_platform_unix.c +++ b/external/physfs/src/physfs_platform_unix.c diff --git a/deps/physfs/src/physfs_platform_windows.c b/external/physfs/src/physfs_platform_windows.c index 652300c..652300c 100644 --- a/deps/physfs/src/physfs_platform_windows.c +++ b/external/physfs/src/physfs_platform_windows.c diff --git a/deps/physfs/src/physfs_platform_winrt.cpp b/external/physfs/src/physfs_platform_winrt.cpp index f50fc9d..f50fc9d 100644 --- a/deps/physfs/src/physfs_platform_winrt.cpp +++ b/external/physfs/src/physfs_platform_winrt.cpp diff --git a/deps/physfs/src/physfs_platforms.h b/external/physfs/src/physfs_platforms.h index 1ac17d9..1ac17d9 100644 --- a/deps/physfs/src/physfs_platforms.h +++ b/external/physfs/src/physfs_platforms.h diff --git a/deps/physfs/src/physfs_unicode.c b/external/physfs/src/physfs_unicode.c index bab4f8b..bab4f8b 100644 --- a/deps/physfs/src/physfs_unicode.c +++ b/external/physfs/src/physfs_unicode.c diff --git a/deps/salad/CMakeLists.txt b/external/salad/CMakeLists.txt index d2d0a68..d2d0a68 100644 --- a/deps/salad/CMakeLists.txt +++ b/external/salad/CMakeLists.txt diff --git a/deps/salad/DESCRIPTION b/external/salad/DESCRIPTION index 921ba34..921ba34 100644 --- a/deps/salad/DESCRIPTION +++ b/external/salad/DESCRIPTION diff --git a/deps/salad/LICENSE b/external/salad/LICENSE index 8fe551f..8fe551f 100644 --- a/deps/salad/LICENSE +++ b/external/salad/LICENSE diff --git a/deps/salad/include/AL/al.h b/external/salad/include/AL/al.h index 20e78dd..20e78dd 100644 --- a/deps/salad/include/AL/al.h +++ b/external/salad/include/AL/al.h diff --git a/deps/salad/include/AL/alc.h b/external/salad/include/AL/alc.h index 4f28de8..4f28de8 100644 --- a/deps/salad/include/AL/alc.h +++ b/external/salad/include/AL/alc.h diff --git a/deps/salad/include/AL/efx.h b/external/salad/include/AL/efx.h index 80fa701..80fa701 100644 --- a/deps/salad/include/AL/efx.h +++ b/external/salad/include/AL/efx.h diff --git a/deps/salad/include/AL/salad.h b/external/salad/include/AL/salad.h index cce2639..cce2639 100644 --- a/deps/salad/include/AL/salad.h +++ b/external/salad/include/AL/salad.h diff --git a/deps/salad/src/salad.c b/external/salad/src/salad.c index 3330b84..3330b84 100644 --- a/deps/salad/src/salad.c +++ b/external/salad/src/salad.c diff --git a/deps/spdlog/CMakeLists.txt b/external/spdlog/CMakeLists.txt index 53160ca..53160ca 100644 --- a/deps/spdlog/CMakeLists.txt +++ b/external/spdlog/CMakeLists.txt diff --git a/deps/spdlog/DESCRIPTION b/external/spdlog/DESCRIPTION index d7fa4ff..d7fa4ff 100644 --- a/deps/spdlog/DESCRIPTION +++ b/external/spdlog/DESCRIPTION diff --git a/deps/spdlog/LICENSE b/external/spdlog/LICENSE index 6c53e20..6c53e20 100644 --- a/deps/spdlog/LICENSE +++ b/external/spdlog/LICENSE diff --git a/deps/spdlog/include/spdlog/async.h b/external/spdlog/include/spdlog/async.h index e96abd1..e96abd1 100644 --- a/deps/spdlog/include/spdlog/async.h +++ b/external/spdlog/include/spdlog/async.h diff --git a/deps/spdlog/include/spdlog/async_logger-inl.h b/external/spdlog/include/spdlog/async_logger-inl.h index 1e79479..1e79479 100644 --- a/deps/spdlog/include/spdlog/async_logger-inl.h +++ b/external/spdlog/include/spdlog/async_logger-inl.h diff --git a/deps/spdlog/include/spdlog/async_logger.h b/external/spdlog/include/spdlog/async_logger.h index 846c4c6..846c4c6 100644 --- a/deps/spdlog/include/spdlog/async_logger.h +++ b/external/spdlog/include/spdlog/async_logger.h diff --git a/deps/spdlog/include/spdlog/cfg/argv.h b/external/spdlog/include/spdlog/cfg/argv.h index 7de2f83..7de2f83 100644 --- a/deps/spdlog/include/spdlog/cfg/argv.h +++ b/external/spdlog/include/spdlog/cfg/argv.h diff --git a/deps/spdlog/include/spdlog/cfg/env.h b/external/spdlog/include/spdlog/cfg/env.h index 6e55414..6e55414 100644 --- a/deps/spdlog/include/spdlog/cfg/env.h +++ b/external/spdlog/include/spdlog/cfg/env.h diff --git a/deps/spdlog/include/spdlog/cfg/helpers-inl.h b/external/spdlog/include/spdlog/cfg/helpers-inl.h index 93650a2..93650a2 100644 --- a/deps/spdlog/include/spdlog/cfg/helpers-inl.h +++ b/external/spdlog/include/spdlog/cfg/helpers-inl.h diff --git a/deps/spdlog/include/spdlog/cfg/helpers.h b/external/spdlog/include/spdlog/cfg/helpers.h index c023818..c023818 100644 --- a/deps/spdlog/include/spdlog/cfg/helpers.h +++ b/external/spdlog/include/spdlog/cfg/helpers.h diff --git a/deps/spdlog/include/spdlog/common-inl.h b/external/spdlog/include/spdlog/common-inl.h index a8a0453..a8a0453 100644 --- a/deps/spdlog/include/spdlog/common-inl.h +++ b/external/spdlog/include/spdlog/common-inl.h diff --git a/deps/spdlog/include/spdlog/common.h b/external/spdlog/include/spdlog/common.h index aca483c..aca483c 100644 --- a/deps/spdlog/include/spdlog/common.h +++ b/external/spdlog/include/spdlog/common.h diff --git a/deps/spdlog/include/spdlog/details/backtracer-inl.h b/external/spdlog/include/spdlog/details/backtracer-inl.h index 43d1002..43d1002 100644 --- a/deps/spdlog/include/spdlog/details/backtracer-inl.h +++ b/external/spdlog/include/spdlog/details/backtracer-inl.h diff --git a/deps/spdlog/include/spdlog/details/backtracer.h b/external/spdlog/include/spdlog/details/backtracer.h index 541339c..541339c 100644 --- a/deps/spdlog/include/spdlog/details/backtracer.h +++ b/external/spdlog/include/spdlog/details/backtracer.h diff --git a/deps/spdlog/include/spdlog/details/circular_q.h b/external/spdlog/include/spdlog/details/circular_q.h index 29e9d25..29e9d25 100644 --- a/deps/spdlog/include/spdlog/details/circular_q.h +++ b/external/spdlog/include/spdlog/details/circular_q.h diff --git a/deps/spdlog/include/spdlog/details/console_globals.h b/external/spdlog/include/spdlog/details/console_globals.h index 9c55210..9c55210 100644 --- a/deps/spdlog/include/spdlog/details/console_globals.h +++ b/external/spdlog/include/spdlog/details/console_globals.h diff --git a/deps/spdlog/include/spdlog/details/file_helper-inl.h b/external/spdlog/include/spdlog/details/file_helper-inl.h index 37d1d46..37d1d46 100644 --- a/deps/spdlog/include/spdlog/details/file_helper-inl.h +++ b/external/spdlog/include/spdlog/details/file_helper-inl.h diff --git a/deps/spdlog/include/spdlog/details/file_helper.h b/external/spdlog/include/spdlog/details/file_helper.h index f0e5d18..f0e5d18 100644 --- a/deps/spdlog/include/spdlog/details/file_helper.h +++ b/external/spdlog/include/spdlog/details/file_helper.h diff --git a/deps/spdlog/include/spdlog/details/fmt_helper.h b/external/spdlog/include/spdlog/details/fmt_helper.h index 6130600..6130600 100644 --- a/deps/spdlog/include/spdlog/details/fmt_helper.h +++ b/external/spdlog/include/spdlog/details/fmt_helper.h diff --git a/deps/spdlog/include/spdlog/details/log_msg-inl.h b/external/spdlog/include/spdlog/details/log_msg-inl.h index aa3a957..aa3a957 100644 --- a/deps/spdlog/include/spdlog/details/log_msg-inl.h +++ b/external/spdlog/include/spdlog/details/log_msg-inl.h diff --git a/deps/spdlog/include/spdlog/details/log_msg.h b/external/spdlog/include/spdlog/details/log_msg.h index 87df1e8..87df1e8 100644 --- a/deps/spdlog/include/spdlog/details/log_msg.h +++ b/external/spdlog/include/spdlog/details/log_msg.h diff --git a/deps/spdlog/include/spdlog/details/log_msg_buffer-inl.h b/external/spdlog/include/spdlog/details/log_msg_buffer-inl.h index 2eb2428..2eb2428 100644 --- a/deps/spdlog/include/spdlog/details/log_msg_buffer-inl.h +++ b/external/spdlog/include/spdlog/details/log_msg_buffer-inl.h diff --git a/deps/spdlog/include/spdlog/details/log_msg_buffer.h b/external/spdlog/include/spdlog/details/log_msg_buffer.h index 1143b3b..1143b3b 100644 --- a/deps/spdlog/include/spdlog/details/log_msg_buffer.h +++ b/external/spdlog/include/spdlog/details/log_msg_buffer.h diff --git a/deps/spdlog/include/spdlog/details/mpmc_blocking_q.h b/external/spdlog/include/spdlog/details/mpmc_blocking_q.h index 5848cca..5848cca 100644 --- a/deps/spdlog/include/spdlog/details/mpmc_blocking_q.h +++ b/external/spdlog/include/spdlog/details/mpmc_blocking_q.h diff --git a/deps/spdlog/include/spdlog/details/null_mutex.h b/external/spdlog/include/spdlog/details/null_mutex.h index e3b3220..e3b3220 100644 --- a/deps/spdlog/include/spdlog/details/null_mutex.h +++ b/external/spdlog/include/spdlog/details/null_mutex.h diff --git a/deps/spdlog/include/spdlog/details/os-inl.h b/external/spdlog/include/spdlog/details/os-inl.h index e4d4771..e4d4771 100644 --- a/deps/spdlog/include/spdlog/details/os-inl.h +++ b/external/spdlog/include/spdlog/details/os-inl.h diff --git a/deps/spdlog/include/spdlog/details/os.h b/external/spdlog/include/spdlog/details/os.h index b1069ed..b1069ed 100644 --- a/deps/spdlog/include/spdlog/details/os.h +++ b/external/spdlog/include/spdlog/details/os.h diff --git a/deps/spdlog/include/spdlog/details/periodic_worker-inl.h b/external/spdlog/include/spdlog/details/periodic_worker-inl.h index 18f11fb..18f11fb 100644 --- a/deps/spdlog/include/spdlog/details/periodic_worker-inl.h +++ b/external/spdlog/include/spdlog/details/periodic_worker-inl.h diff --git a/deps/spdlog/include/spdlog/details/periodic_worker.h b/external/spdlog/include/spdlog/details/periodic_worker.h index d647b66..d647b66 100644 --- a/deps/spdlog/include/spdlog/details/periodic_worker.h +++ b/external/spdlog/include/spdlog/details/periodic_worker.h diff --git a/deps/spdlog/include/spdlog/details/registry-inl.h b/external/spdlog/include/spdlog/details/registry-inl.h index f447848..f447848 100644 --- a/deps/spdlog/include/spdlog/details/registry-inl.h +++ b/external/spdlog/include/spdlog/details/registry-inl.h diff --git a/deps/spdlog/include/spdlog/details/registry.h b/external/spdlog/include/spdlog/details/registry.h index 8afcbd6..8afcbd6 100644 --- a/deps/spdlog/include/spdlog/details/registry.h +++ b/external/spdlog/include/spdlog/details/registry.h diff --git a/deps/spdlog/include/spdlog/details/synchronous_factory.h b/external/spdlog/include/spdlog/details/synchronous_factory.h index 4bd5a51..4bd5a51 100644 --- a/deps/spdlog/include/spdlog/details/synchronous_factory.h +++ b/external/spdlog/include/spdlog/details/synchronous_factory.h diff --git a/deps/spdlog/include/spdlog/details/tcp_client-windows.h b/external/spdlog/include/spdlog/details/tcp_client-windows.h index bf8f7b8..bf8f7b8 100644 --- a/deps/spdlog/include/spdlog/details/tcp_client-windows.h +++ b/external/spdlog/include/spdlog/details/tcp_client-windows.h diff --git a/deps/spdlog/include/spdlog/details/tcp_client.h b/external/spdlog/include/spdlog/details/tcp_client.h index 9d3c40d..9d3c40d 100644 --- a/deps/spdlog/include/spdlog/details/tcp_client.h +++ b/external/spdlog/include/spdlog/details/tcp_client.h diff --git a/deps/spdlog/include/spdlog/details/thread_pool-inl.h b/external/spdlog/include/spdlog/details/thread_pool-inl.h index 17e01c0..17e01c0 100644 --- a/deps/spdlog/include/spdlog/details/thread_pool-inl.h +++ b/external/spdlog/include/spdlog/details/thread_pool-inl.h diff --git a/deps/spdlog/include/spdlog/details/thread_pool.h b/external/spdlog/include/spdlog/details/thread_pool.h index f22b078..f22b078 100644 --- a/deps/spdlog/include/spdlog/details/thread_pool.h +++ b/external/spdlog/include/spdlog/details/thread_pool.h diff --git a/deps/spdlog/include/spdlog/details/udp_client-windows.h b/external/spdlog/include/spdlog/details/udp_client-windows.h index 8b7c223..8b7c223 100644 --- a/deps/spdlog/include/spdlog/details/udp_client-windows.h +++ b/external/spdlog/include/spdlog/details/udp_client-windows.h diff --git a/deps/spdlog/include/spdlog/details/udp_client.h b/external/spdlog/include/spdlog/details/udp_client.h index 95826f5..95826f5 100644 --- a/deps/spdlog/include/spdlog/details/udp_client.h +++ b/external/spdlog/include/spdlog/details/udp_client.h diff --git a/deps/spdlog/include/spdlog/details/windows_include.h b/external/spdlog/include/spdlog/details/windows_include.h index bbab59b..bbab59b 100644 --- a/deps/spdlog/include/spdlog/details/windows_include.h +++ b/external/spdlog/include/spdlog/details/windows_include.h diff --git a/deps/spdlog/include/spdlog/fmt/bin_to_hex.h b/external/spdlog/include/spdlog/fmt/bin_to_hex.h index c2998d5..c2998d5 100644 --- a/deps/spdlog/include/spdlog/fmt/bin_to_hex.h +++ b/external/spdlog/include/spdlog/fmt/bin_to_hex.h diff --git a/deps/spdlog/include/spdlog/fmt/chrono.h b/external/spdlog/include/spdlog/fmt/chrono.h index a72a5bd..a72a5bd 100644 --- a/deps/spdlog/include/spdlog/fmt/chrono.h +++ b/external/spdlog/include/spdlog/fmt/chrono.h diff --git a/deps/spdlog/include/spdlog/fmt/compile.h b/external/spdlog/include/spdlog/fmt/compile.h index 3c9c25d..3c9c25d 100644 --- a/deps/spdlog/include/spdlog/fmt/compile.h +++ b/external/spdlog/include/spdlog/fmt/compile.h diff --git a/deps/spdlog/include/spdlog/fmt/fmt.h b/external/spdlog/include/spdlog/fmt/fmt.h index 7fa6b09..7fa6b09 100644 --- a/deps/spdlog/include/spdlog/fmt/fmt.h +++ b/external/spdlog/include/spdlog/fmt/fmt.h diff --git a/deps/spdlog/include/spdlog/fmt/ostr.h b/external/spdlog/include/spdlog/fmt/ostr.h index 2b90105..2b90105 100644 --- a/deps/spdlog/include/spdlog/fmt/ostr.h +++ b/external/spdlog/include/spdlog/fmt/ostr.h diff --git a/deps/spdlog/include/spdlog/fmt/ranges.h b/external/spdlog/include/spdlog/fmt/ranges.h index 5bb91e9..5bb91e9 100644 --- a/deps/spdlog/include/spdlog/fmt/ranges.h +++ b/external/spdlog/include/spdlog/fmt/ranges.h diff --git a/deps/spdlog/include/spdlog/fmt/std.h b/external/spdlog/include/spdlog/fmt/std.h index dabe6f6..dabe6f6 100644 --- a/deps/spdlog/include/spdlog/fmt/std.h +++ b/external/spdlog/include/spdlog/fmt/std.h diff --git a/deps/spdlog/include/spdlog/fmt/xchar.h b/external/spdlog/include/spdlog/fmt/xchar.h index 2525f05..2525f05 100644 --- a/deps/spdlog/include/spdlog/fmt/xchar.h +++ b/external/spdlog/include/spdlog/fmt/xchar.h diff --git a/deps/spdlog/include/spdlog/formatter.h b/external/spdlog/include/spdlog/formatter.h index 4d482f8..4d482f8 100644 --- a/deps/spdlog/include/spdlog/formatter.h +++ b/external/spdlog/include/spdlog/formatter.h diff --git a/deps/spdlog/include/spdlog/fwd.h b/external/spdlog/include/spdlog/fwd.h index 647b16b..647b16b 100644 --- a/deps/spdlog/include/spdlog/fwd.h +++ b/external/spdlog/include/spdlog/fwd.h diff --git a/deps/spdlog/include/spdlog/logger-inl.h b/external/spdlog/include/spdlog/logger-inl.h index 5218fe4..5218fe4 100644 --- a/deps/spdlog/include/spdlog/logger-inl.h +++ b/external/spdlog/include/spdlog/logger-inl.h diff --git a/deps/spdlog/include/spdlog/logger.h b/external/spdlog/include/spdlog/logger.h index f49bdc0..f49bdc0 100644 --- a/deps/spdlog/include/spdlog/logger.h +++ b/external/spdlog/include/spdlog/logger.h diff --git a/deps/spdlog/include/spdlog/mdc.h b/external/spdlog/include/spdlog/mdc.h index 80b6f25..80b6f25 100644 --- a/deps/spdlog/include/spdlog/mdc.h +++ b/external/spdlog/include/spdlog/mdc.h diff --git a/deps/spdlog/include/spdlog/pattern_formatter-inl.h b/external/spdlog/include/spdlog/pattern_formatter-inl.h index b53d805..b53d805 100644 --- a/deps/spdlog/include/spdlog/pattern_formatter-inl.h +++ b/external/spdlog/include/spdlog/pattern_formatter-inl.h diff --git a/deps/spdlog/include/spdlog/pattern_formatter.h b/external/spdlog/include/spdlog/pattern_formatter.h index ececd67..ececd67 100644 --- a/deps/spdlog/include/spdlog/pattern_formatter.h +++ b/external/spdlog/include/spdlog/pattern_formatter.h diff --git a/deps/spdlog/include/spdlog/sinks/android_sink.h b/external/spdlog/include/spdlog/sinks/android_sink.h index 4435a56..4435a56 100644 --- a/deps/spdlog/include/spdlog/sinks/android_sink.h +++ b/external/spdlog/include/spdlog/sinks/android_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h b/external/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h index 2194f67..2194f67 100644 --- a/deps/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/ansicolor_sink.h b/external/spdlog/include/spdlog/sinks/ansicolor_sink.h index d0dadd7..d0dadd7 100644 --- a/deps/spdlog/include/spdlog/sinks/ansicolor_sink.h +++ b/external/spdlog/include/spdlog/sinks/ansicolor_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/base_sink-inl.h b/external/spdlog/include/spdlog/sinks/base_sink-inl.h index ada161b..ada161b 100644 --- a/deps/spdlog/include/spdlog/sinks/base_sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/base_sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/base_sink.h b/external/spdlog/include/spdlog/sinks/base_sink.h index 1b4bb06..1b4bb06 100644 --- a/deps/spdlog/include/spdlog/sinks/base_sink.h +++ b/external/spdlog/include/spdlog/sinks/base_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/basic_file_sink-inl.h b/external/spdlog/include/spdlog/sinks/basic_file_sink-inl.h index f7c1abf..f7c1abf 100644 --- a/deps/spdlog/include/spdlog/sinks/basic_file_sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/basic_file_sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/basic_file_sink.h b/external/spdlog/include/spdlog/sinks/basic_file_sink.h index 699caa1..699caa1 100644 --- a/deps/spdlog/include/spdlog/sinks/basic_file_sink.h +++ b/external/spdlog/include/spdlog/sinks/basic_file_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/callback_sink.h b/external/spdlog/include/spdlog/sinks/callback_sink.h index 5f8b6bc..5f8b6bc 100644 --- a/deps/spdlog/include/spdlog/sinks/callback_sink.h +++ b/external/spdlog/include/spdlog/sinks/callback_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/daily_file_sink.h b/external/spdlog/include/spdlog/sinks/daily_file_sink.h index 884145f..884145f 100644 --- a/deps/spdlog/include/spdlog/sinks/daily_file_sink.h +++ b/external/spdlog/include/spdlog/sinks/daily_file_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/dist_sink.h b/external/spdlog/include/spdlog/sinks/dist_sink.h index 69c4971..69c4971 100644 --- a/deps/spdlog/include/spdlog/sinks/dist_sink.h +++ b/external/spdlog/include/spdlog/sinks/dist_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/dup_filter_sink.h b/external/spdlog/include/spdlog/sinks/dup_filter_sink.h index 1498142..1498142 100644 --- a/deps/spdlog/include/spdlog/sinks/dup_filter_sink.h +++ b/external/spdlog/include/spdlog/sinks/dup_filter_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/hourly_file_sink.h b/external/spdlog/include/spdlog/sinks/hourly_file_sink.h index 3e61872..3e61872 100644 --- a/deps/spdlog/include/spdlog/sinks/hourly_file_sink.h +++ b/external/spdlog/include/spdlog/sinks/hourly_file_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/kafka_sink.h b/external/spdlog/include/spdlog/sinks/kafka_sink.h index 91e9878..91e9878 100644 --- a/deps/spdlog/include/spdlog/sinks/kafka_sink.h +++ b/external/spdlog/include/spdlog/sinks/kafka_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/mongo_sink.h b/external/spdlog/include/spdlog/sinks/mongo_sink.h index c5b38ab..c5b38ab 100644 --- a/deps/spdlog/include/spdlog/sinks/mongo_sink.h +++ b/external/spdlog/include/spdlog/sinks/mongo_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/msvc_sink.h b/external/spdlog/include/spdlog/sinks/msvc_sink.h index c28d6eb..c28d6eb 100644 --- a/deps/spdlog/include/spdlog/sinks/msvc_sink.h +++ b/external/spdlog/include/spdlog/sinks/msvc_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/null_sink.h b/external/spdlog/include/spdlog/sinks/null_sink.h index c51247f..c51247f 100644 --- a/deps/spdlog/include/spdlog/sinks/null_sink.h +++ b/external/spdlog/include/spdlog/sinks/null_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/ostream_sink.h b/external/spdlog/include/spdlog/sinks/ostream_sink.h index 6af9dd0..6af9dd0 100644 --- a/deps/spdlog/include/spdlog/sinks/ostream_sink.h +++ b/external/spdlog/include/spdlog/sinks/ostream_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/qt_sinks.h b/external/spdlog/include/spdlog/sinks/qt_sinks.h index d319e84..d319e84 100644 --- a/deps/spdlog/include/spdlog/sinks/qt_sinks.h +++ b/external/spdlog/include/spdlog/sinks/qt_sinks.h diff --git a/deps/spdlog/include/spdlog/sinks/ringbuffer_sink.h b/external/spdlog/include/spdlog/sinks/ringbuffer_sink.h index 6156c6a..6156c6a 100644 --- a/deps/spdlog/include/spdlog/sinks/ringbuffer_sink.h +++ b/external/spdlog/include/spdlog/sinks/ringbuffer_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h b/external/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h index bf9351e..bf9351e 100644 --- a/deps/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/rotating_file_sink.h b/external/spdlog/include/spdlog/sinks/rotating_file_sink.h index cd43d34..cd43d34 100644 --- a/deps/spdlog/include/spdlog/sinks/rotating_file_sink.h +++ b/external/spdlog/include/spdlog/sinks/rotating_file_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/sink-inl.h b/external/spdlog/include/spdlog/sinks/sink-inl.h index e4b2714..e4b2714 100644 --- a/deps/spdlog/include/spdlog/sinks/sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/sink.h b/external/spdlog/include/spdlog/sinks/sink.h index 5850685..5850685 100644 --- a/deps/spdlog/include/spdlog/sinks/sink.h +++ b/external/spdlog/include/spdlog/sinks/sink.h diff --git a/deps/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h b/external/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h index 166e386..166e386 100644 --- a/deps/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h +++ b/external/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/stdout_color_sinks.h b/external/spdlog/include/spdlog/sinks/stdout_color_sinks.h index 72991fe..72991fe 100644 --- a/deps/spdlog/include/spdlog/sinks/stdout_color_sinks.h +++ b/external/spdlog/include/spdlog/sinks/stdout_color_sinks.h diff --git a/deps/spdlog/include/spdlog/sinks/stdout_sinks-inl.h b/external/spdlog/include/spdlog/sinks/stdout_sinks-inl.h index f98244d..f98244d 100644 --- a/deps/spdlog/include/spdlog/sinks/stdout_sinks-inl.h +++ b/external/spdlog/include/spdlog/sinks/stdout_sinks-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/stdout_sinks.h b/external/spdlog/include/spdlog/sinks/stdout_sinks.h index 6ef0996..6ef0996 100644 --- a/deps/spdlog/include/spdlog/sinks/stdout_sinks.h +++ b/external/spdlog/include/spdlog/sinks/stdout_sinks.h diff --git a/deps/spdlog/include/spdlog/sinks/syslog_sink.h b/external/spdlog/include/spdlog/sinks/syslog_sink.h index 913d41b..913d41b 100644 --- a/deps/spdlog/include/spdlog/sinks/syslog_sink.h +++ b/external/spdlog/include/spdlog/sinks/syslog_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/systemd_sink.h b/external/spdlog/include/spdlog/sinks/systemd_sink.h index d2cd55f..d2cd55f 100644 --- a/deps/spdlog/include/spdlog/sinks/systemd_sink.h +++ b/external/spdlog/include/spdlog/sinks/systemd_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/tcp_sink.h b/external/spdlog/include/spdlog/sinks/tcp_sink.h index 2534964..2534964 100644 --- a/deps/spdlog/include/spdlog/sinks/tcp_sink.h +++ b/external/spdlog/include/spdlog/sinks/tcp_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/udp_sink.h b/external/spdlog/include/spdlog/sinks/udp_sink.h index 4bff0fd..4bff0fd 100644 --- a/deps/spdlog/include/spdlog/sinks/udp_sink.h +++ b/external/spdlog/include/spdlog/sinks/udp_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/win_eventlog_sink.h b/external/spdlog/include/spdlog/sinks/win_eventlog_sink.h index 2c9b582..2c9b582 100644 --- a/deps/spdlog/include/spdlog/sinks/win_eventlog_sink.h +++ b/external/spdlog/include/spdlog/sinks/win_eventlog_sink.h diff --git a/deps/spdlog/include/spdlog/sinks/wincolor_sink-inl.h b/external/spdlog/include/spdlog/sinks/wincolor_sink-inl.h index 696db56..696db56 100644 --- a/deps/spdlog/include/spdlog/sinks/wincolor_sink-inl.h +++ b/external/spdlog/include/spdlog/sinks/wincolor_sink-inl.h diff --git a/deps/spdlog/include/spdlog/sinks/wincolor_sink.h b/external/spdlog/include/spdlog/sinks/wincolor_sink.h index 8ba594c..8ba594c 100644 --- a/deps/spdlog/include/spdlog/sinks/wincolor_sink.h +++ b/external/spdlog/include/spdlog/sinks/wincolor_sink.h diff --git a/deps/spdlog/include/spdlog/spdlog-inl.h b/external/spdlog/include/spdlog/spdlog-inl.h index 97c3622..97c3622 100644 --- a/deps/spdlog/include/spdlog/spdlog-inl.h +++ b/external/spdlog/include/spdlog/spdlog-inl.h diff --git a/deps/spdlog/include/spdlog/spdlog.h b/external/spdlog/include/spdlog/spdlog.h index a8afbce..a8afbce 100644 --- a/deps/spdlog/include/spdlog/spdlog.h +++ b/external/spdlog/include/spdlog/spdlog.h diff --git a/deps/spdlog/include/spdlog/stopwatch.h b/external/spdlog/include/spdlog/stopwatch.h index 54ab3d3..54ab3d3 100644 --- a/deps/spdlog/include/spdlog/stopwatch.h +++ b/external/spdlog/include/spdlog/stopwatch.h diff --git a/deps/spdlog/include/spdlog/tweakme.h b/external/spdlog/include/spdlog/tweakme.h index a47a907..a47a907 100644 --- a/deps/spdlog/include/spdlog/tweakme.h +++ b/external/spdlog/include/spdlog/tweakme.h diff --git a/deps/spdlog/include/spdlog/version.h b/external/spdlog/include/spdlog/version.h index 7c5e129..7c5e129 100644 --- a/deps/spdlog/include/spdlog/version.h +++ b/external/spdlog/include/spdlog/version.h diff --git a/deps/spdlog/src/async.cpp b/external/spdlog/src/async.cpp index 026185a..026185a 100644 --- a/deps/spdlog/src/async.cpp +++ b/external/spdlog/src/async.cpp diff --git a/deps/spdlog/src/bundled_fmtlib_format.cpp b/external/spdlog/src/bundled_fmtlib_format.cpp index 462508d..462508d 100644 --- a/deps/spdlog/src/bundled_fmtlib_format.cpp +++ b/external/spdlog/src/bundled_fmtlib_format.cpp diff --git a/deps/spdlog/src/cfg.cpp b/external/spdlog/src/cfg.cpp index ebdea16..ebdea16 100644 --- a/deps/spdlog/src/cfg.cpp +++ b/external/spdlog/src/cfg.cpp diff --git a/deps/spdlog/src/color_sinks.cpp b/external/spdlog/src/color_sinks.cpp index c44db19..c44db19 100644 --- a/deps/spdlog/src/color_sinks.cpp +++ b/external/spdlog/src/color_sinks.cpp diff --git a/deps/spdlog/src/file_sinks.cpp b/external/spdlog/src/file_sinks.cpp index 04cb6c1..04cb6c1 100644 --- a/deps/spdlog/src/file_sinks.cpp +++ b/external/spdlog/src/file_sinks.cpp diff --git a/deps/spdlog/src/spdlog.cpp b/external/spdlog/src/spdlog.cpp index 9f8390b..9f8390b 100644 --- a/deps/spdlog/src/spdlog.cpp +++ b/external/spdlog/src/spdlog.cpp diff --git a/deps/spdlog/src/stdout_sinks.cpp b/external/spdlog/src/stdout_sinks.cpp index bf4cfae..bf4cfae 100644 --- a/deps/spdlog/src/stdout_sinks.cpp +++ b/external/spdlog/src/stdout_sinks.cpp diff --git a/deps/stb/CMakeLists.txt b/external/stb/CMakeLists.txt index 0fa97be..0fa97be 100644 --- a/deps/stb/CMakeLists.txt +++ b/external/stb/CMakeLists.txt diff --git a/deps/stb/DESCRIPTION b/external/stb/DESCRIPTION index 95e175c..95e175c 100644 --- a/deps/stb/DESCRIPTION +++ b/external/stb/DESCRIPTION diff --git a/deps/stb/LICENSE b/external/stb/LICENSE index 730dc8a..730dc8a 100644 --- a/deps/stb/LICENSE +++ b/external/stb/LICENSE diff --git a/deps/stb/include/stb_image.h b/external/stb/include/stb_image.h index 9eedabe..9eedabe 100644 --- a/deps/stb/include/stb_image.h +++ b/external/stb/include/stb_image.h diff --git a/deps/stb/include/stb_image_write.h b/external/stb/include/stb_image_write.h index e4b32ed..e4b32ed 100644 --- a/deps/stb/include/stb_image_write.h +++ b/external/stb/include/stb_image_write.h diff --git a/deps/stb/src/stb_impl.c b/external/stb/src/stb_impl.c index 08bf6ef..08bf6ef 100644 --- a/deps/stb/src/stb_impl.c +++ b/external/stb/src/stb_impl.c diff --git a/deps/thread_pool/CMakeLists.txt b/external/thread_pool/CMakeLists.txt index 6e7be0a..6e7be0a 100644 --- a/deps/thread_pool/CMakeLists.txt +++ b/external/thread_pool/CMakeLists.txt diff --git a/deps/thread_pool/DESCRIPTION b/external/thread_pool/DESCRIPTION index 3647ee8..3647ee8 100644 --- a/deps/thread_pool/DESCRIPTION +++ b/external/thread_pool/DESCRIPTION diff --git a/deps/thread_pool/LICENSE b/external/thread_pool/LICENSE index 5a7c645..5a7c645 100644 --- a/deps/thread_pool/LICENSE +++ b/external/thread_pool/LICENSE diff --git a/deps/thread_pool/include/BS_thread_pool.hpp b/external/thread_pool/include/BS_thread_pool.hpp index e9bb7ce..e9bb7ce 100644 --- a/deps/thread_pool/include/BS_thread_pool.hpp +++ b/external/thread_pool/include/BS_thread_pool.hpp diff --git a/misc/client_splash.xcf b/media/client_splash.xcf Binary files differindex 0a3730f..0a3730f 100644 --- a/misc/client_splash.xcf +++ b/media/client_splash.xcf diff --git a/media/historic/2022_crc64_randomness.png b/media/historic/2022_crc64_randomness.png Binary files differnew file mode 100644 index 0000000..b197ccf --- /dev/null +++ b/media/historic/2022_crc64_randomness.png diff --git a/media/historic/renderdoc_screenshot_01.png b/media/historic/renderdoc_screenshot_01.png Binary files differnew file mode 100644 index 0000000..6c24e82 --- /dev/null +++ b/media/historic/renderdoc_screenshot_01.png diff --git a/media/nsis-header.bmp b/media/nsis-header.bmp Binary files differnew file mode 100644 index 0000000..148775a --- /dev/null +++ b/media/nsis-header.bmp diff --git a/game/server/vserver.ico b/media/nsis-installer.ico Binary files differindex 02ff006..02ff006 100644 --- a/game/server/vserver.ico +++ b/media/nsis-installer.ico diff --git a/media/nsis-splash.bmp b/media/nsis-splash.bmp Binary files differnew file mode 100644 index 0000000..b4a7445 --- /dev/null +++ b/media/nsis-splash.bmp diff --git a/misc/vclient.bbmodel b/media/vclient.bbmodel index f7b7ef9..f7b7ef9 100644 --- a/misc/vclient.bbmodel +++ b/media/vclient.bbmodel diff --git a/misc/vclient.png b/media/vclient.png Binary files differindex 4d7212e..4d7212e 100644 --- a/misc/vclient.png +++ b/media/vclient.png diff --git a/misc/vserver.bbmodel b/media/vserver.bbmodel index 807cf5f..807cf5f 100644 --- a/misc/vserver.bbmodel +++ b/media/vserver.bbmodel diff --git a/misc/vserver.png b/media/vserver.png Binary files differindex fdbd82b..fdbd82b 100644 --- a/misc/vserver.png +++ b/media/vserver.png diff --git a/scripts/build-unix-debug.sh b/scripts/build-unix-debug.sh new file mode 100644 index 0000000..0c8387f --- /dev/null +++ b/scripts/build-unix-debug.sh @@ -0,0 +1,5 @@ +#!/bin/sh +cd "$(dirname $(dirname ${0}))" || exit 1 +cmake -B build/unix-debug -DCMAKE_BUILD_TYPE=Debug || exit 1 +cmake --build build/unix-debug --config Debug --parallel || exit 1 +exit 0 diff --git a/scripts/build-unix-release.sh b/scripts/build-unix-release.sh new file mode 100644 index 0000000..682b99b --- /dev/null +++ b/scripts/build-unix-release.sh @@ -0,0 +1,5 @@ +#!/bin/sh +cd "$(dirname $(dirname ${0}))" || exit 1 +cmake -B build/unix-release -DCMAKE_BUILD_TYPE=Release || exit 1 +cmake --build build/unix-release --config Release --parallel || exit 1 +exit 0 diff --git a/scripts/build-win32-debug.bat b/scripts/build-win32-debug.bat new file mode 100644 index 0000000..2f930f4 --- /dev/null +++ b/scripts/build-win32-debug.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +cmake -B build\win32 -A Win32 +if %errorlevel% neq 0 exit /b %errorlevel% +cmake --build build\win32 --config Debug --parallel +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/build-win32-release.bat b/scripts/build-win32-release.bat new file mode 100644 index 0000000..fc5bf09 --- /dev/null +++ b/scripts/build-win32-release.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +cmake -B build\win32 -A Win32 +if %errorlevel% neq 0 exit /b %errorlevel% +cmake --build build\win32 --config Release --parallel +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/build-win64-debug.bat b/scripts/build-win64-debug.bat new file mode 100644 index 0000000..c9b4f34 --- /dev/null +++ b/scripts/build-win64-debug.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +cmake -B build\win64 -A x64 +if %errorlevel% neq 0 exit /b %errorlevel% +cmake --build build\win64 --config Debug --parallel +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/build-win64-release.bat b/scripts/build-win64-release.bat new file mode 100644 index 0000000..a2fd274 --- /dev/null +++ b/scripts/build-win64-release.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +cmake -B build\win64 -A x64 +if %errorlevel% neq 0 exit /b %errorlevel% +cmake --build build\win64 --config Release --parallel +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/deps/thirdparty.py b/scripts/generate-thirdparty.py index 7171bf4..369ac19 100644 --- a/deps/thirdparty.py +++ b/scripts/generate-thirdparty.py @@ -46,7 +46,7 @@ dependencies = get_dependencies(dependencies_dir) assert len(dependencies) > 0, "No licenses found in the dependencies directory." with open("thirdparty.txt", 'w', encoding='utf-8') as out_file: - out_file.write("QFengine uses third-party code for certain functions. All the\n") + out_file.write("Voxelius uses third-party code for certain functions. All the\n") out_file.write("license texts are included below using an automated script; this generated\n") out_file.write("file is to be included in binary distributions of the project.\n\n") @@ -56,5 +56,5 @@ with open("thirdparty.txt", 'w', encoding='utf-8') as out_file: out_file.write(f"{name} - {description}\n") else: out_file.write(f"{name}\n") - out_file.write(f"{'=' * 80}\n") + out_file.write(f"{'=' * 80}\n\n") out_file.write(f"{license}\n\n\n") diff --git a/scripts/package-unix.sh b/scripts/package-unix.sh new file mode 100644 index 0000000..f2a8f42 --- /dev/null +++ b/scripts/package-unix.sh @@ -0,0 +1,5 @@ +#!/bin/sh +cd "$(dirname $(dirname ${0}))" || exit 1 +${SHELL} scripts/build-unix-release.sh || exit 1 +cpack -G ${1:-TGZ} --config build/unix-release/CPackConfig.cmake || exit 1 +exit 0 diff --git a/scripts/package-win32-nsis.bat b/scripts/package-win32-nsis.bat new file mode 100644 index 0000000..cc21a4f --- /dev/null +++ b/scripts/package-win32-nsis.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +call scripts\build-win32-release.bat +if %errorlevel% neq 0 exit /b %errorlevel% +cpack -G NSIS --config build\win32\CPackConfig.cmake +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/package-win32-zip.bat b/scripts/package-win32-zip.bat new file mode 100644 index 0000000..4ac435f --- /dev/null +++ b/scripts/package-win32-zip.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +call scripts\build-win32-release.bat +if %errorlevel% neq 0 exit /b %errorlevel% +cpack -G ZIP --config build\win32\CPackConfig.cmake +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/package-win64-nsis.bat b/scripts/package-win64-nsis.bat new file mode 100644 index 0000000..e4f8324 --- /dev/null +++ b/scripts/package-win64-nsis.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +call scripts\build-win64-release.bat +if %errorlevel% neq 0 exit /b %errorlevel% +cpack -G NSIS --config build\win64\CPackConfig.cmake +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/scripts/package-win64-zip.bat b/scripts/package-win64-zip.bat new file mode 100644 index 0000000..1f9633c --- /dev/null +++ b/scripts/package-win64-zip.bat @@ -0,0 +1,7 @@ +@echo off +cd /D "%~dp0\.." +call scripts\build-win64-release.bat +if %errorlevel% neq 0 exit /b %errorlevel% +cpack -G ZIP --config build\win64\CPackConfig.cmake +if %errorlevel% neq 0 exit /b %errorlevel% +if /I %0 EQU "%~dpnx0" pause diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..ac6b9d0 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(core) +add_subdirectory(game) diff --git a/core/CMakeLists.txt b/src/core/CMakeLists.txt index 16cc4f0..7a3edfc 100644 --- a/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -11,7 +11,7 @@ add_library(core STATIC "${CMAKE_CURRENT_LIST_DIR}/version.cc" "${CMAKE_CURRENT_LIST_DIR}/version.hh") target_compile_features(core PUBLIC cxx_std_20) -target_include_directories(core PUBLIC "${PROJECT_SOURCE_DIR}") +target_include_directories(core PUBLIC "${PROJECT_SOURCE_DIR}/src") target_precompile_headers(core PRIVATE "${CMAKE_CURRENT_LIST_DIR}/pch.hh") target_link_libraries(core PUBLIC enet emhash glm physfs spdlog stb thread_pool) diff --git a/core/config/CMakeLists.txt b/src/core/config/CMakeLists.txt index 39752d4..39752d4 100644 --- a/core/config/CMakeLists.txt +++ b/src/core/config/CMakeLists.txt diff --git a/core/config/boolean.cc b/src/core/config/boolean.cc index 5981b6d..45d5a38 100644 --- a/core/config/boolean.cc +++ b/src/core/config/boolean.cc @@ -1,43 +1,43 @@ -#include "core/pch.hh"
-
-#include "core/config/boolean.hh"
-
-config::Boolean::Boolean(bool default_value)
-{
- m_value = default_value;
-}
-
-void config::Boolean::set(std::string_view value)
-{
- m_value = from_string(value);
-}
-
-std::string_view config::Boolean::get(void) const
-{
- return to_string(m_value);
-}
-
-bool config::Boolean::get_value(void) const
-{
- return m_value;
-}
-
-void config::Boolean::set_value(bool value)
-{
- m_value = value;
-}
-
-std::string_view config::Boolean::to_string(bool value)
-{
- if(value) {
- return "true";
- }
- else {
- return "false";
- }
-}
-
-bool config::Boolean::from_string(std::string_view value)
-{
- return value == "true" && value != "false";
-}
+#include "core/pch.hh" + +#include "core/config/boolean.hh" + +config::Boolean::Boolean(bool default_value) +{ + m_value = default_value; +} + +void config::Boolean::set(std::string_view value) +{ + m_value = from_string(value); +} + +std::string_view config::Boolean::get(void) const +{ + return to_string(m_value); +} + +bool config::Boolean::get_value(void) const +{ + return m_value; +} + +void config::Boolean::set_value(bool value) +{ + m_value = value; +} + +std::string_view config::Boolean::to_string(bool value) +{ + if(value) { + return "true"; + } + else { + return "false"; + } +} + +bool config::Boolean::from_string(std::string_view value) +{ + return value == "true" && value != "false"; +} diff --git a/core/config/boolean.hh b/src/core/config/boolean.hh index f4d3acd..cfd8b0b 100644 --- a/core/config/boolean.hh +++ b/src/core/config/boolean.hh @@ -1,25 +1,25 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-namespace config
-{
-class Boolean : public IValue {
-public:
- explicit Boolean(bool default_value = false);
- virtual ~Boolean(void) = default;
-
- virtual void set(std::string_view value) override;
- virtual std::string_view get(void) const override;
-
- bool get_value(void) const;
- void set_value(bool value);
-
-private:
- bool m_value;
-
-public:
- static std::string_view to_string(bool value);
- static bool from_string(std::string_view value);
-};
-} // namespace config
+#pragma once + +#include "core/config/ivalue.hh" + +namespace config +{ +class Boolean : public IValue { +public: + explicit Boolean(bool default_value = false); + virtual ~Boolean(void) = default; + + virtual void set(std::string_view value) override; + virtual std::string_view get(void) const override; + + bool get_value(void) const; + void set_value(bool value); + +private: + bool m_value; + +public: + static std::string_view to_string(bool value); + static bool from_string(std::string_view value); +}; +} // namespace config diff --git a/core/config/ivalue.hh b/src/core/config/ivalue.hh index 782da76..13e9a3a 100644 --- a/core/config/ivalue.hh +++ b/src/core/config/ivalue.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace config
-{
-class IValue {
-public:
- virtual ~IValue(void) = default;
- virtual void set(std::string_view value) = 0;
- virtual std::string_view get(void) const = 0;
-};
-} // namespace config
+#pragma once + +namespace config +{ +class IValue { +public: + virtual ~IValue(void) = default; + virtual void set(std::string_view value) = 0; + virtual std::string_view get(void) const = 0; +}; +} // namespace config diff --git a/core/config/number.hh b/src/core/config/number.hh index 59d3f47..4f185e1 100644 --- a/core/config/number.hh +++ b/src/core/config/number.hh @@ -1,130 +1,130 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-#include "core/math/concepts.hh"
-
-namespace config
-{
-template<math::arithmetic T>
-class Number : public IValue {
-public:
- explicit Number(T default_value = T(0));
- explicit Number(T default_value, T min_value, T max_value);
- virtual ~Number(void) = default;
-
- virtual void set(std::string_view value) override;
- virtual std::string_view get(void) const override;
-
- T get_value(void) const;
- void set_value(T value);
-
- T get_min_value(void) const;
- T get_max_value(void) const;
- void set_limits(T min_value, T max_value);
-
-private:
- T m_value;
- T m_min_value;
- T m_max_value;
- std::string m_string;
-};
-} // namespace config
-
-namespace config
-{
-class Int final : public Number<int> {
-public:
- using Number<int>::Number;
-};
-
-class Float final : public Number<float> {
-public:
- using Number<float>::Number;
-};
-
-class Unsigned final : public Number<unsigned int> {
-public:
- using Number<unsigned int>::Number;
-};
-
-class Unsigned64 final : public Number<std::uint64_t> {
-public:
- using Number<std::uint64_t>::Number;
-};
-
-class SizeType final : public Number<std::size_t> {
-public:
- using Number<std::size_t>::Number;
-};
-} // namespace config
-
-template<math::arithmetic T>
-inline config::Number<T>::Number(T default_value)
-{
- m_value = default_value;
- m_min_value = std::numeric_limits<T>::lowest();
- m_max_value = std::numeric_limits<T>::max();
- m_string = std::to_string(default_value);
-}
-
-template<math::arithmetic T>
-inline config::Number<T>::Number(T default_value, T min_value, T max_value)
-{
- m_value = default_value;
- m_min_value = min_value;
- m_max_value = max_value;
- m_string = std::to_string(default_value);
-}
-
-template<math::arithmetic T>
-inline void config::Number<T>::set(std::string_view value)
-{
- T parsed_value;
- auto result = std::from_chars(value.data(), value.data() + value.size(), parsed_value);
-
- if(result.ec == std::errc()) {
- m_value = std::clamp(parsed_value, m_min_value, m_max_value);
- m_string = std::to_string(m_value);
- }
-}
-
-template<math::arithmetic T>
-inline std::string_view config::Number<T>::get(void) const
-{
- return m_string;
-}
-
-template<math::arithmetic T>
-inline T config::Number<T>::get_value(void) const
-{
- return m_value;
-}
-
-template<math::arithmetic T>
-inline void config::Number<T>::set_value(T value)
-{
- m_value = std::clamp(value, m_min_value, m_max_value);
- m_string = std::to_string(m_value);
-}
-
-template<math::arithmetic T>
-inline T config::Number<T>::get_min_value(void) const
-{
- return m_min_value;
-}
-
-template<math::arithmetic T>
-inline T config::Number<T>::get_max_value(void) const
-{
- return m_max_value;
-}
-
-template<math::arithmetic T>
-inline void config::Number<T>::set_limits(T min_value, T max_value)
-{
- m_min_value = min_value;
- m_max_value = max_value;
- m_value = std::clamp(m_value, m_min_value, m_max_value);
- m_string = std::to_string(m_value);
-}
+#pragma once + +#include "core/config/ivalue.hh" + +#include "core/math/concepts.hh" + +namespace config +{ +template<math::arithmetic T> +class Number : public IValue { +public: + explicit Number(T default_value = T(0)); + explicit Number(T default_value, T min_value, T max_value); + virtual ~Number(void) = default; + + virtual void set(std::string_view value) override; + virtual std::string_view get(void) const override; + + T get_value(void) const; + void set_value(T value); + + T get_min_value(void) const; + T get_max_value(void) const; + void set_limits(T min_value, T max_value); + +private: + T m_value; + T m_min_value; + T m_max_value; + std::string m_string; +}; +} // namespace config + +namespace config +{ +class Int final : public Number<int> { +public: + using Number<int>::Number; +}; + +class Float final : public Number<float> { +public: + using Number<float>::Number; +}; + +class Unsigned final : public Number<unsigned int> { +public: + using Number<unsigned int>::Number; +}; + +class Unsigned64 final : public Number<std::uint64_t> { +public: + using Number<std::uint64_t>::Number; +}; + +class SizeType final : public Number<std::size_t> { +public: + using Number<std::size_t>::Number; +}; +} // namespace config + +template<math::arithmetic T> +inline config::Number<T>::Number(T default_value) +{ + m_value = default_value; + m_min_value = std::numeric_limits<T>::lowest(); + m_max_value = std::numeric_limits<T>::max(); + m_string = std::to_string(default_value); +} + +template<math::arithmetic T> +inline config::Number<T>::Number(T default_value, T min_value, T max_value) +{ + m_value = default_value; + m_min_value = min_value; + m_max_value = max_value; + m_string = std::to_string(default_value); +} + +template<math::arithmetic T> +inline void config::Number<T>::set(std::string_view value) +{ + T parsed_value; + auto result = std::from_chars(value.data(), value.data() + value.size(), parsed_value); + + if(result.ec == std::errc()) { + m_value = std::clamp(parsed_value, m_min_value, m_max_value); + m_string = std::to_string(m_value); + } +} + +template<math::arithmetic T> +inline std::string_view config::Number<T>::get(void) const +{ + return m_string; +} + +template<math::arithmetic T> +inline T config::Number<T>::get_value(void) const +{ + return m_value; +} + +template<math::arithmetic T> +inline void config::Number<T>::set_value(T value) +{ + m_value = std::clamp(value, m_min_value, m_max_value); + m_string = std::to_string(m_value); +} + +template<math::arithmetic T> +inline T config::Number<T>::get_min_value(void) const +{ + return m_min_value; +} + +template<math::arithmetic T> +inline T config::Number<T>::get_max_value(void) const +{ + return m_max_value; +} + +template<math::arithmetic T> +inline void config::Number<T>::set_limits(T min_value, T max_value) +{ + m_min_value = min_value; + m_max_value = max_value; + m_value = std::clamp(m_value, m_min_value, m_max_value); + m_string = std::to_string(m_value); +} diff --git a/core/config/string.cc b/src/core/config/string.cc index 8fb9d70..198b448 100644 --- a/core/config/string.cc +++ b/src/core/config/string.cc @@ -1,18 +1,18 @@ -#include "core/pch.hh"
-
-#include "core/config/string.hh"
-
-config::String::String(std::string_view default_value)
-{
- m_value = default_value;
-}
-
-void config::String::set(std::string_view value)
-{
- m_value = value;
-}
-
-std::string_view config::String::get(void) const
-{
- return m_value;
-}
+#include "core/pch.hh" + +#include "core/config/string.hh" + +config::String::String(std::string_view default_value) +{ + m_value = default_value; +} + +void config::String::set(std::string_view value) +{ + m_value = value; +} + +std::string_view config::String::get(void) const +{ + return m_value; +} diff --git a/core/config/string.hh b/src/core/config/string.hh index d7bbbc1..8fd3901 100644 --- a/core/config/string.hh +++ b/src/core/config/string.hh @@ -1,31 +1,31 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-namespace config
-{
-class String : public IValue {
-public:
- explicit String(std::string_view default_value);
- virtual ~String(void) = default;
-
- virtual void set(std::string_view value) override;
- virtual std::string_view get(void) const override;
-
- constexpr const std::string& get_value(void) const noexcept;
- constexpr const char* c_str(void) const noexcept;
-
-private:
- std::string m_value;
-};
-} // namespace config
-
-constexpr const std::string& config::String::get_value(void) const noexcept
-{
- return m_value;
-}
-
-constexpr const char* config::String::c_str(void) const noexcept
-{
- return m_value.c_str();
-}
+#pragma once + +#include "core/config/ivalue.hh" + +namespace config +{ +class String : public IValue { +public: + explicit String(std::string_view default_value); + virtual ~String(void) = default; + + virtual void set(std::string_view value) override; + virtual std::string_view get(void) const override; + + constexpr const std::string& get_value(void) const noexcept; + constexpr const char* c_str(void) const noexcept; + +private: + std::string m_value; +}; +} // namespace config + +constexpr const std::string& config::String::get_value(void) const noexcept +{ + return m_value; +} + +constexpr const char* config::String::c_str(void) const noexcept +{ + return m_value.c_str(); +} diff --git a/core/io/CMakeLists.txt b/src/core/io/CMakeLists.txt index 3fe9fb1..3fe9fb1 100644 --- a/core/io/CMakeLists.txt +++ b/src/core/io/CMakeLists.txt diff --git a/core/io/buffer.cc b/src/core/io/buffer.cc index d3bf7bb..0f781a0 100644 --- a/core/io/buffer.cc +++ b/src/core/io/buffer.cc @@ -1,345 +1,345 @@ -#include "core/pch.hh"
-
-#include "core/io/buffer.hh"
-
-#include "core/math/constexpr.hh"
-
-io::ReadBuffer::ReadBuffer(const ReadBuffer& other)
-{
- reset(other.data(), other.size());
-}
-
-io::ReadBuffer::ReadBuffer(const void* data, std::size_t size)
-{
- assert(data);
-
- reset(data, size);
-}
-
-io::ReadBuffer::ReadBuffer(const ENetPacket* packet)
-{
- assert(packet);
-
- reset(packet);
-}
-
-io::ReadBuffer::ReadBuffer(PHYSFS_File* file)
-{
- assert(file);
-
- reset(file);
-}
-
-std::size_t io::ReadBuffer::size(void) const
-{
- return m_vector.size();
-}
-
-const std::byte* io::ReadBuffer::data(void) const
-{
- return m_vector.data();
-}
-
-void io::ReadBuffer::reset(const void* data, std::size_t size)
-{
- assert(data);
-
- auto bytes = reinterpret_cast<const std::byte*>(data);
- m_vector.assign(bytes, bytes + size);
- m_position = 0U;
-}
-
-void io::ReadBuffer::reset(const ENetPacket* packet)
-{
- assert(packet);
-
- auto bytes_ptr = reinterpret_cast<const std::byte*>(packet->data);
- m_vector.assign(bytes_ptr, bytes_ptr + packet->dataLength);
- m_position = 0;
-}
-
-void io::ReadBuffer::reset(PHYSFS_File* file)
-{
- assert(file);
-
- m_vector.resize(PHYSFS_fileLength(file));
- m_position = 0;
-
- PHYSFS_seek(file, 0);
- PHYSFS_readBytes(file, m_vector.data(), m_vector.size());
-}
-
-template<>
-std::byte io::ReadBuffer::read<std::byte>(void)
-{
- if(m_position < m_vector.size()) {
- auto result = m_vector[m_position];
- m_position += 1U;
- return result;
- }
-
- m_position += 1U;
- return static_cast<std::byte>(0x00);
-}
-
-template<>
-std::uint8_t io::ReadBuffer::read<std::uint8_t>(void)
-{
- if((m_position + 1U) <= m_vector.size()) {
- auto result = static_cast<std::uint8_t>(m_vector[m_position]);
- m_position += 1U;
- return result;
- }
-
- m_position += 1U;
- return 0;
-}
-
-template<>
-std::uint16_t io::ReadBuffer::read<std::uint16_t>(void)
-{
- if((m_position + 2U) <= m_vector.size()) {
- auto result = UINT16_C(0x0000);
- result |= (UINT16_C(0x00FF) & static_cast<std::uint16_t>(m_vector[m_position + 0U])) << 8U;
- result |= (UINT16_C(0x00FF) & static_cast<std::uint16_t>(m_vector[m_position + 1U])) << 0U;
- m_position += 2U;
- return result;
- }
-
- m_position += 2U;
- return 0;
-}
-
-template<>
-std::uint32_t io::ReadBuffer::read<std::uint32_t>(void)
-{
- if((m_position + 4U) <= m_vector.size()) {
- auto result = UINT32_C(0x00000000);
- result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 0U])) << 24U;
- result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 1U])) << 16U;
- result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 2U])) << 8U;
- result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 3U])) << 0U;
- m_position += 4U;
- return result;
- }
-
- m_position += 4U;
- return 0;
-}
-
-template<>
-std::uint64_t io::ReadBuffer::read<std::uint64_t>(void)
-{
- if((m_position + 8U) <= m_vector.size()) {
- auto result = UINT64_C(0x0000000000000000);
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 0U])) << 56U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 1U])) << 48U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 2U])) << 40U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 3U])) << 32U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 4U])) << 24U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 5U])) << 16U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 6U])) << 8U;
- result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 7U])) << 0U;
- m_position += 8U;
- return result;
- }
-
- m_position += 8U;
- return 0;
-}
-
-template<>
-float io::ReadBuffer::read<float>(void)
-{
- return std::bit_cast<float>(read<std::uint32_t>());
-}
-
-template<>
-std::int8_t io::ReadBuffer::read<std::int8_t>(void)
-{
- return std::bit_cast<std::int8_t>(read<std::uint8_t>());
-}
-
-template<>
-std::int16_t io::ReadBuffer::read<std::int16_t>(void)
-{
- return std::bit_cast<std::int16_t>(read<std::uint16_t>());
-}
-
-template<>
-std::int32_t io::ReadBuffer::read<std::int32_t>(void)
-{
- return std::bit_cast<std::int32_t>(read<std::uint32_t>());
-}
-
-template<>
-std::int64_t io::ReadBuffer::read<std::int64_t>(void)
-{
- return std::bit_cast<std::int64_t>(read<std::uint64_t>());
-}
-
-template<>
-std::string io::ReadBuffer::read<std::string>(void)
-{
- std::string result;
- result.resize(read<std::uint16_t>());
-
- for(std::size_t i = 0; i < result.size(); ++i) {
- if(m_position < m_vector.size()) {
- result[i] = static_cast<char>(m_vector[m_position]);
- }
-
- m_position += 1U;
- }
-
- return result;
-}
-
-void io::ReadBuffer::read(void* buffer, std::size_t size)
-{
- auto bytes = reinterpret_cast<std::byte*>(buffer);
- auto amount_to_read = std::min(size, m_vector.size() - m_position);
-
- if(amount_to_read > 0) {
- std::copy(m_vector.cbegin() + m_position, m_vector.cbegin() + m_position + amount_to_read, bytes);
- }
-
- m_position += size;
-}
-
-io::WriteBuffer::WriteBuffer(const WriteBuffer& other)
-{
- m_vector = other.m_vector;
-}
-
-std::size_t io::WriteBuffer::size(void) const
-{
- return m_vector.size();
-}
-
-const std::byte* io::WriteBuffer::data(void) const
-{
- return m_vector.data();
-}
-
-void io::WriteBuffer::reset(void)
-{
- m_vector.clear();
-}
-
-void io::WriteBuffer::write(const WriteBuffer& other)
-{
- m_vector.insert(m_vector.end(), other.m_vector.begin(), other.m_vector.end());
-}
-
-void io::WriteBuffer::write(const void* data, std::size_t size)
-{
- assert(data);
-
- auto bytes = reinterpret_cast<const std::byte*>(data);
- m_vector.insert(m_vector.end(), bytes, bytes + size);
-}
-
-template<>
-void io::WriteBuffer::write<std::byte>(const std::byte value)
-{
- m_vector.push_back(value);
-}
-
-template<>
-void io::WriteBuffer::write<std::uint8_t>(const std::uint8_t value)
-{
- m_vector.push_back(static_cast<std::byte>(value));
-}
-
-template<>
-void io::WriteBuffer::write<std::uint16_t>(const std::uint16_t value)
-{
- m_vector.push_back(static_cast<std::byte>(UINT16_C(0xFF) & ((value & UINT16_C(0xFF00)) >> 8U)));
- m_vector.push_back(static_cast<std::byte>(UINT16_C(0xFF) & ((value & UINT16_C(0x00FF)) >> 0U)));
-}
-
-template<>
-void io::WriteBuffer::write<std::uint32_t>(const std::uint32_t value)
-{
- m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0xFF000000)) >> 24U)));
- m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x00FF0000)) >> 16U)));
- m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x0000FF00)) >> 8U)));
- m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x000000FF)) >> 0U)));
-}
-
-template<>
-void io::WriteBuffer::write<std::uint64_t>(const std::uint64_t value)
-{
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0xFF00000000000000)) >> 56U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00FF000000000000)) >> 48U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x0000FF0000000000)) >> 40U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x000000FF00000000)) >> 32U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00000000FF000000)) >> 24U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x0000000000FF0000)) >> 16U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x000000000000FF00)) >> 8U)));
- m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00000000000000FF)) >> 0U)));
-}
-
-template<>
-void io::WriteBuffer::write(const float value)
-{
- write(std::bit_cast<std::uint32_t>(value));
-}
-
-template<>
-void io::WriteBuffer::write(const std::int8_t value)
-{
- write(std::bit_cast<std::uint8_t>(value));
-}
-
-template<>
-void io::WriteBuffer::write(const std::int16_t value)
-{
- write(std::bit_cast<std::uint16_t>(value));
-}
-
-template<>
-void io::WriteBuffer::write(const std::int32_t value)
-{
- write(std::bit_cast<std::uint32_t>(value));
-}
-
-template<>
-void io::WriteBuffer::write(const std::int64_t value)
-{
- write(std::bit_cast<std::uint64_t>(value));
-}
-
-template<>
-void io::WriteBuffer::write<std::string_view>(const std::string_view value)
-{
- write<std::uint16_t>(value.size());
-
- for(const auto& character : value) {
- m_vector.push_back(static_cast<std::byte>(character));
- }
-}
-
-PHYSFS_File* io::WriteBuffer::to_file(const std::string& path, bool append) const
-{
- PHYSFS_File* file = nullptr;
-
- if(append) {
- file = PHYSFS_openAppend(path.c_str());
- }
- else {
- file = PHYSFS_openWrite(path.c_str());
- }
-
- if(file) {
- PHYSFS_writeBytes(file, m_vector.data(), m_vector.size());
- }
-
- return file;
-}
-
-ENetPacket* io::WriteBuffer::to_packet(enet_uint32 flags) const
-{
- return enet_packet_create(m_vector.data(), m_vector.size(), flags);
-}
+#include "core/pch.hh" + +#include "core/io/buffer.hh" + +#include "core/math/constexpr.hh" + +io::ReadBuffer::ReadBuffer(const ReadBuffer& other) +{ + reset(other.data(), other.size()); +} + +io::ReadBuffer::ReadBuffer(const void* data, std::size_t size) +{ + assert(data); + + reset(data, size); +} + +io::ReadBuffer::ReadBuffer(const ENetPacket* packet) +{ + assert(packet); + + reset(packet); +} + +io::ReadBuffer::ReadBuffer(PHYSFS_File* file) +{ + assert(file); + + reset(file); +} + +std::size_t io::ReadBuffer::size(void) const +{ + return m_vector.size(); +} + +const std::byte* io::ReadBuffer::data(void) const +{ + return m_vector.data(); +} + +void io::ReadBuffer::reset(const void* data, std::size_t size) +{ + assert(data); + + auto bytes = reinterpret_cast<const std::byte*>(data); + m_vector.assign(bytes, bytes + size); + m_position = 0U; +} + +void io::ReadBuffer::reset(const ENetPacket* packet) +{ + assert(packet); + + auto bytes_ptr = reinterpret_cast<const std::byte*>(packet->data); + m_vector.assign(bytes_ptr, bytes_ptr + packet->dataLength); + m_position = 0; +} + +void io::ReadBuffer::reset(PHYSFS_File* file) +{ + assert(file); + + m_vector.resize(PHYSFS_fileLength(file)); + m_position = 0; + + PHYSFS_seek(file, 0); + PHYSFS_readBytes(file, m_vector.data(), m_vector.size()); +} + +template<> +std::byte io::ReadBuffer::read<std::byte>(void) +{ + if(m_position < m_vector.size()) { + auto result = m_vector[m_position]; + m_position += 1U; + return result; + } + + m_position += 1U; + return static_cast<std::byte>(0x00); +} + +template<> +std::uint8_t io::ReadBuffer::read<std::uint8_t>(void) +{ + if((m_position + 1U) <= m_vector.size()) { + auto result = static_cast<std::uint8_t>(m_vector[m_position]); + m_position += 1U; + return result; + } + + m_position += 1U; + return 0; +} + +template<> +std::uint16_t io::ReadBuffer::read<std::uint16_t>(void) +{ + if((m_position + 2U) <= m_vector.size()) { + auto result = UINT16_C(0x0000); + result |= (UINT16_C(0x00FF) & static_cast<std::uint16_t>(m_vector[m_position + 0U])) << 8U; + result |= (UINT16_C(0x00FF) & static_cast<std::uint16_t>(m_vector[m_position + 1U])) << 0U; + m_position += 2U; + return result; + } + + m_position += 2U; + return 0; +} + +template<> +std::uint32_t io::ReadBuffer::read<std::uint32_t>(void) +{ + if((m_position + 4U) <= m_vector.size()) { + auto result = UINT32_C(0x00000000); + result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 0U])) << 24U; + result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 1U])) << 16U; + result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 2U])) << 8U; + result |= (UINT32_C(0x000000FF) & static_cast<std::uint32_t>(m_vector[m_position + 3U])) << 0U; + m_position += 4U; + return result; + } + + m_position += 4U; + return 0; +} + +template<> +std::uint64_t io::ReadBuffer::read<std::uint64_t>(void) +{ + if((m_position + 8U) <= m_vector.size()) { + auto result = UINT64_C(0x0000000000000000); + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 0U])) << 56U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 1U])) << 48U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 2U])) << 40U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 3U])) << 32U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 4U])) << 24U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 5U])) << 16U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 6U])) << 8U; + result |= (UINT64_C(0x00000000000000FF) & static_cast<std::uint64_t>(m_vector[m_position + 7U])) << 0U; + m_position += 8U; + return result; + } + + m_position += 8U; + return 0; +} + +template<> +float io::ReadBuffer::read<float>(void) +{ + return std::bit_cast<float>(read<std::uint32_t>()); +} + +template<> +std::int8_t io::ReadBuffer::read<std::int8_t>(void) +{ + return std::bit_cast<std::int8_t>(read<std::uint8_t>()); +} + +template<> +std::int16_t io::ReadBuffer::read<std::int16_t>(void) +{ + return std::bit_cast<std::int16_t>(read<std::uint16_t>()); +} + +template<> +std::int32_t io::ReadBuffer::read<std::int32_t>(void) +{ + return std::bit_cast<std::int32_t>(read<std::uint32_t>()); +} + +template<> +std::int64_t io::ReadBuffer::read<std::int64_t>(void) +{ + return std::bit_cast<std::int64_t>(read<std::uint64_t>()); +} + +template<> +std::string io::ReadBuffer::read<std::string>(void) +{ + std::string result; + result.resize(read<std::uint16_t>()); + + for(std::size_t i = 0; i < result.size(); ++i) { + if(m_position < m_vector.size()) { + result[i] = static_cast<char>(m_vector[m_position]); + } + + m_position += 1U; + } + + return result; +} + +void io::ReadBuffer::read(void* buffer, std::size_t size) +{ + auto bytes = reinterpret_cast<std::byte*>(buffer); + auto amount_to_read = std::min(size, m_vector.size() - m_position); + + if(amount_to_read > 0) { + std::copy(m_vector.cbegin() + m_position, m_vector.cbegin() + m_position + amount_to_read, bytes); + } + + m_position += size; +} + +io::WriteBuffer::WriteBuffer(const WriteBuffer& other) +{ + m_vector = other.m_vector; +} + +std::size_t io::WriteBuffer::size(void) const +{ + return m_vector.size(); +} + +const std::byte* io::WriteBuffer::data(void) const +{ + return m_vector.data(); +} + +void io::WriteBuffer::reset(void) +{ + m_vector.clear(); +} + +void io::WriteBuffer::write(const WriteBuffer& other) +{ + m_vector.insert(m_vector.end(), other.m_vector.begin(), other.m_vector.end()); +} + +void io::WriteBuffer::write(const void* data, std::size_t size) +{ + assert(data); + + auto bytes = reinterpret_cast<const std::byte*>(data); + m_vector.insert(m_vector.end(), bytes, bytes + size); +} + +template<> +void io::WriteBuffer::write<std::byte>(const std::byte value) +{ + m_vector.push_back(value); +} + +template<> +void io::WriteBuffer::write<std::uint8_t>(const std::uint8_t value) +{ + m_vector.push_back(static_cast<std::byte>(value)); +} + +template<> +void io::WriteBuffer::write<std::uint16_t>(const std::uint16_t value) +{ + m_vector.push_back(static_cast<std::byte>(UINT16_C(0xFF) & ((value & UINT16_C(0xFF00)) >> 8U))); + m_vector.push_back(static_cast<std::byte>(UINT16_C(0xFF) & ((value & UINT16_C(0x00FF)) >> 0U))); +} + +template<> +void io::WriteBuffer::write<std::uint32_t>(const std::uint32_t value) +{ + m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0xFF000000)) >> 24U))); + m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x00FF0000)) >> 16U))); + m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x0000FF00)) >> 8U))); + m_vector.push_back(static_cast<std::byte>(UINT32_C(0xFF) & ((value & UINT32_C(0x000000FF)) >> 0U))); +} + +template<> +void io::WriteBuffer::write<std::uint64_t>(const std::uint64_t value) +{ + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0xFF00000000000000)) >> 56U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00FF000000000000)) >> 48U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x0000FF0000000000)) >> 40U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x000000FF00000000)) >> 32U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00000000FF000000)) >> 24U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x0000000000FF0000)) >> 16U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x000000000000FF00)) >> 8U))); + m_vector.push_back(static_cast<std::byte>(UINT64_C(0xFF) & ((value & UINT64_C(0x00000000000000FF)) >> 0U))); +} + +template<> +void io::WriteBuffer::write(const float value) +{ + write(std::bit_cast<std::uint32_t>(value)); +} + +template<> +void io::WriteBuffer::write(const std::int8_t value) +{ + write(std::bit_cast<std::uint8_t>(value)); +} + +template<> +void io::WriteBuffer::write(const std::int16_t value) +{ + write(std::bit_cast<std::uint16_t>(value)); +} + +template<> +void io::WriteBuffer::write(const std::int32_t value) +{ + write(std::bit_cast<std::uint32_t>(value)); +} + +template<> +void io::WriteBuffer::write(const std::int64_t value) +{ + write(std::bit_cast<std::uint64_t>(value)); +} + +template<> +void io::WriteBuffer::write<std::string_view>(const std::string_view value) +{ + write<std::uint16_t>(static_cast<std::uint16_t>(value.size())); + + for(const auto& character : value) { + m_vector.push_back(static_cast<std::byte>(character)); + } +} + +PHYSFS_File* io::WriteBuffer::to_file(const std::string& path, bool append) const +{ + PHYSFS_File* file = nullptr; + + if(append) { + file = PHYSFS_openAppend(path.c_str()); + } + else { + file = PHYSFS_openWrite(path.c_str()); + } + + if(file) { + PHYSFS_writeBytes(file, m_vector.data(), m_vector.size()); + } + + return file; +} + +ENetPacket* io::WriteBuffer::to_packet(enet_uint32 flags) const +{ + return enet_packet_create(m_vector.data(), m_vector.size(), flags); +} diff --git a/core/io/buffer.hh b/src/core/io/buffer.hh index 5f1ab66..96a37b1 100644 --- a/core/io/buffer.hh +++ b/src/core/io/buffer.hh @@ -1,88 +1,88 @@ -namespace io
-{
-class ReadBuffer final {
-public:
- ReadBuffer(void) = default;
- explicit ReadBuffer(const ReadBuffer& other);
- explicit ReadBuffer(const void* data, std::size_t size);
- explicit ReadBuffer(const ENetPacket* packet);
- explicit ReadBuffer(PHYSFS_File* file);
- virtual ~ReadBuffer(void) = default;
-
- std::size_t size(void) const;
- const std::byte* data(void) const;
-
- void reset(const void* data, std::size_t size);
- void reset(const ENetPacket* packet);
- void reset(PHYSFS_File* file);
-
- constexpr void rewind(void);
- constexpr bool is_ended(void) const;
-
- void read(void* buffer, std::size_t size);
-
- template<typename T>
- T read(void);
-
- template<typename T>
- ReadBuffer& operator>>(T& value);
-
-private:
- std::vector<std::byte> m_vector;
- std::size_t m_position;
-};
-} // namespace io
-
-namespace io
-{
-class WriteBuffer final {
-public:
- WriteBuffer(void) = default;
- explicit WriteBuffer(const WriteBuffer& other);
- virtual ~WriteBuffer(void) = default;
-
- std::size_t size(void) const;
- const std::byte* data(void) const;
-
- void reset(void);
-
- void write(const WriteBuffer& other);
- void write(const void* data, std::size_t size);
-
- template<typename T>
- void write(const T value);
-
- template<typename T>
- WriteBuffer& operator<<(const T value);
-
- PHYSFS_File* to_file(const std::string& path, bool append = false) const;
- ENetPacket* to_packet(enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE) const;
-
-private:
- std::vector<std::byte> m_vector;
-};
-} // namespace io
-
-constexpr void io::ReadBuffer::rewind(void)
-{
- m_position = 0;
-}
-
-constexpr bool io::ReadBuffer::is_ended(void) const
-{
- return m_position >= m_vector.size();
-}
-
-template<typename T>
-io::ReadBuffer& io::ReadBuffer::operator>>(T& value)
-{
- value = read<T>();
- return *this;
-}
-
-template<typename T>
-io::WriteBuffer& io::WriteBuffer::operator<<(const T value)
-{
- write<T>(value);
- return *this;
-}
+namespace io +{ +class ReadBuffer final { +public: + ReadBuffer(void) = default; + explicit ReadBuffer(const ReadBuffer& other); + explicit ReadBuffer(const void* data, std::size_t size); + explicit ReadBuffer(const ENetPacket* packet); + explicit ReadBuffer(PHYSFS_File* file); + virtual ~ReadBuffer(void) = default; + + std::size_t size(void) const; + const std::byte* data(void) const; + + void reset(const void* data, std::size_t size); + void reset(const ENetPacket* packet); + void reset(PHYSFS_File* file); + + constexpr void rewind(void); + constexpr bool is_ended(void) const; + + void read(void* buffer, std::size_t size); + + template<typename T> + T read(void); + + template<typename T> + ReadBuffer& operator>>(T& value); + +private: + std::vector<std::byte> m_vector; + std::size_t m_position; +}; +} // namespace io + +namespace io +{ +class WriteBuffer final { +public: + WriteBuffer(void) = default; + explicit WriteBuffer(const WriteBuffer& other); + virtual ~WriteBuffer(void) = default; + + std::size_t size(void) const; + const std::byte* data(void) const; + + void reset(void); + + void write(const WriteBuffer& other); + void write(const void* data, std::size_t size); + + template<typename T> + void write(const T value); + + template<typename T> + WriteBuffer& operator<<(const T value); + + PHYSFS_File* to_file(const std::string& path, bool append = false) const; + ENetPacket* to_packet(enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE) const; + +private: + std::vector<std::byte> m_vector; +}; +} // namespace io + +constexpr void io::ReadBuffer::rewind(void) +{ + m_position = 0; +} + +constexpr bool io::ReadBuffer::is_ended(void) const +{ + return m_position >= m_vector.size(); +} + +template<typename T> +io::ReadBuffer& io::ReadBuffer::operator>>(T& value) +{ + value = read<T>(); + return *this; +} + +template<typename T> +io::WriteBuffer& io::WriteBuffer::operator<<(const T value) +{ + write<T>(value); + return *this; +} diff --git a/core/io/cmdline.cc b/src/core/io/cmdline.cc index a876ace..7a00f37 100644 --- a/core/io/cmdline.cc +++ b/src/core/io/cmdline.cc @@ -1,95 +1,95 @@ -#include "core/pch.hh"
-
-#include "core/io/cmdline.hh"
-
-// Valid options always start with OPTION_PREFIX, can contain
-// a bunch of OPTION_PREFIX'es inside and never end with one
-constexpr static char OPTION_PREFIX = '-';
-
-static std::unordered_map<std::string, std::string> options;
-
-static inline bool is_option_string(const std::string& string)
-{
- if(string.find_last_of(OPTION_PREFIX) >= (string.size() - 1)) {
- return false;
- }
-
- return string[0] == OPTION_PREFIX;
-}
-
-static inline std::string get_option(const std::string& string)
-{
- std::size_t i;
- for(i = 0; string[i] == OPTION_PREFIX; ++i) {
- // empty
- }
-
- return std::string(string.cbegin() + i, string.cend());
-}
-
-void io::cmdline::create(int argc, char** argv)
-{
- for(int idx = 1; idx < argc; ++idx) {
- std::string string = argv[idx];
-
- if(!is_option_string(string)) {
- spdlog::warn("cmdline: non-argument at {}: {}", idx, string);
- continue;
- }
-
- auto option_string = get_option(string);
- auto next_idx = idx + 1;
-
- if(next_idx < argc) {
- std::string argument = argv[next_idx];
-
- if(!is_option_string(argument)) {
- options.insert_or_assign(option_string, argument);
- idx = next_idx;
- continue;
- }
- }
-
- // The option is either last or has no
- // argument (happens when there is a valid
- // option right next to the one we're parsing)
- options.insert_or_assign(option_string, std::string());
- }
-}
-
-void io::cmdline::insert(std::string_view option)
-{
- options.insert_or_assign(std::string(option), std::string());
-}
-
-void io::cmdline::insert(std::string_view option, std::string_view argument)
-{
- options.insert_or_assign(std::string(option), std::string(argument));
-}
-
-std::string_view io::cmdline::get(std::string_view option, std::string_view fallback)
-{
- auto it = options.find(std::string(option));
-
- if(it == options.cend()) {
- return fallback;
- }
-
- return it->second;
-}
-
-const char* io::cmdline::get_cstr(std::string_view option, const char* fallback)
-{
- auto it = options.find(std::string(option));
-
- if(it == options.cend()) {
- return fallback;
- }
-
- return it->second.c_str();
-}
-
-bool io::cmdline::contains(std::string_view option)
-{
- return options.count(std::string(option));
-}
+#include "core/pch.hh" + +#include "core/io/cmdline.hh" + +// Valid options always start with OPTION_PREFIX, can contain +// a bunch of OPTION_PREFIX'es inside and never end with one +constexpr static char OPTION_PREFIX = '-'; + +static std::unordered_map<std::string, std::string> options; + +static inline bool is_option_string(const std::string& string) +{ + if(string.find_last_of(OPTION_PREFIX) >= (string.size() - 1)) { + return false; + } + + return string[0] == OPTION_PREFIX; +} + +static inline std::string get_option(const std::string& string) +{ + std::size_t i; + for(i = 0; string[i] == OPTION_PREFIX; ++i) { + // empty + } + + return std::string(string.cbegin() + i, string.cend()); +} + +void io::cmdline::create(int argc, char** argv) +{ + for(int idx = 1; idx < argc; ++idx) { + std::string string = argv[idx]; + + if(!is_option_string(string)) { + spdlog::warn("cmdline: non-argument at {}: {}", idx, string); + continue; + } + + auto option_string = get_option(string); + auto next_idx = idx + 1; + + if(next_idx < argc) { + std::string argument = argv[next_idx]; + + if(!is_option_string(argument)) { + options.insert_or_assign(option_string, argument); + idx = next_idx; + continue; + } + } + + // The option is either last or has no + // argument (happens when there is a valid + // option right next to the one we're parsing) + options.insert_or_assign(option_string, std::string()); + } +} + +void io::cmdline::insert(std::string_view option) +{ + options.insert_or_assign(std::string(option), std::string()); +} + +void io::cmdline::insert(std::string_view option, std::string_view argument) +{ + options.insert_or_assign(std::string(option), std::string(argument)); +} + +std::string_view io::cmdline::get(std::string_view option, std::string_view fallback) +{ + auto it = options.find(std::string(option)); + + if(it == options.cend()) { + return fallback; + } + + return it->second; +} + +const char* io::cmdline::get_cstr(std::string_view option, const char* fallback) +{ + auto it = options.find(std::string(option)); + + if(it == options.cend()) { + return fallback; + } + + return it->second.c_str(); +} + +bool io::cmdline::contains(std::string_view option) +{ + return options.count(std::string(option)); +} diff --git a/core/io/cmdline.hh b/src/core/io/cmdline.hh index 6e2ab9a..e90433c 100644 --- a/core/io/cmdline.hh +++ b/src/core/io/cmdline.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace io::cmdline
-{
-void create(int argc, char** argv);
-void insert(std::string_view option);
-void insert(std::string_view option, std::string_view argument);
-std::string_view get(std::string_view option, std::string_view fallback = "");
-const char* get_cstr(std::string_view option, const char* fallback = nullptr);
-bool contains(std::string_view option);
-} // namespace io::cmdline
+#pragma once + +namespace io::cmdline +{ +void create(int argc, char** argv); +void insert(std::string_view option); +void insert(std::string_view option, std::string_view argument); +std::string_view get(std::string_view option, std::string_view fallback = ""); +const char* get_cstr(std::string_view option, const char* fallback = nullptr); +bool contains(std::string_view option); +} // namespace io::cmdline diff --git a/core/io/config_map.cc b/src/core/io/config_map.cc index 24206f2..57692a7 100644 --- a/core/io/config_map.cc +++ b/src/core/io/config_map.cc @@ -1,136 +1,136 @@ -#include "core/pch.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/config/ivalue.hh"
-
-#include "core/io/cmdline.hh"
-
-#include "core/utils/string.hh"
-
-#include "core/version.hh"
-
-void io::ConfigMap::load_cmdline(void)
-{
- for(auto it : m_values) {
- if(auto value = io::cmdline::get_cstr(it.first.c_str())) {
- it.second->set(value);
- }
- }
-}
-
-bool io::ConfigMap::load_file(std::string_view path)
-{
- if(auto file = PHYSFS_openRead(std::string(path).c_str())) {
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- std::string line;
- std::string kv_string;
- std::istringstream stream(source);
-
- while(std::getline(stream, line)) {
- auto comment = line.find_first_of('#');
-
- if(comment == std::string::npos) {
- kv_string = utils::trim_whitespace(line);
- }
- else {
- kv_string = utils::trim_whitespace(line.substr(0, comment));
- }
-
- if(utils::is_whitespace(kv_string)) {
- // Ignore empty or commented out lines
- continue;
- }
-
- auto separator = kv_string.find('=');
-
- if(separator == std::string::npos) {
- spdlog::warn("config: {}: invalid line: {}", path, line);
- continue;
- }
-
- auto kv_name = utils::trim_whitespace(kv_string.substr(0, separator));
- auto kv_value = utils::trim_whitespace(kv_string.substr(separator + 1));
-
- auto kv_pair = m_values.find(kv_name);
-
- if(kv_pair == m_values.cend()) {
- spdlog::warn("config: {}: unknown key: {}", path, kv_name);
- continue;
- }
-
- kv_pair->second->set(kv_value.c_str());
- }
-
- return true;
- }
-
- return false;
-}
-
-bool io::ConfigMap::save_file(std::string_view path) const
-{
- std::ostringstream stream;
-
- auto curtime = std::time(nullptr);
-
- stream << "# Voxelius " << version::semver << " configuration file" << std::endl;
- stream << "# Generated at: " << std::put_time(std::gmtime(&curtime), "%Y-%m-%d %H:%M:%S %z") << std::endl << std::endl;
-
- for(const auto& it : m_values) {
- stream << it.first << "=";
- stream << it.second->get();
- stream << std::endl;
- }
-
- if(auto file = PHYSFS_openWrite(std::string(path).c_str())) {
- auto source = stream.str();
- PHYSFS_writeBytes(file, source.data(), source.size());
- PHYSFS_close(file);
- return true;
- }
-
- return false;
-}
-
-bool io::ConfigMap::set_value(std::string_view name, std::string_view value)
-{
- auto kv_pair = m_values.find(std::string(name));
-
- if(kv_pair != m_values.cend()) {
- kv_pair->second->set(value);
- return true;
- }
-
- return false;
-}
-
-std::string_view io::ConfigMap::get_value(std::string_view name) const
-{
- auto kv_pair = m_values.find(std::string(name));
- if(kv_pair != m_values.cend()) {
- return kv_pair->second->get();
- }
-
- return std::string_view();
-}
-
-void io::ConfigMap::add_value(std::string_view name, config::IValue& vref)
-{
- m_values.insert_or_assign(std::string(name), &vref);
-}
-
-const config::IValue* io::ConfigMap::find(std::string_view name) const
-{
- auto kv_pair = m_values.find(std::string(name));
-
- if(kv_pair != m_values.cend()) {
- return kv_pair->second;
- }
- else {
- return nullptr;
- }
-}
+#include "core/pch.hh" + +#include "core/io/config_map.hh" + +#include "core/config/ivalue.hh" + +#include "core/io/cmdline.hh" + +#include "core/utils/string.hh" + +#include "core/version.hh" + +void io::ConfigMap::load_cmdline(void) +{ + for(auto it : m_values) { + if(auto value = io::cmdline::get_cstr(it.first.c_str())) { + it.second->set(value); + } + } +} + +bool io::ConfigMap::load_file(std::string_view path) +{ + if(auto file = PHYSFS_openRead(std::string(path).c_str())) { + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + std::string line; + std::string kv_string; + std::istringstream stream(source); + + while(std::getline(stream, line)) { + auto comment = line.find_first_of('#'); + + if(comment == std::string::npos) { + kv_string = utils::trim_whitespace(line); + } + else { + kv_string = utils::trim_whitespace(line.substr(0, comment)); + } + + if(utils::is_whitespace(kv_string)) { + // Ignore empty or commented out lines + continue; + } + + auto separator = kv_string.find('='); + + if(separator == std::string::npos) { + spdlog::warn("config: {}: invalid line: {}", path, line); + continue; + } + + auto kv_name = utils::trim_whitespace(kv_string.substr(0, separator)); + auto kv_value = utils::trim_whitespace(kv_string.substr(separator + 1)); + + auto kv_pair = m_values.find(kv_name); + + if(kv_pair == m_values.cend()) { + spdlog::warn("config: {}: unknown key: {}", path, kv_name); + continue; + } + + kv_pair->second->set(kv_value.c_str()); + } + + return true; + } + + return false; +} + +bool io::ConfigMap::save_file(std::string_view path) const +{ + std::ostringstream stream; + + auto curtime = std::time(nullptr); + + stream << "# Voxelius " << version::triplet << " configuration file" << std::endl; + stream << "# Generated at: " << std::put_time(std::gmtime(&curtime), "%Y-%m-%d %H:%M:%S %z") << std::endl << std::endl; + + for(const auto& it : m_values) { + stream << it.first << "="; + stream << it.second->get(); + stream << std::endl; + } + + if(auto file = PHYSFS_openWrite(std::string(path).c_str())) { + auto source = stream.str(); + PHYSFS_writeBytes(file, source.data(), source.size()); + PHYSFS_close(file); + return true; + } + + return false; +} + +bool io::ConfigMap::set_value(std::string_view name, std::string_view value) +{ + auto kv_pair = m_values.find(std::string(name)); + + if(kv_pair != m_values.cend()) { + kv_pair->second->set(value); + return true; + } + + return false; +} + +std::string_view io::ConfigMap::get_value(std::string_view name) const +{ + auto kv_pair = m_values.find(std::string(name)); + if(kv_pair != m_values.cend()) { + return kv_pair->second->get(); + } + + return std::string_view(); +} + +void io::ConfigMap::add_value(std::string_view name, config::IValue& vref) +{ + m_values.insert_or_assign(std::string(name), &vref); +} + +const config::IValue* io::ConfigMap::find(std::string_view name) const +{ + auto kv_pair = m_values.find(std::string(name)); + + if(kv_pair != m_values.cend()) { + return kv_pair->second; + } + else { + return nullptr; + } +} diff --git a/core/io/config_map.hh b/src/core/io/config_map.hh index 6b99564..b0cd579 100644 --- a/core/io/config_map.hh +++ b/src/core/io/config_map.hh @@ -1,29 +1,29 @@ -#pragma once
-
-namespace config
-{
-class IValue;
-} // namespace config
-
-namespace io
-{
-class ConfigMap final {
-public:
- ConfigMap(void) = default;
- virtual ~ConfigMap(void) = default;
-
- void load_cmdline(void);
- bool load_file(std::string_view path);
- bool save_file(std::string_view path) const;
-
- bool set_value(std::string_view name, std::string_view value);
- std::string_view get_value(std::string_view name) const;
-
- void add_value(std::string_view name, config::IValue& vref);
-
- const config::IValue* find(std::string_view name) const;
-
-private:
- std::unordered_map<std::string, config::IValue*> m_values;
-};
-} // namespace io
+#pragma once + +namespace config +{ +class IValue; +} // namespace config + +namespace io +{ +class ConfigMap final { +public: + ConfigMap(void) = default; + virtual ~ConfigMap(void) = default; + + void load_cmdline(void); + bool load_file(std::string_view path); + bool save_file(std::string_view path) const; + + bool set_value(std::string_view name, std::string_view value); + std::string_view get_value(std::string_view name) const; + + void add_value(std::string_view name, config::IValue& vref); + + const config::IValue* find(std::string_view name) const; + +private: + std::unordered_map<std::string, config::IValue*> m_values; +}; +} // namespace io diff --git a/core/io/physfs.cc b/src/core/io/physfs.cc index 1c36f88..1c36f88 100644 --- a/core/io/physfs.cc +++ b/src/core/io/physfs.cc diff --git a/core/io/physfs.hh b/src/core/io/physfs.hh index 01282ad..01282ad 100644 --- a/core/io/physfs.hh +++ b/src/core/io/physfs.hh diff --git a/core/math/CMakeLists.txt b/src/core/math/CMakeLists.txt index bcb45aa..bcb45aa 100644 --- a/core/math/CMakeLists.txt +++ b/src/core/math/CMakeLists.txt diff --git a/core/math/aabb.hh b/src/core/math/aabb.hh index 9a64aad..a235a9b 100644 --- a/core/math/aabb.hh +++ b/src/core/math/aabb.hh @@ -1,111 +1,111 @@ -#pragma once
-
-#include "core/math/concepts.hh"
-
-namespace math
-{
-template<arithmetic T>
-class AABB {
-public:
- using value_type = T;
- using vector_type = glm::vec<3, T>;
-
- constexpr AABB(void) = default;
- constexpr explicit AABB(const vector_type& start, const vector_type& end);
- virtual ~AABB(void) = default;
-
- constexpr void set_bounds(const vector_type& start, const vector_type& end);
- constexpr void set_offset(const vector_type& base, const vector_type& size);
-
- constexpr bool contains(const vector_type& point) const;
- constexpr bool intersect(const AABB<value_type>& other_box) const;
-
- constexpr AABB<value_type> combine(const AABB<value_type>& other_box) const;
- constexpr AABB<value_type> multiply(const AABB<value_type>& other_box) const;
- constexpr AABB<value_type> push(const vector_type& vector) const;
-
-public:
- vector_type min {};
- vector_type max {};
-};
-} // namespace math
-
-namespace math
-{
-using AABBf = AABB<float>;
-} // namespace math
-
-template<math::arithmetic T>
-constexpr math::AABB<T>::AABB(const vector_type& start, const vector_type& end)
-{
- set_bounds(start, end);
-}
-
-template<math::arithmetic T>
-constexpr void math::AABB<T>::set_bounds(const vector_type& start, const vector_type& end)
-{
- min = start;
- max = end;
-}
-
-template<math::arithmetic T>
-constexpr void math::AABB<T>::set_offset(const vector_type& base, const vector_type& size)
-{
- min = base;
- max = base + size;
-}
-
-template<math::arithmetic T>
-constexpr bool math::AABB<T>::contains(const vector_type& point) const
-{
- auto result = true;
- result = result && (point.x >= min.x) && (point.x <= max.x);
- result = result && (point.y >= min.y) && (point.y <= max.y);
- result = result && (point.z >= min.z) && (point.z <= max.z);
- return result;
-}
-
-template<math::arithmetic T>
-constexpr bool math::AABB<T>::intersect(const AABB<value_type>& other_box) const
-{
- auto result = true;
- result = result && (min.x <= other_box.max.x) && (max.x >= other_box.min.x);
- result = result && (min.y <= other_box.max.y) && (max.y >= other_box.min.y);
- result = result && (min.z <= other_box.max.z) && (max.z >= other_box.min.z);
- return result;
-}
-
-template<math::arithmetic T>
-constexpr math::AABB<T> math::AABB<T>::combine(const AABB<value_type>& other_box) const
-{
- AABB<value_type> result;
- result.min.x = glm::min(min.x, other_box.min.x);
- result.min.y = glm::min(min.y, other_box.min.y);
- result.min.z = glm::min(min.z, other_box.min.z);
- result.max.x = glm::max(max.x, other_box.max.x);
- result.max.y = glm::max(max.y, other_box.max.y);
- result.max.z = glm::max(max.z, other_box.max.z);
- return result;
-}
-
-template<math::arithmetic T>
-constexpr math::AABB<T> math::AABB<T>::multiply(const AABB<value_type>& other_box) const
-{
- AABB<value_type> result;
- result.min.x = glm::max(min.x, other_box.min.x);
- result.min.y = glm::max(min.y, other_box.min.y);
- result.min.z = glm::max(min.z, other_box.min.z);
- result.max.x = glm::min(max.x, other_box.max.x);
- result.max.y = glm::min(max.y, other_box.max.y);
- result.max.z = glm::min(max.z, other_box.max.z);
- return result;
-}
-
-template<math::arithmetic T>
-constexpr math::AABB<T> math::AABB<T>::push(const vector_type& vector) const
-{
- AABB<value_type> result;
- result.min = min + vector;
- result.max = max + vector;
- return result;
-}
+#pragma once + +#include "core/math/concepts.hh" + +namespace math +{ +template<arithmetic T> +class AABB { +public: + using value_type = T; + using vector_type = glm::vec<3, T>; + + constexpr AABB(void) = default; + constexpr explicit AABB(const vector_type& start, const vector_type& end); + virtual ~AABB(void) = default; + + constexpr void set_bounds(const vector_type& start, const vector_type& end); + constexpr void set_offset(const vector_type& base, const vector_type& size); + + constexpr bool contains(const vector_type& point) const; + constexpr bool intersect(const AABB<value_type>& other_box) const; + + constexpr AABB<value_type> combine(const AABB<value_type>& other_box) const; + constexpr AABB<value_type> multiply(const AABB<value_type>& other_box) const; + constexpr AABB<value_type> push(const vector_type& vector) const; + +public: + vector_type min {}; + vector_type max {}; +}; +} // namespace math + +namespace math +{ +using AABBf = AABB<float>; +} // namespace math + +template<math::arithmetic T> +constexpr math::AABB<T>::AABB(const vector_type& start, const vector_type& end) +{ + set_bounds(start, end); +} + +template<math::arithmetic T> +constexpr void math::AABB<T>::set_bounds(const vector_type& start, const vector_type& end) +{ + min = start; + max = end; +} + +template<math::arithmetic T> +constexpr void math::AABB<T>::set_offset(const vector_type& base, const vector_type& size) +{ + min = base; + max = base + size; +} + +template<math::arithmetic T> +constexpr bool math::AABB<T>::contains(const vector_type& point) const +{ + auto result = true; + result = result && (point.x >= min.x) && (point.x <= max.x); + result = result && (point.y >= min.y) && (point.y <= max.y); + result = result && (point.z >= min.z) && (point.z <= max.z); + return result; +} + +template<math::arithmetic T> +constexpr bool math::AABB<T>::intersect(const AABB<value_type>& other_box) const +{ + auto result = true; + result = result && (min.x <= other_box.max.x) && (max.x >= other_box.min.x); + result = result && (min.y <= other_box.max.y) && (max.y >= other_box.min.y); + result = result && (min.z <= other_box.max.z) && (max.z >= other_box.min.z); + return result; +} + +template<math::arithmetic T> +constexpr math::AABB<T> math::AABB<T>::combine(const AABB<value_type>& other_box) const +{ + AABB<value_type> result; + result.min.x = glm::min(min.x, other_box.min.x); + result.min.y = glm::min(min.y, other_box.min.y); + result.min.z = glm::min(min.z, other_box.min.z); + result.max.x = glm::max(max.x, other_box.max.x); + result.max.y = glm::max(max.y, other_box.max.y); + result.max.z = glm::max(max.z, other_box.max.z); + return result; +} + +template<math::arithmetic T> +constexpr math::AABB<T> math::AABB<T>::multiply(const AABB<value_type>& other_box) const +{ + AABB<value_type> result; + result.min.x = glm::max(min.x, other_box.min.x); + result.min.y = glm::max(min.y, other_box.min.y); + result.min.z = glm::max(min.z, other_box.min.z); + result.max.x = glm::min(max.x, other_box.max.x); + result.max.y = glm::min(max.y, other_box.max.y); + result.max.z = glm::min(max.z, other_box.max.z); + return result; +} + +template<math::arithmetic T> +constexpr math::AABB<T> math::AABB<T>::push(const vector_type& vector) const +{ + AABB<value_type> result; + result.min = min + vector; + result.max = max + vector; + return result; +} diff --git a/core/math/angles.hh b/src/core/math/angles.hh index edc2f65..174f320 100644 --- a/core/math/angles.hh +++ b/src/core/math/angles.hh @@ -1,103 +1,103 @@ -#pragma once
-
-#include "core/math/constexpr.hh"
-
-constexpr float A180 = math::radians(180.0f);
-constexpr float A360 = math::radians(360.0f);
-
-namespace math
-{
-float wrap_180(float angle);
-float wrap_360(float angle);
-} // namespace math
-
-namespace math
-{
-glm::fvec3 wrap_180(const glm::fvec3& angles);
-glm::fvec3 wrap_360(const glm::fvec3& angles);
-} // namespace math
-
-namespace math
-{
-void vectors(const glm::fvec3& angles, glm::fvec3& forward);
-void vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up);
-} // namespace math
-
-inline float math::wrap_180(float angle)
-{
- const auto result = std::fmod(angle + A180, A360);
-
- if(result < 0.0f) {
- return result + A180;
- }
-
- return result - A180;
-}
-
-inline float math::wrap_360(float angle)
-{
- return std::fmod(std::fmod(angle, A360) + A360, A360);
-}
-
-inline glm::fvec3 math::wrap_180(const glm::fvec3& angles)
-{
- return glm::fvec3 {
- math::wrap_180(angles.x),
- math::wrap_180(angles.y),
- math::wrap_180(angles.z),
- };
-}
-
-inline glm::fvec3 math::wrap_360(const glm::fvec3& angles)
-{
- return glm::fvec3 {
- math::wrap_360(angles.x),
- math::wrap_360(angles.y),
- math::wrap_360(angles.z),
- };
-}
-
-inline void math::vectors(const glm::fvec3& angles, glm::fvec3& forward)
-{
- const float cosp = std::cos(angles.x);
- const float cosy = std::cos(angles.y);
- const float sinp = std::sin(angles.x);
- const float siny = std::sin(angles.y);
-
- forward.x = cosp * siny * (-1.0f);
- forward.y = sinp;
- forward.z = cosp * cosy * (-1.0f);
-}
-
-inline void math::vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up)
-{
- if(!forward && !right && !up) {
- // There's no point in figuring out
- // direction vectors if nothing is passed
- // in the function to store that stuff in
- return;
- }
-
- const auto pcv = glm::cos(angles);
- const auto psv = glm::sin(angles);
- const auto ncv = pcv * (-1.0f);
- const auto nsv = psv * (-1.0f);
-
- if(forward) {
- forward->x = pcv.x * nsv.y;
- forward->y = psv.x;
- forward->z = pcv.x * ncv.y;
- }
-
- if(right) {
- right->x = pcv.z * pcv.y;
- right->y = psv.z * pcv.y;
- right->z = nsv.y;
- }
-
- if(up) {
- up->x = psv.x * psv.y * pcv.z + ncv.y * psv.z;
- up->y = pcv.x * pcv.z;
- up->z = nsv.x * ncv.y * pcv.z + psv.y * psv.z;
- }
-}
+#pragma once + +#include "core/math/constexpr.hh" + +constexpr float A180 = math::radians(180.0f); +constexpr float A360 = math::radians(360.0f); + +namespace math +{ +float wrap_180(float angle); +float wrap_360(float angle); +} // namespace math + +namespace math +{ +glm::fvec3 wrap_180(const glm::fvec3& angles); +glm::fvec3 wrap_360(const glm::fvec3& angles); +} // namespace math + +namespace math +{ +void vectors(const glm::fvec3& angles, glm::fvec3& forward); +void vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up); +} // namespace math + +inline float math::wrap_180(float angle) +{ + const auto result = std::fmod(angle + A180, A360); + + if(result < 0.0f) { + return result + A180; + } + + return result - A180; +} + +inline float math::wrap_360(float angle) +{ + return std::fmod(std::fmod(angle, A360) + A360, A360); +} + +inline glm::fvec3 math::wrap_180(const glm::fvec3& angles) +{ + return glm::fvec3 { + math::wrap_180(angles.x), + math::wrap_180(angles.y), + math::wrap_180(angles.z), + }; +} + +inline glm::fvec3 math::wrap_360(const glm::fvec3& angles) +{ + return glm::fvec3 { + math::wrap_360(angles.x), + math::wrap_360(angles.y), + math::wrap_360(angles.z), + }; +} + +inline void math::vectors(const glm::fvec3& angles, glm::fvec3& forward) +{ + const float cosp = std::cos(angles.x); + const float cosy = std::cos(angles.y); + const float sinp = std::sin(angles.x); + const float siny = std::sin(angles.y); + + forward.x = cosp * siny * (-1.0f); + forward.y = sinp; + forward.z = cosp * cosy * (-1.0f); +} + +inline void math::vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up) +{ + if(!forward && !right && !up) { + // There's no point in figuring out + // direction vectors if nothing is passed + // in the function to store that stuff in + return; + } + + const auto pcv = glm::cos(angles); + const auto psv = glm::sin(angles); + const auto ncv = pcv * (-1.0f); + const auto nsv = psv * (-1.0f); + + if(forward) { + forward->x = pcv.x * nsv.y; + forward->y = psv.x; + forward->z = pcv.x * ncv.y; + } + + if(right) { + right->x = pcv.z * pcv.y; + right->y = psv.z * pcv.y; + right->z = nsv.y; + } + + if(up) { + up->x = psv.x * psv.y * pcv.z + ncv.y * psv.z; + up->y = pcv.x * pcv.z; + up->z = nsv.x * ncv.y * pcv.z + psv.y * psv.z; + } +} diff --git a/core/math/concepts.hh b/src/core/math/concepts.hh index 19d372c..6ad5cb7 100644 --- a/core/math/concepts.hh +++ b/src/core/math/concepts.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace math
-{
-template<typename type>
-concept arithmetic = std::is_arithmetic_v<type>;
-template<typename type>
-concept signed_arithmetic = std::is_arithmetic_v<type> && std::is_signed_v<type>;
-template<typename type>
-concept unsigned_arithmetic = std::is_arithmetic_v<type> && std::is_unsigned_v<type>;
-} // namespace math
+#pragma once + +namespace math +{ +template<typename type> +concept arithmetic = std::is_arithmetic_v<type>; +template<typename type> +concept signed_arithmetic = std::is_arithmetic_v<type> && std::is_signed_v<type>; +template<typename type> +concept unsigned_arithmetic = std::is_arithmetic_v<type> && std::is_unsigned_v<type>; +} // namespace math diff --git a/core/math/constexpr.hh b/src/core/math/constexpr.hh index 6641f23..4158803 100644 --- a/core/math/constexpr.hh +++ b/src/core/math/constexpr.hh @@ -1,72 +1,72 @@ -#pragma once
-
-#include "core/math/concepts.hh"
-
-namespace math
-{
-template<typename type, std::size_t size>
-constexpr std::size_t array_size(const type (&)[size]);
-} // namespace math
-
-namespace math
-{
-template<std::integral scalar>
-constexpr scalar log2(const scalar x);
-template<std::signed_integral scalar>
-constexpr scalar mod_signed(const scalar x, const scalar m);
-template<math::signed_arithmetic result_scalar, math::arithmetic scalar>
-constexpr result_scalar sign(const scalar x);
-} // namespace math
-
-namespace math
-{
-template<math::arithmetic scalar>
-constexpr scalar degrees(const scalar x);
-template<math::arithmetic scalar>
-constexpr scalar radians(const scalar x);
-} // namespace math
-
-template<typename type, std::size_t size>
-constexpr std::size_t math::array_size(const type (&)[size])
-{
- return size;
-}
-
-template<std::integral scalar>
-constexpr scalar math::log2(const scalar x)
-{
- if(x < static_cast<scalar>(2))
- return static_cast<scalar>(0);
- return math::log2<scalar>((x + static_cast<scalar>(1)) >> 1) + static_cast<scalar>(1);
-}
-
-template<std::signed_integral scalar>
-constexpr scalar math::mod_signed(const scalar x, const scalar m)
-{
- auto result = static_cast<scalar>(x % m);
- if(result < static_cast<scalar>(0))
- return result + m;
- return result;
-}
-
-template<math::signed_arithmetic result_scalar, math::arithmetic scalar>
-constexpr result_scalar math::sign(const scalar x)
-{
- if(x < static_cast<scalar>(0))
- return static_cast<result_scalar>(-1);
- if(x > static_cast<scalar>(0))
- return static_cast<result_scalar>(+1);
- return static_cast<result_scalar>(0);
-}
-
-template<math::arithmetic scalar>
-constexpr scalar math::degrees(const scalar x)
-{
- return static_cast<scalar>(static_cast<double>(x) * 180.0 / M_PI);
-}
-
-template<math::arithmetic scalar>
-constexpr scalar math::radians(const scalar x)
-{
- return static_cast<scalar>(static_cast<double>(x) * M_PI / 180.0);
-}
+#pragma once + +#include "core/math/concepts.hh" + +namespace math +{ +template<typename type, std::size_t size> +constexpr std::size_t array_size(const type (&)[size]); +} // namespace math + +namespace math +{ +template<std::integral scalar> +constexpr scalar log2(const scalar x); +template<std::signed_integral scalar> +constexpr scalar mod_signed(const scalar x, const scalar m); +template<math::signed_arithmetic result_scalar, math::arithmetic scalar> +constexpr result_scalar sign(const scalar x); +} // namespace math + +namespace math +{ +template<math::arithmetic scalar> +constexpr scalar degrees(const scalar x); +template<math::arithmetic scalar> +constexpr scalar radians(const scalar x); +} // namespace math + +template<typename type, std::size_t size> +constexpr std::size_t math::array_size(const type (&)[size]) +{ + return size; +} + +template<std::integral scalar> +constexpr scalar math::log2(const scalar x) +{ + if(x < static_cast<scalar>(2)) + return static_cast<scalar>(0); + return math::log2<scalar>((x + static_cast<scalar>(1)) >> 1) + static_cast<scalar>(1); +} + +template<std::signed_integral scalar> +constexpr scalar math::mod_signed(const scalar x, const scalar m) +{ + auto result = static_cast<scalar>(x % m); + if(result < static_cast<scalar>(0)) + return result + m; + return result; +} + +template<math::signed_arithmetic result_scalar, math::arithmetic scalar> +constexpr result_scalar math::sign(const scalar x) +{ + if(x < static_cast<scalar>(0)) + return static_cast<result_scalar>(-1); + if(x > static_cast<scalar>(0)) + return static_cast<result_scalar>(+1); + return static_cast<result_scalar>(0); +} + +template<math::arithmetic scalar> +constexpr scalar math::degrees(const scalar x) +{ + return static_cast<scalar>(static_cast<double>(x) * 180.0 / M_PI); +} + +template<math::arithmetic scalar> +constexpr scalar math::radians(const scalar x) +{ + return static_cast<scalar>(static_cast<double>(x) * M_PI / 180.0); +} diff --git a/core/math/crc64.cc b/src/core/math/crc64.cc index ea7841d..99a4b20 100644 --- a/core/math/crc64.cc +++ b/src/core/math/crc64.cc @@ -1,76 +1,76 @@ -#include "core/pch.hh"
-
-#include "core/math/crc64.hh"
-
-// The lookup table for CRC64 checksum; this lookup
-// table is generated using ECMA-182 compilant parameters:
-// - Polynomial: `0x42F0E1EBA9EA3693`
-// - Initial value: `0x0000000000000000`
-// - Final xor: `0x0000000000000000`
-// CRC Calculator: https://www.sunshine2k.de/coding/javascript/crc/crc_js.html
-constexpr static const std::uint64_t crc_table[256] = { 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
- 0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D,
- 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
- 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3,
- 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4,
- 0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D,
- 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
- 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x172F5B3033043EBF, 0x55DFBADB9AEE082C,
- 0x92CE98E760D05399, 0xD03E790CC93A650A, 0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584,
- 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B, 0x3821458AADA7578F, 0x7AD1A461044D611C,
- 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5,
- 0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63,
- 0x16D7A787B7FAA0D6, 0x5427466C1E109645, 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324,
- 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB, 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253,
- 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA,
- 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0x676DD025684A91A1, 0x259D31CEC1A0A732,
- 0xE28C13F23B9EFC87, 0xA07CF2199274CA14, 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
- 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC,
- 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425,
- 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, 0x3971ED50550C43C1, 0x7B810CBBFCE67552,
- 0xBC902E8706D82EE7, 0xFE60CF6CAF321874, 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15,
- 0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E,
- 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7,
- 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F,
- 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97,
- 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 0x02A151B5F156289C, 0x4051B05E58BC1E0F,
- 0x87409262A28245BA, 0xC5B073890B687329, 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
- 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0x73B3727A52B393CC, 0x31439391FB59A55F,
- 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18,
- 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7, 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F,
- 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96,
- 0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E,
- 0x020905D88D03A2BB, 0x40F9E43324E99428, 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57,
- 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288, 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF,
- 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
- 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 0x03F1F96F09FD3CD2, 0x41011884A0170A41,
- 0x86103AB85A2951F4, 0xC4E0DB53F3C36767, 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
- 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, 0xE085162AB69D5E3C, 0xA275F7C11F7768AF,
- 0x6564D5FDE549331A, 0x279434164CA30589, 0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
- 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37, 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE,
- 0xBE317F32F78E067B, 0xFCC19ED95E6430E8, 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066,
- 0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, 0x14DEA25F3AF9026D, 0x562E43B4931334FE,
- 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507 };
-
-std::uint64_t math::crc64(const void* buffer, std::size_t size, std::uint64_t combine)
-{
- auto data = reinterpret_cast<const std::uint8_t*>(buffer);
- for(std::size_t i = 0; i < size; ++i)
- combine = crc_table[((combine >> 56) ^ data[i]) & 0xFF] ^ (combine << 8);
- return combine;
-}
-
-std::uint64_t math::crc64(const std::vector<std::byte>& buffer, std::uint64_t combine)
-{
- return math::crc64(buffer.data(), buffer.size(), combine);
-}
-
-std::uint64_t math::crc64(const std::string& buffer, std::uint64_t combine)
-{
- return math::crc64(buffer.data(), buffer.size(), combine);
-}
-
-std::uint64_t math::crc64(std::string_view buffer, std::uint64_t combine)
-{
- return math::crc64(buffer.data(), buffer.size(), combine);
-}
+#include "core/pch.hh" + +#include "core/math/crc64.hh" + +// The lookup table for CRC64 checksum; this lookup +// table is generated using ECMA-182 compilant parameters: +// - Polynomial: `0x42F0E1EBA9EA3693` +// - Initial value: `0x0000000000000000` +// - Final xor: `0x0000000000000000` +// CRC Calculator: https://www.sunshine2k.de/coding/javascript/crc/crc_js.html +constexpr static const std::uint64_t crc_table[256] = { 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, + 0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, + 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4, + 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, + 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, + 0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, + 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4, + 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x172F5B3033043EBF, 0x55DFBADB9AEE082C, + 0x92CE98E760D05399, 0xD03E790CC93A650A, 0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, + 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B, 0x3821458AADA7578F, 0x7AD1A461044D611C, + 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, + 0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, + 0x16D7A787B7FAA0D6, 0x5427466C1E109645, 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324, + 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB, 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, + 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, + 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0x676DD025684A91A1, 0x259D31CEC1A0A732, + 0xE28C13F23B9EFC87, 0xA07CF2199274CA14, 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144, + 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, + 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, + 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, 0x3971ED50550C43C1, 0x7B810CBBFCE67552, + 0xBC902E8706D82EE7, 0xFE60CF6CAF321874, 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, + 0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, + 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7, + 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, + 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, + 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 0x02A151B5F156289C, 0x4051B05E58BC1E0F, + 0x87409262A28245BA, 0xC5B073890B687329, 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6, + 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0x73B3727A52B393CC, 0x31439391FB59A55F, + 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, + 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7, 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, + 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, + 0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, + 0x020905D88D03A2BB, 0x40F9E43324E99428, 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57, + 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288, 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, + 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36, + 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 0x03F1F96F09FD3CD2, 0x41011884A0170A41, + 0x86103AB85A2951F4, 0xC4E0DB53F3C36767, 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206, + 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, 0xE085162AB69D5E3C, 0xA275F7C11F7768AF, + 0x6564D5FDE549331A, 0x279434164CA30589, 0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956, + 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37, 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, + 0xBE317F32F78E067B, 0xFCC19ED95E6430E8, 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, + 0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, 0x14DEA25F3AF9026D, 0x562E43B4931334FE, + 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507 }; + +std::uint64_t math::crc64(const void* buffer, std::size_t size, std::uint64_t combine) +{ + auto data = reinterpret_cast<const std::uint8_t*>(buffer); + for(std::size_t i = 0; i < size; ++i) + combine = crc_table[((combine >> 56) ^ data[i]) & 0xFF] ^ (combine << 8); + return combine; +} + +std::uint64_t math::crc64(const std::vector<std::byte>& buffer, std::uint64_t combine) +{ + return math::crc64(buffer.data(), buffer.size(), combine); +} + +std::uint64_t math::crc64(const std::string& buffer, std::uint64_t combine) +{ + return math::crc64(buffer.data(), buffer.size(), combine); +} + +std::uint64_t math::crc64(std::string_view buffer, std::uint64_t combine) +{ + return math::crc64(buffer.data(), buffer.size(), combine); +} diff --git a/core/math/crc64.hh b/src/core/math/crc64.hh index 5a6fea4..3ece0df 100644 --- a/core/math/crc64.hh +++ b/src/core/math/crc64.hh @@ -1,9 +1,9 @@ -#pragma once
-
-namespace math
-{
-std::uint64_t crc64(const void* buffer, std::size_t size, std::uint64_t combine = UINT64_C(0));
-std::uint64_t crc64(const std::vector<std::byte>& buffer, std::uint64_t combine = UINT64_C(0));
-std::uint64_t crc64(const std::string& buffer, std::uint64_t combine = UINT64_C(0));
-std::uint64_t crc64(std::string_view buffer, std::uint64_t combine = UINT64_C(0));
-} // namespace math
+#pragma once + +namespace math +{ +std::uint64_t crc64(const void* buffer, std::size_t size, std::uint64_t combine = UINT64_C(0)); +std::uint64_t crc64(const std::vector<std::byte>& buffer, std::uint64_t combine = UINT64_C(0)); +std::uint64_t crc64(const std::string& buffer, std::uint64_t combine = UINT64_C(0)); +std::uint64_t crc64(std::string_view buffer, std::uint64_t combine = UINT64_C(0)); +} // namespace math diff --git a/core/math/vectors.hh b/src/core/math/vectors.hh index ff2b8c9..bc11dd0 100644 --- a/core/math/vectors.hh +++ b/src/core/math/vectors.hh @@ -1,43 +1,43 @@ -#pragma once
-
-#include "core/math/concepts.hh"
-
-// core/vectors.hh - because NO ONE would POSSIBLY
-// need integer-based distance calculations in a
-// game about voxels. That would be INSANE! :D
-
-namespace math
-{
-template<math::arithmetic T>
-constexpr static inline const T length2(const glm::vec<2, T>& vector);
-template<math::arithmetic T>
-constexpr static inline const T length2(const glm::vec<3, T>& vector);
-template<math::arithmetic T>
-constexpr static inline const T distance2(const glm::vec<2, T>& vector_a, const glm::vec<2, T>& vector_b);
-template<math::arithmetic T>
-constexpr static inline const T distance2(const glm::vec<3, T>& vector_a, const glm::vec<3, T>& vector_b);
-} // namespace math
-
-template<math::arithmetic T>
-constexpr static inline const T math::length2(const glm::vec<2, T>& vector)
-{
- return (vector.x * vector.x) + (vector.y * vector.y);
-}
-
-template<math::arithmetic T>
-constexpr static inline const T math::length2(const glm::vec<3, T>& vector)
-{
- return (vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z);
-}
-
-template<math::arithmetic T>
-constexpr static inline const T math::distance2(const glm::vec<2, T>& vector_a, const glm::vec<2, T>& vector_b)
-{
- return math::length2(vector_a - vector_b);
-}
-
-template<math::arithmetic T>
-constexpr static inline const T math::distance2(const glm::vec<3, T>& vector_a, const glm::vec<3, T>& vector_b)
-{
- return math::length2(vector_a - vector_b);
-}
+#pragma once + +#include "core/math/concepts.hh" + +// core/vectors.hh - because NO ONE would POSSIBLY +// need integer-based distance calculations in a +// game about voxels. That would be INSANE! :D + +namespace math +{ +template<math::arithmetic T> +constexpr static inline const T length2(const glm::vec<2, T>& vector); +template<math::arithmetic T> +constexpr static inline const T length2(const glm::vec<3, T>& vector); +template<math::arithmetic T> +constexpr static inline const T distance2(const glm::vec<2, T>& vector_a, const glm::vec<2, T>& vector_b); +template<math::arithmetic T> +constexpr static inline const T distance2(const glm::vec<3, T>& vector_a, const glm::vec<3, T>& vector_b); +} // namespace math + +template<math::arithmetic T> +constexpr static inline const T math::length2(const glm::vec<2, T>& vector) +{ + return (vector.x * vector.x) + (vector.y * vector.y); +} + +template<math::arithmetic T> +constexpr static inline const T math::length2(const glm::vec<3, T>& vector) +{ + return (vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z); +} + +template<math::arithmetic T> +constexpr static inline const T math::distance2(const glm::vec<2, T>& vector_a, const glm::vec<2, T>& vector_b) +{ + return math::length2(vector_a - vector_b); +} + +template<math::arithmetic T> +constexpr static inline const T math::distance2(const glm::vec<3, T>& vector_a, const glm::vec<3, T>& vector_b) +{ + return math::length2(vector_a - vector_b); +} diff --git a/core/pch.hh b/src/core/pch.hh index 410b819..17417a5 100644 --- a/core/pch.hh +++ b/src/core/pch.hh @@ -1,49 +1,49 @@ -#pragma once
-
-#include <cinttypes>
-#include <cmath>
-#include <cstdarg>
-#include <cstddef>
-#include <cstdint>
-
-#include <algorithm>
-#include <chrono>
-#include <concepts>
-#include <filesystem>
-#include <format>
-#include <iostream>
-#include <limits>
-#include <mutex>
-#include <random>
-#include <sstream>
-#include <stdexcept>
-#include <thread>
-#include <type_traits>
-#include <typeindex>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include <BS_thread_pool.hpp>
-
-#include <emhash/hash_table8.hpp>
-
-#include <enet/enet.h>
-
-#include <glm/fwd.hpp>
-
-#include <glm/mat4x4.hpp>
-#include <glm/vec2.hpp>
-#include <glm/vec3.hpp>
-#include <glm/vec4.hpp>
-
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/quaternion.hpp>
-#include <glm/gtc/type_ptr.hpp>
-
-#include <physfs.h>
-
-#include <spdlog/spdlog.h>
-
-#include <stb_image.h>
-#include <stb_image_write.h>
+#pragma once + +#include <cinttypes> +#include <cmath> +#include <cstdarg> +#include <cstddef> +#include <cstdint> + +#include <algorithm> +#include <chrono> +#include <concepts> +#include <filesystem> +#include <format> +#include <iostream> +#include <limits> +#include <mutex> +#include <random> +#include <sstream> +#include <stdexcept> +#include <thread> +#include <type_traits> +#include <typeindex> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +#include <BS_thread_pool.hpp> + +#include <emhash/hash_table8.hpp> + +#include <enet/enet.h> + +#include <glm/fwd.hpp> + +#include <glm/mat4x4.hpp> +#include <glm/vec2.hpp> +#include <glm/vec3.hpp> +#include <glm/vec4.hpp> + +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/quaternion.hpp> +#include <glm/gtc/type_ptr.hpp> + +#include <physfs.h> + +#include <spdlog/spdlog.h> + +#include <stb_image.h> +#include <stb_image_write.h> diff --git a/core/resource/CMakeLists.txt b/src/core/resource/CMakeLists.txt index 840b3c2..840b3c2 100644 --- a/core/resource/CMakeLists.txt +++ b/src/core/resource/CMakeLists.txt diff --git a/core/resource/image.cc b/src/core/resource/image.cc index 8c83c55..8ab98db 100644 --- a/core/resource/image.cc +++ b/src/core/resource/image.cc @@ -1,81 +1,81 @@ -#include "core/pch.hh"
-
-#include "core/resource/image.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/io/physfs.hh"
-
-static int stbi_physfs_read(void* context, char* data, int size)
-{
- return PHYSFS_readBytes(reinterpret_cast<PHYSFS_File*>(context), data, size);
-}
-
-static void stbi_physfs_skip(void* context, int count)
-{
- auto file = reinterpret_cast<PHYSFS_File*>(context);
- PHYSFS_seek(file, PHYSFS_tell(file) + count);
-}
-
-static int stbi_physfs_eof(void* context)
-{
- return PHYSFS_eof(reinterpret_cast<PHYSFS_File*>(context));
-}
-
-static const void* image_load_func(const char* name, std::uint32_t flags)
-{
- assert(name);
-
- stbi_io_callbacks callbacks;
- callbacks.read = &stbi_physfs_read;
- callbacks.skip = &stbi_physfs_skip;
- callbacks.eof = &stbi_physfs_eof;
-
- stbi_set_flip_vertically_on_load(bool(flags & IMAGE_LOAD_FLIP));
-
- auto file = PHYSFS_openRead(name);
-
- if(file == nullptr) {
- spdlog::error("image: {}: {}", name, io::physfs_error());
- return nullptr;
- }
-
- int desired_channels;
-
- if(flags & IMAGE_LOAD_GRAY) {
- desired_channels = STBI_grey;
- }
- else {
- desired_channels = STBI_rgb_alpha;
- }
-
- int width, height, channels;
- auto pixels = stbi_load_from_callbacks(&callbacks, file, &width, &height, &channels, desired_channels);
-
- PHYSFS_close(file);
-
- if(pixels == nullptr) {
- spdlog::error("image: {}: {}", name, stbi_failure_reason());
- return nullptr;
- }
-
- auto image = new Image;
- image->pixels = pixels;
- image->size = glm::ivec2(width, height);
- return image;
-}
-
-static void image_free_func(const void* resource)
-{
- assert(resource);
-
- auto image = reinterpret_cast<const Image*>(resource);
- stbi_image_free(image->pixels);
-
- delete image;
-}
-
-void Image::register_resource(void)
-{
- resource::register_loader<Image>(&image_load_func, &image_free_func);
-}
+#include "core/pch.hh" + +#include "core/resource/image.hh" + +#include "core/resource/resource.hh" + +#include "core/io/physfs.hh" + +static int stbi_physfs_read(void* context, char* data, int size) +{ + return static_cast<int>(PHYSFS_readBytes(reinterpret_cast<PHYSFS_File*>(context), data, size)); +} + +static void stbi_physfs_skip(void* context, int count) +{ + auto file = reinterpret_cast<PHYSFS_File*>(context); + PHYSFS_seek(file, PHYSFS_tell(file) + count); +} + +static int stbi_physfs_eof(void* context) +{ + return PHYSFS_eof(reinterpret_cast<PHYSFS_File*>(context)); +} + +static const void* image_load_func(const char* name, std::uint32_t flags) +{ + assert(name); + + stbi_io_callbacks callbacks; + callbacks.read = &stbi_physfs_read; + callbacks.skip = &stbi_physfs_skip; + callbacks.eof = &stbi_physfs_eof; + + stbi_set_flip_vertically_on_load(bool(flags & IMAGE_LOAD_FLIP)); + + auto file = PHYSFS_openRead(name); + + if(file == nullptr) { + spdlog::error("image: {}: {}", name, io::physfs_error()); + return nullptr; + } + + int desired_channels; + + if(flags & IMAGE_LOAD_GRAY) { + desired_channels = STBI_grey; + } + else { + desired_channels = STBI_rgb_alpha; + } + + int width, height, channels; + auto pixels = stbi_load_from_callbacks(&callbacks, file, &width, &height, &channels, desired_channels); + + PHYSFS_close(file); + + if(pixels == nullptr) { + spdlog::error("image: {}: {}", name, stbi_failure_reason()); + return nullptr; + } + + auto image = new Image; + image->pixels = pixels; + image->size = glm::ivec2(width, height); + return image; +} + +static void image_free_func(const void* resource) +{ + assert(resource); + + auto image = reinterpret_cast<const Image*>(resource); + stbi_image_free(image->pixels); + + delete image; +} + +void Image::register_resource(void) +{ + resource::register_loader<Image>(&image_load_func, &image_free_func); +} diff --git a/core/resource/image.hh b/src/core/resource/image.hh index 8867b97..575591f 100644 --- a/core/resource/image.hh +++ b/src/core/resource/image.hh @@ -1,11 +1,11 @@ -#pragma once
-
-constexpr static unsigned int IMAGE_LOAD_GRAY = 0x0001U;
-constexpr static unsigned int IMAGE_LOAD_FLIP = 0x0002U;
-
-struct Image final {
- static void register_resource(void);
-
- stbi_uc* pixels;
- glm::ivec2 size;
-};
+#pragma once + +constexpr static unsigned int IMAGE_LOAD_GRAY = 0x0001U; +constexpr static unsigned int IMAGE_LOAD_FLIP = 0x0002U; + +struct Image final { + static void register_resource(void); + + stbi_uc* pixels; + glm::ivec2 size; +}; diff --git a/core/resource/resource.cc b/src/core/resource/resource.cc index 7ca2ef9..926dfc5 100644 --- a/core/resource/resource.cc +++ b/src/core/resource/resource.cc @@ -1,126 +1,126 @@ -#include "core/pch.hh"
-
-#include "core/resource/resource.hh"
-
-struct ResourceLoader final {
- ResourceLoadFunc load_func;
- ResourceFreeFunc free_func;
- emhash8::HashMap<std::string, std::shared_ptr<const void>> resources;
- std::vector<std::shared_ptr<const void>> cache;
- std::string class_name;
-};
-
-static emhash8::HashMap<std::type_index, std::unique_ptr<ResourceLoader>> loaders;
-
-void resource::detail::register_loader(const std::type_info& type, ResourceLoadFunc load_func, ResourceFreeFunc free_func)
-{
- assert(load_func);
- assert(free_func);
-
- auto type_index = std::type_index(type);
- auto loader = std::make_unique<ResourceLoader>();
- loader->class_name = type.name();
- loader->load_func = load_func;
- loader->free_func = free_func;
-
- assert(!loaders.contains(type_index));
-
- loaders.insert_or_assign(type_index, std::move(loader));
-}
-
-std::shared_ptr<const void> resource::detail::load_resource(const std::type_info& type, std::string_view name, std::uint32_t flags)
-{
- auto name_str = std::string(name);
- auto type_index = std::type_index(type);
- auto loader = loaders.find(type_index);
-
- if(loader == loaders.cend()) {
- spdlog::error("resource: no loader registered for type [{}]", type.name());
- return nullptr;
- }
-
- auto resource_it = loader->second->resources.find(name_str);
-
- if(resource_it == loader->second->resources.cend()) {
- auto resource_raw = loader->second->load_func(name_str.c_str(), flags);
-
- if(resource_raw == nullptr) {
- spdlog::error("resource: {} [{}]: load failed", loader->second->class_name, name);
- return nullptr;
- }
-
- std::shared_ptr<const void> resource_ptr(resource_raw, [](const void* ptr) { /* empty */ });
- auto loaded_it = loader->second->resources.insert_or_assign(name_str, std::move(resource_ptr));
-
- if(flags & RESOURCE_CACHE) {
- loader->second->cache.push_back(loaded_it.first->second);
- }
-
- return loaded_it.first->second;
- }
-
- return resource_it->second;
-}
-
-std::shared_ptr<const void> resource::detail::find_resource(const std::type_info& type, std::string_view name)
-{
- auto name_str = std::string(name);
- auto type_index = std::type_index(type);
- auto loader = loaders.find(type_index);
-
- if(loader == loaders.cend()) {
- spdlog::error("resource: no loader registered for type [{}]", type.name());
- return nullptr;
- }
-
- auto resource_it = loader->second->resources.find(name_str);
-
- if(resource_it == loader->second->resources.cend()) {
- spdlog::error("resource: {} [{}]: not found", loader->second->class_name, name);
- return nullptr;
- }
-
- return resource_it->second;
-}
-
-void resource::hard_cleanup(void)
-{
- for(auto& [type_index, loader] : loaders) {
- loader->cache.clear();
-
- for(auto& [name, resource_ptr] : loader->resources) {
- if(resource_ptr.use_count() > 1) {
- spdlog::warn("resource: zombie resource: {} [{}] [use_count={}]", name, loader->class_name, resource_ptr.use_count());
- }
- else {
- spdlog::debug("resource: releasing {} [{}]", name, loader->class_name);
- }
-
- loader->free_func(resource_ptr.get());
- }
-
- loader->resources.clear();
- }
-
- loaders.clear();
-}
-
-void resource::soft_cleanup(void)
-{
- for(auto& [type_index, loader] : loaders) {
- auto resource_it = loader->resources.begin();
-
- while(resource_it != loader->resources.end()) {
- if(resource_it->second.use_count() <= 1) {
- spdlog::debug("resource: releasing {} [{}]", resource_it->first, loader->class_name);
-
- loader->free_func(resource_it->second.get());
- resource_it = loader->resources.erase(resource_it);
-
- continue;
- }
-
- resource_it = std::next(resource_it);
- }
- }
-}
+#include "core/pch.hh" + +#include "core/resource/resource.hh" + +struct ResourceLoader final { + ResourceLoadFunc load_func; + ResourceFreeFunc free_func; + emhash8::HashMap<std::string, std::shared_ptr<const void>> resources; + std::vector<std::shared_ptr<const void>> cache; + std::string class_name; +}; + +static emhash8::HashMap<std::type_index, std::unique_ptr<ResourceLoader>> loaders; + +void resource::detail::register_loader(const std::type_info& type, ResourceLoadFunc load_func, ResourceFreeFunc free_func) +{ + assert(load_func); + assert(free_func); + + auto type_index = std::type_index(type); + auto loader = std::make_unique<ResourceLoader>(); + loader->class_name = type.name(); + loader->load_func = load_func; + loader->free_func = free_func; + + assert(!loaders.contains(type_index)); + + loaders.insert_or_assign(type_index, std::move(loader)); +} + +std::shared_ptr<const void> resource::detail::load_resource(const std::type_info& type, std::string_view name, std::uint32_t flags) +{ + auto name_str = std::string(name); + auto type_index = std::type_index(type); + auto loader = loaders.find(type_index); + + if(loader == loaders.cend()) { + spdlog::error("resource: no loader registered for type [{}]", type.name()); + return nullptr; + } + + auto resource_it = loader->second->resources.find(name_str); + + if(resource_it == loader->second->resources.cend()) { + auto resource_raw = loader->second->load_func(name_str.c_str(), flags); + + if(resource_raw == nullptr) { + spdlog::error("resource: {} [{}]: load failed", loader->second->class_name, name); + return nullptr; + } + + std::shared_ptr<const void> resource_ptr(resource_raw, [](const void* ptr) { /* empty */ }); + auto loaded_it = loader->second->resources.insert_or_assign(name_str, std::move(resource_ptr)); + + if(flags & RESOURCE_CACHE) { + loader->second->cache.push_back(loaded_it.first->second); + } + + return loaded_it.first->second; + } + + return resource_it->second; +} + +std::shared_ptr<const void> resource::detail::find_resource(const std::type_info& type, std::string_view name) +{ + auto name_str = std::string(name); + auto type_index = std::type_index(type); + auto loader = loaders.find(type_index); + + if(loader == loaders.cend()) { + spdlog::error("resource: no loader registered for type [{}]", type.name()); + return nullptr; + } + + auto resource_it = loader->second->resources.find(name_str); + + if(resource_it == loader->second->resources.cend()) { + spdlog::error("resource: {} [{}]: not found", loader->second->class_name, name); + return nullptr; + } + + return resource_it->second; +} + +void resource::hard_cleanup(void) +{ + for(auto& [type_index, loader] : loaders) { + loader->cache.clear(); + + for(auto& [name, resource_ptr] : loader->resources) { + if(resource_ptr.use_count() > 1) { + spdlog::warn("resource: zombie resource: {} [{}] [use_count={}]", name, loader->class_name, resource_ptr.use_count()); + } + else { + spdlog::debug("resource: releasing {} [{}]", name, loader->class_name); + } + + loader->free_func(resource_ptr.get()); + } + + loader->resources.clear(); + } + + loaders.clear(); +} + +void resource::soft_cleanup(void) +{ + for(auto& [type_index, loader] : loaders) { + auto resource_it = loader->resources.begin(); + + while(resource_it != loader->resources.end()) { + if(resource_it->second.use_count() <= 1) { + spdlog::debug("resource: releasing {} [{}]", resource_it->first, loader->class_name); + + loader->free_func(resource_it->second.get()); + resource_it = loader->resources.erase(resource_it); + + continue; + } + + resource_it = std::next(resource_it); + } + } +} diff --git a/core/resource/resource.hh b/src/core/resource/resource.hh index fbca130..105c7ff 100644 --- a/core/resource/resource.hh +++ b/src/core/resource/resource.hh @@ -1,53 +1,53 @@ -#pragma once
-
-template<typename T>
-using resource_ptr = std::shared_ptr<const T>;
-
-constexpr std::uint32_t RESOURCE_CACHE = 0x00000001U; ///< Cache the resource after loading
-constexpr std::uint32_t RESOURCE_USER = 0xFFFFFF00U; ///< User-defined flags for custom behavior
-
-using ResourceLoadFunc = const void* (*)(const char* name, std::uint32_t flags);
-using ResourceFreeFunc = void (*)(const void* resource);
-
-namespace resource::detail
-{
-void register_loader(const std::type_info& type, ResourceLoadFunc load_func, ResourceFreeFunc free_func);
-resource_ptr<void> load_resource(const std::type_info& type, std::string_view name, std::uint32_t flags);
-resource_ptr<void> find_resource(const std::type_info& type, std::string_view name);
-} // namespace resource::detail
-
-namespace resource
-{
-template<typename T>
-void register_loader(ResourceLoadFunc load_func, ResourceFreeFunc free_func);
-template<typename T>
-resource_ptr<T> load(std::string_view name, std::uint32_t flags = 0U);
-template<typename T>
-resource_ptr<T> find(std::string_view name);
-} // namespace resource
-
-namespace resource
-{
-void hard_cleanup(void);
-void soft_cleanup(void);
-} // namespace resource
-
-template<typename T>
-void resource::register_loader(ResourceLoadFunc load_func, ResourceFreeFunc free_func)
-{
- resource::detail::register_loader(typeid(T), load_func, free_func);
-}
-
-template<typename T>
-resource_ptr<T> resource::load(std::string_view name, std::uint32_t flags)
-{
- auto result = resource::detail::load_resource(typeid(T), name, flags);
- return std::reinterpret_pointer_cast<const T>(result);
-}
-
-template<typename T>
-resource_ptr<T> resource::find(std::string_view name)
-{
- auto result = resource::detail::find_resource(typeid(T), name);
- return std::reinterpret_pointer_cast<const T>(result);
-}
+#pragma once + +template<typename T> +using resource_ptr = std::shared_ptr<const T>; + +constexpr std::uint32_t RESOURCE_CACHE = 0x00000001U; ///< Cache the resource after loading +constexpr std::uint32_t RESOURCE_USER = 0xFFFFFF00U; ///< User-defined flags for custom behavior + +using ResourceLoadFunc = const void* (*)(const char* name, std::uint32_t flags); +using ResourceFreeFunc = void (*)(const void* resource); + +namespace resource::detail +{ +void register_loader(const std::type_info& type, ResourceLoadFunc load_func, ResourceFreeFunc free_func); +resource_ptr<void> load_resource(const std::type_info& type, std::string_view name, std::uint32_t flags); +resource_ptr<void> find_resource(const std::type_info& type, std::string_view name); +} // namespace resource::detail + +namespace resource +{ +template<typename T> +void register_loader(ResourceLoadFunc load_func, ResourceFreeFunc free_func); +template<typename T> +resource_ptr<T> load(std::string_view name, std::uint32_t flags = 0U); +template<typename T> +resource_ptr<T> find(std::string_view name); +} // namespace resource + +namespace resource +{ +void hard_cleanup(void); +void soft_cleanup(void); +} // namespace resource + +template<typename T> +void resource::register_loader(ResourceLoadFunc load_func, ResourceFreeFunc free_func) +{ + resource::detail::register_loader(typeid(T), load_func, free_func); +} + +template<typename T> +resource_ptr<T> resource::load(std::string_view name, std::uint32_t flags) +{ + auto result = resource::detail::load_resource(typeid(T), name, flags); + return std::reinterpret_pointer_cast<const T>(result); +} + +template<typename T> +resource_ptr<T> resource::find(std::string_view name) +{ + auto result = resource::detail::find_resource(typeid(T), name); + return std::reinterpret_pointer_cast<const T>(result); +} diff --git a/core/threading.cc b/src/core/threading.cc index 8514481..03c0e8e 100644 --- a/core/threading.cc +++ b/src/core/threading.cc @@ -1,128 +1,128 @@ -#include "core/pch.hh"
-
-#include "core/threading.hh"
-
-#include "core/io/cmdline.hh"
-
-#include "core/math/constexpr.hh"
-
-constexpr static std::string_view DEFAULT_POOL_SIZE_ARG = "4";
-
-static BS::light_thread_pool* thread_pool;
-static std::deque<Task*> task_deque;
-
-static void task_process(Task* task)
-{
- task->set_status(task_status::PROCESSING);
- task->process();
-
- if(task->get_status() == task_status::PROCESSING) {
- // If the task status is still PROCESSING
- // it can be deduced it hasn't been cancelled
- task->set_status(task_status::COMPLETED);
- }
-}
-
-task_status Task::get_status(void) const
-{
- return m_status;
-}
-
-void Task::set_status(task_status status)
-{
- m_status = status;
-}
-
-void threading::init(void)
-{
- auto argument = io::cmdline::get("threads", DEFAULT_POOL_SIZE_ARG);
- auto num_concurrent_threads = std::thread::hardware_concurrency();
- unsigned int thread_pool_size;
-
- if(num_concurrent_threads && 0 == argument.compare("max")) {
- // Use the maximum available number of concurrent
- // hardware threads provided by the implementation
- thread_pool_size = num_concurrent_threads;
- }
- else {
- if(num_concurrent_threads) {
- auto result = std::from_chars(argument.data(), argument.data() + argument.size(), thread_pool_size);
-
- if(result.ec == std::errc()) {
- thread_pool_size = glm::clamp<unsigned int>(thread_pool_size, 1U, num_concurrent_threads);
- }
- else {
- thread_pool_size = 4U;
- }
- }
- else {
- auto result = std::from_chars(argument.data(), argument.data() + argument.size(), thread_pool_size);
-
- if(result.ec == std::errc()) {
- thread_pool_size = glm::max<unsigned int>(thread_pool_size, 1U);
- }
- else {
- thread_pool_size = 4U;
- }
- }
- }
-
- spdlog::info("threading: using {} threads for pooling tasks", thread_pool_size);
-
- thread_pool = new BS::light_thread_pool(thread_pool_size);
-
- task_deque.clear();
-}
-
-void threading::shutdown(void)
-{
- for(auto task : task_deque) {
- auto status = task->get_status();
- if((status != task_status::CANCELLED) || (status != task_status::COMPLETED)) {
- task->set_status(task_status::CANCELLED);
- }
- }
-
- thread_pool->purge();
- thread_pool->wait();
-
- for(auto task : task_deque)
- delete task;
- task_deque.clear();
-
- delete thread_pool;
-}
-
-void threading::update(void)
-{
- auto task_iter = task_deque.cbegin();
-
- while(task_iter != task_deque.cend()) {
- auto task_ptr = *task_iter;
- auto status = task_ptr->get_status();
-
- if(status == task_status::CANCELLED) {
- delete task_ptr;
- task_iter = task_deque.erase(task_iter);
- continue;
- }
-
- if(status == task_status::COMPLETED) {
- task_ptr->finalize();
- delete task_ptr;
- task_iter = task_deque.erase(task_iter);
- continue;
- }
-
- task_iter = std::next(task_iter);
- }
-}
-
-void threading::detail::submit_new(Task* task)
-{
- task->set_status(task_status::ENQUEUED);
-
- static_cast<void>(thread_pool->submit_task(std::bind(&task_process, task)));
-
- task_deque.push_back(task);
-}
+#include "core/pch.hh" + +#include "core/threading.hh" + +#include "core/io/cmdline.hh" + +#include "core/math/constexpr.hh" + +constexpr static std::string_view DEFAULT_POOL_SIZE_ARG = "4"; + +static BS::light_thread_pool* thread_pool; +static std::deque<Task*> task_deque; + +static void task_process(Task* task) +{ + task->set_status(task_status::PROCESSING); + task->process(); + + if(task->get_status() == task_status::PROCESSING) { + // If the task status is still PROCESSING + // it can be deduced it hasn't been cancelled + task->set_status(task_status::COMPLETED); + } +} + +task_status Task::get_status(void) const +{ + return m_status; +} + +void Task::set_status(task_status status) +{ + m_status = status; +} + +void threading::init(void) +{ + auto argument = io::cmdline::get("threads", DEFAULT_POOL_SIZE_ARG); + auto num_concurrent_threads = std::thread::hardware_concurrency(); + unsigned int thread_pool_size; + + if(num_concurrent_threads && 0 == argument.compare("max")) { + // Use the maximum available number of concurrent + // hardware threads provided by the implementation + thread_pool_size = num_concurrent_threads; + } + else { + if(num_concurrent_threads) { + auto result = std::from_chars(argument.data(), argument.data() + argument.size(), thread_pool_size); + + if(result.ec == std::errc()) { + thread_pool_size = glm::clamp<unsigned int>(thread_pool_size, 1U, num_concurrent_threads); + } + else { + thread_pool_size = 4U; + } + } + else { + auto result = std::from_chars(argument.data(), argument.data() + argument.size(), thread_pool_size); + + if(result.ec == std::errc()) { + thread_pool_size = glm::max<unsigned int>(thread_pool_size, 1U); + } + else { + thread_pool_size = 4U; + } + } + } + + spdlog::info("threading: using {} threads for pooling tasks", thread_pool_size); + + thread_pool = new BS::light_thread_pool(thread_pool_size); + + task_deque.clear(); +} + +void threading::shutdown(void) +{ + for(auto task : task_deque) { + auto status = task->get_status(); + if((status != task_status::CANCELLED) || (status != task_status::COMPLETED)) { + task->set_status(task_status::CANCELLED); + } + } + + thread_pool->purge(); + thread_pool->wait(); + + for(auto task : task_deque) + delete task; + task_deque.clear(); + + delete thread_pool; +} + +void threading::update(void) +{ + auto task_iter = task_deque.cbegin(); + + while(task_iter != task_deque.cend()) { + auto task_ptr = *task_iter; + auto status = task_ptr->get_status(); + + if(status == task_status::CANCELLED) { + delete task_ptr; + task_iter = task_deque.erase(task_iter); + continue; + } + + if(status == task_status::COMPLETED) { + task_ptr->finalize(); + delete task_ptr; + task_iter = task_deque.erase(task_iter); + continue; + } + + task_iter = std::next(task_iter); + } +} + +void threading::detail::submit_new(Task* task) +{ + task->set_status(task_status::ENQUEUED); + + static_cast<void>(thread_pool->submit_task(std::bind(&task_process, task))); + + task_deque.push_back(task); +} diff --git a/core/threading.hh b/src/core/threading.hh index 2225907..14f17f8 100644 --- a/core/threading.hh +++ b/src/core/threading.hh @@ -1,46 +1,46 @@ -#pragma once
-
-enum class task_status : unsigned int {
- ENQUEUED = 0x0000U,
- PROCESSING = 0x0001U,
- COMPLETED = 0x0002U,
- CANCELLED = 0x0004U,
-};
-
-class Task {
-public:
- virtual ~Task(void) = default;
- virtual void process(void) = 0;
- virtual void finalize(void) = 0;
-
- task_status get_status(void) const;
- void set_status(task_status status);
-
-protected:
- std::atomic<task_status> m_status;
- std::future<void> m_future;
-};
-
-namespace threading
-{
-void init(void);
-void shutdown(void);
-void update(void);
-} // namespace threading
-
-namespace threading::detail
-{
-void submit_new(Task* task);
-} // namespace threading::detail
-
-namespace threading
-{
-template<typename T, typename... AT>
-void submit(AT&&... args);
-} // namespace threading
-
-template<typename T, typename... AT>
-inline void threading::submit(AT&&... args)
-{
- threading::detail::submit_new(new T(args...));
-}
+#pragma once + +enum class task_status : unsigned int { + ENQUEUED = 0x0000U, + PROCESSING = 0x0001U, + COMPLETED = 0x0002U, + CANCELLED = 0x0004U, +}; + +class Task { +public: + virtual ~Task(void) = default; + virtual void process(void) = 0; + virtual void finalize(void) = 0; + + task_status get_status(void) const; + void set_status(task_status status); + +protected: + std::atomic<task_status> m_status; + std::future<void> m_future; +}; + +namespace threading +{ +void init(void); +void shutdown(void); +void update(void); +} // namespace threading + +namespace threading::detail +{ +void submit_new(Task* task); +} // namespace threading::detail + +namespace threading +{ +template<typename T, typename... AT> +void submit(AT&&... args); +} // namespace threading + +template<typename T, typename... AT> +inline void threading::submit(AT&&... args) +{ + threading::detail::submit_new(new T(args...)); +} diff --git a/core/utils/CMakeLists.txt b/src/core/utils/CMakeLists.txt index 4f96261..4f96261 100644 --- a/core/utils/CMakeLists.txt +++ b/src/core/utils/CMakeLists.txt diff --git a/core/utils/epoch.cc b/src/core/utils/epoch.cc index be5d4bd..36bdb79 100644 --- a/core/utils/epoch.cc +++ b/src/core/utils/epoch.cc @@ -1,39 +1,39 @@ -#include "core/pch.hh"
-
-#include "core/utils/epoch.hh"
-
-std::uint64_t utils::unix_seconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count());
-}
-
-std::uint64_t utils::unix_milliseconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
-}
-
-std::uint64_t utils::unix_microseconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count());
-}
-
-std::int64_t utils::signed_unix_seconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count());
-}
-
-std::int64_t utils::signed_unix_milliseconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
-}
-
-std::int64_t utils::signed_unix_microseconds(void)
-{
- const auto elapsed = std::chrono::system_clock::now().time_since_epoch();
- return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count());
-}
+#include "core/pch.hh" + +#include "core/utils/epoch.hh" + +std::uint64_t utils::unix_seconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count()); +} + +std::uint64_t utils::unix_milliseconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()); +} + +std::uint64_t utils::unix_microseconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()); +} + +std::int64_t utils::signed_unix_seconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count()); +} + +std::int64_t utils::signed_unix_milliseconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()); +} + +std::int64_t utils::signed_unix_microseconds(void) +{ + const auto elapsed = std::chrono::system_clock::now().time_since_epoch(); + return static_cast<std::int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()); +} diff --git a/core/utils/epoch.hh b/src/core/utils/epoch.hh index 1df564c..4bf5460 100644 --- a/core/utils/epoch.hh +++ b/src/core/utils/epoch.hh @@ -1,15 +1,15 @@ -#pragma once
-
-namespace utils
-{
-std::uint64_t unix_seconds(void);
-std::uint64_t unix_milliseconds(void);
-std::uint64_t unix_microseconds(void);
-} // namespace utils
-
-namespace utils
-{
-std::int64_t signed_unix_seconds(void);
-std::int64_t signed_unix_milliseconds(void);
-std::int64_t signed_unix_microseconds(void);
-} // namespace utils
+#pragma once + +namespace utils +{ +std::uint64_t unix_seconds(void); +std::uint64_t unix_milliseconds(void); +std::uint64_t unix_microseconds(void); +} // namespace utils + +namespace utils +{ +std::int64_t signed_unix_seconds(void); +std::int64_t signed_unix_milliseconds(void); +std::int64_t signed_unix_microseconds(void); +} // namespace utils diff --git a/core/utils/string.cc b/src/core/utils/string.cc index 4bdc073..dd3d567 100644 --- a/core/utils/string.cc +++ b/src/core/utils/string.cc @@ -1,57 +1,57 @@ -#include "core/pch.hh"
-
-#include "core/utils/string.hh"
-
-constexpr static const char* WHITESPACE_CHARS = " \t\r\n";
-
-bool utils::is_whitespace(const std::string& string)
-{
- if(string.find_first_not_of(WHITESPACE_CHARS) == std::string::npos) {
- return true;
- }
- else if((string.size() == 1) && string[0] == 0x00) {
- return true;
- }
- else {
- return string.empty();
- }
-}
-
-std::string utils::join(const std::vector<std::string>& strings, const std::string& separator)
-{
- std::ostringstream stream;
- for(const std::string& str : strings)
- stream << str << separator;
- return stream.str();
-}
-
-std::vector<std::string> utils::split(const std::string& string, const std::string& separator)
-{
- std::size_t pos = 0;
- std::size_t prev = 0;
- std::vector<std::string> result;
-
- while((pos = string.find(separator, prev)) != std::string::npos) {
- result.push_back(string.substr(prev, pos - prev));
- prev = pos + separator.length();
- }
-
- if(prev <= string.length()) {
- result.push_back(string.substr(prev, string.length() - prev));
- }
-
- return result;
-}
-
-std::string utils::trim_whitespace(const std::string& string)
-{
- auto su = string.find_first_not_of(WHITESPACE_CHARS);
- auto sv = string.find_last_not_of(WHITESPACE_CHARS);
-
- if(su == std::string::npos) {
- return std::string();
- }
- else {
- return string.substr(su, sv - su + 1);
- }
-}
+#include "core/pch.hh" + +#include "core/utils/string.hh" + +constexpr static const char* WHITESPACE_CHARS = " \t\r\n"; + +bool utils::is_whitespace(const std::string& string) +{ + if(string.find_first_not_of(WHITESPACE_CHARS) == std::string::npos) { + return true; + } + else if((string.size() == 1) && string[0] == 0x00) { + return true; + } + else { + return string.empty(); + } +} + +std::string utils::join(const std::vector<std::string>& strings, const std::string& separator) +{ + std::ostringstream stream; + for(const std::string& str : strings) + stream << str << separator; + return stream.str(); +} + +std::vector<std::string> utils::split(const std::string& string, const std::string& separator) +{ + std::size_t pos = 0; + std::size_t prev = 0; + std::vector<std::string> result; + + while((pos = string.find(separator, prev)) != std::string::npos) { + result.push_back(string.substr(prev, pos - prev)); + prev = pos + separator.length(); + } + + if(prev <= string.length()) { + result.push_back(string.substr(prev, string.length() - prev)); + } + + return result; +} + +std::string utils::trim_whitespace(const std::string& string) +{ + auto su = string.find_first_not_of(WHITESPACE_CHARS); + auto sv = string.find_last_not_of(WHITESPACE_CHARS); + + if(su == std::string::npos) { + return std::string(); + } + else { + return string.substr(su, sv - su + 1); + } +} diff --git a/core/utils/string.hh b/src/core/utils/string.hh index 0e896fd..827c3ca 100644 --- a/core/utils/string.hh +++ b/src/core/utils/string.hh @@ -1,17 +1,17 @@ -#pragma once
-
-namespace utils
-{
-bool is_whitespace(const std::string& string);
-} // namespace utils
-
-namespace utils
-{
-std::string join(const std::vector<std::string>& strings, const std::string& separator);
-std::vector<std::string> split(const std::string& string, const std::string& separator);
-} // namespace utils
-
-namespace utils
-{
-std::string trim_whitespace(const std::string& string);
-} // namespace utils
+#pragma once + +namespace utils +{ +bool is_whitespace(const std::string& string); +} // namespace utils + +namespace utils +{ +std::string join(const std::vector<std::string>& strings, const std::string& separator); +std::vector<std::string> split(const std::string& string, const std::string& separator); +} // namespace utils + +namespace utils +{ +std::string trim_whitespace(const std::string& string); +} // namespace utils diff --git a/src/core/version.cc b/src/core/version.cc new file mode 100644 index 0000000..f508aa0 --- /dev/null +++ b/src/core/version.cc @@ -0,0 +1,15 @@ +#include "core/pch.hh" + +#include "core/version.hh" + +// clang-format off +const unsigned short version::major = 16; +const unsigned short version::minor = 0; +const unsigned short version::patch = 1; +// clang-format on + +const std::string_view version::commit = "d304b608"; +const std::string_view version::branch = "master"; +const std::string_view version::triplet = "16.0.1"; + +const std::string_view version::full = "16.0.1-d304b608"; diff --git a/src/core/version.cc.in b/src/core/version.cc.in new file mode 100644 index 0000000..5424a73 --- /dev/null +++ b/src/core/version.cc.in @@ -0,0 +1,15 @@ +#include "core/pch.hh" + +#include "core/version.hh" + +// clang-format off +const unsigned short version::major = ${PROJECT_VERSION_MAJOR}; +const unsigned short version::minor = ${PROJECT_VERSION_MINOR}; +const unsigned short version::patch = ${PROJECT_VERSION_PATCH}; +// clang-format on + +const std::string_view version::commit = "${GIT_COMMIT}"; +const std::string_view version::branch = "${GIT_BRANCH}"; +const std::string_view version::triplet = "${PROJECT_VERSION}"; + +const std::string_view version::full = "${PROJECT_VERSION}-${GIT_COMMIT}"; diff --git a/src/core/version.hh b/src/core/version.hh new file mode 100644 index 0000000..c033a3e --- /dev/null +++ b/src/core/version.hh @@ -0,0 +1,20 @@ +#pragma once + +namespace version +{ +extern const unsigned short major; +extern const unsigned short minor; +extern const unsigned short patch; +} // namespace version + +namespace version +{ +extern const std::string_view commit; +extern const std::string_view branch; +extern const std::string_view triplet; +} // namespace version + +namespace version +{ +extern const std::string_view full; +} // namespace version diff --git a/game/CMakeLists.txt b/src/game/CMakeLists.txt index 24e5c2d..0144726 100644 --- a/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -1,6 +1,4 @@ -if(BUILD_VCLIENT OR BUILD_VSERVER) - add_subdirectory(shared) -endif() +add_subdirectory(shared) if(BUILD_VCLIENT) add_subdirectory(client) diff --git a/game/client/CMakeLists.txt b/src/game/client/CMakeLists.txt index 633e486..af30497 100644 --- a/game/client/CMakeLists.txt +++ b/src/game/client/CMakeLists.txt @@ -20,8 +20,8 @@ add_executable(vclient "${CMAKE_CURRENT_LIST_DIR}/toggles.hh") target_compile_features(vclient PUBLIC cxx_std_20) target_compile_definitions(vclient PUBLIC GLFW_INCLUDE_NONE) -target_include_directories(vclient PRIVATE "${PROJECT_SOURCE_DIR}") -target_include_directories(vclient PRIVATE "${PROJECT_SOURCE_DIR}/game") +target_include_directories(vclient PRIVATE "${PROJECT_SOURCE_DIR}/src") +target_include_directories(vclient PRIVATE "${PROJECT_SOURCE_DIR}/src/game") target_precompile_headers(vclient PRIVATE "${CMAKE_CURRENT_LIST_DIR}/pch.hh") target_link_libraries(vclient PUBLIC shared dr_libs glad glfw imgui imgui-glfw imgui-opengl3 salad) diff --git a/game/client/config/CMakeLists.txt b/src/game/client/config/CMakeLists.txt index 0536160..0536160 100644 --- a/game/client/config/CMakeLists.txt +++ b/src/game/client/config/CMakeLists.txt diff --git a/game/client/config/gamepad_axis.cc b/src/game/client/config/gamepad_axis.cc index 9cc731c..c6f9e3d 100644 --- a/game/client/config/gamepad_axis.cc +++ b/src/game/client/config/gamepad_axis.cc @@ -1,115 +1,115 @@ -#include "client/pch.hh"
-
-#include "client/config/gamepad_axis.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/io/gamepad.hh"
-
-constexpr static std::string_view UNKNOWN_AXIS_NAME = "UNKNOWN";
-
-static const std::pair<int, std::string_view> axis_names[] = {
- { GLFW_GAMEPAD_AXIS_LEFT_X, "LEFT_X" },
- { GLFW_GAMEPAD_AXIS_LEFT_Y, "LEFT_Y" },
- { GLFW_GAMEPAD_AXIS_RIGHT_X, "RIGHT_X" },
- { GLFW_GAMEPAD_AXIS_RIGHT_Y, "RIGHT_Y" },
- { GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, "LEFT_TRIG" },
- { GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, "RIGHT_TRIG" },
-};
-
-static std::string_view get_axis_name(int axis)
-{
- for(const auto& it : axis_names) {
- if(it.first != axis) {
- continue;
- }
-
- return it.second;
- }
-
- return UNKNOWN_AXIS_NAME;
-}
-
-config::GamepadAxis::GamepadAxis(void) : GamepadAxis(io::INVALID_GAMEPAD_AXIS, false)
-{
-}
-
-config::GamepadAxis::GamepadAxis(int axis, bool inverted)
-{
- m_inverted = inverted;
- m_gamepad_axis = axis;
- m_name = get_axis_name(axis);
- m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
-}
-
-std::string_view config::GamepadAxis::get(void) const
-{
- return m_full_string;
-}
-
-void config::GamepadAxis::set(std::string_view value)
-{
- char new_name[64];
- unsigned int new_invert;
- std::string value_str(value);
-
- if(2 == std::sscanf(value_str.c_str(), "%63[^:]:%u", new_name, &new_invert)) {
- for(const auto& it : axis_names) {
- if(0 == it.second.compare(new_name)) {
- m_inverted = new_invert;
- m_gamepad_axis = it.first;
- m_name = get_axis_name(m_gamepad_axis);
- m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
- return;
- }
- }
- }
-
- m_inverted = false;
- m_gamepad_axis = io::INVALID_GAMEPAD_AXIS;
- m_name = UNKNOWN_AXIS_NAME;
- m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
-}
-
-int config::GamepadAxis::get_axis(void) const
-{
- return m_gamepad_axis;
-}
-
-void config::GamepadAxis::set_axis(int axis)
-{
- m_gamepad_axis = axis;
- m_name = get_axis_name(axis);
- m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
-}
-
-bool config::GamepadAxis::is_inverted(void) const
-{
- return m_inverted;
-}
-
-void config::GamepadAxis::set_inverted(bool inverted)
-{
- m_inverted = inverted;
- m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
-}
-
-float config::GamepadAxis::get_value(const GLFWgamepadstate& state, float deadzone) const
-{
- if(m_gamepad_axis <= math::array_size(state.axes)) {
- auto value = state.axes[m_gamepad_axis];
-
- if(glm::abs(value) > deadzone) {
- return m_inverted ? -value : value;
- }
-
- return 0.0f;
- }
-
- return 0.0f;
-}
-
-std::string_view config::GamepadAxis::get_name(void) const
-{
- return m_name;
-}
+#include "client/pch.hh" + +#include "client/config/gamepad_axis.hh" + +#include "core/math/constexpr.hh" + +#include "client/io/gamepad.hh" + +constexpr static std::string_view UNKNOWN_AXIS_NAME = "UNKNOWN"; + +static const std::pair<int, std::string_view> axis_names[] = { + { GLFW_GAMEPAD_AXIS_LEFT_X, "LEFT_X" }, + { GLFW_GAMEPAD_AXIS_LEFT_Y, "LEFT_Y" }, + { GLFW_GAMEPAD_AXIS_RIGHT_X, "RIGHT_X" }, + { GLFW_GAMEPAD_AXIS_RIGHT_Y, "RIGHT_Y" }, + { GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, "LEFT_TRIG" }, + { GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, "RIGHT_TRIG" }, +}; + +static std::string_view get_axis_name(int axis) +{ + for(const auto& it : axis_names) { + if(it.first != axis) { + continue; + } + + return it.second; + } + + return UNKNOWN_AXIS_NAME; +} + +config::GamepadAxis::GamepadAxis(void) : GamepadAxis(io::INVALID_GAMEPAD_AXIS, false) +{ +} + +config::GamepadAxis::GamepadAxis(int axis, bool inverted) +{ + m_inverted = inverted; + m_gamepad_axis = axis; + m_name = get_axis_name(axis); + m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U); +} + +std::string_view config::GamepadAxis::get(void) const +{ + return m_full_string; +} + +void config::GamepadAxis::set(std::string_view value) +{ + char new_name[64]; + unsigned int new_invert; + std::string value_str(value); + + if(2 == std::sscanf(value_str.c_str(), "%63[^:]:%u", new_name, &new_invert)) { + for(const auto& it : axis_names) { + if(0 == it.second.compare(new_name)) { + m_inverted = new_invert; + m_gamepad_axis = it.first; + m_name = get_axis_name(m_gamepad_axis); + m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U); + return; + } + } + } + + m_inverted = false; + m_gamepad_axis = io::INVALID_GAMEPAD_AXIS; + m_name = UNKNOWN_AXIS_NAME; + m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U); +} + +int config::GamepadAxis::get_axis(void) const +{ + return m_gamepad_axis; +} + +void config::GamepadAxis::set_axis(int axis) +{ + m_gamepad_axis = axis; + m_name = get_axis_name(axis); + m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U); +} + +bool config::GamepadAxis::is_inverted(void) const +{ + return m_inverted; +} + +void config::GamepadAxis::set_inverted(bool inverted) +{ + m_inverted = inverted; + m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U); +} + +float config::GamepadAxis::get_value(const GLFWgamepadstate& state, float deadzone) const +{ + if(m_gamepad_axis <= math::array_size(state.axes)) { + auto value = state.axes[m_gamepad_axis]; + + if(glm::abs(value) > deadzone) { + return m_inverted ? -value : value; + } + + return 0.0f; + } + + return 0.0f; +} + +std::string_view config::GamepadAxis::get_name(void) const +{ + return m_name; +} diff --git a/game/client/config/gamepad_axis.hh b/src/game/client/config/gamepad_axis.hh index 80c323f..9392a35 100644 --- a/game/client/config/gamepad_axis.hh +++ b/src/game/client/config/gamepad_axis.hh @@ -1,38 +1,38 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-struct GLFWgamepadstate;
-
-namespace config
-{
-class GamepadAxis final : public IValue {
-public:
- explicit GamepadAxis(void);
- explicit GamepadAxis(int axis, bool inverted);
- virtual ~GamepadAxis(void) = default;
-
- virtual std::string_view get(void) const override;
- virtual void set(std::string_view value) override;
-
- int get_axis(void) const;
- void set_axis(int axis);
-
- bool is_inverted(void) const;
- void set_inverted(bool inverted);
-
- float get_value(const GLFWgamepadstate& state, float deadzone = 0.0f) const;
-
- // Conventional get/set methods implemented by
- // this configuration value actually contain the
- // inversion flag. Since we're updating that flag
- // in the UI by means of a separate checkbox, we only need the name here
- std::string_view get_name(void) const;
-
-private:
- bool m_inverted;
- int m_gamepad_axis;
- std::string m_full_string;
- std::string_view m_name;
-};
-} // namespace config
+#pragma once + +#include "core/config/ivalue.hh" + +struct GLFWgamepadstate; + +namespace config +{ +class GamepadAxis final : public IValue { +public: + explicit GamepadAxis(void); + explicit GamepadAxis(int axis, bool inverted); + virtual ~GamepadAxis(void) = default; + + virtual std::string_view get(void) const override; + virtual void set(std::string_view value) override; + + int get_axis(void) const; + void set_axis(int axis); + + bool is_inverted(void) const; + void set_inverted(bool inverted); + + float get_value(const GLFWgamepadstate& state, float deadzone = 0.0f) const; + + // Conventional get/set methods implemented by + // this configuration value actually contain the + // inversion flag. Since we're updating that flag + // in the UI by means of a separate checkbox, we only need the name here + std::string_view get_name(void) const; + +private: + bool m_inverted; + int m_gamepad_axis; + std::string m_full_string; + std::string_view m_name; +}; +} // namespace config diff --git a/game/client/config/gamepad_button.cc b/src/game/client/config/gamepad_button.cc index 5141de3..07e4457 100644 --- a/game/client/config/gamepad_button.cc +++ b/src/game/client/config/gamepad_button.cc @@ -1,90 +1,90 @@ -#include "client/pch.hh"
-
-#include "client/config/gamepad_button.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/io/gamepad.hh"
-
-constexpr static std::string_view UNKNOWN_BUTTON_NAME = "UNKNOWN";
-
-static const std::pair<int, std::string_view> button_names[] = {
- { GLFW_GAMEPAD_BUTTON_A, "A" },
- { GLFW_GAMEPAD_BUTTON_B, "B" },
- { GLFW_GAMEPAD_BUTTON_X, "X" },
- { GLFW_GAMEPAD_BUTTON_Y, "Y" },
- { GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, "L_BUMP" },
- { GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, "R_BUMP" },
- { GLFW_GAMEPAD_BUTTON_BACK, "BACK" },
- { GLFW_GAMEPAD_BUTTON_START, "START" },
- { GLFW_GAMEPAD_BUTTON_GUIDE, "GUIDE" },
- { GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "L_THUMB" },
- { GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "R_THUMB" },
- { GLFW_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP" },
- { GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT" },
- { GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN" },
- { GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT" },
-};
-
-static std::string_view get_button_name(int button)
-{
- for(const auto& it : button_names) {
- if(it.first == button) {
- return it.second;
- }
- }
-
- return UNKNOWN_BUTTON_NAME;
-}
-
-config::GamepadButton::GamepadButton(void)
-{
- m_gamepad_button = io::INVALID_GAMEPAD_BUTTON;
- m_name = UNKNOWN_BUTTON_NAME;
-}
-
-config::GamepadButton::GamepadButton(int button)
-{
- m_gamepad_button = button;
- m_name = get_button_name(button);
-}
-
-std::string_view config::GamepadButton::get(void) const
-{
- return m_name;
-}
-
-void config::GamepadButton::set(std::string_view value)
-{
- for(const auto& it : button_names) {
- if(0 == it.second.compare(value)) {
- m_gamepad_button = it.first;
- m_name = it.second;
- return;
- }
- }
-
- m_gamepad_button = io::INVALID_GAMEPAD_BUTTON;
- m_name = UNKNOWN_BUTTON_NAME;
-}
-
-int config::GamepadButton::get_button(void) const
-{
- return m_gamepad_button;
-}
-
-void config::GamepadButton::set_button(int button)
-{
- m_gamepad_button = button;
- m_name = get_button_name(button);
-}
-
-bool config::GamepadButton::equals(int button) const
-{
- return m_gamepad_button == button;
-}
-
-bool config::GamepadButton::is_pressed(const GLFWgamepadstate& state) const
-{
- return m_gamepad_button < math::array_size(state.buttons) && state.buttons[m_gamepad_button] == GLFW_PRESS;
-}
+#include "client/pch.hh" + +#include "client/config/gamepad_button.hh" + +#include "core/math/constexpr.hh" + +#include "client/io/gamepad.hh" + +constexpr static std::string_view UNKNOWN_BUTTON_NAME = "UNKNOWN"; + +static const std::pair<int, std::string_view> button_names[] = { + { GLFW_GAMEPAD_BUTTON_A, "A" }, + { GLFW_GAMEPAD_BUTTON_B, "B" }, + { GLFW_GAMEPAD_BUTTON_X, "X" }, + { GLFW_GAMEPAD_BUTTON_Y, "Y" }, + { GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, "L_BUMP" }, + { GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, "R_BUMP" }, + { GLFW_GAMEPAD_BUTTON_BACK, "BACK" }, + { GLFW_GAMEPAD_BUTTON_START, "START" }, + { GLFW_GAMEPAD_BUTTON_GUIDE, "GUIDE" }, + { GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "L_THUMB" }, + { GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "R_THUMB" }, + { GLFW_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP" }, + { GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT" }, + { GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN" }, + { GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT" }, +}; + +static std::string_view get_button_name(int button) +{ + for(const auto& it : button_names) { + if(it.first == button) { + return it.second; + } + } + + return UNKNOWN_BUTTON_NAME; +} + +config::GamepadButton::GamepadButton(void) +{ + m_gamepad_button = io::INVALID_GAMEPAD_BUTTON; + m_name = UNKNOWN_BUTTON_NAME; +} + +config::GamepadButton::GamepadButton(int button) +{ + m_gamepad_button = button; + m_name = get_button_name(button); +} + +std::string_view config::GamepadButton::get(void) const +{ + return m_name; +} + +void config::GamepadButton::set(std::string_view value) +{ + for(const auto& it : button_names) { + if(0 == it.second.compare(value)) { + m_gamepad_button = it.first; + m_name = it.second; + return; + } + } + + m_gamepad_button = io::INVALID_GAMEPAD_BUTTON; + m_name = UNKNOWN_BUTTON_NAME; +} + +int config::GamepadButton::get_button(void) const +{ + return m_gamepad_button; +} + +void config::GamepadButton::set_button(int button) +{ + m_gamepad_button = button; + m_name = get_button_name(button); +} + +bool config::GamepadButton::equals(int button) const +{ + return m_gamepad_button == button; +} + +bool config::GamepadButton::is_pressed(const GLFWgamepadstate& state) const +{ + return m_gamepad_button < math::array_size(state.buttons) && state.buttons[m_gamepad_button] == GLFW_PRESS; +} diff --git a/game/client/config/gamepad_button.hh b/src/game/client/config/gamepad_button.hh index f11fe4f..584c353 100644 --- a/game/client/config/gamepad_button.hh +++ b/src/game/client/config/gamepad_button.hh @@ -1,28 +1,28 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-struct GLFWgamepadstate;
-
-namespace config
-{
-class GamepadButton final : public IValue {
-public:
- explicit GamepadButton(void);
- explicit GamepadButton(int button);
- virtual ~GamepadButton(void) = default;
-
- virtual std::string_view get(void) const override;
- virtual void set(std::string_view value) override;
-
- int get_button(void) const;
- void set_button(int button);
-
- bool equals(int button) const;
- bool is_pressed(const GLFWgamepadstate& state) const;
-
-private:
- int m_gamepad_button;
- std::string_view m_name;
-};
-} // namespace config
+#pragma once + +#include "core/config/ivalue.hh" + +struct GLFWgamepadstate; + +namespace config +{ +class GamepadButton final : public IValue { +public: + explicit GamepadButton(void); + explicit GamepadButton(int button); + virtual ~GamepadButton(void) = default; + + virtual std::string_view get(void) const override; + virtual void set(std::string_view value) override; + + int get_button(void) const; + void set_button(int button); + + bool equals(int button) const; + bool is_pressed(const GLFWgamepadstate& state) const; + +private: + int m_gamepad_button; + std::string_view m_name; +}; +} // namespace config diff --git a/game/client/config/keybind.cc b/src/game/client/config/keybind.cc index befdca2..e254f7b 100644 --- a/game/client/config/keybind.cc +++ b/src/game/client/config/keybind.cc @@ -1,202 +1,202 @@ -#include "client/pch.hh"
-
-#include "client/config/keybind.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/const.hh"
-
-constexpr static std::string_view UNKNOWN_KEY_NAME = "UNKNOWN";
-
-static const std::pair<int, std::string_view> key_names[] = {
- { GLFW_KEY_SPACE, "SPACE" },
- { GLFW_KEY_APOSTROPHE, "'" },
- { GLFW_KEY_COMMA, "," },
- { GLFW_KEY_MINUS, "-" },
- { GLFW_KEY_PERIOD, "." },
- { GLFW_KEY_SLASH, "/" },
- { GLFW_KEY_0, "0" },
- { GLFW_KEY_1, "1" },
- { GLFW_KEY_2, "2" },
- { GLFW_KEY_3, "3" },
- { GLFW_KEY_4, "4" },
- { GLFW_KEY_5, "5" },
- { GLFW_KEY_6, "6" },
- { GLFW_KEY_7, "7" },
- { GLFW_KEY_8, "8" },
- { GLFW_KEY_9, "9" },
- { GLFW_KEY_SEMICOLON, ";" },
- { GLFW_KEY_EQUAL, "=" },
- { GLFW_KEY_A, "A" },
- { GLFW_KEY_B, "B" },
- { GLFW_KEY_C, "C" },
- { GLFW_KEY_D, "D" },
- { GLFW_KEY_E, "E" },
- { GLFW_KEY_F, "F" },
- { GLFW_KEY_G, "G" },
- { GLFW_KEY_H, "H" },
- { GLFW_KEY_I, "I" },
- { GLFW_KEY_J, "J" },
- { GLFW_KEY_K, "K" },
- { GLFW_KEY_L, "L" },
- { GLFW_KEY_M, "M" },
- { GLFW_KEY_N, "N" },
- { GLFW_KEY_O, "O" },
- { GLFW_KEY_P, "P" },
- { GLFW_KEY_Q, "Q" },
- { GLFW_KEY_R, "R" },
- { GLFW_KEY_S, "S" },
- { GLFW_KEY_T, "T" },
- { GLFW_KEY_U, "U" },
- { GLFW_KEY_V, "V" },
- { GLFW_KEY_W, "W" },
- { GLFW_KEY_X, "X" },
- { GLFW_KEY_Y, "Y" },
- { GLFW_KEY_Z, "Z" },
- { GLFW_KEY_LEFT_BRACKET, "[" },
- { GLFW_KEY_BACKSLASH, "\\" },
- { GLFW_KEY_RIGHT_BRACKET, "]" },
- { GLFW_KEY_GRAVE_ACCENT, "`" },
- { GLFW_KEY_WORLD_1, "WORLD_1" },
- { GLFW_KEY_WORLD_2, "WORLD_2" },
- { GLFW_KEY_ESCAPE, "ESCAPE" },
- { GLFW_KEY_ENTER, "ENTER" },
- { GLFW_KEY_TAB, "TAB" },
- { GLFW_KEY_BACKSPACE, "BACKSPACE" },
- { GLFW_KEY_INSERT, "INSERT" },
- { GLFW_KEY_DELETE, "DELETE" },
- { GLFW_KEY_RIGHT, "RIGHT" },
- { GLFW_KEY_LEFT, "LEFT" },
- { GLFW_KEY_DOWN, "DOWN" },
- { GLFW_KEY_UP, "UP" },
- { GLFW_KEY_PAGE_UP, "PAGE_UP" },
- { GLFW_KEY_PAGE_DOWN, "PAGE_DOWN" },
- { GLFW_KEY_HOME, "HOME" },
- { GLFW_KEY_END, "END" },
- { GLFW_KEY_CAPS_LOCK, "CAPS_LOCK" },
- { GLFW_KEY_SCROLL_LOCK, "SCROLL_LOCK" },
- { GLFW_KEY_NUM_LOCK, "NUM_LOCK" },
- { GLFW_KEY_PRINT_SCREEN, "PRINT_SCREEN" },
- { GLFW_KEY_PAUSE, "PAUSE" },
- { GLFW_KEY_F1, "F1" },
- { GLFW_KEY_F2, "F2" },
- { GLFW_KEY_F3, "F3" },
- { GLFW_KEY_F4, "F4" },
- { GLFW_KEY_F5, "F5" },
- { GLFW_KEY_F6, "F6" },
- { GLFW_KEY_F7, "F7" },
- { GLFW_KEY_F8, "F8" },
- { GLFW_KEY_F9, "F9" },
- { GLFW_KEY_F10, "F10" },
- { GLFW_KEY_F11, "F11" },
- { GLFW_KEY_F12, "F12" },
- { GLFW_KEY_F13, "F13" },
- { GLFW_KEY_F14, "F14" },
- { GLFW_KEY_F15, "F15" },
- { GLFW_KEY_F16, "F16" },
- { GLFW_KEY_F17, "F17" },
- { GLFW_KEY_F18, "F18" },
- { GLFW_KEY_F19, "F19" },
- { GLFW_KEY_F20, "F20" },
- { GLFW_KEY_F21, "F21" },
- { GLFW_KEY_F22, "F22" },
- { GLFW_KEY_F23, "F23" },
- { GLFW_KEY_F24, "F24" },
- { GLFW_KEY_F25, "F25" },
- { GLFW_KEY_KP_0, "KEYPAD_0" },
- { GLFW_KEY_KP_1, "KEYPAD_1" },
- { GLFW_KEY_KP_2, "KEYPAD_2" },
- { GLFW_KEY_KP_3, "KEYPAD_3" },
- { GLFW_KEY_KP_4, "KEYPAD_4" },
- { GLFW_KEY_KP_5, "KEYPAD_5" },
- { GLFW_KEY_KP_6, "KEYPAD_6" },
- { GLFW_KEY_KP_7, "KEYPAD_7" },
- { GLFW_KEY_KP_8, "KEYPAD_8" },
- { GLFW_KEY_KP_9, "KEYPAD_9" },
- { GLFW_KEY_KP_DECIMAL, "KEYPAD_POINT" },
- { GLFW_KEY_KP_DIVIDE, "KEYPAD_DIV" },
- { GLFW_KEY_KP_MULTIPLY, "KEYPAD_MUL" },
- { GLFW_KEY_KP_SUBTRACT, "KEYPAD_MINUS" },
- { GLFW_KEY_KP_ADD, "KEYPAD_PLUS" },
- { GLFW_KEY_KP_ENTER, "KEYPAD_ENTER" },
- { GLFW_KEY_KP_EQUAL, "KEYPAD_EQUAL" },
- { GLFW_KEY_LEFT_SHIFT, "LEFT_SHIFT" },
- { GLFW_KEY_LEFT_CONTROL, "LEFT_CTRL" },
- { GLFW_KEY_LEFT_ALT, "LEFT_ALT" },
- { GLFW_KEY_LEFT_SUPER, "LEFT_SUPER" },
- { GLFW_KEY_RIGHT_SHIFT, "RIGHT_SHIFT" },
- { GLFW_KEY_RIGHT_CONTROL, "RIGHT_CTRL" },
- { GLFW_KEY_RIGHT_ALT, "RIGHT_ALT" },
- { GLFW_KEY_RIGHT_SUPER, "RIGHT_SUPER" },
- { GLFW_KEY_MENU, "MENU" },
-};
-
-static std::string_view get_key_name(int keycode)
-{
- for(const auto& it : key_names) {
- if(it.first == keycode) {
- return it.second;
- }
- }
-
- return UNKNOWN_KEY_NAME;
-}
-
-config::KeyBind::KeyBind(void)
-{
- m_glfw_keycode = GLFW_KEY_UNKNOWN;
- m_name = UNKNOWN_KEY_NAME;
-}
-
-config::KeyBind::KeyBind(int default_value)
-{
- if(default_value == DEBUG_KEY) {
- m_glfw_keycode = GLFW_KEY_UNKNOWN;
- m_name = UNKNOWN_KEY_NAME;
- }
- else {
- m_glfw_keycode = default_value;
- m_name = get_key_name(default_value);
- }
-}
-
-void config::KeyBind::set(std::string_view value)
-{
- for(const auto& it : key_names) {
- if((it.first != DEBUG_KEY) && 0 == it.second.compare(value)) {
- m_glfw_keycode = it.first;
- m_name = it.second;
- return;
- }
- }
-
- m_glfw_keycode = GLFW_KEY_UNKNOWN;
- m_name = UNKNOWN_KEY_NAME;
-}
-
-std::string_view config::KeyBind::get(void) const
-{
- return m_name;
-}
-
-void config::KeyBind::set_key(int keycode)
-{
- if(keycode == DEBUG_KEY) {
- m_glfw_keycode = GLFW_KEY_UNKNOWN;
- m_name = UNKNOWN_KEY_NAME;
- }
- else {
- m_glfw_keycode = keycode;
- m_name = get_key_name(keycode);
- }
-}
-
-int config::KeyBind::get_key(void) const
-{
- return m_glfw_keycode;
-}
-
-bool config::KeyBind::equals(int keycode) const
-{
- return m_glfw_keycode == keycode;
-}
+#include "client/pch.hh" + +#include "client/config/keybind.hh" + +#include "core/math/constexpr.hh" + +#include "client/const.hh" + +constexpr static std::string_view UNKNOWN_KEY_NAME = "UNKNOWN"; + +static const std::pair<int, std::string_view> key_names[] = { + { GLFW_KEY_SPACE, "SPACE" }, + { GLFW_KEY_APOSTROPHE, "'" }, + { GLFW_KEY_COMMA, "," }, + { GLFW_KEY_MINUS, "-" }, + { GLFW_KEY_PERIOD, "." }, + { GLFW_KEY_SLASH, "/" }, + { GLFW_KEY_0, "0" }, + { GLFW_KEY_1, "1" }, + { GLFW_KEY_2, "2" }, + { GLFW_KEY_3, "3" }, + { GLFW_KEY_4, "4" }, + { GLFW_KEY_5, "5" }, + { GLFW_KEY_6, "6" }, + { GLFW_KEY_7, "7" }, + { GLFW_KEY_8, "8" }, + { GLFW_KEY_9, "9" }, + { GLFW_KEY_SEMICOLON, ";" }, + { GLFW_KEY_EQUAL, "=" }, + { GLFW_KEY_A, "A" }, + { GLFW_KEY_B, "B" }, + { GLFW_KEY_C, "C" }, + { GLFW_KEY_D, "D" }, + { GLFW_KEY_E, "E" }, + { GLFW_KEY_F, "F" }, + { GLFW_KEY_G, "G" }, + { GLFW_KEY_H, "H" }, + { GLFW_KEY_I, "I" }, + { GLFW_KEY_J, "J" }, + { GLFW_KEY_K, "K" }, + { GLFW_KEY_L, "L" }, + { GLFW_KEY_M, "M" }, + { GLFW_KEY_N, "N" }, + { GLFW_KEY_O, "O" }, + { GLFW_KEY_P, "P" }, + { GLFW_KEY_Q, "Q" }, + { GLFW_KEY_R, "R" }, + { GLFW_KEY_S, "S" }, + { GLFW_KEY_T, "T" }, + { GLFW_KEY_U, "U" }, + { GLFW_KEY_V, "V" }, + { GLFW_KEY_W, "W" }, + { GLFW_KEY_X, "X" }, + { GLFW_KEY_Y, "Y" }, + { GLFW_KEY_Z, "Z" }, + { GLFW_KEY_LEFT_BRACKET, "[" }, + { GLFW_KEY_BACKSLASH, "\\" }, + { GLFW_KEY_RIGHT_BRACKET, "]" }, + { GLFW_KEY_GRAVE_ACCENT, "`" }, + { GLFW_KEY_WORLD_1, "WORLD_1" }, + { GLFW_KEY_WORLD_2, "WORLD_2" }, + { GLFW_KEY_ESCAPE, "ESCAPE" }, + { GLFW_KEY_ENTER, "ENTER" }, + { GLFW_KEY_TAB, "TAB" }, + { GLFW_KEY_BACKSPACE, "BACKSPACE" }, + { GLFW_KEY_INSERT, "INSERT" }, + { GLFW_KEY_DELETE, "DELETE" }, + { GLFW_KEY_RIGHT, "RIGHT" }, + { GLFW_KEY_LEFT, "LEFT" }, + { GLFW_KEY_DOWN, "DOWN" }, + { GLFW_KEY_UP, "UP" }, + { GLFW_KEY_PAGE_UP, "PAGE_UP" }, + { GLFW_KEY_PAGE_DOWN, "PAGE_DOWN" }, + { GLFW_KEY_HOME, "HOME" }, + { GLFW_KEY_END, "END" }, + { GLFW_KEY_CAPS_LOCK, "CAPS_LOCK" }, + { GLFW_KEY_SCROLL_LOCK, "SCROLL_LOCK" }, + { GLFW_KEY_NUM_LOCK, "NUM_LOCK" }, + { GLFW_KEY_PRINT_SCREEN, "PRINT_SCREEN" }, + { GLFW_KEY_PAUSE, "PAUSE" }, + { GLFW_KEY_F1, "F1" }, + { GLFW_KEY_F2, "F2" }, + { GLFW_KEY_F3, "F3" }, + { GLFW_KEY_F4, "F4" }, + { GLFW_KEY_F5, "F5" }, + { GLFW_KEY_F6, "F6" }, + { GLFW_KEY_F7, "F7" }, + { GLFW_KEY_F8, "F8" }, + { GLFW_KEY_F9, "F9" }, + { GLFW_KEY_F10, "F10" }, + { GLFW_KEY_F11, "F11" }, + { GLFW_KEY_F12, "F12" }, + { GLFW_KEY_F13, "F13" }, + { GLFW_KEY_F14, "F14" }, + { GLFW_KEY_F15, "F15" }, + { GLFW_KEY_F16, "F16" }, + { GLFW_KEY_F17, "F17" }, + { GLFW_KEY_F18, "F18" }, + { GLFW_KEY_F19, "F19" }, + { GLFW_KEY_F20, "F20" }, + { GLFW_KEY_F21, "F21" }, + { GLFW_KEY_F22, "F22" }, + { GLFW_KEY_F23, "F23" }, + { GLFW_KEY_F24, "F24" }, + { GLFW_KEY_F25, "F25" }, + { GLFW_KEY_KP_0, "KEYPAD_0" }, + { GLFW_KEY_KP_1, "KEYPAD_1" }, + { GLFW_KEY_KP_2, "KEYPAD_2" }, + { GLFW_KEY_KP_3, "KEYPAD_3" }, + { GLFW_KEY_KP_4, "KEYPAD_4" }, + { GLFW_KEY_KP_5, "KEYPAD_5" }, + { GLFW_KEY_KP_6, "KEYPAD_6" }, + { GLFW_KEY_KP_7, "KEYPAD_7" }, + { GLFW_KEY_KP_8, "KEYPAD_8" }, + { GLFW_KEY_KP_9, "KEYPAD_9" }, + { GLFW_KEY_KP_DECIMAL, "KEYPAD_POINT" }, + { GLFW_KEY_KP_DIVIDE, "KEYPAD_DIV" }, + { GLFW_KEY_KP_MULTIPLY, "KEYPAD_MUL" }, + { GLFW_KEY_KP_SUBTRACT, "KEYPAD_MINUS" }, + { GLFW_KEY_KP_ADD, "KEYPAD_PLUS" }, + { GLFW_KEY_KP_ENTER, "KEYPAD_ENTER" }, + { GLFW_KEY_KP_EQUAL, "KEYPAD_EQUAL" }, + { GLFW_KEY_LEFT_SHIFT, "LEFT_SHIFT" }, + { GLFW_KEY_LEFT_CONTROL, "LEFT_CTRL" }, + { GLFW_KEY_LEFT_ALT, "LEFT_ALT" }, + { GLFW_KEY_LEFT_SUPER, "LEFT_SUPER" }, + { GLFW_KEY_RIGHT_SHIFT, "RIGHT_SHIFT" }, + { GLFW_KEY_RIGHT_CONTROL, "RIGHT_CTRL" }, + { GLFW_KEY_RIGHT_ALT, "RIGHT_ALT" }, + { GLFW_KEY_RIGHT_SUPER, "RIGHT_SUPER" }, + { GLFW_KEY_MENU, "MENU" }, +}; + +static std::string_view get_key_name(int keycode) +{ + for(const auto& it : key_names) { + if(it.first == keycode) { + return it.second; + } + } + + return UNKNOWN_KEY_NAME; +} + +config::KeyBind::KeyBind(void) +{ + m_glfw_keycode = GLFW_KEY_UNKNOWN; + m_name = UNKNOWN_KEY_NAME; +} + +config::KeyBind::KeyBind(int default_value) +{ + if(default_value == DEBUG_KEY) { + m_glfw_keycode = GLFW_KEY_UNKNOWN; + m_name = UNKNOWN_KEY_NAME; + } + else { + m_glfw_keycode = default_value; + m_name = get_key_name(default_value); + } +} + +void config::KeyBind::set(std::string_view value) +{ + for(const auto& it : key_names) { + if((it.first != DEBUG_KEY) && 0 == it.second.compare(value)) { + m_glfw_keycode = it.first; + m_name = it.second; + return; + } + } + + m_glfw_keycode = GLFW_KEY_UNKNOWN; + m_name = UNKNOWN_KEY_NAME; +} + +std::string_view config::KeyBind::get(void) const +{ + return m_name; +} + +void config::KeyBind::set_key(int keycode) +{ + if(keycode == DEBUG_KEY) { + m_glfw_keycode = GLFW_KEY_UNKNOWN; + m_name = UNKNOWN_KEY_NAME; + } + else { + m_glfw_keycode = keycode; + m_name = get_key_name(keycode); + } +} + +int config::KeyBind::get_key(void) const +{ + return m_glfw_keycode; +} + +bool config::KeyBind::equals(int keycode) const +{ + return m_glfw_keycode == keycode; +} diff --git a/game/client/config/keybind.hh b/src/game/client/config/keybind.hh index 51a67d6..dff6c18 100644 --- a/game/client/config/keybind.hh +++ b/src/game/client/config/keybind.hh @@ -1,25 +1,25 @@ -#pragma once
-
-#include "core/config/ivalue.hh"
-
-namespace config
-{
-class KeyBind final : public IValue {
-public:
- explicit KeyBind(void);
- explicit KeyBind(int default_value);
- virtual ~KeyBind(void) = default;
-
- virtual void set(std::string_view value) override;
- virtual std::string_view get(void) const override;
-
- void set_key(int keycode);
- int get_key(void) const;
-
- bool equals(int keycode) const;
-
-private:
- std::string_view m_name;
- int m_glfw_keycode;
-};
-} // namespace config
+#pragma once + +#include "core/config/ivalue.hh" + +namespace config +{ +class KeyBind final : public IValue { +public: + explicit KeyBind(void); + explicit KeyBind(int default_value); + virtual ~KeyBind(void) = default; + + virtual void set(std::string_view value) override; + virtual std::string_view get(void) const override; + + void set_key(int keycode); + int get_key(void) const; + + bool equals(int keycode) const; + +private: + std::string_view m_name; + int m_glfw_keycode; +}; +} // namespace config diff --git a/game/client/const.hh b/src/game/client/const.hh index b1e458f..461b500 100644 --- a/game/client/const.hh +++ b/src/game/client/const.hh @@ -1,23 +1,23 @@ -#pragma once
-
-#include "shared/const.hh"
-
-// This key is then going to be reserved for only
-// the debug toggles and users won't be able to
-// use this key for conventional gameplay things
-constexpr static int DEBUG_KEY = GLFW_KEY_F3;
-
-constexpr static int BASE_WIDTH = 320;
-constexpr static int BASE_HEIGHT = 240;
-
-constexpr static int MIN_WIDTH = 2 * BASE_WIDTH;
-constexpr static int MIN_HEIGHT = 2 * BASE_HEIGHT;
-
-constexpr static int DEFAULT_WIDTH = 720;
-constexpr static int DEFAULT_HEIGHT = 480;
-
-static_assert(DEFAULT_WIDTH >= MIN_WIDTH);
-static_assert(DEFAULT_HEIGHT >= MIN_HEIGHT);
-
-constexpr static float MIN_PITCH = 0.0625f;
-constexpr static float MAX_PITCH = 10.0f;
+#pragma once + +#include "shared/const.hh" + +// This key is then going to be reserved for only +// the debug toggles and users won't be able to +// use this key for conventional gameplay things +constexpr static int DEBUG_KEY = GLFW_KEY_F3; + +constexpr static int BASE_WIDTH = 320; +constexpr static int BASE_HEIGHT = 240; + +constexpr static int MIN_WIDTH = 2 * BASE_WIDTH; +constexpr static int MIN_HEIGHT = 2 * BASE_HEIGHT; + +constexpr static int DEFAULT_WIDTH = 720; +constexpr static int DEFAULT_HEIGHT = 480; + +static_assert(DEFAULT_WIDTH >= MIN_WIDTH); +static_assert(DEFAULT_HEIGHT >= MIN_HEIGHT); + +constexpr static float MIN_PITCH = 0.0625f; +constexpr static float MAX_PITCH = 10.0f; diff --git a/game/client/entity/CMakeLists.txt b/src/game/client/entity/CMakeLists.txt index 4da10d6..4da10d6 100644 --- a/game/client/entity/CMakeLists.txt +++ b/src/game/client/entity/CMakeLists.txt diff --git a/game/client/entity/camera.cc b/src/game/client/entity/camera.cc index 471f2b6..3badd9d 100644 --- a/game/client/entity/camera.cc +++ b/src/game/client/entity/camera.cc @@ -1,114 +1,114 @@ -#include "client/pch.hh"
-
-#include "client/entity/camera.hh"
-
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/angles.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "client/entity/player_move.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-#include "client/toggles.hh"
-
-config::Float entity::camera::roll_angle(2.0f, 0.0f, 4.0f);
-config::Float entity::camera::vertical_fov(90.0f, 45.0f, 110.0f);
-config::Unsigned entity::camera::view_distance(16U, 4U, 32U);
-
-glm::fvec3 entity::camera::angles;
-glm::fvec3 entity::camera::direction;
-glm::fmat4x4 entity::camera::matrix;
-chunk_pos entity::camera::position_chunk;
-glm::fvec3 entity::camera::position_local;
-
-static void reset_camera(void)
-{
- entity::camera::angles = glm::fvec3(0.0f, 0.0f, 0.0f);
- entity::camera::direction = DIR_FORWARD<float>;
- entity::camera::matrix = glm::identity<glm::fmat4x4>();
- entity::camera::position_chunk = chunk_pos(0, 0, 0);
- entity::camera::position_local = glm::fvec3(0.0f, 0.0f, 0.0f);
-}
-
-// Gracefully contributed by PQCraft himself in 2024
-// making PlatinumSrc and Voxelius kind of related to each other
-static glm::fmat4x4 platinumsrc_viewmatrix(const glm::fvec3& position, const glm::fvec3& angles)
-{
- glm::fvec3 forward, up;
- math::vectors(angles, &forward, nullptr, &up);
-
- auto result = glm::identity<glm::fmat4x4>();
- result[0][0] = forward.y * up.z - forward.z * up.y;
- result[1][0] = forward.z * up.x - forward.x * up.z;
- result[2][0] = forward.x * up.y - forward.y * up.x;
- result[3][0] = -result[0][0] * position.x - result[1][0] * position.y - result[2][0] * position.z;
- result[0][1] = up.x;
- result[1][1] = up.y;
- result[2][1] = up.z;
- result[3][1] = -up.x * position.x - up.y * position.y - up.z * position.z;
- result[0][2] = -forward.x;
- result[1][2] = -forward.y;
- result[2][2] = -forward.z;
- result[3][2] = forward.x * position.x + forward.y * position.y + forward.z * position.z;
- return result;
-}
-
-void entity::camera::init(void)
-{
- globals::client_config.add_value("camera.roll_angle", entity::camera::roll_angle);
- globals::client_config.add_value("camera.vertical_fov", entity::camera::vertical_fov);
- globals::client_config.add_value("camera.view_distance", entity::camera::view_distance);
-
- settings::add_slider(1, entity::camera::vertical_fov, settings_location::GENERAL, "camera.vertical_fov", true, "%.0f");
- settings::add_slider(0, entity::camera::view_distance, settings_location::VIDEO, "camera.view_distance", false);
- settings::add_slider(10, entity::camera::roll_angle, settings_location::VIDEO, "camera.roll_angle", true, "%.01f");
-
- reset_camera();
-}
-
-void entity::camera::update(void)
-{
- if(!session::is_ingame()) {
- reset_camera();
- return;
- }
-
- const auto& head = globals::dimension->entities.get<entity::client::HeadIntr>(globals::player);
- const auto& transform = globals::dimension->entities.get<entity::client::TransformIntr>(globals::player);
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
-
- entity::camera::angles = transform.angles + head.angles;
- entity::camera::position_chunk = transform.chunk;
- entity::camera::position_local = transform.local + head.offset;
-
- glm::fvec3 right_vector, up_vector;
- math::vectors(entity::camera::angles, &entity::camera::direction, &right_vector, &up_vector);
-
- auto client_angles = entity::camera::angles;
-
- if(!toggles::get(TOGGLE_PM_FLIGHT)) {
- // Apply the quake-like view rolling
- client_angles[2] = math::radians(-entity::camera::roll_angle.get_value()
- * glm::dot(velocity.value / PMOVE_MAX_SPEED_GROUND, right_vector));
- }
-
- const auto z_near = 0.01f;
- const auto z_far = 1.25f * static_cast<float>(CHUNK_SIZE * entity::camera::view_distance.get_value());
-
- auto proj = glm::perspective(math::radians(entity::camera::vertical_fov.get_value()), globals::aspect, z_near, z_far);
- auto view = platinumsrc_viewmatrix(entity::camera::position_local, client_angles);
-
- entity::camera::matrix = proj * view;
-}
+#include "client/pch.hh" + +#include "client/entity/camera.hh" + +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/angles.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "client/entity/player_move.hh" + +#include "client/gui/settings.hh" + +#include "client/const.hh" +#include "client/globals.hh" +#include "client/session.hh" +#include "client/toggles.hh" + +config::Float entity::camera::roll_angle(2.0f, 0.0f, 4.0f); +config::Float entity::camera::vertical_fov(90.0f, 45.0f, 110.0f); +config::Unsigned entity::camera::view_distance(16U, 4U, 32U); + +glm::fvec3 entity::camera::angles; +glm::fvec3 entity::camera::direction; +glm::fmat4x4 entity::camera::matrix; +chunk_pos entity::camera::position_chunk; +glm::fvec3 entity::camera::position_local; + +static void reset_camera(void) +{ + entity::camera::angles = glm::fvec3(0.0f, 0.0f, 0.0f); + entity::camera::direction = DIR_FORWARD<float>; + entity::camera::matrix = glm::identity<glm::fmat4x4>(); + entity::camera::position_chunk = chunk_pos(0, 0, 0); + entity::camera::position_local = glm::fvec3(0.0f, 0.0f, 0.0f); +} + +// Gracefully contributed by PQCraft himself in 2024 +// making PlatinumSrc and Voxelius kind of related to each other +static glm::fmat4x4 platinumsrc_viewmatrix(const glm::fvec3& position, const glm::fvec3& angles) +{ + glm::fvec3 forward, up; + math::vectors(angles, &forward, nullptr, &up); + + auto result = glm::identity<glm::fmat4x4>(); + result[0][0] = forward.y * up.z - forward.z * up.y; + result[1][0] = forward.z * up.x - forward.x * up.z; + result[2][0] = forward.x * up.y - forward.y * up.x; + result[3][0] = -result[0][0] * position.x - result[1][0] * position.y - result[2][0] * position.z; + result[0][1] = up.x; + result[1][1] = up.y; + result[2][1] = up.z; + result[3][1] = -up.x * position.x - up.y * position.y - up.z * position.z; + result[0][2] = -forward.x; + result[1][2] = -forward.y; + result[2][2] = -forward.z; + result[3][2] = forward.x * position.x + forward.y * position.y + forward.z * position.z; + return result; +} + +void entity::camera::init(void) +{ + globals::client_config.add_value("camera.roll_angle", entity::camera::roll_angle); + globals::client_config.add_value("camera.vertical_fov", entity::camera::vertical_fov); + globals::client_config.add_value("camera.view_distance", entity::camera::view_distance); + + settings::add_slider(1, entity::camera::vertical_fov, settings_location::GENERAL, "camera.vertical_fov", true, "%.0f"); + settings::add_slider(0, entity::camera::view_distance, settings_location::VIDEO, "camera.view_distance", false); + settings::add_slider(10, entity::camera::roll_angle, settings_location::VIDEO, "camera.roll_angle", true, "%.01f"); + + reset_camera(); +} + +void entity::camera::update(void) +{ + if(!session::is_ingame()) { + reset_camera(); + return; + } + + const auto& head = globals::dimension->entities.get<entity::client::HeadIntr>(globals::player); + const auto& transform = globals::dimension->entities.get<entity::client::TransformIntr>(globals::player); + const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player); + + entity::camera::angles = transform.angles + head.angles; + entity::camera::position_chunk = transform.chunk; + entity::camera::position_local = transform.local + head.offset; + + glm::fvec3 right_vector, up_vector; + math::vectors(entity::camera::angles, &entity::camera::direction, &right_vector, &up_vector); + + auto client_angles = entity::camera::angles; + + if(!toggles::get(TOGGLE_PM_FLIGHT)) { + // Apply the quake-like view rolling + client_angles[2] = math::radians(-entity::camera::roll_angle.get_value() + * glm::dot(velocity.value / PMOVE_MAX_SPEED_GROUND, right_vector)); + } + + const auto z_near = 0.01f; + const auto z_far = 1.25f * static_cast<float>(CHUNK_SIZE * entity::camera::view_distance.get_value()); + + auto proj = glm::perspective(math::radians(entity::camera::vertical_fov.get_value()), globals::aspect, z_near, z_far); + auto view = platinumsrc_viewmatrix(entity::camera::position_local, client_angles); + + entity::camera::matrix = proj * view; +} diff --git a/game/client/entity/camera.hh b/src/game/client/entity/camera.hh index faefe78..67baf72 100644 --- a/game/client/entity/camera.hh +++ b/src/game/client/entity/camera.hh @@ -1,31 +1,31 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace config
-{
-class Float;
-class Unsigned;
-} // namespace config
-
-namespace entity::camera
-{
-extern config::Float roll_angle;
-extern config::Float vertical_fov;
-extern config::Unsigned view_distance;
-} // namespace entity::camera
-
-namespace entity::camera
-{
-extern glm::fvec3 angles;
-extern glm::fvec3 direction;
-extern glm::fmat4x4 matrix;
-extern chunk_pos position_chunk;
-extern glm::fvec3 position_local;
-} // namespace entity::camera
-
-namespace entity::camera
-{
-void init(void);
-void update(void);
-} // namespace entity::camera
+#pragma once + +#include "shared/types.hh" + +namespace config +{ +class Float; +class Unsigned; +} // namespace config + +namespace entity::camera +{ +extern config::Float roll_angle; +extern config::Float vertical_fov; +extern config::Unsigned view_distance; +} // namespace entity::camera + +namespace entity::camera +{ +extern glm::fvec3 angles; +extern glm::fvec3 direction; +extern glm::fmat4x4 matrix; +extern chunk_pos position_chunk; +extern glm::fvec3 position_local; +} // namespace entity::camera + +namespace entity::camera +{ +void init(void); +void update(void); +} // namespace entity::camera diff --git a/game/client/entity/factory.cc b/src/game/client/entity/factory.cc index 5a1785a..f6f6079 100644 --- a/game/client/entity/factory.cc +++ b/src/game/client/entity/factory.cc @@ -1,30 +1,30 @@ -#include "client/pch.hh"
-
-#include "client/entity/factory.hh"
-
-#include "shared/entity/factory.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "client/entity/sound_emitter.hh"
-
-#include "client/globals.hh"
-
-void entity::client::create_player(world::Dimension* dimension, entt::entity entity)
-{
- entity::shared::create_player(dimension, entity);
-
- const auto& head = dimension->entities.get<entity::Head>(entity);
- dimension->entities.emplace_or_replace<entity::client::HeadIntr>(entity, head);
- dimension->entities.emplace_or_replace<entity::client::HeadPrev>(entity, head);
-
- const auto& transform = dimension->entities.get<entity::Transform>(entity);
- dimension->entities.emplace_or_replace<entity::client::TransformIntr>(entity, transform);
- dimension->entities.emplace_or_replace<entity::client::TransformPrev>(entity, transform);
-
- if(globals::sound_ctx) {
- dimension->entities.emplace_or_replace<entity::SoundEmitter>(entity);
- }
-}
+#include "client/pch.hh" + +#include "client/entity/factory.hh" + +#include "shared/entity/factory.hh" +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" + +#include "shared/world/dimension.hh" + +#include "client/entity/sound_emitter.hh" + +#include "client/globals.hh" + +void entity::client::create_player(world::Dimension* dimension, entt::entity entity) +{ + entity::shared::create_player(dimension, entity); + + const auto& head = dimension->entities.get<entity::Head>(entity); + dimension->entities.emplace_or_replace<entity::client::HeadIntr>(entity, head); + dimension->entities.emplace_or_replace<entity::client::HeadPrev>(entity, head); + + const auto& transform = dimension->entities.get<entity::Transform>(entity); + dimension->entities.emplace_or_replace<entity::client::TransformIntr>(entity, transform); + dimension->entities.emplace_or_replace<entity::client::TransformPrev>(entity, transform); + + if(globals::sound_ctx) { + dimension->entities.emplace_or_replace<entity::SoundEmitter>(entity); + } +} diff --git a/game/client/entity/factory.hh b/src/game/client/entity/factory.hh index 8cc8208..63e6e44 100644 --- a/game/client/entity/factory.hh +++ b/src/game/client/entity/factory.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity::client
-{
-void create_player(world::Dimension* dimension, entt::entity entity);
-} // namespace entity::client
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity::client +{ +void create_player(world::Dimension* dimension, entt::entity entity); +} // namespace entity::client diff --git a/game/client/entity/interpolation.cc b/src/game/client/entity/interpolation.cc index c88fcf2..a9a3349 100644 --- a/game/client/entity/interpolation.cc +++ b/src/game/client/entity/interpolation.cc @@ -1,64 +1,64 @@ -#include "client/pch.hh"
-
-#include "client/entity/interpolation.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-#include "client/globals.hh"
-
-static void transform_interpolate(float alpha)
-{
- auto group = globals::dimension->entities.group<entity::client::TransformIntr>(
- entt::get<entity::Transform, entity::client::TransformPrev>);
-
- for(auto [entity, interp, current, previous] : group.each()) {
- interp.angles[0] = glm::mix(previous.angles[0], current.angles[0], alpha);
- interp.angles[1] = glm::mix(previous.angles[1], current.angles[1], alpha);
- interp.angles[2] = glm::mix(previous.angles[2], current.angles[2], alpha);
-
- // Figure out previous chunk-local floating-point coordinates transformed
- // to the current WorldCoord's chunk domain coordinates; we're interpolating
- // against these instead of using previous.position.local to prevent jittering
- auto previous_shift = coord::to_relative(current.chunk, current.local, previous.chunk, previous.local);
- auto previous_local = current.local + previous_shift;
-
- interp.chunk.x = current.chunk.x;
- interp.chunk.y = current.chunk.y;
- interp.chunk.z = current.chunk.z;
-
- interp.local.x = glm::mix(previous_local.x, current.local.x, alpha);
- interp.local.y = glm::mix(previous_local.y, current.local.y, alpha);
- interp.local.z = glm::mix(previous_local.z, current.local.z, alpha);
- }
-}
-
-static void head_interpolate(float alpha)
-{
- auto group = globals::dimension->entities.group<entity::client::HeadIntr>(entt::get<entity::Head, entity::client::HeadPrev>);
-
- for(auto [entity, interp, current, previous] : group.each()) {
- interp.angles[0] = glm::mix(previous.angles[0], current.angles[0], alpha);
- interp.angles[1] = glm::mix(previous.angles[1], current.angles[1], alpha);
- interp.angles[2] = glm::mix(previous.angles[2], current.angles[2], alpha);
-
- interp.offset.x = glm::mix(previous.offset.x, current.offset.x, alpha);
- interp.offset.y = glm::mix(previous.offset.y, current.offset.y, alpha);
- interp.offset.z = glm::mix(previous.offset.z, current.offset.z, alpha);
- }
-}
-
-void entity::interpolation::update(void)
-{
- if(globals::dimension) {
- auto alpha = static_cast<float>(globals::fixed_accumulator) / static_cast<float>(globals::fixed_frametime_us);
- transform_interpolate(alpha);
- head_interpolate(alpha);
- }
+#include "client/pch.hh" + +#include "client/entity/interpolation.hh" + +#include "core/math/constexpr.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +#include "client/globals.hh" + +static void transform_interpolate(float alpha) +{ + auto group = globals::dimension->entities.group<entity::client::TransformIntr>( + entt::get<entity::Transform, entity::client::TransformPrev>); + + for(auto [entity, interp, current, previous] : group.each()) { + interp.angles[0] = glm::mix(previous.angles[0], current.angles[0], alpha); + interp.angles[1] = glm::mix(previous.angles[1], current.angles[1], alpha); + interp.angles[2] = glm::mix(previous.angles[2], current.angles[2], alpha); + + // Figure out previous chunk-local floating-point coordinates transformed + // to the current WorldCoord's chunk domain coordinates; we're interpolating + // against these instead of using previous.position.local to prevent jittering + auto previous_shift = coord::to_relative(current.chunk, current.local, previous.chunk, previous.local); + auto previous_local = current.local + previous_shift; + + interp.chunk.x = current.chunk.x; + interp.chunk.y = current.chunk.y; + interp.chunk.z = current.chunk.z; + + interp.local.x = glm::mix(previous_local.x, current.local.x, alpha); + interp.local.y = glm::mix(previous_local.y, current.local.y, alpha); + interp.local.z = glm::mix(previous_local.z, current.local.z, alpha); + } +} + +static void head_interpolate(float alpha) +{ + auto group = globals::dimension->entities.group<entity::client::HeadIntr>(entt::get<entity::Head, entity::client::HeadPrev>); + + for(auto [entity, interp, current, previous] : group.each()) { + interp.angles[0] = glm::mix(previous.angles[0], current.angles[0], alpha); + interp.angles[1] = glm::mix(previous.angles[1], current.angles[1], alpha); + interp.angles[2] = glm::mix(previous.angles[2], current.angles[2], alpha); + + interp.offset.x = glm::mix(previous.offset.x, current.offset.x, alpha); + interp.offset.y = glm::mix(previous.offset.y, current.offset.y, alpha); + interp.offset.z = glm::mix(previous.offset.z, current.offset.z, alpha); + } +} + +void entity::interpolation::update(void) +{ + if(globals::dimension) { + auto alpha = static_cast<float>(globals::fixed_accumulator) / static_cast<float>(globals::fixed_frametime_us); + transform_interpolate(alpha); + head_interpolate(alpha); + } }
\ No newline at end of file diff --git a/game/client/entity/interpolation.hh b/src/game/client/entity/interpolation.hh index a7c4dac..6935fe8 100644 --- a/game/client/entity/interpolation.hh +++ b/src/game/client/entity/interpolation.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace entity::interpolation
-{
-void update(void);
-} // namespace entity::interpolation
+#pragma once + +namespace entity::interpolation +{ +void update(void); +} // namespace entity::interpolation diff --git a/game/client/entity/listener.cc b/src/game/client/entity/listener.cc index 1223438..a79e8a5 100644 --- a/game/client/entity/listener.cc +++ b/src/game/client/entity/listener.cc @@ -1,42 +1,42 @@ -#include "client/pch.hh"
-
-#include "client/entity/listener.hh"
-
-#include "core/config/number.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-void entity::listener::update(void)
-{
- if(session::is_ingame()) {
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player).value;
- const auto& position = entity::camera::position_local;
-
- alListener3f(AL_POSITION, position.x, position.y, position.z);
- alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
-
- float orientation[6];
- orientation[0] = entity::camera::direction.x;
- orientation[1] = entity::camera::direction.y;
- orientation[2] = entity::camera::direction.z;
- orientation[3] = DIR_UP<float>.x;
- orientation[4] = DIR_UP<float>.y;
- orientation[5] = DIR_UP<float>.z;
-
- alListenerfv(AL_ORIENTATION, orientation);
- }
-
- alListenerf(AL_GAIN, glm::clamp(sound::volume_master.get_value() * 0.01f, 0.0f, 1.0f));
-}
+#include "client/pch.hh" + +#include "client/entity/listener.hh" + +#include "core/config/number.hh" + +#include "core/math/constexpr.hh" + +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "client/entity/camera.hh" + +#include "client/sound/sound.hh" + +#include "client/const.hh" +#include "client/globals.hh" +#include "client/session.hh" + +void entity::listener::update(void) +{ + if(session::is_ingame()) { + const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player).value; + const auto& position = entity::camera::position_local; + + alListener3f(AL_POSITION, position.x, position.y, position.z); + alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); + + float orientation[6]; + orientation[0] = entity::camera::direction.x; + orientation[1] = entity::camera::direction.y; + orientation[2] = entity::camera::direction.z; + orientation[3] = DIR_UP<float>.x; + orientation[4] = DIR_UP<float>.y; + orientation[5] = DIR_UP<float>.z; + + alListenerfv(AL_ORIENTATION, orientation); + } + + alListenerf(AL_GAIN, glm::clamp(sound::volume_master.get_value() * 0.01f, 0.0f, 1.0f)); +} diff --git a/game/client/entity/listener.hh b/src/game/client/entity/listener.hh index 817e2fd..594cde1 100644 --- a/game/client/entity/listener.hh +++ b/src/game/client/entity/listener.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace entity::listener
-{
-void update(void);
-} // namespace entity::listener
+#pragma once + +namespace entity::listener +{ +void update(void); +} // namespace entity::listener diff --git a/game/client/entity/player_look.cc b/src/game/client/entity/player_look.cc index b6eaf16..0752e78 100644 --- a/game/client/entity/player_look.cc +++ b/src/game/client/entity/player_look.cc @@ -1,155 +1,155 @@ -#include "client/pch.hh"
-
-#include "client/entity/player_look.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/angles.hh"
-
-#include "shared/entity/head.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "client/config/gamepad_axis.hh"
-#include "client/config/gamepad_button.hh"
-#include "client/config/keybind.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static float PITCH_MIN = -1.0f * math::radians(90.0f);
-constexpr static float PITCH_MAX = +1.0f * math::radians(90.0f);
-
-// Mouse options
-static config::Boolean mouse_raw_input(true);
-static config::Unsigned mouse_sensitivity(25U, 1U, 100U);
-
-// Gamepad options
-static config::Float gamepad_fastlook_factor(1.5f, 1.0f, 5.0f);
-static config::Unsigned gamepad_accel_pitch(15U, 1U, 100U);
-static config::Unsigned gamepad_accel_yaw(25U, 1U, 100U);
-
-// Gamepad axes
-static config::GamepadAxis axis_pitch(GLFW_GAMEPAD_AXIS_LEFT_Y, false);
-static config::GamepadAxis axis_yaw(GLFW_GAMEPAD_AXIS_LEFT_X, false);
-
-// Gamepad buttons
-static config::GamepadButton button_fastlook(GLFW_GAMEPAD_BUTTON_LEFT_THUMB);
-
-static bool fastlook_enabled;
-static glm::fvec2 last_cursor;
-
-static void add_angles(float pitch, float yaw)
-{
- if(session::is_ingame()) {
- auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
-
- head.angles[0] += pitch;
- head.angles[1] += yaw;
- head.angles[0] = glm::clamp(head.angles[0], PITCH_MIN, PITCH_MAX);
- head.angles = math::wrap_180(head.angles);
-
- // Client-side head angles are not interpolated;
- // Re-assigning the previous state after the current
- // state has been already modified is certainly a way
- // to circumvent the interpolation applied to anything with a head
- globals::dimension->entities.emplace_or_replace<entity::client::HeadPrev>(globals::player, head);
- }
-}
-
-static void on_glfw_cursor_pos(const io::GlfwCursorPosEvent& event)
-{
- if(io::gamepad::available && io::gamepad::active.get_value()) {
- // The player is assumed to be using
- // a gamepad instead of mouse and keyboard
- last_cursor = event.pos;
- return;
- }
-
- if(globals::gui_screen || !session::is_ingame()) {
- // UI is visible or we're not in-game
- last_cursor = event.pos;
- return;
- }
-
- auto dx = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.x - last_cursor.x);
- auto dy = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.y - last_cursor.y);
- add_angles(dy, dx);
-
- last_cursor = event.pos;
-}
-
-static void on_gamepad_button(const io::GamepadButtonEvent& event)
-{
- if(button_fastlook.equals(event.button)) {
- fastlook_enabled = event.action == GLFW_PRESS;
- }
-}
-
-void entity::player_look::init(void)
-{
- globals::client_config.add_value("player_look.mouse.raw_input", mouse_raw_input);
- globals::client_config.add_value("player_look.mouse.sensitivity", mouse_sensitivity);
- globals::client_config.add_value("player_look.gamepad.fastlook_factor", gamepad_fastlook_factor);
- globals::client_config.add_value("player_look.gamepad.accel_pitch", gamepad_accel_pitch);
- globals::client_config.add_value("player_look.gamepad.accel_yaw", gamepad_accel_yaw);
- globals::client_config.add_value("player_look.gp_axis.pitch", axis_pitch);
- globals::client_config.add_value("player_look.gp_axis.yaw", axis_yaw);
- globals::client_config.add_value("player_look.gp_button.fastlook", button_fastlook);
-
- settings::add_slider(0, mouse_sensitivity, settings_location::MOUSE, "player_look.mouse.sensitivity", true);
- settings::add_checkbox(1, mouse_raw_input, settings_location::MOUSE, "player_look.mouse.raw_input", true);
-
- settings::add_slider(0, gamepad_accel_pitch, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.accel_pitch", false);
- settings::add_slider(1, gamepad_accel_yaw, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.accel_yaw", false);
- settings::add_gamepad_axis(2, axis_pitch, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_axis.pitch");
- settings::add_gamepad_axis(3, axis_yaw, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_axis.yaw");
- settings::add_slider(4, gamepad_fastlook_factor, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.fastlook_factor", true,
- "%.02f");
- settings::add_gamepad_button(5, button_fastlook, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_button.fastlook");
-
- fastlook_enabled = false;
- last_cursor.x = 0.5f * static_cast<float>(globals::width);
- last_cursor.y = 0.5f * static_cast<float>(globals::height);
-
- globals::dispatcher.sink<io::GlfwCursorPosEvent>().connect<&on_glfw_cursor_pos>();
- globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>();
-}
-
-void entity::player_look::update_late(void)
-{
- if(io::gamepad::available && io::gamepad::active.get_value() && !globals::gui_screen) {
- auto pitch_value = axis_pitch.get_value(io::gamepad::state, io::gamepad::deadzone.get_value());
- auto yaw_value = axis_yaw.get_value(io::gamepad::state, io::gamepad::deadzone.get_value());
-
- if(fastlook_enabled) {
- // Fastlook allows the camera to
- // rotate quicker when a button is held down
- pitch_value *= gamepad_fastlook_factor.get_value();
- yaw_value *= gamepad_fastlook_factor.get_value();
- }
-
- pitch_value *= 0.001f * static_cast<float>(gamepad_accel_pitch.get_value());
- yaw_value *= 0.001f * static_cast<float>(gamepad_accel_yaw.get_value());
-
- add_angles(pitch_value, yaw_value);
- }
-
- if(!globals::gui_screen && session::is_ingame()) {
- glfwSetInputMode(globals::window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- glfwSetInputMode(globals::window, GLFW_RAW_MOUSE_MOTION, mouse_raw_input.get_value());
- }
- else {
- glfwSetInputMode(globals::window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- glfwSetInputMode(globals::window, GLFW_RAW_MOUSE_MOTION, false);
- }
-}
+#include "client/pch.hh" + +#include "client/entity/player_look.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/angles.hh" + +#include "shared/entity/head.hh" + +#include "shared/world/dimension.hh" + +#include "client/config/gamepad_axis.hh" +#include "client/config/gamepad_button.hh" +#include "client/config/keybind.hh" + +#include "client/gui/settings.hh" + +#include "client/io/gamepad.hh" +#include "client/io/glfw.hh" + +#include "client/const.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static float PITCH_MIN = -1.0f * math::radians(90.0f); +constexpr static float PITCH_MAX = +1.0f * math::radians(90.0f); + +// Mouse options +static config::Boolean mouse_raw_input(true); +static config::Unsigned mouse_sensitivity(25U, 1U, 100U); + +// Gamepad options +static config::Float gamepad_fastlook_factor(1.5f, 1.0f, 5.0f); +static config::Unsigned gamepad_accel_pitch(15U, 1U, 100U); +static config::Unsigned gamepad_accel_yaw(25U, 1U, 100U); + +// Gamepad axes +static config::GamepadAxis axis_pitch(GLFW_GAMEPAD_AXIS_LEFT_Y, false); +static config::GamepadAxis axis_yaw(GLFW_GAMEPAD_AXIS_LEFT_X, false); + +// Gamepad buttons +static config::GamepadButton button_fastlook(GLFW_GAMEPAD_BUTTON_LEFT_THUMB); + +static bool fastlook_enabled; +static glm::fvec2 last_cursor; + +static void add_angles(float pitch, float yaw) +{ + if(session::is_ingame()) { + auto& head = globals::dimension->entities.get<entity::Head>(globals::player); + + head.angles[0] += pitch; + head.angles[1] += yaw; + head.angles[0] = glm::clamp(head.angles[0], PITCH_MIN, PITCH_MAX); + head.angles = math::wrap_180(head.angles); + + // Client-side head angles are not interpolated; + // Re-assigning the previous state after the current + // state has been already modified is certainly a way + // to circumvent the interpolation applied to anything with a head + globals::dimension->entities.emplace_or_replace<entity::client::HeadPrev>(globals::player, head); + } +} + +static void on_glfw_cursor_pos(const io::GlfwCursorPosEvent& event) +{ + if(io::gamepad::available && io::gamepad::active.get_value()) { + // The player is assumed to be using + // a gamepad instead of mouse and keyboard + last_cursor = event.pos; + return; + } + + if(globals::gui_screen || !session::is_ingame()) { + // UI is visible or we're not in-game + last_cursor = event.pos; + return; + } + + auto dx = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.x - last_cursor.x); + auto dy = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.y - last_cursor.y); + add_angles(dy, dx); + + last_cursor = event.pos; +} + +static void on_gamepad_button(const io::GamepadButtonEvent& event) +{ + if(button_fastlook.equals(event.button)) { + fastlook_enabled = event.action == GLFW_PRESS; + } +} + +void entity::player_look::init(void) +{ + globals::client_config.add_value("player_look.mouse.raw_input", mouse_raw_input); + globals::client_config.add_value("player_look.mouse.sensitivity", mouse_sensitivity); + globals::client_config.add_value("player_look.gamepad.fastlook_factor", gamepad_fastlook_factor); + globals::client_config.add_value("player_look.gamepad.accel_pitch", gamepad_accel_pitch); + globals::client_config.add_value("player_look.gamepad.accel_yaw", gamepad_accel_yaw); + globals::client_config.add_value("player_look.gp_axis.pitch", axis_pitch); + globals::client_config.add_value("player_look.gp_axis.yaw", axis_yaw); + globals::client_config.add_value("player_look.gp_button.fastlook", button_fastlook); + + settings::add_slider(0, mouse_sensitivity, settings_location::MOUSE, "player_look.mouse.sensitivity", true); + settings::add_checkbox(1, mouse_raw_input, settings_location::MOUSE, "player_look.mouse.raw_input", true); + + settings::add_slider(0, gamepad_accel_pitch, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.accel_pitch", false); + settings::add_slider(1, gamepad_accel_yaw, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.accel_yaw", false); + settings::add_gamepad_axis(2, axis_pitch, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_axis.pitch"); + settings::add_gamepad_axis(3, axis_yaw, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_axis.yaw"); + settings::add_slider(4, gamepad_fastlook_factor, settings_location::GAMEPAD_GAMEPLAY, "player_look.gamepad.fastlook_factor", true, + "%.02f"); + settings::add_gamepad_button(5, button_fastlook, settings_location::GAMEPAD_GAMEPLAY, "player_look.gp_button.fastlook"); + + fastlook_enabled = false; + last_cursor.x = 0.5f * static_cast<float>(globals::width); + last_cursor.y = 0.5f * static_cast<float>(globals::height); + + globals::dispatcher.sink<io::GlfwCursorPosEvent>().connect<&on_glfw_cursor_pos>(); + globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>(); +} + +void entity::player_look::update_late(void) +{ + if(io::gamepad::available && io::gamepad::active.get_value() && !globals::gui_screen) { + auto pitch_value = axis_pitch.get_value(io::gamepad::state, io::gamepad::deadzone.get_value()); + auto yaw_value = axis_yaw.get_value(io::gamepad::state, io::gamepad::deadzone.get_value()); + + if(fastlook_enabled) { + // Fastlook allows the camera to + // rotate quicker when a button is held down + pitch_value *= gamepad_fastlook_factor.get_value(); + yaw_value *= gamepad_fastlook_factor.get_value(); + } + + pitch_value *= 0.001f * static_cast<float>(gamepad_accel_pitch.get_value()); + yaw_value *= 0.001f * static_cast<float>(gamepad_accel_yaw.get_value()); + + add_angles(pitch_value, yaw_value); + } + + if(!globals::gui_screen && session::is_ingame()) { + glfwSetInputMode(globals::window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(globals::window, GLFW_RAW_MOUSE_MOTION, mouse_raw_input.get_value()); + } + else { + glfwSetInputMode(globals::window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetInputMode(globals::window, GLFW_RAW_MOUSE_MOTION, false); + } +} diff --git a/game/client/entity/player_look.hh b/src/game/client/entity/player_look.hh index b347031..0ae18db 100644 --- a/game/client/entity/player_look.hh +++ b/src/game/client/entity/player_look.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace entity::player_look
-{
-void init(void);
-void update_late(void);
-} // namespace entity::player_look
+#pragma once + +namespace entity::player_look +{ +void init(void); +void update_late(void); +} // namespace entity::player_look diff --git a/game/client/entity/player_move.cc b/src/game/client/entity/player_move.cc index 17aaadd..4087b04 100644 --- a/game/client/entity/player_move.cc +++ b/src/game/client/entity/player_move.cc @@ -1,298 +1,298 @@ -#include "client/pch.hh"
-
-#include "client/entity/player_move.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/angles.hh"
-#include "core/math/constexpr.hh"
-
-#include "shared/entity/grounded.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "client/config/gamepad_axis.hh"
-#include "client/config/gamepad_button.hh"
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/settings.hh"
-#include "client/gui/status_lines.hh"
-
-#include "client/io/gamepad.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/world/voxel_sounds.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-#include "client/toggles.hh"
-
-constexpr static std::uint64_t PMOVE_JUMP_COOLDOWN = 500000; // 0.5 seconds
-
-constexpr static float PMOVE_FOOTSTEP_SIZE = 2.0f;
-
-// Movement keys
-static config::KeyBind key_move_forward(GLFW_KEY_W);
-static config::KeyBind key_move_back(GLFW_KEY_S);
-static config::KeyBind key_move_left(GLFW_KEY_A);
-static config::KeyBind key_move_right(GLFW_KEY_D);
-static config::KeyBind key_move_down(GLFW_KEY_LEFT_SHIFT);
-static config::KeyBind key_move_up(GLFW_KEY_SPACE);
-
-// Movement gamepad axes
-static config::GamepadAxis axis_move_forward(GLFW_GAMEPAD_AXIS_RIGHT_X, false);
-static config::GamepadAxis axis_move_sideways(GLFW_GAMEPAD_AXIS_RIGHT_Y, false);
-
-// Movement gamepad buttons
-static config::GamepadButton button_move_down(GLFW_GAMEPAD_BUTTON_DPAD_DOWN);
-static config::GamepadButton button_move_up(GLFW_GAMEPAD_BUTTON_DPAD_UP);
-
-// General movement options
-static config::Boolean enable_speedometer(true);
-
-static glm::fvec3 movement_direction;
-
-static std::uint64_t next_jump_us;
-static float speedometer_value;
-static float footsteps_distance;
-
-static std::mt19937_64 pitch_random;
-static std::uniform_real_distribution<float> pitch_distrib;
-
-// Quake III's PM_Accelerate-ish function used for
-// conventional (gravity-affected non-flight) movement
-static glm::fvec3 pm_accelerate(const glm::fvec3& wishdir, const glm::fvec3& velocity, float wishspeed, float accel)
-{
- auto current_speed = glm::dot(velocity, wishdir);
- auto add_speed = wishspeed - current_speed;
-
- if(add_speed <= 0.0f) {
- // Not accelerating
- return velocity;
- }
-
- auto accel_speed = glm::min(add_speed, accel * globals::fixed_frametime * wishspeed);
-
- auto result = glm::fvec3(velocity);
- result.x += accel_speed * wishdir.x;
- result.z += accel_speed * wishdir.z;
- return result;
-}
-
-// Conventional movement - velocity update when not on the ground
-static glm::fvec3 pm_air_move(const glm::fvec3& wishdir, const glm::fvec3& velocity)
-{
- return pm_accelerate(wishdir, velocity, PMOVE_ACCELERATION_AIR, PMOVE_MAX_SPEED_AIR);
-}
-
-// Conventional movement - velocity uodate when on the ground
-static glm::fvec3 pm_ground_move(const glm::fvec3& wishdir, const glm::fvec3& velocity)
-{
- if(auto speed = glm::length(velocity)) {
- auto speed_drop = speed * PMOVE_FRICTION_GROUND * globals::fixed_frametime;
- auto speed_factor = glm::max(speed - speed_drop, 0.0f) / speed;
- return pm_accelerate(wishdir, velocity * speed_factor, PMOVE_ACCELERATION_GROUND, PMOVE_MAX_SPEED_GROUND);
- }
-
- return pm_accelerate(wishdir, velocity, PMOVE_ACCELERATION_GROUND, PMOVE_MAX_SPEED_GROUND);
-}
-
-// A simpler minecraft-like acceleration model
-// used whenever the TOGGLE_PM_FLIGHT is enabled
-static glm::fvec3 pm_flight_move(const glm::fvec3& wishdir)
-{
- // FIXME: make it smoother
- return wishdir * PMOVE_MAX_SPEED_AIR;
-}
-
-void entity::player_move::init(void)
-{
- movement_direction = ZERO_VEC3<float>;
-
- next_jump_us = 0x0000000000000000U;
- speedometer_value = 0.0f;
- footsteps_distance = 0.0f;
-
- // UNDONE: make this a separate subsystem
- pitch_random.seed(std::random_device()());
- pitch_distrib = std::uniform_real_distribution<float>(0.9f, 1.1f);
-
- globals::client_config.add_value("player_move.key.forward", key_move_forward);
- globals::client_config.add_value("player_move.key.back", key_move_back);
- globals::client_config.add_value("player_move.key.left", key_move_left);
- globals::client_config.add_value("player_move.key.right", key_move_right);
- globals::client_config.add_value("player_move.key.down", key_move_down);
- globals::client_config.add_value("player_move.key.up", key_move_up);
- globals::client_config.add_value("player_move.gp_axis.move_forward", axis_move_forward);
- globals::client_config.add_value("player_move.gp_axis.move_sideways", axis_move_sideways);
- globals::client_config.add_value("player_move.gp_button.move_down", button_move_down);
- globals::client_config.add_value("player_move.gp_button.move_up", button_move_up);
- globals::client_config.add_value("player_move.enable_speedometer", enable_speedometer);
-
- settings::add_keybind(1, key_move_forward, settings_location::KEYBOARD_MOVEMENT, "player_move.key.forward");
- settings::add_keybind(2, key_move_back, settings_location::KEYBOARD_MOVEMENT, "player_move.key.back");
- settings::add_keybind(3, key_move_left, settings_location::KEYBOARD_MOVEMENT, "player_move.key.left");
- settings::add_keybind(4, key_move_right, settings_location::KEYBOARD_MOVEMENT, "player_move.key.right");
- settings::add_keybind(5, key_move_down, settings_location::KEYBOARD_MOVEMENT, "player_move.key.down");
- settings::add_keybind(6, key_move_up, settings_location::KEYBOARD_MOVEMENT, "player_move.key.up");
-
- settings::add_gamepad_axis(0, axis_move_forward, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_axis.move_forward");
- settings::add_gamepad_axis(1, axis_move_sideways, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_axis.move_sideways");
- settings::add_gamepad_button(2, button_move_down, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_button.move_down");
- settings::add_gamepad_button(3, button_move_up, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_button.move_up");
-
- settings::add_checkbox(2, enable_speedometer, settings_location::VIDEO_GUI, "player_move.enable_speedometer", true);
-}
-
-void entity::player_move::fixed_update(void)
-{
- const auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
- auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player);
- auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
-
- // Interpolation - preserve current component states
- globals::dimension->entities.emplace_or_replace<entity::client::TransformPrev>(globals::player, transform);
-
- glm::fvec3 forward, right;
- math::vectors(glm::fvec3(0.0f, head.angles[1], 0.0f), &forward, &right, nullptr);
-
- glm::fvec3 wishdir = ZERO_VEC3<float>;
- glm::fvec3 movevars = glm::fvec3(movement_direction.x, 0.0f, movement_direction.z);
- wishdir.x = glm::dot(movevars, right);
- wishdir.z = glm::dot(movevars, forward);
-
- if(toggles::get(TOGGLE_PM_FLIGHT)) {
- velocity.value = pm_flight_move(glm::fvec3(wishdir.x, movement_direction.y, wishdir.z));
- return;
- }
-
- auto grounded = globals::dimension->entities.try_get<entity::Grounded>(globals::player);
- auto velocity_horizontal = glm::fvec3(velocity.value.x, 0.0f, velocity.value.z);
-
- if(grounded) {
- auto new_velocity = pm_ground_move(wishdir, velocity_horizontal);
- velocity.value.x = new_velocity.x;
- velocity.value.z = new_velocity.z;
-
- auto new_speed = glm::length(new_velocity);
-
- if(new_speed > 0.01f) {
- footsteps_distance += globals::fixed_frametime * new_speed;
- }
- else {
- footsteps_distance = 0.0f;
- }
-
- if(footsteps_distance >= PMOVE_FOOTSTEP_SIZE) {
- if(auto effect = world::voxel_sounds::get_footsteps(grounded->surface)) {
- sound::play_player(effect, false, pitch_distrib(pitch_random));
- }
-
- footsteps_distance = 0.0f;
- }
- }
- else {
- auto new_velocity = pm_air_move(wishdir, velocity_horizontal);
- velocity.value.x = new_velocity.x;
- velocity.value.z = new_velocity.z;
- }
-
- if(movement_direction.y == 0.0f) {
- // Allow players to queue bunny-jumps by quickly
- // releasing and pressing the jump key again without a cooldown
- next_jump_us = 0x0000000000000000U;
- return;
- }
-
- if(grounded && (movement_direction.y > 0.0f) && (globals::curtime >= next_jump_us)) {
- velocity.value.y = -PMOVE_JUMP_FORCE * globals::dimension->get_gravity();
-
- auto new_speed = glm::length(glm::fvec2(velocity.value.x, velocity.value.z));
- auto new_speed_text = std::format("{:.02f} M/S", new_speed);
- auto speed_change = new_speed - speedometer_value;
-
- speedometer_value = new_speed;
-
- next_jump_us = globals::curtime + PMOVE_JUMP_COOLDOWN;
-
- if(enable_speedometer.get_value()) {
- if(glm::abs(speed_change) < 0.01f) {
- // No considerable speed increase within
- // the precision we use to draw the speedometer
- gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(0.7f, 0.7f, 0.7f, 1.0f), 1.0f);
- }
- else if(speed_change < 0.0f) {
- // Speed change is negative, we are actively
- // slowing down; use the red color for the status line
- gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f), 1.0f);
- }
- else {
- // Speed change is positive, we are actively
- // speeding up; use the green color for the status line
- gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f), 1.0f);
- }
- }
-
- if(auto effect = world::voxel_sounds::get_footsteps(grounded->surface)) {
- sound::play_player(effect, false, 1.0f);
- }
- }
-}
-
-void entity::player_move::update_late(void)
-{
- movement_direction = ZERO_VEC3<float>;
-
- if(globals::gui_screen || !session::is_ingame()) {
- // We're either disconnected or have the
- // UI opened up; anyways we shouldn't move
- return;
- }
-
- if(io::gamepad::available && io::gamepad::active.get_value()) {
- if(button_move_down.is_pressed(io::gamepad::state)) {
- movement_direction += DIR_DOWN<float>;
- }
-
- if(button_move_up.is_pressed(io::gamepad::state)) {
- movement_direction += DIR_UP<float>;
- }
-
- movement_direction.x += axis_move_sideways.get_value(io::gamepad::state, io::gamepad::deadzone.get_value());
- movement_direction.z -= axis_move_forward.get_value(io::gamepad::state, io::gamepad::deadzone.get_value());
- }
- else {
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_forward.get_key())) {
- movement_direction += DIR_FORWARD<float>;
- }
-
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_back.get_key())) {
- movement_direction += DIR_BACK<float>;
- }
-
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_left.get_key())) {
- movement_direction += DIR_LEFT<float>;
- }
-
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_right.get_key())) {
- movement_direction += DIR_RIGHT<float>;
- }
-
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_down.get_key())) {
- movement_direction += DIR_DOWN<float>;
- }
-
- if(GLFW_PRESS == glfwGetKey(globals::window, key_move_up.get_key())) {
- movement_direction += DIR_UP<float>;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/entity/player_move.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/angles.hh" +#include "core/math/constexpr.hh" + +#include "shared/entity/grounded.hh" +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "client/config/gamepad_axis.hh" +#include "client/config/gamepad_button.hh" +#include "client/config/keybind.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/settings.hh" +#include "client/gui/status_lines.hh" + +#include "client/io/gamepad.hh" + +#include "client/sound/sound.hh" + +#include "client/world/voxel_sounds.hh" + +#include "client/const.hh" +#include "client/globals.hh" +#include "client/session.hh" +#include "client/toggles.hh" + +constexpr static std::uint64_t PMOVE_JUMP_COOLDOWN = 500000; // 0.5 seconds + +constexpr static float PMOVE_FOOTSTEP_SIZE = 2.0f; + +// Movement keys +static config::KeyBind key_move_forward(GLFW_KEY_W); +static config::KeyBind key_move_back(GLFW_KEY_S); +static config::KeyBind key_move_left(GLFW_KEY_A); +static config::KeyBind key_move_right(GLFW_KEY_D); +static config::KeyBind key_move_down(GLFW_KEY_LEFT_SHIFT); +static config::KeyBind key_move_up(GLFW_KEY_SPACE); + +// Movement gamepad axes +static config::GamepadAxis axis_move_forward(GLFW_GAMEPAD_AXIS_RIGHT_X, false); +static config::GamepadAxis axis_move_sideways(GLFW_GAMEPAD_AXIS_RIGHT_Y, false); + +// Movement gamepad buttons +static config::GamepadButton button_move_down(GLFW_GAMEPAD_BUTTON_DPAD_DOWN); +static config::GamepadButton button_move_up(GLFW_GAMEPAD_BUTTON_DPAD_UP); + +// General movement options +static config::Boolean enable_speedometer(true); + +static glm::fvec3 movement_direction; + +static std::uint64_t next_jump_us; +static float speedometer_value; +static float footsteps_distance; + +static std::mt19937_64 pitch_random; +static std::uniform_real_distribution<float> pitch_distrib; + +// Quake III's PM_Accelerate-ish function used for +// conventional (gravity-affected non-flight) movement +static glm::fvec3 pm_accelerate(const glm::fvec3& wishdir, const glm::fvec3& velocity, float wishspeed, float accel) +{ + auto current_speed = glm::dot(velocity, wishdir); + auto add_speed = wishspeed - current_speed; + + if(add_speed <= 0.0f) { + // Not accelerating + return velocity; + } + + auto accel_speed = glm::min(add_speed, accel * globals::fixed_frametime * wishspeed); + + auto result = glm::fvec3(velocity); + result.x += accel_speed * wishdir.x; + result.z += accel_speed * wishdir.z; + return result; +} + +// Conventional movement - velocity update when not on the ground +static glm::fvec3 pm_air_move(const glm::fvec3& wishdir, const glm::fvec3& velocity) +{ + return pm_accelerate(wishdir, velocity, PMOVE_ACCELERATION_AIR, PMOVE_MAX_SPEED_AIR); +} + +// Conventional movement - velocity uodate when on the ground +static glm::fvec3 pm_ground_move(const glm::fvec3& wishdir, const glm::fvec3& velocity) +{ + if(auto speed = glm::length(velocity)) { + auto speed_drop = speed * PMOVE_FRICTION_GROUND * globals::fixed_frametime; + auto speed_factor = glm::max(speed - speed_drop, 0.0f) / speed; + return pm_accelerate(wishdir, velocity * speed_factor, PMOVE_ACCELERATION_GROUND, PMOVE_MAX_SPEED_GROUND); + } + + return pm_accelerate(wishdir, velocity, PMOVE_ACCELERATION_GROUND, PMOVE_MAX_SPEED_GROUND); +} + +// A simpler minecraft-like acceleration model +// used whenever the TOGGLE_PM_FLIGHT is enabled +static glm::fvec3 pm_flight_move(const glm::fvec3& wishdir) +{ + // FIXME: make it smoother + return wishdir * PMOVE_MAX_SPEED_AIR; +} + +void entity::player_move::init(void) +{ + movement_direction = ZERO_VEC3<float>; + + next_jump_us = 0x0000000000000000U; + speedometer_value = 0.0f; + footsteps_distance = 0.0f; + + // UNDONE: make this a separate subsystem + pitch_random.seed(std::random_device()()); + pitch_distrib = std::uniform_real_distribution<float>(0.9f, 1.1f); + + globals::client_config.add_value("player_move.key.forward", key_move_forward); + globals::client_config.add_value("player_move.key.back", key_move_back); + globals::client_config.add_value("player_move.key.left", key_move_left); + globals::client_config.add_value("player_move.key.right", key_move_right); + globals::client_config.add_value("player_move.key.down", key_move_down); + globals::client_config.add_value("player_move.key.up", key_move_up); + globals::client_config.add_value("player_move.gp_axis.move_forward", axis_move_forward); + globals::client_config.add_value("player_move.gp_axis.move_sideways", axis_move_sideways); + globals::client_config.add_value("player_move.gp_button.move_down", button_move_down); + globals::client_config.add_value("player_move.gp_button.move_up", button_move_up); + globals::client_config.add_value("player_move.enable_speedometer", enable_speedometer); + + settings::add_keybind(1, key_move_forward, settings_location::KEYBOARD_MOVEMENT, "player_move.key.forward"); + settings::add_keybind(2, key_move_back, settings_location::KEYBOARD_MOVEMENT, "player_move.key.back"); + settings::add_keybind(3, key_move_left, settings_location::KEYBOARD_MOVEMENT, "player_move.key.left"); + settings::add_keybind(4, key_move_right, settings_location::KEYBOARD_MOVEMENT, "player_move.key.right"); + settings::add_keybind(5, key_move_down, settings_location::KEYBOARD_MOVEMENT, "player_move.key.down"); + settings::add_keybind(6, key_move_up, settings_location::KEYBOARD_MOVEMENT, "player_move.key.up"); + + settings::add_gamepad_axis(0, axis_move_forward, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_axis.move_forward"); + settings::add_gamepad_axis(1, axis_move_sideways, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_axis.move_sideways"); + settings::add_gamepad_button(2, button_move_down, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_button.move_down"); + settings::add_gamepad_button(3, button_move_up, settings_location::GAMEPAD_MOVEMENT, "player_move.gp_button.move_up"); + + settings::add_checkbox(2, enable_speedometer, settings_location::VIDEO_GUI, "player_move.enable_speedometer", true); +} + +void entity::player_move::fixed_update(void) +{ + const auto& head = globals::dimension->entities.get<entity::Head>(globals::player); + auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player); + auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player); + + // Interpolation - preserve current component states + globals::dimension->entities.emplace_or_replace<entity::client::TransformPrev>(globals::player, transform); + + glm::fvec3 forward, right; + math::vectors(glm::fvec3(0.0f, head.angles[1], 0.0f), &forward, &right, nullptr); + + glm::fvec3 wishdir = ZERO_VEC3<float>; + glm::fvec3 movevars = glm::fvec3(movement_direction.x, 0.0f, movement_direction.z); + wishdir.x = glm::dot(movevars, right); + wishdir.z = glm::dot(movevars, forward); + + if(toggles::get(TOGGLE_PM_FLIGHT)) { + velocity.value = pm_flight_move(glm::fvec3(wishdir.x, movement_direction.y, wishdir.z)); + return; + } + + auto grounded = globals::dimension->entities.try_get<entity::Grounded>(globals::player); + auto velocity_horizontal = glm::fvec3(velocity.value.x, 0.0f, velocity.value.z); + + if(grounded) { + auto new_velocity = pm_ground_move(wishdir, velocity_horizontal); + velocity.value.x = new_velocity.x; + velocity.value.z = new_velocity.z; + + auto new_speed = glm::length(new_velocity); + + if(new_speed > 0.01f) { + footsteps_distance += globals::fixed_frametime * new_speed; + } + else { + footsteps_distance = 0.0f; + } + + if(footsteps_distance >= PMOVE_FOOTSTEP_SIZE) { + if(auto effect = world::voxel_sounds::get_footsteps(grounded->surface)) { + sound::play_player(effect, false, pitch_distrib(pitch_random)); + } + + footsteps_distance = 0.0f; + } + } + else { + auto new_velocity = pm_air_move(wishdir, velocity_horizontal); + velocity.value.x = new_velocity.x; + velocity.value.z = new_velocity.z; + } + + if(movement_direction.y == 0.0f) { + // Allow players to queue bunny-jumps by quickly + // releasing and pressing the jump key again without a cooldown + next_jump_us = 0x0000000000000000U; + return; + } + + if(grounded && (movement_direction.y > 0.0f) && (globals::curtime >= next_jump_us)) { + velocity.value.y = -PMOVE_JUMP_FORCE * globals::dimension->get_gravity(); + + auto new_speed = glm::length(glm::fvec2(velocity.value.x, velocity.value.z)); + auto new_speed_text = std::format("{:.02f} M/S", new_speed); + auto speed_change = new_speed - speedometer_value; + + speedometer_value = new_speed; + + next_jump_us = globals::curtime + PMOVE_JUMP_COOLDOWN; + + if(enable_speedometer.get_value()) { + if(glm::abs(speed_change) < 0.01f) { + // No considerable speed increase within + // the precision we use to draw the speedometer + gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(0.7f, 0.7f, 0.7f, 1.0f), 1.0f); + } + else if(speed_change < 0.0f) { + // Speed change is negative, we are actively + // slowing down; use the red color for the status line + gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); + } + else { + // Speed change is positive, we are actively + // speeding up; use the green color for the status line + gui::status_lines::set(gui::STATUS_DEBUG, new_speed_text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f), 1.0f); + } + } + + if(auto effect = world::voxel_sounds::get_footsteps(grounded->surface)) { + sound::play_player(effect, false, 1.0f); + } + } +} + +void entity::player_move::update_late(void) +{ + movement_direction = ZERO_VEC3<float>; + + if(globals::gui_screen || !session::is_ingame()) { + // We're either disconnected or have the + // UI opened up; anyways we shouldn't move + return; + } + + if(io::gamepad::available && io::gamepad::active.get_value()) { + if(button_move_down.is_pressed(io::gamepad::state)) { + movement_direction += DIR_DOWN<float>; + } + + if(button_move_up.is_pressed(io::gamepad::state)) { + movement_direction += DIR_UP<float>; + } + + movement_direction.x += axis_move_sideways.get_value(io::gamepad::state, io::gamepad::deadzone.get_value()); + movement_direction.z -= axis_move_forward.get_value(io::gamepad::state, io::gamepad::deadzone.get_value()); + } + else { + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_forward.get_key())) { + movement_direction += DIR_FORWARD<float>; + } + + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_back.get_key())) { + movement_direction += DIR_BACK<float>; + } + + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_left.get_key())) { + movement_direction += DIR_LEFT<float>; + } + + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_right.get_key())) { + movement_direction += DIR_RIGHT<float>; + } + + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_down.get_key())) { + movement_direction += DIR_DOWN<float>; + } + + if(GLFW_PRESS == glfwGetKey(globals::window, key_move_up.get_key())) { + movement_direction += DIR_UP<float>; + } + } +} diff --git a/game/client/entity/player_move.hh b/src/game/client/entity/player_move.hh index 8026acf..8c033cc 100644 --- a/game/client/entity/player_move.hh +++ b/src/game/client/entity/player_move.hh @@ -1,15 +1,15 @@ -#pragma once
-
-constexpr static float PMOVE_MAX_SPEED_AIR = 16.0f;
-constexpr static float PMOVE_MAX_SPEED_GROUND = 8.0f;
-constexpr static float PMOVE_ACCELERATION_AIR = 3.0f;
-constexpr static float PMOVE_ACCELERATION_GROUND = 6.0f;
-constexpr static float PMOVE_FRICTION_GROUND = 10.0f;
-constexpr static float PMOVE_JUMP_FORCE = 0.275f;
-
-namespace entity::player_move
-{
-void init(void);
-void fixed_update(void);
-void update_late(void);
-} // namespace entity::player_move
+#pragma once + +constexpr static float PMOVE_MAX_SPEED_AIR = 16.0f; +constexpr static float PMOVE_MAX_SPEED_GROUND = 8.0f; +constexpr static float PMOVE_ACCELERATION_AIR = 3.0f; +constexpr static float PMOVE_ACCELERATION_GROUND = 6.0f; +constexpr static float PMOVE_FRICTION_GROUND = 10.0f; +constexpr static float PMOVE_JUMP_FORCE = 0.275f; + +namespace entity::player_move +{ +void init(void); +void fixed_update(void); +void update_late(void); +} // namespace entity::player_move diff --git a/game/client/entity/sound_emitter.cc b/src/game/client/entity/sound_emitter.cc index 84a66c0..57909ec 100644 --- a/game/client/entity/sound_emitter.cc +++ b/src/game/client/entity/sound_emitter.cc @@ -1,63 +1,63 @@ -#include "client/pch.hh"
-
-#include "client/entity/sound_emitter.hh"
-
-#include "core/config/number.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/globals.hh"
-
-entity::SoundEmitter::SoundEmitter(void)
-{
- alGenSources(1, &source);
- sound = nullptr;
-}
-
-entity::SoundEmitter::~SoundEmitter(void)
-{
- alSourceStop(source);
- alDeleteSources(1, &source);
-}
-
-void entity::SoundEmitter::update(void)
-{
- if(globals::dimension) {
- const auto view = globals::dimension->entities.view<entity::SoundEmitter>();
-
- const auto& pivot = entity::camera::position_chunk;
- const auto gain = glm::clamp(sound::volume_effects.get_value() * 0.01f, 0.0f, 1.0f);
-
- for(const auto [entity, emitter] : view.each()) {
- alSourcef(emitter.source, AL_GAIN, gain);
-
- if(const auto transform = globals::dimension->entities.try_get<entity::client::TransformIntr>(entity)) {
- auto position = coord::to_relative(pivot, transform->chunk, transform->local);
- alSource3f(emitter.source, AL_POSITION, position.x, position.y, position.z);
- }
-
- if(const auto velocity = globals::dimension->entities.try_get<entity::Velocity>(entity)) {
- alSource3f(emitter.source, AL_VELOCITY, velocity->value.x, velocity->value.y, velocity->value.z);
- }
-
- ALint source_state;
- alGetSourcei(emitter.source, AL_SOURCE_STATE, &source_state);
-
- if(source_state == AL_STOPPED) {
- alSourceRewind(emitter.source);
- emitter.sound = nullptr;
- }
- }
- }
-}
+#include "client/pch.hh" + +#include "client/entity/sound_emitter.hh" + +#include "core/config/number.hh" + +#include "core/math/constexpr.hh" + +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +#include "client/entity/camera.hh" + +#include "client/sound/sound.hh" + +#include "client/globals.hh" + +entity::SoundEmitter::SoundEmitter(void) +{ + alGenSources(1, &source); + sound = nullptr; +} + +entity::SoundEmitter::~SoundEmitter(void) +{ + alSourceStop(source); + alDeleteSources(1, &source); +} + +void entity::SoundEmitter::update(void) +{ + if(globals::dimension) { + const auto view = globals::dimension->entities.view<entity::SoundEmitter>(); + + const auto& pivot = entity::camera::position_chunk; + const auto gain = glm::clamp(sound::volume_effects.get_value() * 0.01f, 0.0f, 1.0f); + + for(const auto [entity, emitter] : view.each()) { + alSourcef(emitter.source, AL_GAIN, gain); + + if(const auto transform = globals::dimension->entities.try_get<entity::client::TransformIntr>(entity)) { + auto position = coord::to_relative(pivot, transform->chunk, transform->local); + alSource3f(emitter.source, AL_POSITION, position.x, position.y, position.z); + } + + if(const auto velocity = globals::dimension->entities.try_get<entity::Velocity>(entity)) { + alSource3f(emitter.source, AL_VELOCITY, velocity->value.x, velocity->value.y, velocity->value.z); + } + + ALint source_state; + alGetSourcei(emitter.source, AL_SOURCE_STATE, &source_state); + + if(source_state == AL_STOPPED) { + alSourceRewind(emitter.source); + emitter.sound = nullptr; + } + } + } +} diff --git a/game/client/entity/sound_emitter.hh b/src/game/client/entity/sound_emitter.hh index 14093db..72a3f74 100644 --- a/game/client/entity/sound_emitter.hh +++ b/src/game/client/entity/sound_emitter.hh @@ -1,20 +1,20 @@ -#pragma once
-
-#include "core/resource/resource.hh"
-
-struct SoundEffect;
-
-namespace entity
-{
-struct SoundEmitter final {
- resource_ptr<SoundEffect> sound;
- ALuint source;
-
-public:
- explicit SoundEmitter(void);
- virtual ~SoundEmitter(void);
-
-public:
- static void update(void);
-};
-} // namespace entity
+#pragma once + +#include "core/resource/resource.hh" + +struct SoundEffect; + +namespace entity +{ +struct SoundEmitter final { + resource_ptr<SoundEffect> sound; + ALuint source; + +public: + explicit SoundEmitter(void); + virtual ~SoundEmitter(void); + +public: + static void update(void); +}; +} // namespace entity diff --git a/game/client/experiments.cc b/src/game/client/experiments.cc index 8b0b526..eb415f7 100644 --- a/game/client/experiments.cc +++ b/src/game/client/experiments.cc @@ -1,84 +1,84 @@ -#include "client/pch.hh"
-
-#include "client/experiments.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/item_registry.hh"
-
-#include "shared/game_items.hh"
-#include "shared/game_voxels.hh"
-
-#include "client/gui/chat.hh"
-#include "client/gui/hotbar.hh"
-#include "client/gui/status_lines.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/world/player_target.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event)
-{
- if(!globals::gui_screen && session::is_ingame()) {
- if((event.action == GLFW_PRESS) && world::player_target::voxel) {
- if(event.button == GLFW_MOUSE_BUTTON_LEFT) {
- experiments::attack();
- return;
- }
-
- if(event.button == GLFW_MOUSE_BUTTON_RIGHT) {
- experiments::interact();
- return;
- }
- }
- }
-}
-
-void experiments::init(void)
-{
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
-}
-
-void experiments::init_late(void)
-{
- gui::hotbar::slots[0] = game_items::cobblestone;
- gui::hotbar::slots[1] = game_items::stone;
- gui::hotbar::slots[2] = game_items::dirt;
- gui::hotbar::slots[3] = game_items::grass;
- gui::hotbar::slots[4] = game_items::oak_leaves;
- gui::hotbar::slots[5] = game_items::oak_planks;
- gui::hotbar::slots[6] = game_items::oak_log;
- gui::hotbar::slots[7] = game_items::glass;
- gui::hotbar::slots[8] = game_items::slime;
-}
-
-void experiments::shutdown(void)
-{
-}
-
-void experiments::update(void)
-{
-}
-
-void experiments::update_late(void)
-{
-}
-
-void experiments::attack(void)
-{
- globals::dimension->set_voxel(nullptr, world::player_target::coord);
-}
-
-void experiments::interact(void)
-{
- auto active_item = gui::hotbar::slots[gui::hotbar::active_slot];
-
- if(active_item) {
- if(auto place_voxel = active_item->get_place_voxel()) {
- globals::dimension->set_voxel(place_voxel, world::player_target::coord + world::player_target::normal);
- return;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/experiments.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/item_registry.hh" + +#include "shared/game_items.hh" +#include "shared/game_voxels.hh" + +#include "client/gui/chat.hh" +#include "client/gui/hotbar.hh" +#include "client/gui/status_lines.hh" + +#include "client/io/glfw.hh" + +#include "client/world/player_target.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event) +{ + if(!globals::gui_screen && session::is_ingame()) { + if((event.action == GLFW_PRESS) && world::player_target::voxel) { + if(event.button == GLFW_MOUSE_BUTTON_LEFT) { + experiments::attack(); + return; + } + + if(event.button == GLFW_MOUSE_BUTTON_RIGHT) { + experiments::interact(); + return; + } + } + } +} + +void experiments::init(void) +{ + globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>(); +} + +void experiments::init_late(void) +{ + gui::hotbar::slots[0] = game_items::cobblestone; + gui::hotbar::slots[1] = game_items::stone; + gui::hotbar::slots[2] = game_items::dirt; + gui::hotbar::slots[3] = game_items::grass; + gui::hotbar::slots[4] = game_items::oak_leaves; + gui::hotbar::slots[5] = game_items::oak_planks; + gui::hotbar::slots[6] = game_items::oak_log; + gui::hotbar::slots[7] = game_items::glass; + gui::hotbar::slots[8] = game_items::slime; +} + +void experiments::shutdown(void) +{ +} + +void experiments::update(void) +{ +} + +void experiments::update_late(void) +{ +} + +void experiments::attack(void) +{ + globals::dimension->set_voxel(nullptr, world::player_target::coord); +} + +void experiments::interact(void) +{ + auto active_item = gui::hotbar::slots[gui::hotbar::active_slot]; + + if(active_item) { + if(auto place_voxel = active_item->get_place_voxel()) { + globals::dimension->set_voxel(place_voxel, world::player_target::coord + world::player_target::normal); + return; + } + } +} diff --git a/game/client/experiments.hh b/src/game/client/experiments.hh index c1b0769..ff2cbad 100644 --- a/game/client/experiments.hh +++ b/src/game/client/experiments.hh @@ -1,16 +1,16 @@ -#pragma once
-
-namespace experiments
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void update(void);
-void update_late(void);
-} // namespace experiments
-
-namespace experiments
-{
-void attack(void);
-void interact(void);
-} // namespace experiments
+#pragma once + +namespace experiments +{ +void init(void); +void init_late(void); +void shutdown(void); +void update(void); +void update_late(void); +} // namespace experiments + +namespace experiments +{ +void attack(void); +void interact(void); +} // namespace experiments diff --git a/game/client/game.cc b/src/game/client/game.cc index e772ff8..4b8ffc8 100644 --- a/game/client/game.cc +++ b/src/game/client/game.cc @@ -1,709 +1,708 @@ -#include "client/pch.hh"
-
-#include "client/game.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/angles.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/io/physfs.hh"
-
-#include "shared/entity/collision.hh"
-#include "shared/entity/gravity.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/stasis.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/game_items.hh"
-#include "shared/game_voxels.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/item_registry.hh"
-#include "shared/world/ray_dda.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/protocol.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/entity/camera.hh"
-#include "client/entity/interpolation.hh"
-#include "client/entity/listener.hh"
-#include "client/entity/player_look.hh"
-#include "client/entity/player_move.hh"
-#include "client/entity/sound_emitter.hh"
-
-#include "client/gui/background.hh"
-#include "client/gui/bother.hh"
-#include "client/gui/chat.hh"
-#include "client/gui/crosshair.hh"
-#include "client/gui/direct_connection.hh"
-#include "client/gui/gui_screen.hh"
-#include "client/gui/hotbar.hh"
-#include "client/gui/language.hh"
-#include "client/gui/main_menu.hh"
-#include "client/gui/message_box.hh"
-#include "client/gui/metrics.hh"
-#include "client/gui/play_menu.hh"
-#include "client/gui/progress_bar.hh"
-#include "client/gui/scoreboard.hh"
-#include "client/gui/settings.hh"
-#include "client/gui/splash.hh"
-#include "client/gui/status_lines.hh"
-#include "client/gui/window_title.hh"
-
-#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/world/chunk_mesher.hh"
-#include "client/world/chunk_renderer.hh"
-#include "client/world/chunk_visibility.hh"
-#include "client/world/outline.hh"
-#include "client/world/player_target.hh"
-#include "client/world/skybox.hh"
-#include "client/world/voxel_anims.hh"
-#include "client/world/voxel_atlas.hh"
-#include "client/world/voxel_sounds.hh"
-
-#include "client/const.hh"
-#include "client/experiments.hh"
-#include "client/globals.hh"
-#include "client/receive.hh"
-#include "client/screenshot.hh"
-#include "client/session.hh"
-#include "client/toggles.hh"
-
-config::Boolean client_game::streamer_mode(false);
-config::Boolean client_game::vertical_sync(true);
-config::Boolean client_game::world_curvature(true);
-config::Unsigned client_game::fog_mode(1U, 0U, 2U);
-config::String client_game::username("player");
-
-bool client_game::hide_hud = false;
-
-static config::KeyBind hide_hud_toggle(GLFW_KEY_F1);
-
-static ImFont* load_font(std::string_view path, float size, ImFontConfig& font_config, ImVector<ImWchar>& ranges)
-{
- bool font_load_success;
- std::vector<std::byte> font;
-
- if(!io::read_file(path, font)) {
- spdlog::error("{}: utils::read_file failed", path);
- std::terminate();
- }
-
- auto& io = ImGui::GetIO();
- auto font_ptr = io.Fonts->AddFontFromMemoryTTF(font.data(), font.size(), size, &font_config, ranges.Data);
-
- if(font_ptr == nullptr) {
- spdlog::error("{}: AddFontFromMemoryTTF failed", path);
- std::terminate();
- }
-
- return font_ptr;
-}
-
-static void on_glfw_framebuffer_size(const io::GlfwFramebufferSizeEvent& event)
-{
- if(globals::world_fbo) {
- glDeleteRenderbuffers(1, &globals::world_fbo_depth);
- glDeleteTextures(1, &globals::world_fbo_color);
- glDeleteFramebuffers(1, &globals::world_fbo);
- }
-
- glGenFramebuffers(1, &globals::world_fbo);
- glGenTextures(1, &globals::world_fbo_color);
- glGenRenderbuffers(1, &globals::world_fbo_depth);
-
- glBindTexture(GL_TEXTURE_2D, globals::world_fbo_color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, event.size.x, event.size.y, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
-
- glBindRenderbuffer(GL_RENDERBUFFER, globals::world_fbo_depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, event.size.x, event.size.y);
-
- glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, globals::world_fbo_color, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, globals::world_fbo_depth);
-
- if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- spdlog::critical("opengl: world framebuffer is incomplete");
- glDeleteRenderbuffers(1, &globals::world_fbo_depth);
- glDeleteTextures(1, &globals::world_fbo_color);
- glDeleteFramebuffers(1, &globals::world_fbo);
- std::terminate();
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(!globals::gui_keybind_ptr && hide_hud_toggle.equals(event.key) && (event.action == GLFW_PRESS)) {
- client_game::hide_hud = !client_game::hide_hud;
- }
-}
-
-void client_game::init(void)
-{
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- io.IniFilename = nullptr;
- io.Fonts->Clear();
-
- ImFontConfig font_config;
- font_config.FontDataOwnedByAtlas = false;
-
- ImFontGlyphRangesBuilder builder;
- builder.AddRanges(io.Fonts->GetGlyphRangesDefault());
- builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic());
-
- ImVector<ImWchar> ranges;
- builder.BuildRanges(&ranges);
-
- globals::font_unscii16 = load_font("fonts/unscii-16.ttf", 16.0f, font_config, ranges);
- globals::font_unscii8 = load_font("fonts/unscii-8.ttf", 8.0f, font_config, ranges);
-
- gui::client_splash::init();
- gui::client_splash::render();
-
- globals::client_config.add_value("game.streamer_mode", client_game::streamer_mode);
- globals::client_config.add_value("game.vertical_sync", client_game::vertical_sync);
- globals::client_config.add_value("game.world_curvature", client_game::world_curvature);
- globals::client_config.add_value("game.fog_mode", client_game::fog_mode);
- globals::client_config.add_value("game.username", client_game::username);
- globals::client_config.add_value("game.key.toggle_hide_hud", hide_hud_toggle);
-
- settings::init();
-
- settings::add_checkbox(0, client_game::streamer_mode, settings_location::VIDEO_GUI, "game.streamer_mode", true);
- settings::add_checkbox(5, client_game::vertical_sync, settings_location::VIDEO, "game.vertical_sync", false);
- settings::add_checkbox(4, client_game::world_curvature, settings_location::VIDEO, "game.world_curvature", true);
- settings::add_stepper(3, client_game::fog_mode, settings_location::VIDEO, "game.fog_mode", false);
- settings::add_input(1, client_game::username, settings_location::GENERAL, "game.username", true, false);
- settings::add_keybind(4, hide_hud_toggle, settings_location::KEYBOARD_MISC, "game.key.toggle_hide_hud");
-
- globals::client_host = enet_host_create(nullptr, 1, 1, 0, 0);
-
- if(!globals::client_host) {
- spdlog::critical("game: unable to setup an ENet host");
- std::terminate();
- }
-
- gui::language::init();
-
- session::init();
-
- entity::player_look::init();
- entity::player_move::init();
- world::player_target::init();
-
- io::gamepad::init();
-
- entity::camera::init();
-
- world::voxel_anims::init();
-
- world::outline::init();
- world::chunk_mesher::init();
- world::chunk_renderer::init();
-
- globals::world_fbo = 0;
- globals::world_fbo_color = 0;
- globals::world_fbo_depth = 0;
-
- world::voxel_sounds::init();
-
- world::skybox::init();
-
- ImGuiStyle& style = ImGui::GetStyle();
-
- // Black buttons on a dark background
- // may be harder to read than the text on them
- style.FrameBorderSize = 1.0;
- style.TabBorderSize = 1.0;
-
- // Rounding on elements looks cool but I am
- // aiming for a more or less blocky and
- // visually simple HiDPI-friendly UI style
- style.TabRounding = 0.0f;
- style.GrabRounding = 0.0f;
- style.ChildRounding = 0.0f;
- style.FrameRounding = 0.0f;
- style.PopupRounding = 0.0f;
- style.WindowRounding = 0.0f;
- style.ScrollbarRounding = 0.0f;
-
- style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
- style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
- style.Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f);
- style.Colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
- style.Colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
- style.Colors[ImGuiCol_Border] = ImVec4(0.79f, 0.79f, 0.79f, 0.50f);
- style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
- style.Colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.54f);
- style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.36f, 0.36f, 0.36f, 0.40f);
- style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.63f, 0.63f, 0.63f, 0.67f);
- style.Colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f);
- style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
- style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
- style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f);
- style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f);
- style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f);
- style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
- style.Colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
- style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.81f, 0.81f, 0.81f, 0.75f);
- style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_Button] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f);
- style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
- style.Colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f);
- style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f);
- style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
- style.Colors[ImGuiCol_Separator] = ImVec4(0.49f, 0.49f, 0.49f, 0.50f);
- style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.56f, 0.56f, 0.56f, 0.78f);
- style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
- style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.34f, 0.34f, 0.34f, 0.20f);
- style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.57f, 0.57f, 0.57f, 0.67f);
- style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.95f);
- style.Colors[ImGuiCol_Tab] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f);
- style.Colors[ImGuiCol_TabHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f);
- style.Colors[ImGuiCol_TabActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
- style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.13f, 0.13f, 0.13f, 0.97f);
- style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.44f, 0.44f, 0.44f, 1.00f);
- style.Colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
- style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.69f, 0.00f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.00f, 1.00f, 0.20f, 1.00f);
- style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f);
- style.Colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f);
- style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f);
- style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
- style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
- style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.61f, 0.61f, 0.61f, 0.35f);
- style.Colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f);
- style.Colors[ImGuiCol_NavHighlight] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
- style.Colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
- style.Colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
- style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
-
- // Making my own Game UI for Source Engine
- // taught me one important thing: dimensions
- // of UI elements must be calculated at semi-runtime
- // so there's simply no point for an INI file.
- io.IniFilename = nullptr;
-
- toggles::init();
-
- gui::background::init();
-
- gui::scoreboard::init();
-
- gui::client_chat::init();
-
- gui::bother::init();
-
- gui::main_menu::init();
- gui::play_menu::init();
- gui::progress_bar::init();
- gui::message_box::init();
- gui::direct_connection::init();
-
- gui::crosshair::init();
- gui::hotbar::init();
- gui::metrics::init();
- gui::status_lines::init();
-
- screenshot::init();
-
- globals::gui_keybind_ptr = nullptr;
- globals::gui_scale = 0U;
- globals::gui_screen = GUI_MAIN_MENU;
-
- sound::init_config();
-
- if(globals::sound_ctx) {
- sound::init();
- }
-
- client_receive::init();
-
- experiments::init();
-
- globals::dispatcher.sink<io::GlfwFramebufferSizeEvent>().connect<&on_glfw_framebuffer_size>();
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
-}
-
-void client_game::init_late(void)
-{
- toggles::init_late();
-
- if(globals::sound_ctx) {
- sound::init_late();
- }
-
- gui::language::init_late();
-
- settings::init_late();
-
- gui::client_chat::init_late();
-
- gui::status_lines::init_late();
-
- game_voxels::populate();
- game_items::populate();
-
- std::size_t max_texture_count = 0;
-
- // Figure out the total texture count
- // NOTE: this is very debug, early and a quite
- // conservative limit choice; there must be a better
- // way to make this limit way smaller than it currently is
- for(const auto& voxel : world::voxel_registry::voxels) {
- max_texture_count += voxel->get_default_textures().size();
- max_texture_count += voxel->get_face_textures(world::VFACE_NORTH).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_SOUTH).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_EAST).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_WEST).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_TOP).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_BOTTOM).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_CROSS_NWSE).size();
- max_texture_count += voxel->get_face_textures(world::VFACE_CROSS_NESW).size();
- }
-
- // UNDONE: asset packs for non-16x16 stuff
- world::voxel_atlas::create(16, 16, max_texture_count);
-
- for(auto& voxel : world::voxel_registry::voxels) {
- constexpr std::array faces = {
- world::VFACE_NORTH,
- world::VFACE_SOUTH,
- world::VFACE_EAST,
- world::VFACE_WEST,
- world::VFACE_TOP,
- world::VFACE_BOTTOM,
- world::VFACE_CROSS_NWSE,
- world::VFACE_CROSS_NESW,
- };
-
- for(auto face : faces) {
- if(auto strip = world::voxel_atlas::find_or_load(voxel->get_face_textures(face))) {
- voxel->set_face_cache(face, strip->offset, strip->plane);
- continue;
- }
-
- spdlog::critical("client_gl: {}: failed to load atlas strips", voxel->get_name());
- std::terminate();
- }
- }
-
- world::voxel_atlas::generate_mipmaps();
-
- for(auto& item : world::item_registry::items) {
- item->set_cached_texture(resource::load<TextureGUI>(item->get_texture(), TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T));
- }
-
- experiments::init_late();
-
- gui::client_splash::init_late();
-
- gui::window_title::update();
-}
-
-void client_game::shutdown(void)
-{
- world::voxel_sounds::shutdown();
-
- experiments::shutdown();
-
- session::shutdown();
-
- if(globals::sound_ctx) {
- sound::shutdown();
- }
-
- gui::hotbar::shutdown();
- gui::main_menu::shutdown();
- gui::play_menu::shutdown();
-
- gui::bother::shutdown();
-
- gui::client_chat::shutdown();
-
- gui::background::shutdown();
-
- gui::crosshair::shutdown();
-
- delete globals::dimension;
- globals::player = entt::null;
- globals::dimension = nullptr;
-
- world::item_registry::purge();
- world::voxel_registry::purge();
-
- world::voxel_atlas::destroy();
-
- glDeleteRenderbuffers(1, &globals::world_fbo_depth);
- glDeleteTextures(1, &globals::world_fbo_color);
- glDeleteFramebuffers(1, &globals::world_fbo);
-
- world::outline::shutdown();
- world::chunk_renderer::shutdown();
- world::chunk_mesher::shutdown();
-
- enet_host_destroy(globals::client_host);
-}
-
-void client_game::fixed_update(void)
-{
- entity::player_move::fixed_update();
-
- // Only update world simulation gamesystems
- // if the player can actually observe all the
- // changes these gamesystems cause visually
- if(session::is_ingame()) {
- entity::Collision::fixed_update(globals::dimension);
- entity::Velocity::fixed_update(globals::dimension);
- entity::Transform::fixed_update(globals::dimension);
- entity::Gravity::fixed_update(globals::dimension);
- entity::Stasis::fixed_update(globals::dimension);
- }
-}
-
-void client_game::fixed_update_late(void)
-{
- if(session::is_ingame()) {
- const auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
- const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player);
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
-
- protocol::EntityHead head_packet;
- head_packet.entity = entt::null; // ignored by server
- head_packet.angles = head.angles;
-
- protocol::EntityTransform transform_packet;
- transform_packet.entity = entt::null; // ignored by server
- transform_packet.angles = transform.angles;
- transform_packet.chunk = transform.chunk;
- transform_packet.local = transform.local;
-
- protocol::EntityVelocity velocity_packet;
- velocity_packet.entity = entt::null; // ignored by server
- velocity_packet.value = velocity.value;
-
- protocol::send(session::peer, protocol::encode(head_packet));
- protocol::send(session::peer, protocol::encode(transform_packet));
- protocol::send(session::peer, protocol::encode(velocity_packet));
- }
-}
-
-void client_game::update(void)
-{
- if(session::is_ingame()) {
- if(toggles::get(TOGGLE_PM_FLIGHT)) {
- globals::dimension->entities.remove<entity::Gravity>(globals::player);
- }
- else {
- globals::dimension->entities.emplace_or_replace<entity::Gravity>(globals::player);
- }
- }
-
- if(globals::sound_ctx) {
- sound::update();
-
- entity::listener::update();
-
- entity::SoundEmitter::update();
- }
-
- entity::interpolation::update();
-
- world::player_target::update();
-
- entity::camera::update();
-
- world::voxel_anims::update();
-
- world::chunk_mesher::update();
-
- gui::client_chat::update();
-
- experiments::update();
-
- constexpr auto half_base_width = 0.5f * static_cast<float>(BASE_WIDTH);
- constexpr auto half_base_height = 0.5f * static_cast<float>(BASE_HEIGHT);
-
- auto twice_scale_x = static_cast<float>(globals::width) / half_base_width;
- auto twice_scale_y = static_cast<float>(globals::height) / half_base_height;
-
- auto scale_x = glm::max(1.0f, 0.5f * glm::floor(twice_scale_x));
- auto scale_y = glm::max(1.0f, 0.5f * glm::floor(twice_scale_y));
- auto scale_min = static_cast<unsigned int>(glm::ceil(glm::min(scale_x, scale_y)));
- auto scale_int = glm::max(1U, (scale_min / 2U) * 2U);
-
- auto& io = ImGui::GetIO();
- io.FontGlobalScale = scale_int;
- globals::gui_scale = scale_int;
-}
-
-void client_game::update_late(void)
-{
- ENetEvent enet_event;
-
- while(0 < enet_host_service(globals::client_host, &enet_event, 0)) {
- switch(enet_event.type) {
- case ENET_EVENT_TYPE_CONNECT:
- session::send_login_request();
- break;
- case ENET_EVENT_TYPE_DISCONNECT:
- session::invalidate();
- break;
- case ENET_EVENT_TYPE_RECEIVE:
- protocol::decode(globals::dispatcher, enet_event.packet, enet_event.peer);
- enet_packet_destroy(enet_event.packet);
- break;
- }
- }
-
- entity::player_look::update_late();
- entity::player_move::update_late();
-
- gui::play_menu::update_late();
-
- gui::bother::update_late();
-
- experiments::update_late();
-
- io::gamepad::update_late();
-
- world::chunk_visibility::update_late();
-
- if(client_game::vertical_sync.get_value()) {
- glfwSwapInterval(1);
- }
- else {
- glfwSwapInterval(0);
- }
-}
-
-void client_game::render(void)
-{
- glViewport(0, 0, globals::width, globals::height);
- glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo);
- glClearColor(world::skybox::fog_color.r, world::skybox::fog_color.g, world::skybox::fog_color.b, 1.000f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if(globals::dimension) {
- world::chunk_renderer::render();
- }
-
- glEnable(GL_DEPTH_TEST);
-
- world::player_target::render();
-
- if(globals::dimension) {
- auto group = globals::dimension->entities.group(
- entt::get<entity::Player, entity::Collision, entity::client::HeadIntr, entity::client::TransformIntr>);
-
- world::outline::prepare();
-
- for(const auto [entity, collision, head, transform] : group.each()) {
- if(entity == globals::player) {
- // Don't render ourselves
- continue;
- }
-
- glm::fvec3 forward;
- math::vectors(transform.angles + head.angles, forward);
- forward *= 2.0f;
-
- glm::fvec3 hull_size = collision.aabb.max - collision.aabb.min;
- glm::fvec3 hull_fpos = transform.local + collision.aabb.min;
- glm::fvec3 look = transform.local + head.offset;
-
- world::outline::cube(transform.chunk, hull_fpos, hull_size, 1.0f, glm::fvec4(1.0f, 0.0f, 0.0f, 1.0f));
- world::outline::line(transform.chunk, look, forward, 1.0f, glm::fvec4(0.9f, 0.9f, 0.9f, 1.0f));
- }
- }
-
- glEnable(GL_DEPTH_TEST);
-
- glViewport(0, 0, globals::width, globals::height);
- glClearColor(0.000f, 0.000f, 0.000f, 1.000f);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, globals::world_fbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- glBlitFramebuffer(0, 0, globals::width, globals::height, 0, 0, globals::width, globals::height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-}
-
-void client_game::layout(void)
-{
- if(!session::is_ingame()) {
- gui::background::layout();
- }
-
- if(!globals::gui_screen || (globals::gui_screen == GUI_CHAT)) {
- if(toggles::get(TOGGLE_METRICS_UI) && !client_game::hide_hud) {
- // This contains Minecraft-esque debug information
- // about the hardware, world state and other
- // things that might be uesful
- gui::metrics::layout();
- }
- }
-
- if(session::is_ingame()) {
- gui::client_chat::layout();
- gui::scoreboard::layout();
-
- if(!globals::gui_screen && !client_game::hide_hud) {
- gui::hotbar::layout();
- gui::status_lines::layout();
- gui::crosshair::layout();
- }
- }
-
- if(globals::gui_screen) {
- if(session::is_ingame() && (globals::gui_screen != GUI_CHAT)) {
- const float width_f = static_cast<float>(globals::width);
- const float height_f = static_cast<float>(globals::height);
- const ImU32 darken = ImGui::GetColorU32(ImVec4(0.00f, 0.00f, 0.00f, 0.75f));
- ImGui::GetBackgroundDrawList()->AddRectFilled(ImVec2(), ImVec2(width_f, height_f), darken);
- }
-
- switch(globals::gui_screen) {
- case GUI_MAIN_MENU:
- gui::main_menu::layout();
- break;
- case GUI_PLAY_MENU:
- gui::play_menu::layout();
- break;
- case GUI_SETTINGS:
- settings::layout();
- break;
- case GUI_PROGRESS_BAR:
- gui::progress_bar::layout();
- break;
- case GUI_MESSAGE_BOX:
- gui::message_box::layout();
- break;
- case GUI_DIRECT_CONNECTION:
- gui::direct_connection::layout();
- break;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/game.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" +#include "core/config/string.hh" + +#include "core/io/config_map.hh" + +#include "core/math/angles.hh" + +#include "core/resource/resource.hh" + +#include "core/io/physfs.hh" + +#include "shared/entity/collision.hh" +#include "shared/entity/gravity.hh" +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/stasis.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/game_items.hh" +#include "shared/game_voxels.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/item_registry.hh" +#include "shared/world/ray_dda.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/protocol.hh" + +#include "client/config/keybind.hh" + +#include "client/entity/camera.hh" +#include "client/entity/interpolation.hh" +#include "client/entity/listener.hh" +#include "client/entity/player_look.hh" +#include "client/entity/player_move.hh" +#include "client/entity/sound_emitter.hh" + +#include "client/gui/background.hh" +#include "client/gui/bother.hh" +#include "client/gui/chat.hh" +#include "client/gui/crosshair.hh" +#include "client/gui/direct_connection.hh" +#include "client/gui/gui_screen.hh" +#include "client/gui/hotbar.hh" +#include "client/gui/language.hh" +#include "client/gui/main_menu.hh" +#include "client/gui/message_box.hh" +#include "client/gui/metrics.hh" +#include "client/gui/play_menu.hh" +#include "client/gui/progress_bar.hh" +#include "client/gui/scoreboard.hh" +#include "client/gui/settings.hh" +#include "client/gui/splash.hh" +#include "client/gui/status_lines.hh" +#include "client/gui/window_title.hh" + +#include "client/io/gamepad.hh" +#include "client/io/glfw.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/sound/sound.hh" + +#include "client/world/chunk_mesher.hh" +#include "client/world/chunk_renderer.hh" +#include "client/world/chunk_visibility.hh" +#include "client/world/outline.hh" +#include "client/world/player_target.hh" +#include "client/world/skybox.hh" +#include "client/world/voxel_anims.hh" +#include "client/world/voxel_atlas.hh" +#include "client/world/voxel_sounds.hh" + +#include "client/const.hh" +#include "client/experiments.hh" +#include "client/globals.hh" +#include "client/receive.hh" +#include "client/screenshot.hh" +#include "client/session.hh" +#include "client/toggles.hh" + +config::Boolean client_game::streamer_mode(false); +config::Boolean client_game::vertical_sync(true); +config::Boolean client_game::world_curvature(true); +config::Unsigned client_game::fog_mode(1U, 0U, 2U); +config::String client_game::username("player"); + +bool client_game::hide_hud = false; + +static config::KeyBind hide_hud_toggle(GLFW_KEY_F1); + +static ImFont* load_font(std::string_view path, float size, ImFontConfig& font_config, ImVector<ImWchar>& ranges) +{ + std::vector<std::byte> font; + + if(!io::read_file(path, font)) { + spdlog::error("{}: utils::read_file failed", path); + std::terminate(); + } + + auto& io = ImGui::GetIO(); + auto font_ptr = io.Fonts->AddFontFromMemoryTTF(font.data(), static_cast<int>(font.size()), size, &font_config, ranges.Data); + + if(font_ptr == nullptr) { + spdlog::error("{}: AddFontFromMemoryTTF failed", path); + std::terminate(); + } + + return font_ptr; +} + +static void on_glfw_framebuffer_size(const io::GlfwFramebufferSizeEvent& event) +{ + if(globals::world_fbo) { + glDeleteRenderbuffers(1, &globals::world_fbo_depth); + glDeleteTextures(1, &globals::world_fbo_color); + glDeleteFramebuffers(1, &globals::world_fbo); + } + + glGenFramebuffers(1, &globals::world_fbo); + glGenTextures(1, &globals::world_fbo_color); + glGenRenderbuffers(1, &globals::world_fbo_depth); + + glBindTexture(GL_TEXTURE_2D, globals::world_fbo_color); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, event.size.x, event.size.y, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); + + glBindRenderbuffer(GL_RENDERBUFFER, globals::world_fbo_depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, event.size.x, event.size.y); + + glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, globals::world_fbo_color, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, globals::world_fbo_depth); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + spdlog::critical("opengl: world framebuffer is incomplete"); + glDeleteRenderbuffers(1, &globals::world_fbo_depth); + glDeleteTextures(1, &globals::world_fbo_color); + glDeleteFramebuffers(1, &globals::world_fbo); + std::terminate(); + } +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if(!globals::gui_keybind_ptr && hide_hud_toggle.equals(event.key) && (event.action == GLFW_PRESS)) { + client_game::hide_hud = !client_game::hide_hud; + } +} + +void client_game::init(void) +{ + auto& io = ImGui::GetIO(); + io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.IniFilename = nullptr; + io.Fonts->Clear(); + + ImFontConfig font_config; + font_config.FontDataOwnedByAtlas = false; + + ImFontGlyphRangesBuilder builder; + builder.AddRanges(io.Fonts->GetGlyphRangesDefault()); + builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic()); + + ImVector<ImWchar> ranges; + builder.BuildRanges(&ranges); + + globals::font_unscii16 = load_font("fonts/unscii-16.ttf", 16.0f, font_config, ranges); + globals::font_unscii8 = load_font("fonts/unscii-8.ttf", 8.0f, font_config, ranges); + + gui::client_splash::init(); + gui::client_splash::render(); + + globals::client_config.add_value("game.streamer_mode", client_game::streamer_mode); + globals::client_config.add_value("game.vertical_sync", client_game::vertical_sync); + globals::client_config.add_value("game.world_curvature", client_game::world_curvature); + globals::client_config.add_value("game.fog_mode", client_game::fog_mode); + globals::client_config.add_value("game.username", client_game::username); + globals::client_config.add_value("game.key.toggle_hide_hud", hide_hud_toggle); + + settings::init(); + + settings::add_checkbox(0, client_game::streamer_mode, settings_location::VIDEO_GUI, "game.streamer_mode", true); + settings::add_checkbox(5, client_game::vertical_sync, settings_location::VIDEO, "game.vertical_sync", false); + settings::add_checkbox(4, client_game::world_curvature, settings_location::VIDEO, "game.world_curvature", true); + settings::add_stepper(3, client_game::fog_mode, settings_location::VIDEO, "game.fog_mode", false); + settings::add_input(1, client_game::username, settings_location::GENERAL, "game.username", true, false); + settings::add_keybind(4, hide_hud_toggle, settings_location::KEYBOARD_MISC, "game.key.toggle_hide_hud"); + + globals::client_host = enet_host_create(nullptr, 1, 1, 0, 0); + + if(!globals::client_host) { + spdlog::critical("game: unable to setup an ENet host"); + std::terminate(); + } + + gui::language::init(); + + session::init(); + + entity::player_look::init(); + entity::player_move::init(); + world::player_target::init(); + + io::gamepad::init(); + + entity::camera::init(); + + world::voxel_anims::init(); + + world::outline::init(); + world::chunk_mesher::init(); + world::chunk_renderer::init(); + + globals::world_fbo = 0; + globals::world_fbo_color = 0; + globals::world_fbo_depth = 0; + + world::voxel_sounds::init(); + + world::skybox::init(); + + ImGuiStyle& style = ImGui::GetStyle(); + + // Black buttons on a dark background + // may be harder to read than the text on them + style.FrameBorderSize = 1.0; + style.TabBorderSize = 1.0; + + // Rounding on elements looks cool but I am + // aiming for a more or less blocky and + // visually simple HiDPI-friendly UI style + style.TabRounding = 0.0f; + style.GrabRounding = 0.0f; + style.ChildRounding = 0.0f; + style.FrameRounding = 0.0f; + style.PopupRounding = 0.0f; + style.WindowRounding = 0.0f; + style.ScrollbarRounding = 0.0f; + + style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + style.Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + style.Colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + style.Colors[ImGuiCol_Border] = ImVec4(0.79f, 0.79f, 0.79f, 0.50f); + style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.54f); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.36f, 0.36f, 0.36f, 0.40f); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.63f, 0.63f, 0.63f, 0.67f); + style.Colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); + style.Colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.81f, 0.81f, 0.81f, 0.75f); + style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_Button] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f); + style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); + style.Colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f); + style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); + style.Colors[ImGuiCol_Separator] = ImVec4(0.49f, 0.49f, 0.49f, 0.50f); + style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.56f, 0.56f, 0.56f, 0.78f); + style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.34f, 0.34f, 0.34f, 0.20f); + style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.57f, 0.57f, 0.57f, 0.67f); + style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.95f); + style.Colors[ImGuiCol_Tab] = ImVec4(0.00f, 0.00f, 0.00f, 0.75f); + style.Colors[ImGuiCol_TabHovered] = ImVec4(0.12f, 0.12f, 0.12f, 1.00f); + style.Colors[ImGuiCol_TabActive] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); + style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.13f, 0.13f, 0.13f, 0.97f); + style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.44f, 0.44f, 0.44f, 1.00f); + style.Colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.69f, 0.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.00f, 1.00f, 0.20f, 1.00f); + style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); + style.Colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); + style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); + style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.61f, 0.61f, 0.61f, 0.35f); + style.Colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); + style.Colors[ImGuiCol_NavHighlight] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + style.Colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + style.Colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + + // Making my own Game UI for Source Engine + // taught me one important thing: dimensions + // of UI elements must be calculated at semi-runtime + // so there's simply no point for an INI file. + io.IniFilename = nullptr; + + toggles::init(); + + gui::background::init(); + + gui::scoreboard::init(); + + gui::client_chat::init(); + + gui::bother::init(); + + gui::main_menu::init(); + gui::play_menu::init(); + gui::progress_bar::init(); + gui::message_box::init(); + gui::direct_connection::init(); + + gui::crosshair::init(); + gui::hotbar::init(); + gui::metrics::init(); + gui::status_lines::init(); + + screenshot::init(); + + globals::gui_keybind_ptr = nullptr; + globals::gui_scale = 0U; + globals::gui_screen = GUI_MAIN_MENU; + + sound::init_config(); + + if(globals::sound_ctx) { + sound::init(); + } + + client_receive::init(); + + experiments::init(); + + globals::dispatcher.sink<io::GlfwFramebufferSizeEvent>().connect<&on_glfw_framebuffer_size>(); + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); +} + +void client_game::init_late(void) +{ + toggles::init_late(); + + if(globals::sound_ctx) { + sound::init_late(); + } + + gui::language::init_late(); + + settings::init_late(); + + gui::client_chat::init_late(); + + gui::status_lines::init_late(); + + game_voxels::populate(); + game_items::populate(); + + std::size_t max_texture_count = 0; + + // Figure out the total texture count + // NOTE: this is very debug, early and a quite + // conservative limit choice; there must be a better + // way to make this limit way smaller than it currently is + for(const auto& voxel : world::voxel_registry::voxels) { + max_texture_count += voxel->get_default_textures().size(); + max_texture_count += voxel->get_face_textures(world::VFACE_NORTH).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_SOUTH).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_EAST).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_WEST).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_TOP).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_BOTTOM).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_CROSS_NWSE).size(); + max_texture_count += voxel->get_face_textures(world::VFACE_CROSS_NESW).size(); + } + + // UNDONE: asset packs for non-16x16 stuff + world::voxel_atlas::create(16, 16, max_texture_count); + + for(auto& voxel : world::voxel_registry::voxels) { + constexpr std::array faces = { + world::VFACE_NORTH, + world::VFACE_SOUTH, + world::VFACE_EAST, + world::VFACE_WEST, + world::VFACE_TOP, + world::VFACE_BOTTOM, + world::VFACE_CROSS_NWSE, + world::VFACE_CROSS_NESW, + }; + + for(auto face : faces) { + if(auto strip = world::voxel_atlas::find_or_load(voxel->get_face_textures(face))) { + voxel->set_face_cache(face, strip->offset, strip->plane); + continue; + } + + spdlog::critical("client_gl: {}: failed to load atlas strips", voxel->get_name()); + std::terminate(); + } + } + + world::voxel_atlas::generate_mipmaps(); + + for(auto& item : world::item_registry::items) { + item->set_cached_texture(resource::load<TextureGUI>(item->get_texture(), TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T)); + } + + experiments::init_late(); + + gui::client_splash::init_late(); + + gui::window_title::update(); +} + +void client_game::shutdown(void) +{ + world::voxel_sounds::shutdown(); + + experiments::shutdown(); + + session::shutdown(); + + if(globals::sound_ctx) { + sound::shutdown(); + } + + gui::hotbar::shutdown(); + gui::main_menu::shutdown(); + gui::play_menu::shutdown(); + + gui::bother::shutdown(); + + gui::client_chat::shutdown(); + + gui::background::shutdown(); + + gui::crosshair::shutdown(); + + delete globals::dimension; + globals::player = entt::null; + globals::dimension = nullptr; + + world::item_registry::purge(); + world::voxel_registry::purge(); + + world::voxel_atlas::destroy(); + + glDeleteRenderbuffers(1, &globals::world_fbo_depth); + glDeleteTextures(1, &globals::world_fbo_color); + glDeleteFramebuffers(1, &globals::world_fbo); + + world::outline::shutdown(); + world::chunk_renderer::shutdown(); + world::chunk_mesher::shutdown(); + + enet_host_destroy(globals::client_host); +} + +void client_game::fixed_update(void) +{ + entity::player_move::fixed_update(); + + // Only update world simulation gamesystems + // if the player can actually observe all the + // changes these gamesystems cause visually + if(session::is_ingame()) { + entity::Collision::fixed_update(globals::dimension); + entity::Velocity::fixed_update(globals::dimension); + entity::Transform::fixed_update(globals::dimension); + entity::Gravity::fixed_update(globals::dimension); + entity::Stasis::fixed_update(globals::dimension); + } +} + +void client_game::fixed_update_late(void) +{ + if(session::is_ingame()) { + const auto& head = globals::dimension->entities.get<entity::Head>(globals::player); + const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player); + const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player); + + protocol::EntityHead head_packet; + head_packet.entity = entt::null; // ignored by server + head_packet.angles = head.angles; + + protocol::EntityTransform transform_packet; + transform_packet.entity = entt::null; // ignored by server + transform_packet.angles = transform.angles; + transform_packet.chunk = transform.chunk; + transform_packet.local = transform.local; + + protocol::EntityVelocity velocity_packet; + velocity_packet.entity = entt::null; // ignored by server + velocity_packet.value = velocity.value; + + protocol::send(session::peer, protocol::encode(head_packet)); + protocol::send(session::peer, protocol::encode(transform_packet)); + protocol::send(session::peer, protocol::encode(velocity_packet)); + } +} + +void client_game::update(void) +{ + if(session::is_ingame()) { + if(toggles::get(TOGGLE_PM_FLIGHT)) { + globals::dimension->entities.remove<entity::Gravity>(globals::player); + } + else { + globals::dimension->entities.emplace_or_replace<entity::Gravity>(globals::player); + } + } + + if(globals::sound_ctx) { + sound::update(); + + entity::listener::update(); + + entity::SoundEmitter::update(); + } + + entity::interpolation::update(); + + world::player_target::update(); + + entity::camera::update(); + + world::voxel_anims::update(); + + world::chunk_mesher::update(); + + gui::client_chat::update(); + + experiments::update(); + + constexpr auto half_base_width = 0.5f * static_cast<float>(BASE_WIDTH); + constexpr auto half_base_height = 0.5f * static_cast<float>(BASE_HEIGHT); + + auto twice_scale_x = static_cast<float>(globals::width) / half_base_width; + auto twice_scale_y = static_cast<float>(globals::height) / half_base_height; + + auto scale_x = glm::max(1.0f, 0.5f * glm::floor(twice_scale_x)); + auto scale_y = glm::max(1.0f, 0.5f * glm::floor(twice_scale_y)); + auto scale_min = static_cast<unsigned int>(glm::ceil(glm::min(scale_x, scale_y))); + auto scale_int = glm::max<unsigned int>(1U, (scale_min / 2U) * 2U); + + auto& io = ImGui::GetIO(); + io.FontGlobalScale = scale_int; + globals::gui_scale = scale_int; +} + +void client_game::update_late(void) +{ + ENetEvent enet_event; + + while(0 < enet_host_service(globals::client_host, &enet_event, 0)) { + switch(enet_event.type) { + case ENET_EVENT_TYPE_CONNECT: + session::send_login_request(); + break; + case ENET_EVENT_TYPE_DISCONNECT: + session::invalidate(); + break; + case ENET_EVENT_TYPE_RECEIVE: + protocol::decode(globals::dispatcher, enet_event.packet, enet_event.peer); + enet_packet_destroy(enet_event.packet); + break; + } + } + + entity::player_look::update_late(); + entity::player_move::update_late(); + + gui::play_menu::update_late(); + + gui::bother::update_late(); + + experiments::update_late(); + + io::gamepad::update_late(); + + world::chunk_visibility::update_late(); + + if(client_game::vertical_sync.get_value()) { + glfwSwapInterval(1); + } + else { + glfwSwapInterval(0); + } +} + +void client_game::render(void) +{ + glViewport(0, 0, globals::width, globals::height); + glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo); + glClearColor(world::skybox::fog_color.r, world::skybox::fog_color.g, world::skybox::fog_color.b, 1.000f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(globals::dimension) { + world::chunk_renderer::render(); + } + + glEnable(GL_DEPTH_TEST); + + world::player_target::render(); + + if(globals::dimension) { + auto group = globals::dimension->entities.group( + entt::get<entity::Player, entity::Collision, entity::client::HeadIntr, entity::client::TransformIntr>); + + world::outline::prepare(); + + for(const auto [entity, collision, head, transform] : group.each()) { + if(entity == globals::player) { + // Don't render ourselves + continue; + } + + glm::fvec3 forward; + math::vectors(transform.angles + head.angles, forward); + forward *= 2.0f; + + glm::fvec3 hull_size = collision.aabb.max - collision.aabb.min; + glm::fvec3 hull_fpos = transform.local + collision.aabb.min; + glm::fvec3 look = transform.local + head.offset; + + world::outline::cube(transform.chunk, hull_fpos, hull_size, 1.0f, glm::fvec4(1.0f, 0.0f, 0.0f, 1.0f)); + world::outline::line(transform.chunk, look, forward, 1.0f, glm::fvec4(0.9f, 0.9f, 0.9f, 1.0f)); + } + } + + glEnable(GL_DEPTH_TEST); + + glViewport(0, 0, globals::width, globals::height); + glClearColor(0.000f, 0.000f, 0.000f, 1.000f); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, globals::world_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, globals::width, globals::height, 0, 0, globals::width, globals::height, GL_COLOR_BUFFER_BIT, GL_NEAREST); +} + +void client_game::layout(void) +{ + if(!session::is_ingame()) { + gui::background::layout(); + } + + if(!globals::gui_screen || (globals::gui_screen == GUI_CHAT)) { + if(toggles::get(TOGGLE_METRICS_UI) && !client_game::hide_hud) { + // This contains Minecraft-esque debug information + // about the hardware, world state and other + // things that might be uesful + gui::metrics::layout(); + } + } + + if(session::is_ingame()) { + gui::client_chat::layout(); + gui::scoreboard::layout(); + + if(!globals::gui_screen && !client_game::hide_hud) { + gui::hotbar::layout(); + gui::status_lines::layout(); + gui::crosshair::layout(); + } + } + + if(globals::gui_screen) { + if(session::is_ingame() && (globals::gui_screen != GUI_CHAT)) { + const float width_f = static_cast<float>(globals::width); + const float height_f = static_cast<float>(globals::height); + const ImU32 darken = ImGui::GetColorU32(ImVec4(0.00f, 0.00f, 0.00f, 0.75f)); + ImGui::GetBackgroundDrawList()->AddRectFilled(ImVec2(), ImVec2(width_f, height_f), darken); + } + + switch(globals::gui_screen) { + case GUI_MAIN_MENU: + gui::main_menu::layout(); + break; + case GUI_PLAY_MENU: + gui::play_menu::layout(); + break; + case GUI_SETTINGS: + settings::layout(); + break; + case GUI_PROGRESS_BAR: + gui::progress_bar::layout(); + break; + case GUI_MESSAGE_BOX: + gui::message_box::layout(); + break; + case GUI_DIRECT_CONNECTION: + gui::direct_connection::layout(); + break; + } + } +} diff --git a/game/client/game.hh b/src/game/client/game.hh index 649700a..395acc9 100644 --- a/game/client/game.hh +++ b/src/game/client/game.hh @@ -1,35 +1,35 @@ -#pragma once
-
-namespace config
-{
-class Boolean;
-class String;
-class Unsigned;
-} // namespace config
-
-namespace client_game
-{
-extern config::Boolean streamer_mode;
-extern config::Boolean vertical_sync;
-extern config::Boolean world_curvature;
-extern config::Unsigned fog_mode;
-extern config::String username;
-} // namespace client_game
-
-namespace client_game
-{
-extern bool hide_hud;
-} // namespace client_game
-
-namespace client_game
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void fixed_update(void);
-void fixed_update_late(void);
-void update(void);
-void update_late(void);
-void render(void);
-void layout(void);
-} // namespace client_game
+#pragma once + +namespace config +{ +class Boolean; +class String; +class Unsigned; +} // namespace config + +namespace client_game +{ +extern config::Boolean streamer_mode; +extern config::Boolean vertical_sync; +extern config::Boolean world_curvature; +extern config::Unsigned fog_mode; +extern config::String username; +} // namespace client_game + +namespace client_game +{ +extern bool hide_hud; +} // namespace client_game + +namespace client_game +{ +void init(void); +void init_late(void); +void shutdown(void); +void fixed_update(void); +void fixed_update_late(void); +void update(void); +void update_late(void); +void render(void); +void layout(void); +} // namespace client_game diff --git a/game/client/globals.cc b/src/game/client/globals.cc index 1cf1aeb..1932675 100644 --- a/game/client/globals.cc +++ b/src/game/client/globals.cc @@ -1,47 +1,47 @@ -#include "client/pch.hh"
-
-#include "client/globals.hh"
-
-#include "core/io/config_map.hh"
-
-#include "client/gui/gui_screen.hh"
-
-io::ConfigMap globals::client_config;
-
-GLFWwindow* globals::window;
-
-float globals::window_frametime;
-float globals::window_frametime_avg;
-std::uint64_t globals::window_frametime_us;
-std::uint64_t globals::window_framecount;
-
-std::uint64_t globals::fixed_accumulator;
-
-int globals::width;
-int globals::height;
-float globals::aspect;
-
-GLuint globals::world_fbo;
-GLuint globals::world_fbo_color;
-GLuint globals::world_fbo_depth;
-
-std::size_t globals::num_drawcalls;
-std::size_t globals::num_triangles;
-
-ENetHost* globals::client_host;
-
-world::Dimension* globals::dimension = nullptr;
-entt::entity globals::player;
-
-ImFont* globals::font_unscii16;
-ImFont* globals::font_unscii8;
-
-config::KeyBind* globals::gui_keybind_ptr = nullptr;
-config::GamepadAxis* globals::gui_gamepad_axis_ptr = nullptr;
-config::GamepadButton* globals::gui_gamepad_button_ptr = nullptr;
-
-unsigned int globals::gui_scale = 0U;
-unsigned int globals::gui_screen = GUI_SCREEN_NONE;
-
-ALCdevice* globals::sound_dev;
-ALCcontext* globals::sound_ctx;
+#include "client/pch.hh" + +#include "client/globals.hh" + +#include "core/io/config_map.hh" + +#include "client/gui/gui_screen.hh" + +io::ConfigMap globals::client_config; + +GLFWwindow* globals::window; + +float globals::window_frametime; +float globals::window_frametime_avg; +std::uint64_t globals::window_frametime_us; +std::uint64_t globals::window_framecount; + +std::uint64_t globals::fixed_accumulator; + +int globals::width; +int globals::height; +float globals::aspect; + +GLuint globals::world_fbo; +GLuint globals::world_fbo_color; +GLuint globals::world_fbo_depth; + +std::size_t globals::num_drawcalls; +std::size_t globals::num_triangles; + +ENetHost* globals::client_host; + +world::Dimension* globals::dimension = nullptr; +entt::entity globals::player; + +ImFont* globals::font_unscii16; +ImFont* globals::font_unscii8; + +config::KeyBind* globals::gui_keybind_ptr = nullptr; +config::GamepadAxis* globals::gui_gamepad_axis_ptr = nullptr; +config::GamepadButton* globals::gui_gamepad_button_ptr = nullptr; + +unsigned int globals::gui_scale = 0U; +unsigned int globals::gui_screen = GUI_SCREEN_NONE; + +ALCdevice* globals::sound_dev; +ALCcontext* globals::sound_ctx; diff --git a/game/client/globals.hh b/src/game/client/globals.hh index 41531a9..ba57a9e 100644 --- a/game/client/globals.hh +++ b/src/game/client/globals.hh @@ -1,71 +1,71 @@ -#pragma once
-
-#include "shared/globals.hh"
-
-namespace config
-{
-class KeyBind;
-class GamepadAxis;
-class GamepadButton;
-} // namespace config
-
-namespace io
-{
-class ConfigMap;
-} // namespace io
-
-struct GLFWwindow;
-struct ImFont;
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace globals
-{
-extern io::ConfigMap client_config;
-
-extern GLFWwindow* window;
-
-// Some gamesystems that aren't really
-// gameplay-oriented might still use client
-// framerate to interpolate discrete things
-// so it's still a good idea to keep these available
-extern float window_frametime;
-extern float window_frametime_avg;
-extern std::uint64_t window_frametime_us;
-extern std::uint64_t window_framecount;
-
-// https://gafferongames.com/post/fix_your_timestep/
-extern std::uint64_t fixed_accumulator;
-
-extern int width;
-extern int height;
-extern float aspect;
-
-extern GLuint world_fbo;
-extern GLuint world_fbo_color;
-extern GLuint world_fbo_depth;
-
-extern std::size_t num_drawcalls;
-extern std::size_t num_triangles;
-
-extern ENetHost* client_host;
-
-extern world::Dimension* dimension;
-extern entt::entity player;
-
-extern ImFont* font_unscii16;
-extern ImFont* font_unscii8;
-
-extern config::KeyBind* gui_keybind_ptr;
-extern config::GamepadAxis* gui_gamepad_axis_ptr;
-extern config::GamepadButton* gui_gamepad_button_ptr;
-
-extern unsigned int gui_scale;
-extern unsigned int gui_screen;
-
-extern ALCdevice* sound_dev;
-extern ALCcontext* sound_ctx;
-} // namespace globals
+#pragma once + +#include "shared/globals.hh" + +namespace config +{ +class KeyBind; +class GamepadAxis; +class GamepadButton; +} // namespace config + +namespace io +{ +class ConfigMap; +} // namespace io + +struct GLFWwindow; +struct ImFont; + +namespace world +{ +class Dimension; +} // namespace world + +namespace globals +{ +extern io::ConfigMap client_config; + +extern GLFWwindow* window; + +// Some gamesystems that aren't really +// gameplay-oriented might still use client +// framerate to interpolate discrete things +// so it's still a good idea to keep these available +extern float window_frametime; +extern float window_frametime_avg; +extern std::uint64_t window_frametime_us; +extern std::uint64_t window_framecount; + +// https://gafferongames.com/post/fix_your_timestep/ +extern std::uint64_t fixed_accumulator; + +extern int width; +extern int height; +extern float aspect; + +extern GLuint world_fbo; +extern GLuint world_fbo_color; +extern GLuint world_fbo_depth; + +extern std::size_t num_drawcalls; +extern std::size_t num_triangles; + +extern ENetHost* client_host; + +extern world::Dimension* dimension; +extern entt::entity player; + +extern ImFont* font_unscii16; +extern ImFont* font_unscii8; + +extern config::KeyBind* gui_keybind_ptr; +extern config::GamepadAxis* gui_gamepad_axis_ptr; +extern config::GamepadButton* gui_gamepad_button_ptr; + +extern unsigned int gui_scale; +extern unsigned int gui_screen; + +extern ALCdevice* sound_dev; +extern ALCcontext* sound_ctx; +} // namespace globals diff --git a/game/client/gui/CMakeLists.txt b/src/game/client/gui/CMakeLists.txt index 46d64a1..46d64a1 100644 --- a/game/client/gui/CMakeLists.txt +++ b/src/game/client/gui/CMakeLists.txt diff --git a/game/client/gui/background.cc b/src/game/client/gui/background.cc index d1500bb..50fef01 100644 --- a/game/client/gui/background.cc +++ b/src/game/client/gui/background.cc @@ -1,39 +1,39 @@ -#include "client/pch.hh"
-
-#include "client/gui/background.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-static resource_ptr<TextureGUI> texture;
-
-void gui::background::init(void)
-{
- texture = resource::load<TextureGUI>("textures/gui/background.png", TEXTURE_GUI_LOAD_VFLIP);
-
- if(texture == nullptr) {
- spdlog::critical("background: texture load failed");
- std::terminate();
- }
-}
-
-void gui::background::shutdown(void)
-{
- texture = nullptr;
-}
-
-void gui::background::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetBackgroundDrawList();
-
- auto scaled_width = 0.75f * static_cast<float>(globals::width / globals::gui_scale);
- auto scaled_height = 0.75f * static_cast<float>(globals::height / globals::gui_scale);
- auto scale_uv = ImVec2(scaled_width / static_cast<float>(texture->size.x), scaled_height / static_cast<float>(texture->size.y));
- draw_list->AddImage(texture->handle, ImVec2(0.0f, 0.0f), viewport->Size, ImVec2(0.0f, 0.0f), scale_uv);
-}
+#include "client/pch.hh" + +#include "client/gui/background.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/resource.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/globals.hh" + +static resource_ptr<TextureGUI> texture; + +void gui::background::init(void) +{ + texture = resource::load<TextureGUI>("textures/gui/background.png", TEXTURE_GUI_LOAD_VFLIP); + + if(texture == nullptr) { + spdlog::critical("background: texture load failed"); + std::terminate(); + } +} + +void gui::background::shutdown(void) +{ + texture = nullptr; +} + +void gui::background::layout(void) +{ + auto viewport = ImGui::GetMainViewport(); + auto draw_list = ImGui::GetBackgroundDrawList(); + + auto scaled_width = 0.75f * static_cast<float>(globals::width / globals::gui_scale); + auto scaled_height = 0.75f * static_cast<float>(globals::height / globals::gui_scale); + auto scale_uv = ImVec2(scaled_width / static_cast<float>(texture->size.x), scaled_height / static_cast<float>(texture->size.y)); + draw_list->AddImage(texture->handle, ImVec2(0.0f, 0.0f), viewport->Size, ImVec2(0.0f, 0.0f), scale_uv); +} diff --git a/game/client/gui/background.hh b/src/game/client/gui/background.hh index 6145484..5c72a3f 100644 --- a/game/client/gui/background.hh +++ b/src/game/client/gui/background.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace gui::background
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::background
+#pragma once + +namespace gui::background +{ +void init(void); +void shutdown(void); +void layout(void); +} // namespace gui::background diff --git a/game/client/gui/bother.cc b/src/game/client/gui/bother.cc index e87b9ff..a045284 100644 --- a/game/client/gui/bother.cc +++ b/src/game/client/gui/bother.cc @@ -1,167 +1,167 @@ -#include "client/pch.hh"
-
-#include "client/gui/bother.hh"
-
-#include "core/version.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/globals.hh"
-
-// Maximum amount of peers used for bothering
-constexpr static std::size_t BOTHER_PEERS = 4;
-
-struct BotherQueueItem final {
- unsigned int identity;
- std::string hostname;
- std::uint16_t port;
-};
-
-static ENetHost* bother_host;
-static entt::dispatcher bother_dispatcher;
-static std::unordered_set<unsigned int> bother_set;
-static std::deque<BotherQueueItem> bother_queue;
-
-static void on_status_response_packet(const protocol::StatusResponse& packet)
-{
- auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(packet.peer->data));
-
- bother_set.erase(identity);
-
- gui::BotherResponseEvent event;
- event.identity = identity;
- event.is_server_unreachable = false;
- event.num_players = packet.num_players;
- event.max_players = packet.max_players;
- event.motd = packet.motd;
- event.game_version_major = packet.game_version_major;
- event.game_version_minor = packet.game_version_minor;
- event.game_version_patch = packet.game_version_patch;
- globals::dispatcher.trigger(event);
-
- enet_peer_disconnect(packet.peer, protocol::CHANNEL);
-}
-
-void gui::bother::init(void)
-{
- bother_host = enet_host_create(nullptr, BOTHER_PEERS, 1, 0, 0);
- bother_dispatcher.clear();
- bother_set.clear();
-
- bother_dispatcher.sink<protocol::StatusResponse>().connect<&on_status_response_packet>();
-}
-
-void gui::bother::shutdown(void)
-{
- enet_host_destroy(bother_host);
- bother_dispatcher.clear();
- bother_set.clear();
-}
-
-void gui::bother::update_late(void)
-{
- unsigned int free_peers = 0U;
-
- // Figure out how much times we can call
- // enet_host_connect and reallistically succeed
- for(unsigned int i = 0U; i < bother_host->peerCount; ++i) {
- if(bother_host->peers[i].state != ENET_PEER_STATE_DISCONNECTED) {
- continue;
- }
-
- free_peers += 1U;
- }
-
- for(unsigned int i = 0U; (i < free_peers) && bother_queue.size(); ++i) {
- const auto& item = bother_queue.front();
-
- ENetAddress address;
- enet_address_set_host(&address, item.hostname.c_str());
- address.port = enet_uint16(item.port);
-
- if(auto peer = enet_host_connect(bother_host, &address, 1, 0)) {
- peer->data = reinterpret_cast<void*>(static_cast<std::uintptr_t>(item.identity));
- bother_set.insert(item.identity);
- enet_host_flush(bother_host);
- }
-
- bother_queue.pop_front();
- }
-
- ENetEvent enet_event;
-
- if(0 < enet_host_service(bother_host, &enet_event, 0)) {
- if(enet_event.type == ENET_EVENT_TYPE_CONNECT) {
- protocol::StatusRequest packet;
- packet.game_version_major = version::major;
- protocol::send(enet_event.peer, protocol::encode(packet));
- return;
- }
-
- if(enet_event.type == ENET_EVENT_TYPE_RECEIVE) {
- protocol::decode(bother_dispatcher, enet_event.packet, enet_event.peer);
- enet_packet_destroy(enet_event.packet);
- return;
- }
-
- if(enet_event.type == ENET_EVENT_TYPE_DISCONNECT) {
- auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(enet_event.peer->data));
-
- if(bother_set.count(identity)) {
- BotherResponseEvent event;
- event.identity = identity;
- event.is_server_unreachable = true;
- globals::dispatcher.trigger(event);
- }
-
- bother_set.erase(identity);
-
- return;
- }
- }
-}
-
-void gui::bother::ping(unsigned int identity, std::string_view host, std::uint16_t port)
-{
- if(bother_set.count(identity)) {
- // Already in the process
- return;
- }
-
- for(const auto& item : bother_queue) {
- if(item.identity == identity) {
- // Already in the queue
- return;
- }
- }
-
- BotherQueueItem item;
- item.identity = identity;
- item.hostname = host;
- item.port = port;
-
- bother_queue.push_back(item);
-}
-
-void gui::bother::cancel(unsigned int identity)
-{
- bother_set.erase(identity);
-
- auto item = bother_queue.cbegin();
-
- while(item != bother_queue.cend()) {
- if(item->identity == identity) {
- item = bother_queue.erase(item);
- continue;
- }
-
- item = std::next(item);
- }
-
- for(unsigned int i = 0U; i < bother_host->peerCount; ++i) {
- if(bother_host->peers[i].data == reinterpret_cast<void*>(static_cast<std::uintptr_t>(identity))) {
- enet_peer_reset(&bother_host->peers[i]);
- break;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/gui/bother.hh" + +#include "core/version.hh" + +#include "shared/protocol.hh" + +#include "client/globals.hh" + +// Maximum amount of peers used for bothering +constexpr static std::size_t BOTHER_PEERS = 4; + +struct BotherQueueItem final { + unsigned int identity; + std::string hostname; + std::uint16_t port; +}; + +static ENetHost* bother_host; +static entt::dispatcher bother_dispatcher; +static std::unordered_set<unsigned int> bother_set; +static std::deque<BotherQueueItem> bother_queue; + +static void on_status_response_packet(const protocol::StatusResponse& packet) +{ + auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(packet.peer->data)); + + bother_set.erase(identity); + + gui::BotherResponseEvent event; + event.identity = identity; + event.is_server_unreachable = false; + event.num_players = packet.num_players; + event.max_players = packet.max_players; + event.motd = packet.motd; + event.game_version_major = packet.game_version_major; + event.game_version_minor = packet.game_version_minor; + event.game_version_patch = packet.game_version_patch; + globals::dispatcher.trigger(event); + + enet_peer_disconnect(packet.peer, protocol::CHANNEL); +} + +void gui::bother::init(void) +{ + bother_host = enet_host_create(nullptr, BOTHER_PEERS, 1, 0, 0); + bother_dispatcher.clear(); + bother_set.clear(); + + bother_dispatcher.sink<protocol::StatusResponse>().connect<&on_status_response_packet>(); +} + +void gui::bother::shutdown(void) +{ + enet_host_destroy(bother_host); + bother_dispatcher.clear(); + bother_set.clear(); +} + +void gui::bother::update_late(void) +{ + unsigned int free_peers = 0U; + + // Figure out how much times we can call + // enet_host_connect and reallistically succeed + for(unsigned int i = 0U; i < bother_host->peerCount; ++i) { + if(bother_host->peers[i].state != ENET_PEER_STATE_DISCONNECTED) { + continue; + } + + free_peers += 1U; + } + + for(unsigned int i = 0U; (i < free_peers) && bother_queue.size(); ++i) { + const auto& item = bother_queue.front(); + + ENetAddress address; + enet_address_set_host(&address, item.hostname.c_str()); + address.port = enet_uint16(item.port); + + if(auto peer = enet_host_connect(bother_host, &address, 1, 0)) { + peer->data = reinterpret_cast<void*>(static_cast<std::uintptr_t>(item.identity)); + bother_set.insert(item.identity); + enet_host_flush(bother_host); + } + + bother_queue.pop_front(); + } + + ENetEvent enet_event; + + if(0 < enet_host_service(bother_host, &enet_event, 0)) { + if(enet_event.type == ENET_EVENT_TYPE_CONNECT) { + protocol::StatusRequest packet; + packet.game_version_major = version::major; + protocol::send(enet_event.peer, protocol::encode(packet)); + return; + } + + if(enet_event.type == ENET_EVENT_TYPE_RECEIVE) { + protocol::decode(bother_dispatcher, enet_event.packet, enet_event.peer); + enet_packet_destroy(enet_event.packet); + return; + } + + if(enet_event.type == ENET_EVENT_TYPE_DISCONNECT) { + auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(enet_event.peer->data)); + + if(bother_set.count(identity)) { + BotherResponseEvent event; + event.identity = identity; + event.is_server_unreachable = true; + globals::dispatcher.trigger(event); + } + + bother_set.erase(identity); + + return; + } + } +} + +void gui::bother::ping(unsigned int identity, std::string_view host, std::uint16_t port) +{ + if(bother_set.count(identity)) { + // Already in the process + return; + } + + for(const auto& item : bother_queue) { + if(item.identity == identity) { + // Already in the queue + return; + } + } + + BotherQueueItem item; + item.identity = identity; + item.hostname = host; + item.port = port; + + bother_queue.push_back(item); +} + +void gui::bother::cancel(unsigned int identity) +{ + bother_set.erase(identity); + + auto item = bother_queue.cbegin(); + + while(item != bother_queue.cend()) { + if(item->identity == identity) { + item = bother_queue.erase(item); + continue; + } + + item = std::next(item); + } + + for(unsigned int i = 0U; i < bother_host->peerCount; ++i) { + if(bother_host->peers[i].data == reinterpret_cast<void*>(static_cast<std::uintptr_t>(identity))) { + enet_peer_reset(&bother_host->peers[i]); + break; + } + } +} diff --git a/game/client/gui/bother.hh b/src/game/client/gui/bother.hh index 75e56d1..b0355ca 100644 --- a/game/client/gui/bother.hh +++ b/src/game/client/gui/bother.hh @@ -1,24 +1,24 @@ -#pragma once
-
-namespace gui
-{
-struct BotherResponseEvent final {
- unsigned int identity;
- bool is_server_unreachable;
- std::uint16_t num_players;
- std::uint16_t max_players;
- std::uint32_t game_version_major;
- std::uint32_t game_version_minor;
- std::uint32_t game_version_patch;
- std::string motd;
-};
-} // namespace gui
-
-namespace gui::bother
-{
-void init(void);
-void shutdown(void);
-void update_late(void);
-void ping(unsigned int identity, std::string_view host, std::uint16_t port);
-void cancel(unsigned int identity);
-} // namespace gui::bother
+#pragma once + +namespace gui +{ +struct BotherResponseEvent final { + unsigned int identity; + bool is_server_unreachable; + std::uint16_t num_players; + std::uint16_t max_players; + std::uint32_t game_version_major; + std::uint32_t game_version_minor; + std::uint32_t game_version_patch; + std::string motd; +}; +} // namespace gui + +namespace gui::bother +{ +void init(void); +void shutdown(void); +void update_late(void); +void ping(unsigned int identity, std::string_view host, std::uint16_t port); +void cancel(unsigned int identity); +} // namespace gui::bother diff --git a/game/client/gui/chat.cc b/src/game/client/gui/chat.cc index aaee8c6..70a1668 100644 --- a/game/client/gui/chat.cc +++ b/src/game/client/gui/chat.cc @@ -1,273 +1,273 @@ -#include "client/pch.hh"
-
-#include "client/gui/chat.hh"
-
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/utils/string.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/imdraw_ext.hh"
-#include "client/gui/language.hh"
-#include "client/gui/settings.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/sound_effect.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static unsigned int MAX_HISTORY_SIZE = 128U;
-
-struct GuiChatMessage final {
- std::uint64_t spawn;
- std::string text;
- ImVec4 color;
-};
-
-static config::KeyBind key_chat(GLFW_KEY_ENTER);
-static config::Unsigned history_size(32U, 0U, MAX_HISTORY_SIZE);
-
-static std::deque<GuiChatMessage> history;
-static std::string chat_input;
-static bool needs_focus;
-
-static resource_ptr<SoundEffect> sfx_chat_message;
-
-static void append_text_message(const std::string& sender, const std::string& text)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("<{}> {}", sender, text);
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void append_player_join(const std::string& sender)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("{} {}", sender, gui::language::resolve("chat.client_join"));
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void append_player_leave(const std::string& sender, const std::string& reason)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("{} {} ({})", sender, gui::language::resolve("chat.client_left"), gui::language::resolve(reason.c_str()));
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void on_chat_message_packet(const protocol::ChatMessage& packet)
-{
- if(packet.type == protocol::ChatMessage::TEXT_MESSAGE) {
- append_text_message(packet.sender, packet.message);
- return;
- }
-
- if(packet.type == protocol::ChatMessage::PLAYER_JOIN) {
- append_player_join(packet.sender);
- return;
- }
-
- if(packet.type == protocol::ChatMessage::PLAYER_LEAVE) {
- append_player_leave(packet.sender, packet.message);
- return;
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(event.action == GLFW_PRESS) {
- if((event.key == GLFW_KEY_ENTER) && (globals::gui_screen == GUI_CHAT)) {
- if(!utils::is_whitespace(chat_input)) {
- protocol::ChatMessage packet;
- packet.type = protocol::ChatMessage::TEXT_MESSAGE;
- packet.sender = client_game::username.get();
- packet.message = chat_input;
-
- protocol::send(session::peer, protocol::encode(packet));
- }
-
- globals::gui_screen = GUI_SCREEN_NONE;
-
- chat_input.clear();
-
- return;
- }
-
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_CHAT)) {
- globals::gui_screen = GUI_SCREEN_NONE;
- return;
- }
-
- if(key_chat.equals(event.key) && !globals::gui_screen) {
- globals::gui_screen = GUI_CHAT;
- needs_focus = true;
- return;
- }
- }
-}
-
-void gui::client_chat::init(void)
-{
- globals::client_config.add_value("chat.key", key_chat);
- globals::client_config.add_value("chat.history_size", history_size);
-
- settings::add_keybind(2, key_chat, settings_location::KEYBOARD_MISC, "key.chat");
- settings::add_slider(1, history_size, settings_location::VIDEO_GUI, "chat.history_size", false);
-
- globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>();
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
-
- sfx_chat_message = resource::load<SoundEffect>("sounds/ui/chat_message.wav");
-}
-
-void gui::client_chat::init_late(void)
-{
-}
-
-void gui::client_chat::shutdown(void)
-{
- sfx_chat_message = nullptr;
-}
-
-void gui::client_chat::update(void)
-{
- while(history.size() > history_size.get_value()) {
- history.pop_front();
- }
-}
-
-void gui::client_chat::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.0f, 0.0f);
- auto window_size = ImVec2(0.75f * viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- ImGui::PushFont(globals::font_unscii16, 8.0f);
-
- if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) {
- ImGui::End();
- return;
- }
-
- auto& padding = ImGui::GetStyle().FramePadding;
- auto& spacing = ImGui::GetStyle().ItemSpacing;
- auto font = ImGui::GetFont();
-
- auto draw_list = ImGui::GetWindowDrawList();
-
- // The text input widget occupies the bottom part
- // of the chat window, we need to reserve some space for it
- auto ypos = window_size.y - 2.5f * ImGui::GetFontSize() - 2.0f * padding.y - 2.0f * spacing.y;
-
- if(globals::gui_screen == GUI_CHAT) {
- if(needs_focus) {
- ImGui::SetKeyboardFocusHere();
- needs_focus = false;
- }
-
- ImGui::SetNextItemWidth(window_size.x + 32.0f * padding.x);
- ImGui::SetCursorScreenPos(ImVec2(padding.x, ypos));
- ImGui::InputText("###chat.input", &chat_input);
- }
-
- if(!client_game::hide_hud && ((globals::gui_screen == GUI_SCREEN_NONE) || (globals::gui_screen == GUI_CHAT))) {
- for(auto it = history.crbegin(); it < history.crend(); ++it) {
- auto text_size = ImGui::CalcTextSize(it->text.c_str(), it->text.c_str() + it->text.size(), false, window_size.x);
- auto rect_size = ImVec2(window_size.x, text_size.y + 2.0f * padding.y);
-
- auto rect_pos = ImVec2(padding.x, ypos - text_size.y - 2.0f * padding.y);
- auto rect_end = ImVec2(rect_pos.x + rect_size.x, rect_pos.y + rect_size.y);
- auto text_pos = ImVec2(rect_pos.x + padding.x, rect_pos.y + padding.y);
-
- auto fadeout_seconds = 10.0f;
- auto fadeout = std::exp(-1.0f * std::pow(1.0e-6 * static_cast<float>(globals::curtime - it->spawn) / fadeout_seconds, 10.0f));
-
- float rect_alpha;
- float text_alpha;
-
- if(globals::gui_screen == GUI_CHAT) {
- rect_alpha = 0.75f;
- text_alpha = 1.00f;
- }
- else {
- rect_alpha = 0.50f * fadeout;
- text_alpha = 1.00f * fadeout;
- }
-
- auto rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, rect_alpha);
- auto text_col = ImGui::GetColorU32(ImVec4(it->color.x, it->color.y, it->color.z, it->color.w * text_alpha));
- auto shadow_col = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, text_alpha));
-
- draw_list->AddRectFilled(rect_pos, rect_end, rect_col);
-
- imdraw_ext::text_shadow_w(it->text, text_pos, text_col, shadow_col, font, draw_list, 8.0f, window_size.x);
-
- ypos -= rect_size.y;
- }
- }
-
- ImGui::End();
- ImGui::PopFont();
-}
-
-void gui::client_chat::clear(void)
-{
- history.clear();
-}
-
-void gui::client_chat::refresh_timings(void)
-{
- for(auto it = history.begin(); it < history.end(); ++it) {
- // Reset the spawn time so the fadeout timer
- // is reset; SpawnPlayer handler might call this
- it->spawn = globals::curtime;
- }
-}
-
-void gui::client_chat::print(const std::string& text)
-{
- GuiChatMessage message = {};
- message.spawn = globals::curtime;
- message.text = text;
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
+#include "client/pch.hh" + +#include "client/gui/chat.hh" + +#include "core/config/number.hh" +#include "core/config/string.hh" + +#include "core/io/config_map.hh" + +#include "core/resource/resource.hh" + +#include "core/utils/string.hh" + +#include "shared/protocol.hh" + +#include "client/config/keybind.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/imdraw_ext.hh" +#include "client/gui/language.hh" +#include "client/gui/settings.hh" + +#include "client/io/glfw.hh" + +#include "client/resource/sound_effect.hh" + +#include "client/sound/sound.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; +constexpr static unsigned int MAX_HISTORY_SIZE = 128U; + +struct GuiChatMessage final { + std::uint64_t spawn; + std::string text; + ImVec4 color; +}; + +static config::KeyBind key_chat(GLFW_KEY_ENTER); +static config::Unsigned history_size(32U, 0U, MAX_HISTORY_SIZE); + +static std::deque<GuiChatMessage> history; +static std::string chat_input; +static bool needs_focus; + +static resource_ptr<SoundEffect> sfx_chat_message; + +static void append_text_message(const std::string& sender, const std::string& text) +{ + GuiChatMessage message; + message.spawn = globals::curtime; + message.text = std::format("<{}> {}", sender, text); + message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text); + history.push_back(message); + + if(sfx_chat_message && session::is_ingame()) { + sound::play_ui(sfx_chat_message, false, 1.0f); + } +} + +static void append_player_join(const std::string& sender) +{ + GuiChatMessage message; + message.spawn = globals::curtime; + message.text = std::format("{} {}", sender, gui::language::resolve("chat.client_join")); + message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget); + history.push_back(message); + + if(sfx_chat_message && session::is_ingame()) { + sound::play_ui(sfx_chat_message, false, 1.0f); + } +} + +static void append_player_leave(const std::string& sender, const std::string& reason) +{ + GuiChatMessage message; + message.spawn = globals::curtime; + message.text = std::format("{} {} ({})", sender, gui::language::resolve("chat.client_left"), gui::language::resolve(reason.c_str())); + message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget); + history.push_back(message); + + if(sfx_chat_message && session::is_ingame()) { + sound::play_ui(sfx_chat_message, false, 1.0f); + } +} + +static void on_chat_message_packet(const protocol::ChatMessage& packet) +{ + if(packet.type == protocol::ChatMessage::TEXT_MESSAGE) { + append_text_message(packet.sender, packet.message); + return; + } + + if(packet.type == protocol::ChatMessage::PLAYER_JOIN) { + append_player_join(packet.sender); + return; + } + + if(packet.type == protocol::ChatMessage::PLAYER_LEAVE) { + append_player_leave(packet.sender, packet.message); + return; + } +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if(event.action == GLFW_PRESS) { + if((event.key == GLFW_KEY_ENTER) && (globals::gui_screen == GUI_CHAT)) { + if(!utils::is_whitespace(chat_input)) { + protocol::ChatMessage packet; + packet.type = protocol::ChatMessage::TEXT_MESSAGE; + packet.sender = client_game::username.get(); + packet.message = chat_input; + + protocol::send(session::peer, protocol::encode(packet)); + } + + globals::gui_screen = GUI_SCREEN_NONE; + + chat_input.clear(); + + return; + } + + if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_CHAT)) { + globals::gui_screen = GUI_SCREEN_NONE; + return; + } + + if(key_chat.equals(event.key) && !globals::gui_screen) { + globals::gui_screen = GUI_CHAT; + needs_focus = true; + return; + } + } +} + +void gui::client_chat::init(void) +{ + globals::client_config.add_value("chat.key", key_chat); + globals::client_config.add_value("chat.history_size", history_size); + + settings::add_keybind(2, key_chat, settings_location::KEYBOARD_MISC, "key.chat"); + settings::add_slider(1, history_size, settings_location::VIDEO_GUI, "chat.history_size", false); + + globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>(); + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + + sfx_chat_message = resource::load<SoundEffect>("sounds/ui/chat_message.wav"); +} + +void gui::client_chat::init_late(void) +{ +} + +void gui::client_chat::shutdown(void) +{ + sfx_chat_message = nullptr; +} + +void gui::client_chat::update(void) +{ + while(history.size() > history_size.get_value()) { + history.pop_front(); + } +} + +void gui::client_chat::layout(void) +{ + auto viewport = ImGui::GetMainViewport(); + auto window_start = ImVec2(0.0f, 0.0f); + auto window_size = ImVec2(0.75f * viewport->Size.x, viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + ImGui::PushFont(globals::font_unscii16, 8.0f); + + if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) { + ImGui::End(); + return; + } + + auto& padding = ImGui::GetStyle().FramePadding; + auto& spacing = ImGui::GetStyle().ItemSpacing; + auto font = ImGui::GetFont(); + + auto draw_list = ImGui::GetWindowDrawList(); + + // The text input widget occupies the bottom part + // of the chat window, we need to reserve some space for it + auto ypos = window_size.y - 2.5f * ImGui::GetFontSize() - 2.0f * padding.y - 2.0f * spacing.y; + + if(globals::gui_screen == GUI_CHAT) { + if(needs_focus) { + ImGui::SetKeyboardFocusHere(); + needs_focus = false; + } + + ImGui::SetNextItemWidth(window_size.x + 32.0f * padding.x); + ImGui::SetCursorScreenPos(ImVec2(padding.x, ypos)); + ImGui::InputText("###chat.input", &chat_input); + } + + if(!client_game::hide_hud && ((globals::gui_screen == GUI_SCREEN_NONE) || (globals::gui_screen == GUI_CHAT))) { + for(auto it = history.crbegin(); it < history.crend(); ++it) { + auto text_size = ImGui::CalcTextSize(it->text.c_str(), it->text.c_str() + it->text.size(), false, window_size.x); + auto rect_size = ImVec2(window_size.x, text_size.y + 2.0f * padding.y); + + auto rect_pos = ImVec2(padding.x, ypos - text_size.y - 2.0f * padding.y); + auto rect_end = ImVec2(rect_pos.x + rect_size.x, rect_pos.y + rect_size.y); + auto text_pos = ImVec2(rect_pos.x + padding.x, rect_pos.y + padding.y); + + auto fadeout_seconds = 10.0f; + auto fadeout = std::exp(-1.0f * std::pow(1.0e-6f * static_cast<float>(globals::curtime - it->spawn) / fadeout_seconds, 10.0f)); + + float rect_alpha; + float text_alpha; + + if(globals::gui_screen == GUI_CHAT) { + rect_alpha = 0.75f; + text_alpha = 1.00f; + } + else { + rect_alpha = 0.50f * fadeout; + text_alpha = 1.00f * fadeout; + } + + auto rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, rect_alpha); + auto text_col = ImGui::GetColorU32(ImVec4(it->color.x, it->color.y, it->color.z, it->color.w * text_alpha)); + auto shadow_col = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, text_alpha)); + + draw_list->AddRectFilled(rect_pos, rect_end, rect_col); + + imdraw_ext::text_shadow_w(it->text, text_pos, text_col, shadow_col, font, draw_list, 8.0f, window_size.x); + + ypos -= rect_size.y; + } + } + + ImGui::End(); + ImGui::PopFont(); +} + +void gui::client_chat::clear(void) +{ + history.clear(); +} + +void gui::client_chat::refresh_timings(void) +{ + for(auto it = history.begin(); it < history.end(); ++it) { + // Reset the spawn time so the fadeout timer + // is reset; SpawnPlayer handler might call this + it->spawn = globals::curtime; + } +} + +void gui::client_chat::print(const std::string& text) +{ + GuiChatMessage message = {}; + message.spawn = globals::curtime; + message.text = text; + message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text); + history.push_back(message); + + if(sfx_chat_message && session::is_ingame()) { + sound::play_ui(sfx_chat_message, false, 1.0f); + } +} diff --git a/game/client/gui/chat.hh b/src/game/client/gui/chat.hh index 2fc6fb3..6a3ea33 100644 --- a/game/client/gui/chat.hh +++ b/src/game/client/gui/chat.hh @@ -1,17 +1,17 @@ -#pragma once
-
-namespace gui::client_chat
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void update(void);
-void layout(void);
-} // namespace gui::client_chat
-
-namespace gui::client_chat
-{
-void clear(void);
-void refresh_timings(void);
-void print(const std::string& string);
-} // namespace gui::client_chat
+#pragma once + +namespace gui::client_chat +{ +void init(void); +void init_late(void); +void shutdown(void); +void update(void); +void layout(void); +} // namespace gui::client_chat + +namespace gui::client_chat +{ +void clear(void); +void refresh_timings(void); +void print(const std::string& string); +} // namespace gui::client_chat diff --git a/game/client/gui/crosshair.cc b/src/game/client/gui/crosshair.cc index 2e6eeba..649602f 100644 --- a/game/client/gui/crosshair.cc +++ b/src/game/client/gui/crosshair.cc @@ -1,43 +1,43 @@ -#include "client/pch.hh"
-
-#include "client/gui/crosshair.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-static resource_ptr<TextureGUI> texture;
-
-void gui::crosshair::init(void)
-{
- texture = resource::load<TextureGUI>("textures/gui/hud_crosshair.png",
- TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T | TEXTURE_GUI_LOAD_VFLIP);
-
- if(texture == nullptr) {
- spdlog::critical("crosshair: texture load failed");
- std::terminate();
- }
-}
-
-void gui::crosshair::shutdown(void)
-{
- texture = nullptr;
-}
-
-void gui::crosshair::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- auto scaled_width = glm::max<int>(texture->size.x, globals::gui_scale * texture->size.x / 2);
- auto scaled_height = glm::max<int>(texture->size.y, globals::gui_scale * texture->size.y / 2);
- auto start = ImVec2(static_cast<int>(0.5f * viewport->Size.x) - (scaled_width / 2),
- static_cast<int>(0.5f * viewport->Size.y) - (scaled_height / 2));
- auto end = ImVec2(start.x + scaled_width, start.y + scaled_height);
- draw_list->AddImage(texture->handle, start, end);
-}
+#include "client/pch.hh" + +#include "client/gui/crosshair.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/resource.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +static resource_ptr<TextureGUI> texture; + +void gui::crosshair::init(void) +{ + texture = resource::load<TextureGUI>("textures/gui/hud_crosshair.png", + TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T | TEXTURE_GUI_LOAD_VFLIP); + + if(texture == nullptr) { + spdlog::critical("crosshair: texture load failed"); + std::terminate(); + } +} + +void gui::crosshair::shutdown(void) +{ + texture = nullptr; +} + +void gui::crosshair::layout(void) +{ + auto viewport = ImGui::GetMainViewport(); + auto draw_list = ImGui::GetForegroundDrawList(); + + auto scaled_width = glm::max<int>(texture->size.x, static_cast<int>(globals::gui_scale * texture->size.x / 2.0f)); + auto scaled_height = glm::max<int>(texture->size.y, static_cast<int>(globals::gui_scale * texture->size.y / 2.0f)); + auto start = ImVec2(static_cast<int>(0.5f * viewport->Size.x) - (scaled_width / 2.0f), + static_cast<float>(static_cast<int>(0.5f * viewport->Size.y) - (scaled_height / 2.0f))); + auto end = ImVec2(start.x + scaled_width, start.y + scaled_height); + draw_list->AddImage(texture->handle, start, end); +} diff --git a/game/client/gui/crosshair.hh b/src/game/client/gui/crosshair.hh index dca5725..589727e 100644 --- a/game/client/gui/crosshair.hh +++ b/src/game/client/gui/crosshair.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace gui::crosshair
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::crosshair
+#pragma once + +namespace gui::crosshair +{ +void init(void); +void shutdown(void); +void layout(void); +} // namespace gui::crosshair diff --git a/game/client/gui/direct_connection.cc b/src/game/client/gui/direct_connection.cc index c521232..39ea2b5 100644 --- a/game/client/gui/direct_connection.cc +++ b/src/game/client/gui/direct_connection.cc @@ -1,145 +1,145 @@ -#include "client/pch.hh"
-
-#include "client/gui/direct_connection.hh"
-
-#include "core/config/boolean.hh"
-
-#include "core/utils/string.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_title;
-static std::string str_connect;
-static std::string str_cancel;
-
-static std::string str_hostname;
-static std::string str_password;
-
-static std::string direct_hostname;
-static std::string direct_password;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_DIRECT_CONNECTION) {
- globals::gui_screen = GUI_PLAY_MENU;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_title = gui::language::resolve("direct_connection.title");
- str_connect = gui::language::resolve_gui("direct_connection.connect");
- str_cancel = gui::language::resolve_gui("direct_connection.cancel");
-
- str_hostname = gui::language::resolve("direct_connection.hostname");
- str_password = gui::language::resolve("direct_connection.password");
-}
-
-static void connect_to_server(void)
-{
- auto parts = utils::split(direct_hostname, ":");
- std::string parsed_hostname;
- std::uint16_t parsed_port;
-
- if(!parts[0].empty()) {
- parsed_hostname = parts[0];
- }
- else {
- parsed_hostname = std::string("localhost");
- }
-
- if(parts.size() >= 2) {
- parsed_port = glm::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX);
- }
- else {
- parsed_port = protocol::PORT;
- }
-
- session::connect(parsed_hostname.c_str(), parsed_port, direct_password.c_str());
-}
-
-void gui::direct_connection::init(void)
-{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void gui::direct_connection::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.25f * viewport->Size.x, 0.20f * viewport->Size.y);
- auto window_size = ImVec2(0.50f * viewport->Size.x, 0.80f * viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIDirectConnect", nullptr, WINDOW_FLAGS)) {
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 16.0f * globals::gui_scale));
-
- ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank;
-
- if(client_game::streamer_mode.get_value()) {
- // Hide server hostname to avoid things like
- // followers flooding the server that is streamed online
- hostname_flags |= ImGuiInputTextFlags_Password;
- }
-
- auto avail_width = ImGui::GetContentRegionAvail().x;
-
- ImGui::PushItemWidth(avail_width);
-
- ImGui::InputText("###UIDirectConnect_hostname", &direct_hostname, hostname_flags);
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_hostname.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- ImGui::InputText("###UIDirectConnect_password", &direct_password, ImGuiInputTextFlags_Password);
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_password.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- ImGui::PopItemWidth();
-
- ImGui::Dummy(ImVec2(0.0f, 4.0f * globals::gui_scale));
-
- ImGui::BeginDisabled(utils::is_whitespace(direct_hostname));
-
- if(ImGui::Button(str_connect.c_str(), ImVec2(avail_width, 0.0f))) {
- connect_to_server();
- }
-
- ImGui::EndDisabled();
-
- if(ImGui::Button(str_cancel.c_str(), ImVec2(avail_width, 0.0f))) {
- globals::gui_screen = GUI_PLAY_MENU;
- }
- }
-
- ImGui::End();
-}
+#include "client/pch.hh" + +#include "client/gui/direct_connection.hh" + +#include "core/config/boolean.hh" + +#include "core/utils/string.hh" + +#include "shared/protocol.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" + +#include "client/io/glfw.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +static std::string str_title; +static std::string str_connect; +static std::string str_cancel; + +static std::string str_hostname; +static std::string str_password; + +static std::string direct_hostname; +static std::string direct_password; + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) { + if(globals::gui_screen == GUI_DIRECT_CONNECTION) { + globals::gui_screen = GUI_PLAY_MENU; + return; + } + } +} + +static void on_language_set(const gui::LanguageSetEvent& event) +{ + str_title = gui::language::resolve("direct_connection.title"); + str_connect = gui::language::resolve_gui("direct_connection.connect"); + str_cancel = gui::language::resolve_gui("direct_connection.cancel"); + + str_hostname = gui::language::resolve("direct_connection.hostname"); + str_password = gui::language::resolve("direct_connection.password"); +} + +static void connect_to_server(void) +{ + auto parts = utils::split(direct_hostname, ":"); + std::string parsed_hostname; + std::uint16_t parsed_port; + + if(!parts[0].empty()) { + parsed_hostname = parts[0]; + } + else { + parsed_hostname = std::string("localhost"); + } + + if(parts.size() >= 2) { + parsed_port = glm::clamp<std::uint16_t>(static_cast<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10)), 1024U, UINT16_MAX); + } + else { + parsed_port = protocol::PORT; + } + + session::connect(parsed_hostname.c_str(), parsed_port, direct_password.c_str()); +} + +void gui::direct_connection::init(void) +{ + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>(); +} + +void gui::direct_connection::layout(void) +{ + auto viewport = ImGui::GetMainViewport(); + auto window_start = ImVec2(0.25f * viewport->Size.x, 0.20f * viewport->Size.y); + auto window_size = ImVec2(0.50f * viewport->Size.x, 0.80f * viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###UIDirectConnect", nullptr, WINDOW_FLAGS)) { + const float title_width = ImGui::CalcTextSize(str_title.c_str()).x; + ImGui::SetCursorPosX(0.5f * (window_size.x - title_width)); + ImGui::TextUnformatted(str_title.c_str()); + + ImGui::Dummy(ImVec2(0.0f, 16.0f * globals::gui_scale)); + + ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank; + + if(client_game::streamer_mode.get_value()) { + // Hide server hostname to avoid things like + // followers flooding the server that is streamed online + hostname_flags |= ImGuiInputTextFlags_Password; + } + + auto avail_width = ImGui::GetContentRegionAvail().x; + + ImGui::PushItemWidth(avail_width); + + ImGui::InputText("###UIDirectConnect_hostname", &direct_hostname, hostname_flags); + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(str_hostname.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::InputText("###UIDirectConnect_password", &direct_password, ImGuiInputTextFlags_Password); + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(str_password.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::PopItemWidth(); + + ImGui::Dummy(ImVec2(0.0f, 4.0f * globals::gui_scale)); + + ImGui::BeginDisabled(utils::is_whitespace(direct_hostname)); + + if(ImGui::Button(str_connect.c_str(), ImVec2(avail_width, 0.0f))) { + connect_to_server(); + } + + ImGui::EndDisabled(); + + if(ImGui::Button(str_cancel.c_str(), ImVec2(avail_width, 0.0f))) { + globals::gui_screen = GUI_PLAY_MENU; + } + } + + ImGui::End(); +} diff --git a/game/client/gui/direct_connection.hh b/src/game/client/gui/direct_connection.hh index c63156b..aa02d7c 100644 --- a/game/client/gui/direct_connection.hh +++ b/src/game/client/gui/direct_connection.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace gui::direct_connection
-{
-void init(void);
-void layout(void);
-} // namespace gui::direct_connection
+#pragma once + +namespace gui::direct_connection +{ +void init(void); +void layout(void); +} // namespace gui::direct_connection diff --git a/game/client/gui/gui_screen.hh b/src/game/client/gui/gui_screen.hh index c29f701..2eae310 100644 --- a/game/client/gui/gui_screen.hh +++ b/src/game/client/gui/gui_screen.hh @@ -1,10 +1,10 @@ -#pragma once
-
-constexpr static unsigned int GUI_SCREEN_NONE = 0x0000U;
-constexpr static unsigned int GUI_MAIN_MENU = 0x0001U;
-constexpr static unsigned int GUI_PLAY_MENU = 0x0002U;
-constexpr static unsigned int GUI_SETTINGS = 0x0003U;
-constexpr static unsigned int GUI_PROGRESS_BAR = 0x0004U;
-constexpr static unsigned int GUI_MESSAGE_BOX = 0x0005U;
-constexpr static unsigned int GUI_CHAT = 0x0006U;
-constexpr static unsigned int GUI_DIRECT_CONNECTION = 0x0007U;
+#pragma once + +constexpr static unsigned int GUI_SCREEN_NONE = 0x0000U; +constexpr static unsigned int GUI_MAIN_MENU = 0x0001U; +constexpr static unsigned int GUI_PLAY_MENU = 0x0002U; +constexpr static unsigned int GUI_SETTINGS = 0x0003U; +constexpr static unsigned int GUI_PROGRESS_BAR = 0x0004U; +constexpr static unsigned int GUI_MESSAGE_BOX = 0x0005U; +constexpr static unsigned int GUI_CHAT = 0x0006U; +constexpr static unsigned int GUI_DIRECT_CONNECTION = 0x0007U; diff --git a/game/client/gui/hotbar.cc b/src/game/client/gui/hotbar.cc index e9458dd..663f263 100644 --- a/game/client/gui/hotbar.cc +++ b/src/game/client/gui/hotbar.cc @@ -1,182 +1,182 @@ -#include "client/pch.hh"
-
-#include "client/gui/hotbar.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/resource/resource.hh"
-
-#include "shared/world/item_registry.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/settings.hh"
-#include "client/gui/status_lines.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-constexpr static float ITEM_SIZE = 20.0f;
-constexpr static float ITEM_PADDING = 2.0f;
-constexpr static float SELECTOR_PADDING = 1.0f;
-constexpr static float HOTBAR_PADDING = 2.0f;
-
-unsigned int gui::hotbar::active_slot = 0U;
-std::array<const world::Item*, HOTBAR_SIZE> gui::hotbar::slots = {};
-
-static config::KeyBind hotbar_keys[HOTBAR_SIZE];
-
-static resource_ptr<TextureGUI> hotbar_background;
-static resource_ptr<TextureGUI> hotbar_selector;
-
-static ImU32 get_color_alpha(ImGuiCol style_color, float alpha)
-{
- const auto& color = ImGui::GetStyleColorVec4(style_color);
- return ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, alpha));
-}
-
-static void update_hotbar_item(void)
-{
- auto current_item = gui::hotbar::slots[gui::hotbar::active_slot];
-
- if(current_item == nullptr) {
- gui::status_lines::unset(gui::STATUS_HOTBAR);
- }
- else {
- gui::status_lines::set(gui::STATUS_HOTBAR, current_item->get_name(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), 5.0f);
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.action == GLFW_PRESS) && !globals::gui_screen) {
- for(unsigned int i = 0U; i < HOTBAR_SIZE; ++i) {
- if(hotbar_keys[i].equals(event.key)) {
- gui::hotbar::active_slot = i;
- update_hotbar_item();
- break;
- }
- }
- }
-}
-
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
-{
- if(!globals::gui_screen) {
- if(event.dy < 0.0) {
- gui::hotbar::next_slot();
- return;
- }
-
- if(event.dy > 0.0) {
- gui::hotbar::prev_slot();
- return;
- }
- }
-}
-
-void gui::hotbar::init(void)
-{
- hotbar_keys[0].set_key(GLFW_KEY_1);
- hotbar_keys[1].set_key(GLFW_KEY_2);
- hotbar_keys[2].set_key(GLFW_KEY_3);
- hotbar_keys[3].set_key(GLFW_KEY_4);
- hotbar_keys[4].set_key(GLFW_KEY_5);
- hotbar_keys[5].set_key(GLFW_KEY_6);
- hotbar_keys[6].set_key(GLFW_KEY_7);
- hotbar_keys[7].set_key(GLFW_KEY_8);
- hotbar_keys[8].set_key(GLFW_KEY_9);
-
- globals::client_config.add_value("hotbar.key.0", hotbar_keys[0]);
- globals::client_config.add_value("hotbar.key.1", hotbar_keys[1]);
- globals::client_config.add_value("hotbar.key.3", hotbar_keys[2]);
- globals::client_config.add_value("hotbar.key.4", hotbar_keys[3]);
- globals::client_config.add_value("hotbar.key.5", hotbar_keys[4]);
- globals::client_config.add_value("hotbar.key.6", hotbar_keys[5]);
- globals::client_config.add_value("hotbar.key.7", hotbar_keys[6]);
- globals::client_config.add_value("hotbar.key.8", hotbar_keys[7]);
- globals::client_config.add_value("hotbar.key.9", hotbar_keys[8]);
-
- settings::add_keybind(10, hotbar_keys[0], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.0");
- settings::add_keybind(11, hotbar_keys[1], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.1");
- settings::add_keybind(12, hotbar_keys[2], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.2");
- settings::add_keybind(13, hotbar_keys[3], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.3");
- settings::add_keybind(14, hotbar_keys[4], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.4");
- settings::add_keybind(15, hotbar_keys[5], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.5");
- settings::add_keybind(16, hotbar_keys[6], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.6");
- settings::add_keybind(17, hotbar_keys[7], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.7");
- settings::add_keybind(18, hotbar_keys[8], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.8");
-
- hotbar_background = resource::load<TextureGUI>("textures/gui/hud_hotbar.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
- hotbar_selector = resource::load<TextureGUI>("textures/gui/hud_selector.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
-}
-
-void gui::hotbar::shutdown(void)
-{
- hotbar_background = nullptr;
- hotbar_selector = nullptr;
-}
-
-void gui::hotbar::layout(void)
-{
- auto& style = ImGui::GetStyle();
-
- auto item_size = ITEM_SIZE * globals::gui_scale;
- auto hotbar_width = HOTBAR_SIZE * item_size;
- auto hotbar_padding = HOTBAR_PADDING * globals::gui_scale;
-
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- // Draw the hotbar background image
- auto background_start = ImVec2(0.5f * viewport->Size.x - 0.5f * hotbar_width, viewport->Size.y - item_size - hotbar_padding);
- auto background_end = ImVec2(background_start.x + hotbar_width, background_start.y + item_size);
- draw_list->AddImage(hotbar_background->handle, background_start, background_end);
-
- // Draw the hotbar selector image
- auto selector_padding_a = SELECTOR_PADDING * globals::gui_scale;
- auto selector_padding_b = SELECTOR_PADDING * globals::gui_scale * 2.0f;
- auto selector_start = ImVec2(background_start.x + gui::hotbar::active_slot * item_size - selector_padding_a,
- background_start.y - selector_padding_a);
- auto selector_end = ImVec2(selector_start.x + item_size + selector_padding_b, selector_start.y + item_size + selector_padding_b);
- draw_list->AddImage(hotbar_selector->handle, selector_start, selector_end);
-
- // Figure out item texture padding values
- auto item_padding_a = ITEM_PADDING * globals::gui_scale;
- auto item_padding_b = ITEM_PADDING * globals::gui_scale * 2.0f;
-
- // Draw individual item textures in the hotbar
- for(std::size_t i = 0; i < HOTBAR_SIZE; ++i) {
- auto item = gui::hotbar::slots[i];
-
- if((item == nullptr) || (item->get_cached_texture() == nullptr)) {
- // There's either no item in the slot
- // or the item doesn't have a texture
- continue;
- }
-
- const auto item_start = ImVec2(background_start.x + i * item_size + item_padding_a, background_start.y + item_padding_a);
- const auto item_end = ImVec2(item_start.x + item_size - item_padding_b, item_start.y + item_size - item_padding_b);
- draw_list->AddImage(item->get_cached_texture()->handle, item_start, item_end);
- }
-}
-
-void gui::hotbar::next_slot(void)
-{
- gui::hotbar::active_slot += 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
- update_hotbar_item();
-}
-
-void gui::hotbar::prev_slot(void)
-{
- gui::hotbar::active_slot += HOTBAR_SIZE - 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
- update_hotbar_item();
-}
+#include "client/pch.hh" + +#include "client/gui/hotbar.hh" + +#include "core/io/config_map.hh" + +#include "core/resource/resource.hh" + +#include "shared/world/item_registry.hh" + +#include "client/config/keybind.hh" + +#include "client/gui/settings.hh" +#include "client/gui/status_lines.hh" + +#include "client/io/glfw.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/globals.hh" + +constexpr static float ITEM_SIZE = 20.0f; +constexpr static float ITEM_PADDING = 2.0f; +constexpr static float SELECTOR_PADDING = 1.0f; +constexpr static float HOTBAR_PADDING = 2.0f; + +unsigned int gui::hotbar::active_slot = 0U; +std::array<const world::Item*, HOTBAR_SIZE> gui::hotbar::slots = {}; + +static config::KeyBind hotbar_keys[HOTBAR_SIZE]; + +static resource_ptr<TextureGUI> hotbar_background; +static resource_ptr<TextureGUI> hotbar_selector; + +static ImU32 get_color_alpha(ImGuiCol style_color, float alpha) +{ + const auto& color = ImGui::GetStyleColorVec4(style_color); + return ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, alpha)); +} + +static void update_hotbar_item(void) +{ + auto current_item = gui::hotbar::slots[gui::hotbar::active_slot]; + + if(current_item == nullptr) { + gui::status_lines::unset(gui::STATUS_HOTBAR); + } + else { + gui::status_lines::set(gui::STATUS_HOTBAR, current_item->get_name(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), 5.0f); + } +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if((event.action == GLFW_PRESS) && !globals::gui_screen) { + for(unsigned int i = 0U; i < HOTBAR_SIZE; ++i) { + if(hotbar_keys[i].equals(event.key)) { + gui::hotbar::active_slot = i; + update_hotbar_item(); + break; + } + } + } +} + +static void on_glfw_scroll(const io::GlfwScrollEvent& event) +{ + if(!globals::gui_screen) { + if(event.dy < 0.0) { + gui::hotbar::next_slot(); + return; + } + + if(event.dy > 0.0) { + gui::hotbar::prev_slot(); + return; + } + } +} + +void gui::hotbar::init(void) +{ + hotbar_keys[0].set_key(GLFW_KEY_1); + hotbar_keys[1].set_key(GLFW_KEY_2); + hotbar_keys[2].set_key(GLFW_KEY_3); + hotbar_keys[3].set_key(GLFW_KEY_4); + hotbar_keys[4].set_key(GLFW_KEY_5); + hotbar_keys[5].set_key(GLFW_KEY_6); + hotbar_keys[6].set_key(GLFW_KEY_7); + hotbar_keys[7].set_key(GLFW_KEY_8); + hotbar_keys[8].set_key(GLFW_KEY_9); + + globals::client_config.add_value("hotbar.key.0", hotbar_keys[0]); + globals::client_config.add_value("hotbar.key.1", hotbar_keys[1]); + globals::client_config.add_value("hotbar.key.3", hotbar_keys[2]); + globals::client_config.add_value("hotbar.key.4", hotbar_keys[3]); + globals::client_config.add_value("hotbar.key.5", hotbar_keys[4]); + globals::client_config.add_value("hotbar.key.6", hotbar_keys[5]); + globals::client_config.add_value("hotbar.key.7", hotbar_keys[6]); + globals::client_config.add_value("hotbar.key.8", hotbar_keys[7]); + globals::client_config.add_value("hotbar.key.9", hotbar_keys[8]); + + settings::add_keybind(10, hotbar_keys[0], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.0"); + settings::add_keybind(11, hotbar_keys[1], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.1"); + settings::add_keybind(12, hotbar_keys[2], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.2"); + settings::add_keybind(13, hotbar_keys[3], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.3"); + settings::add_keybind(14, hotbar_keys[4], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.4"); + settings::add_keybind(15, hotbar_keys[5], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.5"); + settings::add_keybind(16, hotbar_keys[6], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.6"); + settings::add_keybind(17, hotbar_keys[7], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.7"); + settings::add_keybind(18, hotbar_keys[8], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.8"); + + hotbar_background = resource::load<TextureGUI>("textures/gui/hud_hotbar.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T); + hotbar_selector = resource::load<TextureGUI>("textures/gui/hud_selector.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T); + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>(); +} + +void gui::hotbar::shutdown(void) +{ + hotbar_background = nullptr; + hotbar_selector = nullptr; +} + +void gui::hotbar::layout(void) +{ + auto& style = ImGui::GetStyle(); + + auto item_size = ITEM_SIZE * globals::gui_scale; + auto hotbar_width = HOTBAR_SIZE * item_size; + auto hotbar_padding = HOTBAR_PADDING * globals::gui_scale; + + auto viewport = ImGui::GetMainViewport(); + auto draw_list = ImGui::GetForegroundDrawList(); + + // Draw the hotbar background image + auto background_start = ImVec2(0.5f * viewport->Size.x - 0.5f * hotbar_width, viewport->Size.y - item_size - hotbar_padding); + auto background_end = ImVec2(background_start.x + hotbar_width, background_start.y + item_size); + draw_list->AddImage(hotbar_background->handle, background_start, background_end); + + // Draw the hotbar selector image + auto selector_padding_a = SELECTOR_PADDING * globals::gui_scale; + auto selector_padding_b = SELECTOR_PADDING * globals::gui_scale * 2.0f; + auto selector_start = ImVec2(background_start.x + gui::hotbar::active_slot * item_size - selector_padding_a, + background_start.y - selector_padding_a); + auto selector_end = ImVec2(selector_start.x + item_size + selector_padding_b, selector_start.y + item_size + selector_padding_b); + draw_list->AddImage(hotbar_selector->handle, selector_start, selector_end); + + // Figure out item texture padding values + auto item_padding_a = ITEM_PADDING * globals::gui_scale; + auto item_padding_b = ITEM_PADDING * globals::gui_scale * 2.0f; + + // Draw individual item textures in the hotbar + for(std::size_t i = 0; i < HOTBAR_SIZE; ++i) { + auto item = gui::hotbar::slots[i]; + + if((item == nullptr) || (item->get_cached_texture() == nullptr)) { + // There's either no item in the slot + // or the item doesn't have a texture + continue; + } + + const auto item_start = ImVec2(background_start.x + i * item_size + item_padding_a, background_start.y + item_padding_a); + const auto item_end = ImVec2(item_start.x + item_size - item_padding_b, item_start.y + item_size - item_padding_b); + draw_list->AddImage(item->get_cached_texture()->handle, item_start, item_end); + } +} + +void gui::hotbar::next_slot(void) +{ + gui::hotbar::active_slot += 1U; + gui::hotbar::active_slot %= HOTBAR_SIZE; + update_hotbar_item(); +} + +void gui::hotbar::prev_slot(void) +{ + gui::hotbar::active_slot += HOTBAR_SIZE - 1U; + gui::hotbar::active_slot %= HOTBAR_SIZE; + update_hotbar_item(); +} diff --git a/game/client/gui/hotbar.hh b/src/game/client/gui/hotbar.hh index 223dbc9..c529230 100644 --- a/game/client/gui/hotbar.hh +++ b/src/game/client/gui/hotbar.hh @@ -1,30 +1,30 @@ -#pragma once
-
-// TODO: design an inventory system and an item
-// registry and integrate the hotbar into that system
-
-namespace world
-{
-class Item;
-} // namespace world
-
-constexpr static unsigned int HOTBAR_SIZE = 9U;
-
-namespace gui::hotbar
-{
-extern unsigned int active_slot;
-extern std::array<const world::Item*, HOTBAR_SIZE> slots;
-} // namespace gui::hotbar
-
-namespace gui::hotbar
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::hotbar
-
-namespace gui::hotbar
-{
-void next_slot(void);
-void prev_slot(void);
-} // namespace gui::hotbar
+#pragma once + +// TODO: design an inventory system and an item +// registry and integrate the hotbar into that system + +namespace world +{ +class Item; +} // namespace world + +constexpr static unsigned int HOTBAR_SIZE = 9U; + +namespace gui::hotbar +{ +extern unsigned int active_slot; +extern std::array<const world::Item*, HOTBAR_SIZE> slots; +} // namespace gui::hotbar + +namespace gui::hotbar +{ +void init(void); +void shutdown(void); +void layout(void); +} // namespace gui::hotbar + +namespace gui::hotbar +{ +void next_slot(void); +void prev_slot(void); +} // namespace gui::hotbar diff --git a/game/client/gui/imdraw_ext.cc b/src/game/client/gui/imdraw_ext.cc index c3d40c9..4b44d5f 100644 --- a/game/client/gui/imdraw_ext.cc +++ b/src/game/client/gui/imdraw_ext.cc @@ -1,34 +1,34 @@ -#include "client/pch.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/globals.hh"
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list)
-{
- imdraw_ext::text_shadow(text, position, text_color, shadow_color, font, draw_list, font->LegacySize);
-}
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size());
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size());
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width)
-{
- imdraw_ext::text_shadow_w(text, position, text_color, shadow_color, font, draw_list, font->LegacySize, wrap_width);
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size(),
- wrap_width);
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size(), wrap_width);
-}
+#include "client/pch.hh" + +#include "client/gui/imdraw_ext.hh" + +#include "client/globals.hh" + +void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list) +{ + imdraw_ext::text_shadow(text, position, text_color, shadow_color, font, draw_list, font->LegacySize); +} + +void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list, float font_size) +{ + const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale); + draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size()); + draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size()); +} + +void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list, float wrap_width) +{ + imdraw_ext::text_shadow_w(text, position, text_color, shadow_color, font, draw_list, font->LegacySize, wrap_width); +} + +void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list, float font_size, float wrap_width) +{ + const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale); + draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size(), + wrap_width); + draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size(), wrap_width); +} diff --git a/game/client/gui/imdraw_ext.hh b/src/game/client/gui/imdraw_ext.hh index e1475b2..a7e1503 100644 --- a/game/client/gui/imdraw_ext.hh +++ b/src/game/client/gui/imdraw_ext.hh @@ -1,17 +1,17 @@ -#pragma once
-
-namespace gui::imdraw_ext
-{
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list);
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, ImDrawList* draw_list,
- float font_size);
-} // namespace gui::imdraw_ext
-
-namespace gui::imdraw_ext
-{
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width);
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width);
-} // namespace gui::imdraw_ext
+#pragma once + +namespace gui::imdraw_ext +{ +void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list); +void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, ImDrawList* draw_list, + float font_size); +} // namespace gui::imdraw_ext + +namespace gui::imdraw_ext +{ +void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list, float wrap_width); +void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, + ImDrawList* draw_list, float font_size, float wrap_width); +} // namespace gui::imdraw_ext diff --git a/game/client/gui/language.cc b/src/game/client/gui/language.cc index d10f88b..0109ae6 100644 --- a/game/client/gui/language.cc +++ b/src/game/client/gui/language.cc @@ -1,202 +1,202 @@ -#include "client/pch.hh"
-
-#include "client/gui/language.hh"
-
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-#include "core/io/physfs.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/globals.hh"
-
-constexpr static std::string_view DEFAULT_LANGUAGE = "en_US";
-
-// Available languages are kept in a special manifest file which
-// is essentially a key-value map of semi-IETF-compliant language tags
-// and the language's endonym; after reading the manifest, the translation
-// system knows what language it can load and will act accordingly
-constexpr static std::string_view MANIFEST_PATH = "lang/manifest.json";
-
-static gui::LanguageManifest manifest;
-static gui::LanguageIterator current_language;
-static std::unordered_map<std::string, std::string> language_map;
-static std::unordered_map<std::string, gui::LanguageIterator> ietf_map;
-static config::String config_language(DEFAULT_LANGUAGE);
-
-static void send_language_event(gui::LanguageIterator new_language)
-{
- gui::LanguageSetEvent event;
- event.new_language = new_language;
- globals::dispatcher.trigger(event);
-}
-
-void gui::language::init(void)
-{
- globals::client_config.add_value("language", config_language);
-
- settings::add_language_select(0, settings_location::GENERAL, "language");
-
- auto file = PHYSFS_openRead(std::string(MANIFEST_PATH).c_str());
-
- if(file == nullptr) {
- spdlog::critical("language: {}: {}", MANIFEST_PATH, io::physfs_error());
- std::terminate();
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::critical("language: {}: parse error", MANIFEST_PATH);
- json_value_free(jsonv);
- std::terminate();
- }
-
- for(std::size_t i = 0; i < count; ++i) {
- const auto ietf = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto endonym = json_value_get_string(value);
-
- if(ietf && endonym) {
- LanguageInfo info;
- info.ietf = std::string(ietf);
- info.endonym = std::string(endonym);
- info.display = std::format("{} ({})", endonym, ietf);
- manifest.push_back(info);
- }
- }
-
- for(auto it = manifest.cbegin(); it != manifest.cend(); ++it) {
- ietf_map.emplace(it->ietf, it);
- }
-
- json_value_free(jsonv);
-
- // This is temporary! This value will
- // be overriden in init_late after the
- // config system updates config_language
- current_language = manifest.cend();
-}
-
-void gui::language::init_late(void)
-{
- auto user_language = ietf_map.find(config_language.get_value());
-
- if(user_language != ietf_map.cend()) {
- gui::language::set(user_language->second);
- return;
- }
-
- auto fallback = ietf_map.find(std::string(DEFAULT_LANGUAGE));
-
- if(fallback != ietf_map.cend()) {
- gui::language::set(fallback->second);
- return;
- }
-
- spdlog::critical("language: we're doomed!");
- spdlog::critical("language: {} doesn't exist!", DEFAULT_LANGUAGE);
- std::terminate();
-}
-
-void gui::language::set(LanguageIterator new_language)
-{
- if(new_language != manifest.cend()) {
- auto path = std::format("lang/lang.{}.json", new_language->ietf);
-
- auto file = PHYSFS_openRead(path.c_str());
-
- if(file == nullptr) {
- spdlog::warn("language: {}: {}", path, io::physfs_error());
- send_language_event(new_language);
- return;
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::warn("language: {}: parse error", path);
- send_language_event(new_language);
- json_value_free(jsonv);
- return;
- }
-
- language_map.clear();
-
- for(size_t i = 0; i < count; ++i) {
- const auto key = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto value_str = json_value_get_string(value);
-
- if(key && value_str) {
- language_map.emplace(key, value_str);
- continue;
- }
- }
-
- json_value_free(jsonv);
-
- current_language = new_language;
- config_language.set(new_language->ietf.c_str());
- }
-
- send_language_event(new_language);
-}
-
-gui::LanguageIterator gui::language::get_current(void)
-{
- return current_language;
-}
-
-gui::LanguageIterator gui::language::find(std::string_view ietf)
-{
- const auto it = ietf_map.find(std::string(ietf));
- if(it != ietf_map.cend()) {
- return it->second;
- }
- else {
- return manifest.cend();
- }
-}
-
-gui::LanguageIterator gui::language::cbegin(void)
-{
- return manifest.cbegin();
-}
-
-gui::LanguageIterator gui::language::cend(void)
-{
- return manifest.cend();
-}
-
-std::string_view gui::language::resolve(std::string_view key)
-{
- const auto it = language_map.find(std::string(key));
-
- if(it != language_map.cend()) {
- return it->second;
- }
-
- return key;
-}
-
-std::string gui::language::resolve_gui(std::string_view key)
-{
- // We need window tags to retain their hierarchy when a language
- // dynamically changes; ImGui allows to provide hidden unique identifiers
- // to GUI primitives that have their name change dynamically, so we're using this
- return std::format("{}###{}", gui::language::resolve(key), key);
-}
+#include "client/pch.hh" + +#include "client/gui/language.hh" + +#include "core/config/string.hh" + +#include "core/io/config_map.hh" +#include "core/io/physfs.hh" + +#include "client/gui/settings.hh" + +#include "client/globals.hh" + +constexpr static std::string_view DEFAULT_LANGUAGE = "en_US"; + +// Available languages are kept in a special manifest file which +// is essentially a key-value map of semi-IETF-compliant language tags +// and the language's endonym; after reading the manifest, the translation +// system knows what language it can load and will act accordingly +constexpr static std::string_view MANIFEST_PATH = "lang/manifest.json"; + +static gui::LanguageManifest manifest; +static gui::LanguageIterator current_language; +static std::unordered_map<std::string, std::string> language_map; +static std::unordered_map<std::string, gui::LanguageIterator> ietf_map; +static config::String config_language(DEFAULT_LANGUAGE); + +static void send_language_event(gui::LanguageIterator new_language) +{ + gui::LanguageSetEvent event; + event.new_language = new_language; + globals::dispatcher.trigger(event); +} + +void gui::language::init(void) +{ + globals::client_config.add_value("language", config_language); + + settings::add_language_select(0, settings_location::GENERAL, "language"); + + auto file = PHYSFS_openRead(std::string(MANIFEST_PATH).c_str()); + + if(file == nullptr) { + spdlog::critical("language: {}: {}", MANIFEST_PATH, io::physfs_error()); + std::terminate(); + } + + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + auto jsonv = json_parse_string(source.c_str()); + const auto json = json_value_get_object(jsonv); + const auto count = json_object_get_count(json); + + if((jsonv == nullptr) || (json == nullptr) || (count == 0)) { + spdlog::critical("language: {}: parse error", MANIFEST_PATH); + json_value_free(jsonv); + std::terminate(); + } + + for(std::size_t i = 0; i < count; ++i) { + const auto ietf = json_object_get_name(json, i); + const auto value = json_object_get_value_at(json, i); + const auto endonym = json_value_get_string(value); + + if(ietf && endonym) { + LanguageInfo info; + info.ietf = std::string(ietf); + info.endonym = std::string(endonym); + info.display = std::format("{} ({})", endonym, ietf); + manifest.push_back(info); + } + } + + for(auto it = manifest.cbegin(); it != manifest.cend(); ++it) { + ietf_map.emplace(it->ietf, it); + } + + json_value_free(jsonv); + + // This is temporary! This value will + // be overriden in init_late after the + // config system updates config_language + current_language = manifest.cend(); +} + +void gui::language::init_late(void) +{ + auto user_language = ietf_map.find(config_language.get_value()); + + if(user_language != ietf_map.cend()) { + gui::language::set(user_language->second); + return; + } + + auto fallback = ietf_map.find(std::string(DEFAULT_LANGUAGE)); + + if(fallback != ietf_map.cend()) { + gui::language::set(fallback->second); + return; + } + + spdlog::critical("language: we're doomed!"); + spdlog::critical("language: {} doesn't exist!", DEFAULT_LANGUAGE); + std::terminate(); +} + +void gui::language::set(LanguageIterator new_language) +{ + if(new_language != manifest.cend()) { + auto path = std::format("lang/lang.{}.json", new_language->ietf); + + auto file = PHYSFS_openRead(path.c_str()); + + if(file == nullptr) { + spdlog::warn("language: {}: {}", path, io::physfs_error()); + send_language_event(new_language); + return; + } + + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + auto jsonv = json_parse_string(source.c_str()); + const auto json = json_value_get_object(jsonv); + const auto count = json_object_get_count(json); + + if((jsonv == nullptr) || (json == nullptr) || (count == 0)) { + spdlog::warn("language: {}: parse error", path); + send_language_event(new_language); + json_value_free(jsonv); + return; + } + + language_map.clear(); + + for(size_t i = 0; i < count; ++i) { + const auto key = json_object_get_name(json, i); + const auto value = json_object_get_value_at(json, i); + const auto value_str = json_value_get_string(value); + + if(key && value_str) { + language_map.emplace(key, value_str); + continue; + } + } + + json_value_free(jsonv); + + current_language = new_language; + config_language.set(new_language->ietf.c_str()); + } + + send_language_event(new_language); +} + +gui::LanguageIterator gui::language::get_current(void) +{ + return current_language; +} + +gui::LanguageIterator gui::language::find(std::string_view ietf) +{ + const auto it = ietf_map.find(std::string(ietf)); + if(it != ietf_map.cend()) { + return it->second; + } + else { + return manifest.cend(); + } +} + +gui::LanguageIterator gui::language::cbegin(void) +{ + return manifest.cbegin(); +} + +gui::LanguageIterator gui::language::cend(void) +{ + return manifest.cend(); +} + +std::string_view gui::language::resolve(std::string_view key) +{ + const auto it = language_map.find(std::string(key)); + + if(it != language_map.cend()) { + return it->second; + } + + return key; +} + +std::string gui::language::resolve_gui(std::string_view key) +{ + // We need window tags to retain their hierarchy when a language + // dynamically changes; ImGui allows to provide hidden unique identifiers + // to GUI primitives that have their name change dynamically, so we're using this + return std::format("{}###{}", gui::language::resolve(key), key); +} diff --git a/game/client/gui/language.hh b/src/game/client/gui/language.hh index 0628941..90132d7 100644 --- a/game/client/gui/language.hh +++ b/src/game/client/gui/language.hh @@ -1,42 +1,42 @@ -#pragma once
-
-namespace gui
-{
-struct LanguageInfo final {
- std::string endonym; // Language's self-name
- std::string display; // Display for the settings GUI
- std::string ietf; // Semi-compliant language abbreviation
-};
-
-using LanguageManifest = std::vector<LanguageInfo>;
-using LanguageIterator = LanguageManifest::const_iterator;
-
-struct LanguageSetEvent final {
- LanguageIterator new_language;
-};
-} // namespace gui
-
-namespace gui::language
-{
-void init(void);
-void init_late(void);
-} // namespace gui::language
-
-namespace gui::language
-{
-void set(LanguageIterator new_language);
-} // namespace gui::language
-
-namespace gui::language
-{
-LanguageIterator get_current(void);
-LanguageIterator find(std::string_view ietf);
-LanguageIterator cbegin(void);
-LanguageIterator cend(void);
-} // namespace gui::language
-
-namespace gui::language
-{
-std::string_view resolve(std::string_view key);
-std::string resolve_gui(std::string_view key);
-} // namespace gui::language
+#pragma once + +namespace gui +{ +struct LanguageInfo final { + std::string endonym; // Language's self-name + std::string display; // Display for the settings GUI + std::string ietf; // Semi-compliant language abbreviation +}; + +using LanguageManifest = std::vector<LanguageInfo>; +using LanguageIterator = LanguageManifest::const_iterator; + +struct LanguageSetEvent final { + LanguageIterator new_language; +}; +} // namespace gui + +namespace gui::language +{ +void init(void); +void init_late(void); +} // namespace gui::language + +namespace gui::language +{ +void set(LanguageIterator new_language); +} // namespace gui::language + +namespace gui::language +{ +LanguageIterator get_current(void); +LanguageIterator find(std::string_view ietf); +LanguageIterator cbegin(void); +LanguageIterator cend(void); +} // namespace gui::language + +namespace gui::language +{ +std::string_view resolve(std::string_view key); +std::string resolve_gui(std::string_view key); +} // namespace gui::language diff --git a/game/client/gui/main_menu.cc b/src/game/client/gui/main_menu.cc index 6c0ee37..d60a507 100644 --- a/game/client/gui/main_menu.cc +++ b/src/game/client/gui/main_menu.cc @@ -1,172 +1,172 @@ -#include "client/pch.hh"
-
-#include "client/gui/main_menu.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/version.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-#include "client/gui/window_title.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_play;
-static std::string str_resume;
-static std::string str_settings;
-static std::string str_leave;
-static std::string str_quit;
-
-static resource_ptr<TextureGUI> title;
-static float title_aspect;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(session::is_ingame() && (event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_SCREEN_NONE) {
- globals::gui_screen = GUI_MAIN_MENU;
- return;
- }
-
- if(globals::gui_screen == GUI_MAIN_MENU) {
- globals::gui_screen = GUI_SCREEN_NONE;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_play = gui::language::resolve_gui("main_menu.play");
- str_resume = gui::language::resolve_gui("main_menu.resume");
- str_settings = gui::language::resolve("main_menu.settings");
- str_leave = gui::language::resolve("main_menu.leave");
- str_quit = gui::language::resolve("main_menu.quit");
-}
-
-void gui::main_menu::init(void)
-{
- title = resource::load<TextureGUI>("textures/gui/menu_title.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
-
- if(title == nullptr) {
- spdlog::critical("main_menu: texture load failed");
- std::terminate();
- }
-
- if(title->size.x > title->size.y) {
- title_aspect = static_cast<float>(title->size.x) / static_cast<float>(title->size.y);
- }
- else {
- title_aspect = static_cast<float>(title->size.y) / static_cast<float>(title->size.x);
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void gui::main_menu::shutdown(void)
-{
- title = nullptr;
-}
-
-void gui::main_menu::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.15f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###main_menu", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 2.0f * globals::gui_scale));
-
- if(session::is_ingame()) {
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
- }
- else {
- auto reference_height = 0.225f * window_size.y;
- auto image_width = glm::min(window_size.x, reference_height * title_aspect);
- auto image_height = image_width / title_aspect;
- ImGui::SetCursorPosX(0.5f * (window_size.x - image_width));
- ImGui::Image(title->handle, ImVec2(image_width, image_height));
- }
-
- ImGui::Dummy(ImVec2(0.0f, 24.0f * globals::gui_scale));
-
- const float button_width = 240.0f * globals::gui_scale;
- const float button_xpos = 0.5f * (window_size.x - button_width);
-
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_resume.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SCREEN_NONE;
- }
-
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_play.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_PLAY_MENU;
- }
-
- ImGui::Spacing();
- }
-
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_settings.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SETTINGS;
- }
-
- ImGui::Spacing();
-
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_leave.c_str(), ImVec2(button_width, 0.0f))) {
- session::disconnect("protocol.client_disconnect");
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- }
-
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_quit.c_str(), ImVec2(button_width, 0.0f))) {
- glfwSetWindowShouldClose(globals::window, true);
- }
-
- ImGui::Spacing();
- }
-
- if(!session::is_ingame()) {
- const auto& padding = ImGui::GetStyle().FramePadding;
- const auto& spacing = ImGui::GetStyle().ItemSpacing;
-
- ImGui::PushFont(globals::font_unscii8, 4.0f);
- ImGui::SetCursorScreenPos(ImVec2(padding.x + spacing.x, window_size.y - ImGui::GetFontSize() - padding.y - spacing.y));
- ImGui::Text("Voxelius %*s", version::semver.size(), version::semver.data()); // string_view is not always null-terminated
- ImGui::PopFont();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
+#include "client/pch.hh" + +#include "client/gui/main_menu.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/resource.hh" + +#include "core/version.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" +#include "client/gui/window_title.hh" + +#include "client/io/glfw.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +static std::string str_play; +static std::string str_resume; +static std::string str_settings; +static std::string str_leave; +static std::string str_quit; + +static resource_ptr<TextureGUI> title; +static float title_aspect; + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if(session::is_ingame() && (event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) { + if(globals::gui_screen == GUI_SCREEN_NONE) { + globals::gui_screen = GUI_MAIN_MENU; + return; + } + + if(globals::gui_screen == GUI_MAIN_MENU) { + globals::gui_screen = GUI_SCREEN_NONE; + return; + } + } +} + +static void on_language_set(const gui::LanguageSetEvent& event) +{ + str_play = gui::language::resolve_gui("main_menu.play"); + str_resume = gui::language::resolve_gui("main_menu.resume"); + str_settings = gui::language::resolve("main_menu.settings"); + str_leave = gui::language::resolve("main_menu.leave"); + str_quit = gui::language::resolve("main_menu.quit"); +} + +void gui::main_menu::init(void) +{ + title = resource::load<TextureGUI>("textures/gui/menu_title.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T); + + if(title == nullptr) { + spdlog::critical("main_menu: texture load failed"); + std::terminate(); + } + + if(title->size.x > title->size.y) { + title_aspect = static_cast<float>(title->size.x) / static_cast<float>(title->size.y); + } + else { + title_aspect = static_cast<float>(title->size.y) / static_cast<float>(title->size.x); + } + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>(); +} + +void gui::main_menu::shutdown(void) +{ + title = nullptr; +} + +void gui::main_menu::layout(void) +{ + const auto viewport = ImGui::GetMainViewport(); + const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.15f); + const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###main_menu", nullptr, WINDOW_FLAGS)) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 2.0f * globals::gui_scale)); + + if(session::is_ingame()) { + ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale)); + } + else { + auto reference_height = 0.225f * window_size.y; + auto image_width = glm::min(window_size.x, reference_height * title_aspect); + auto image_height = image_width / title_aspect; + ImGui::SetCursorPosX(0.5f * (window_size.x - image_width)); + ImGui::Image(title->handle, ImVec2(image_width, image_height)); + } + + ImGui::Dummy(ImVec2(0.0f, 24.0f * globals::gui_scale)); + + const float button_width = 240.0f * globals::gui_scale; + const float button_xpos = 0.5f * (window_size.x - button_width); + + if(session::is_ingame()) { + ImGui::SetCursorPosX(button_xpos); + + if(ImGui::Button(str_resume.c_str(), ImVec2(button_width, 0.0f))) { + globals::gui_screen = GUI_SCREEN_NONE; + } + + ImGui::Spacing(); + } + else { + ImGui::SetCursorPosX(button_xpos); + + if(ImGui::Button(str_play.c_str(), ImVec2(button_width, 0.0f))) { + globals::gui_screen = GUI_PLAY_MENU; + } + + ImGui::Spacing(); + } + + ImGui::SetCursorPosX(button_xpos); + + if(ImGui::Button(str_settings.c_str(), ImVec2(button_width, 0.0f))) { + globals::gui_screen = GUI_SETTINGS; + } + + ImGui::Spacing(); + + if(session::is_ingame()) { + ImGui::SetCursorPosX(button_xpos); + + if(ImGui::Button(str_leave.c_str(), ImVec2(button_width, 0.0f))) { + session::disconnect("protocol.client_disconnect"); + globals::gui_screen = GUI_PLAY_MENU; + gui::window_title::update(); + } + + ImGui::Spacing(); + } + else { + ImGui::SetCursorPosX(button_xpos); + + if(ImGui::Button(str_quit.c_str(), ImVec2(button_width, 0.0f))) { + glfwSetWindowShouldClose(globals::window, true); + } + + ImGui::Spacing(); + } + + if(!session::is_ingame()) { + const auto& padding = ImGui::GetStyle().FramePadding; + const auto& spacing = ImGui::GetStyle().ItemSpacing; + + ImGui::PushFont(globals::font_unscii8, 4.0f); + ImGui::SetCursorScreenPos(ImVec2(padding.x + spacing.x, window_size.y - ImGui::GetFontSize() - padding.y - spacing.y)); + ImGui::Text("Voxelius %*s", version::full.size(), version::full.data()); // string_view is not always null-terminated + ImGui::PopFont(); + } + + ImGui::PopStyleVar(); + } + + ImGui::End(); +} diff --git a/game/client/gui/main_menu.hh b/src/game/client/gui/main_menu.hh index 8e30e38..205f078 100644 --- a/game/client/gui/main_menu.hh +++ b/src/game/client/gui/main_menu.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace gui::main_menu
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::main_menu
+#pragma once + +namespace gui::main_menu +{ +void init(void); +void shutdown(void); +void layout(void); +} // namespace gui::main_menu diff --git a/game/client/gui/message_box.cc b/src/game/client/gui/message_box.cc index b7f109a..59e2d33 100644 --- a/game/client/gui/message_box.cc +++ b/src/game/client/gui/message_box.cc @@ -1,95 +1,95 @@ -#include "client/pch.hh"
-
-#include "client/gui/message_box.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-struct Button final {
- gui::message_box_action action;
- std::string str_title;
-};
-
-static std::string str_title;
-static std::string str_subtitle;
-static std::vector<Button> buttons;
-
-void gui::message_box::init(void)
-{
- str_title = std::string();
- str_subtitle = std::string();
- buttons.clear();
-}
-
-void gui::message_box::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale));
-
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale));
-
- if(!str_subtitle.empty()) {
- const float subtitle_width = ImGui::CalcTextSize(str_subtitle.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - subtitle_width));
- ImGui::TextUnformatted(str_subtitle.c_str());
- }
-
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
-
- for(const auto& button : buttons) {
- const float button_width = 0.8f * ImGui::CalcItemWidth();
- ImGui::SetCursorPosX(0.5f * (window_size.x - button_width));
-
- if(ImGui::Button(button.str_title.c_str(), ImVec2(button_width, 0.0f))) {
- if(button.action) {
- button.action();
- }
- }
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::message_box::reset(void)
-{
- str_title.clear();
- str_subtitle.clear();
- buttons.clear();
-}
-
-void gui::message_box::set_title(std::string_view title)
-{
- str_title = gui::language::resolve(title);
-}
-
-void gui::message_box::set_subtitle(std::string_view subtitle)
-{
- str_subtitle = gui::language::resolve(subtitle);
-}
-
-void gui::message_box::add_button(std::string_view text, const message_box_action& action)
-{
- Button button = {};
- button.str_title = std::format("{}###MessageBox_Button{}", gui::language::resolve(text), buttons.size());
- button.action = action;
-
- buttons.push_back(button);
-}
+#include "client/pch.hh" + +#include "client/gui/message_box.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" + +#include "client/globals.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +struct Button final { + gui::message_box_action action; + std::string str_title; +}; + +static std::string str_title; +static std::string str_subtitle; +static std::vector<Button> buttons; + +void gui::message_box::init(void) +{ + str_title = std::string(); + str_subtitle = std::string(); + buttons.clear(); +} + +void gui::message_box::layout(void) +{ + const auto viewport = ImGui::GetMainViewport(); + const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f); + const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale)); + + const float title_width = ImGui::CalcTextSize(str_title.c_str()).x; + ImGui::SetCursorPosX(0.5f * (window_size.x - title_width)); + ImGui::TextUnformatted(str_title.c_str()); + + ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale)); + + if(!str_subtitle.empty()) { + const float subtitle_width = ImGui::CalcTextSize(str_subtitle.c_str()).x; + ImGui::SetCursorPosX(0.5f * (window_size.x - subtitle_width)); + ImGui::TextUnformatted(str_subtitle.c_str()); + } + + ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale)); + + for(const auto& button : buttons) { + const float button_width = 0.8f * ImGui::CalcItemWidth(); + ImGui::SetCursorPosX(0.5f * (window_size.x - button_width)); + + if(ImGui::Button(button.str_title.c_str(), ImVec2(button_width, 0.0f))) { + if(button.action) { + button.action(); + } + } + } + + ImGui::PopStyleVar(); + } + + ImGui::End(); +} + +void gui::message_box::reset(void) +{ + str_title.clear(); + str_subtitle.clear(); + buttons.clear(); +} + +void gui::message_box::set_title(std::string_view title) +{ + str_title = gui::language::resolve(title); +} + +void gui::message_box::set_subtitle(std::string_view subtitle) +{ + str_subtitle = gui::language::resolve(subtitle); +} + +void gui::message_box::add_button(std::string_view text, const message_box_action& action) +{ + Button button = {}; + button.str_title = std::format("{}###MessageBox_Button{}", gui::language::resolve(text), buttons.size()); + button.action = action; + + buttons.push_back(button); +} diff --git a/game/client/gui/message_box.hh b/src/game/client/gui/message_box.hh index 06a3b8b..74a6fbf 100644 --- a/game/client/gui/message_box.hh +++ b/src/game/client/gui/message_box.hh @@ -1,20 +1,20 @@ -#pragma once
-
-namespace gui
-{
-using message_box_action = void (*)(void);
-} // namespace gui
-
-namespace gui::message_box
-{
-void init(void);
-void layout(void);
-void reset(void);
-} // namespace gui::message_box
-
-namespace gui::message_box
-{
-void set_title(std::string_view title);
-void set_subtitle(std::string_view subtitle);
-void add_button(std::string_view text, const message_box_action& action);
-} // namespace gui::message_box
+#pragma once + +namespace gui +{ +using message_box_action = void (*)(void); +} // namespace gui + +namespace gui::message_box +{ +void init(void); +void layout(void); +void reset(void); +} // namespace gui::message_box + +namespace gui::message_box +{ +void set_title(std::string_view title); +void set_subtitle(std::string_view subtitle); +void add_button(std::string_view text, const message_box_action& action); +} // namespace gui::message_box diff --git a/game/client/gui/metrics.cc b/src/game/client/gui/metrics.cc index ef47880..bf46649 100644 --- a/game/client/gui/metrics.cc +++ b/src/game/client/gui/metrics.cc @@ -1,103 +1,103 @@ -#include "client/pch.hh"
-
-#include "client/gui/metrics.hh"
-
-#include "core/version.hh"
-
-#include "shared/entity/grounded.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs
- | ImGuiWindowFlags_NoNav;
-
-static std::basic_string<GLubyte> r_version;
-static std::basic_string<GLubyte> r_renderer;
-
-void gui::metrics::init(void)
-{
- r_version = std::basic_string<GLubyte>(glGetString(GL_VERSION));
- r_renderer = std::basic_string<GLubyte>(glGetString(GL_RENDERER));
-}
-
-void gui::metrics::layout(void)
-{
- if(!session::is_ingame()) {
- // Sanity check; we are checking this
- // in client_game before calling layout
- // on HUD-ish GUI systems but still
- return;
- }
-
- auto draw_list = ImGui::GetForegroundDrawList();
-
- // FIXME: maybe use style colors instead of hardcoding?
- auto text_color = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
- auto shadow_color = ImGui::GetColorU32(ImVec4(0.1f, 0.1f, 0.1f, 1.0f));
-
- auto font_size = 4.0f;
- auto position = ImVec2(8.0f, 8.0f);
- auto y_step = 1.5f * globals::gui_scale * font_size;
-
- // Draw version
- auto version_line = std::format("Voxelius {} [{}]", version::semver, version::commit);
- gui::imdraw_ext::text_shadow(version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += 1.5f * y_step;
-
- // Draw client-side window framerate metrics
- auto window_framerate = 1.0f / globals::window_frametime_avg;
- auto window_frametime = 1000.0f * globals::window_frametime_avg;
- auto window_fps_line = std::format("{:.02f} FPS [{:.02f} ms]", window_framerate, window_frametime);
- gui::imdraw_ext::text_shadow(window_fps_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw world rendering metrics
- auto drawcall_line = std::format("World: {} DC / {} TRI", globals::num_drawcalls, globals::num_triangles);
- gui::imdraw_ext::text_shadow(drawcall_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw OpenGL version string
- auto r_version_line = std::format("GL_VERSION: {}", reinterpret_cast<const char*>(r_version.c_str()));
- gui::imdraw_ext::text_shadow(r_version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw OpenGL renderer string
- auto r_renderer_line = std::format("GL_RENDERER: {}", reinterpret_cast<const char*>(r_renderer.c_str()));
- gui::imdraw_ext::text_shadow(r_renderer_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += 1.5f * y_step;
-
- const auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
- const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player);
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
-
- // Draw player voxel position
- auto voxel_position = coord::to_voxel(transform.chunk, transform.local);
- auto voxel_line = std::format("voxel: [{} {} {}]", voxel_position.x, voxel_position.y, voxel_position.z);
- gui::imdraw_ext::text_shadow(voxel_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw player world position
- auto world_line = std::format("world: [{} {} {}] [{:.03f} {:.03f} {:.03f}]", transform.chunk.x, transform.chunk.y, transform.chunk.z,
- transform.local.x, transform.local.y, transform.local.z);
- gui::imdraw_ext::text_shadow(world_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw player look angles
- auto angles = glm::degrees(transform.angles + head.angles);
- auto angle_line = std::format("angle: [{: .03f} {: .03f} {: .03f}]", angles[0], angles[1], angles[2]);
- gui::imdraw_ext::text_shadow(angle_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-}
+#include "client/pch.hh" + +#include "client/gui/metrics.hh" + +#include "core/version.hh" + +#include "shared/entity/grounded.hh" +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +#include "client/entity/camera.hh" + +#include "client/gui/imdraw_ext.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs + | ImGuiWindowFlags_NoNav; + +static std::basic_string<GLubyte> r_version; +static std::basic_string<GLubyte> r_renderer; + +void gui::metrics::init(void) +{ + r_version = std::basic_string<GLubyte>(glGetString(GL_VERSION)); + r_renderer = std::basic_string<GLubyte>(glGetString(GL_RENDERER)); +} + +void gui::metrics::layout(void) +{ + if(!session::is_ingame()) { + // Sanity check; we are checking this + // in client_game before calling layout + // on HUD-ish GUI systems but still + return; + } + + auto draw_list = ImGui::GetForegroundDrawList(); + + // FIXME: maybe use style colors instead of hardcoding? + auto text_color = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); + auto shadow_color = ImGui::GetColorU32(ImVec4(0.1f, 0.1f, 0.1f, 1.0f)); + + auto font_size = 4.0f; + auto position = ImVec2(8.0f, 8.0f); + auto y_step = 1.5f * globals::gui_scale * font_size; + + // Draw version + auto version_line = std::format("Voxelius {}", version::full); + gui::imdraw_ext::text_shadow(version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += 1.5f * y_step; + + // Draw client-side window framerate metrics + auto window_framerate = 1.0f / globals::window_frametime_avg; + auto window_frametime = 1000.0f * globals::window_frametime_avg; + auto window_fps_line = std::format("{:.02f} FPS [{:.02f} ms]", window_framerate, window_frametime); + gui::imdraw_ext::text_shadow(window_fps_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; + + // Draw world rendering metrics + auto drawcall_line = std::format("World: {} DC / {} TRI", globals::num_drawcalls, globals::num_triangles); + gui::imdraw_ext::text_shadow(drawcall_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; + + // Draw OpenGL version string + auto r_version_line = std::format("GL_VERSION: {}", reinterpret_cast<const char*>(r_version.c_str())); + gui::imdraw_ext::text_shadow(r_version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; + + // Draw OpenGL renderer string + auto r_renderer_line = std::format("GL_RENDERER: {}", reinterpret_cast<const char*>(r_renderer.c_str())); + gui::imdraw_ext::text_shadow(r_renderer_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += 1.5f * y_step; + + const auto& head = globals::dimension->entities.get<entity::Head>(globals::player); + const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player); + const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player); + + // Draw player voxel position + auto voxel_position = coord::to_voxel(transform.chunk, transform.local); + auto voxel_line = std::format("voxel: [{} {} {}]", voxel_position.x, voxel_position.y, voxel_position.z); + gui::imdraw_ext::text_shadow(voxel_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; + + // Draw player world position + auto world_line = std::format("world: [{} {} {}] [{:.03f} {:.03f} {:.03f}]", transform.chunk.x, transform.chunk.y, transform.chunk.z, + transform.local.x, transform.local.y, transform.local.z); + gui::imdraw_ext::text_shadow(world_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; + + // Draw player look angles + auto angles = glm::degrees(transform.angles + head.angles); + auto angle_line = std::format("angle: [{: .03f} {: .03f} {: .03f}]", angles[0], angles[1], angles[2]); + gui::imdraw_ext::text_shadow(angle_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size); + position.y += y_step; +} diff --git a/game/client/gui/metrics.hh b/src/game/client/gui/metrics.hh index 6bec5cb..4898332 100644 --- a/game/client/gui/metrics.hh +++ b/src/game/client/gui/metrics.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace gui::metrics
-{
-void init(void);
-void layout(void);
-} // namespace gui::metrics
+#pragma once + +namespace gui::metrics +{ +void init(void); +void layout(void); +} // namespace gui::metrics diff --git a/game/client/gui/play_menu.cc b/src/game/client/gui/play_menu.cc index cd7f730..5b1ecde 100644 --- a/game/client/gui/play_menu.cc +++ b/src/game/client/gui/play_menu.cc @@ -1,594 +1,594 @@ -#include "client/pch.hh"
-
-#include "client/gui/play_menu.hh"
-
-#include "core/config/boolean.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/utils/string.hh"
-
-#include "core/version.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/gui/bother.hh"
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static std::string_view DEFAULT_SERVER_NAME = "Voxelius Server";
-constexpr static std::string_view SERVERS_TXT = "servers.txt";
-
-constexpr static std::size_t MAX_SERVER_ITEM_NAME = 18;
-
-enum class item_status : unsigned int {
- UNKNOWN = 0x0000U,
- PINGING = 0x0001U,
- REACHED = 0x0002U,
- FAILURE = 0x0003U,
-};
-
-struct ServerStatusItem final {
- std::string name;
- std::string password;
- std::string hostname;
- std::uint16_t port;
-
- // Things pulled from bother events
- std::uint16_t num_players;
- std::uint16_t max_players;
- std::string motd;
- std::uint16_t game_version_major;
- std::uint16_t game_version_minor;
- std::uint16_t game_version_patch;
-
- // Unique identifier that monotonically
- // grows with each new server added and
- // doesn't reset with each server removed
- unsigned int identity;
-
- item_status status;
-};
-
-static std::string str_tab_servers;
-
-static std::string str_join;
-static std::string str_connect;
-static std::string str_add;
-static std::string str_edit;
-static std::string str_remove;
-static std::string str_refresh;
-
-static std::string str_status_init;
-static std::string str_status_ping;
-static std::string str_status_fail;
-
-static std::string input_itemname;
-static std::string input_hostname;
-static std::string input_password;
-
-static unsigned int next_identity;
-static std::deque<ServerStatusItem*> servers_deque;
-static ServerStatusItem* selected_server;
-static bool editing_server;
-static bool adding_server;
-static bool needs_focus;
-
-static void parse_hostname(ServerStatusItem* item, const std::string& hostname)
-{
- auto parts = utils::split(hostname, ":");
-
- if(!parts[0].empty()) {
- item->hostname = parts[0];
- }
- else {
- item->hostname = std::string("localhost");
- }
-
- if(parts.size() >= 2) {
- item->port = glm::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX);
- }
- else {
- item->port = protocol::PORT;
- }
-}
-
-static void add_new_server(void)
-{
- auto item = new ServerStatusItem();
- item->port = protocol::PORT;
- item->max_players = UINT16_MAX;
- item->num_players = UINT16_MAX;
- item->identity = next_identity;
- item->status = item_status::UNKNOWN;
- item->game_version_major = 0U;
- item->game_version_minor = 0U;
- item->game_version_patch = 0U;
-
- next_identity += 1U;
-
- input_itemname = DEFAULT_SERVER_NAME;
- input_hostname = std::string();
- input_password = std::string();
-
- servers_deque.push_back(item);
- selected_server = item;
- editing_server = true;
- adding_server = true;
- needs_focus = true;
-}
-
-static void edit_selected_server(void)
-{
- input_itemname = selected_server->name;
-
- if(selected_server->port != protocol::PORT) {
- input_hostname = std::format("{}:{}", selected_server->hostname, selected_server->port);
- }
- else {
- input_hostname = selected_server->hostname;
- }
-
- input_password = selected_server->password;
-
- editing_server = true;
- needs_focus = true;
-}
-
-static void remove_selected_server(void)
-{
- gui::bother::cancel(selected_server->identity);
-
- for(auto it = servers_deque.cbegin(); it != servers_deque.cend(); ++it) {
- if(selected_server == (*it)) {
- delete selected_server;
- selected_server = nullptr;
- servers_deque.erase(it);
- return;
- }
- }
-}
-
-static void join_selected_server(void)
-{
- if(!session::peer) {
- session::connect(selected_server->hostname.c_str(), selected_server->port, selected_server->password.c_str());
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_PLAY_MENU) {
- if(editing_server) {
- if(adding_server) {
- remove_selected_server();
- }
- else {
- input_itemname.clear();
- input_hostname.clear();
- input_password.clear();
- editing_server = false;
- adding_server = false;
- return;
- }
- }
-
- globals::gui_screen = GUI_MAIN_MENU;
- selected_server = nullptr;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_tab_servers = gui::language::resolve_gui("play_menu.tab.servers");
-
- str_join = gui::language::resolve_gui("play_menu.join");
- str_connect = gui::language::resolve_gui("play_menu.connect");
- str_add = gui::language::resolve_gui("play_menu.add");
- str_edit = gui::language::resolve_gui("play_menu.edit");
- str_remove = gui::language::resolve_gui("play_menu.remove");
- str_refresh = gui::language::resolve_gui("play_menu.refresh");
-
- str_status_init = gui::language::resolve("play_menu.status.init");
- str_status_ping = gui::language::resolve("play_menu.status.ping");
- str_status_fail = gui::language::resolve("play_menu.status.fail");
-}
-
-static void on_bother_response(const gui::BotherResponseEvent& event)
-{
- for(auto item : servers_deque) {
- if(item->identity == event.identity) {
- if(event.is_server_unreachable) {
- item->num_players = UINT16_MAX;
- item->max_players = UINT16_MAX;
- item->motd = str_status_fail;
- item->status = item_status::FAILURE;
- item->game_version_major = 0U;
- item->game_version_minor = 0U;
- item->game_version_patch = 0U;
- }
- else {
- item->num_players = event.num_players;
- item->max_players = event.max_players;
- item->motd = event.motd;
- item->status = item_status::REACHED;
- item->game_version_major = event.game_version_major;
- item->game_version_minor = event.game_version_minor;
- item->game_version_patch = event.game_version_patch;
- }
-
- break;
- }
- }
-}
-
-static void layout_server_item(ServerStatusItem* item)
-{
- // Preserve the cursor at which we draw stuff
- const ImVec2& cursor = ImGui::GetCursorScreenPos();
- const ImVec2& padding = ImGui::GetStyle().FramePadding;
- const ImVec2& spacing = ImGui::GetStyle().ItemSpacing;
-
- const float item_width = ImGui::GetContentRegionAvail().x;
- const float line_height = ImGui::GetTextLineHeightWithSpacing();
- const std::string sid = std::format("###play_menu.servers.{}", static_cast<void*>(item));
- if(ImGui::Selectable(sid.c_str(), (item == selected_server), 0, ImVec2(0.0, 2.0f * (line_height + padding.y + spacing.y)))) {
- selected_server = item;
- editing_server = false;
- }
-
- if(ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
- // Double clicked - join the selected server
- join_selected_server();
- }
-
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
-
- if(item == selected_server) {
- const ImVec2 start = ImVec2(cursor.x, cursor.y);
- const ImVec2 end = ImVec2(start.x + item_width, start.y + 2.0f * (line_height + padding.y + spacing.y));
- draw_list->AddRect(start, end, ImGui::GetColorU32(ImGuiCol_Text), 0.0f, 0, globals::gui_scale);
- }
-
- const ImVec2 name_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y);
- draw_list->AddText(name_pos, ImGui::GetColorU32(ImGuiCol_Text), item->name.c_str(), item->name.c_str() + item->name.size());
-
- if(item->status == item_status::REACHED) {
- auto stats = std::format("{}/{}", item->num_players, item->max_players);
- auto stats_size = ImGui::CalcTextSize(stats.c_str(), stats.c_str() + stats.size());
- auto stats_pos = ImVec2(cursor.x + item_width - stats_size.x - padding.x, cursor.y + padding.y);
- draw_list->AddText(stats_pos, ImGui::GetColorU32(ImGuiCol_TextDisabled), stats.c_str(), stats.c_str() + stats.size());
-
- auto major_version_mismatch = item->game_version_major != version::major;
- auto minor_version_mismatch = item->game_version_minor != version::minor;
- auto patch_version_mismatch = item->game_version_patch != version::patch;
-
- ImU32 version_color;
-
- if(major_version_mismatch || minor_version_mismatch || patch_version_mismatch) {
- version_color = ImGui::GetColorU32(major_version_mismatch ? ImGuiCol_PlotLinesHovered : ImGuiCol_DragDropTarget);
- }
- else {
- version_color = ImGui::GetColorU32(ImGuiCol_PlotHistogram);
- }
-
- ImGui::PushFont(globals::font_unscii8, 4.0f);
-
- std::string version_toast;
-
- if(item->game_version_major < 16U) {
- // Pre v16.x.x servers didn't send minor and patch versions
- // and also used a different versioning scheme; post v16 the
- // major version became the protocol version and the semver lost the tweak part
- version_toast = std::string("15.x.x");
- }
- else {
- version_toast = std::format("{}.{}.{}", item->game_version_major, item->game_version_minor, item->game_version_patch);
- }
-
- auto version_size = ImGui::CalcTextSize(version_toast.c_str(), version_toast.c_str() + version_toast.size());
- auto version_pos = ImVec2(stats_pos.x - version_size.x - padding.x - 4.0f * globals::gui_scale,
- cursor.y + padding.y + 0.5f * (stats_size.y - version_size.y));
- auto version_end = ImVec2(version_pos.x + version_size.x, version_pos.y + version_size.y);
-
- auto outline_pos = ImVec2(version_pos.x - 2U * globals::gui_scale, version_pos.y - 2U * globals::gui_scale);
- auto outline_end = ImVec2(version_end.x + 2U * globals::gui_scale, version_end.y + 2U * globals::gui_scale);
- auto outline_thickness = glm::max<float>(1.0f, 0.5f * static_cast<float>(globals::gui_scale));
-
- draw_list->AddRect(outline_pos, outline_end, version_color, 0.0f, 0, outline_thickness);
- draw_list->AddText(version_pos, version_color, version_toast.c_str(), version_toast.c_str() + version_toast.size());
-
- ImGui::PopFont();
- }
-
- ImU32 motd_color = {};
- const std::string* motd_text;
-
- switch(item->status) {
- case item_status::UNKNOWN:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &str_status_init;
- break;
- case item_status::PINGING:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &str_status_ping;
- break;
- case item_status::REACHED:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &item->motd;
- break;
- default:
- motd_color = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered);
- motd_text = &str_status_fail;
- break;
- }
-
- const ImVec2 motd_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y + line_height);
- draw_list->AddText(motd_pos, motd_color, motd_text->c_str(), motd_text->c_str() + motd_text->size());
-}
-
-static void layout_server_edit(ServerStatusItem* item)
-{
- if(needs_focus) {
- ImGui::SetKeyboardFocusHere();
- needs_focus = false;
- }
-
- ImGui::SetNextItemWidth(-0.25f * ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_itemname", &input_itemname);
- ImGui::SameLine();
-
- const bool ignore_input = utils::is_whitespace(input_itemname) || input_hostname.empty();
-
- ImGui::BeginDisabled(ignore_input);
-
- if(ImGui::Button("OK###play_menu.servers.submit_input", ImVec2(-1.0f, 0.0f))
- || (!ignore_input && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
- parse_hostname(item, input_hostname);
- item->password = input_password;
- item->name = input_itemname.substr(0, MAX_SERVER_ITEM_NAME);
- item->status = item_status::UNKNOWN;
- editing_server = false;
- adding_server = false;
-
- input_itemname.clear();
- input_hostname.clear();
-
- gui::bother::cancel(item->identity);
- }
-
- ImGui::EndDisabled();
-
- ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank;
-
- if(client_game::streamer_mode.get_value()) {
- // Hide server hostname to avoid things like
- // followers flooding the server that is streamed online
- hostname_flags |= ImGuiInputTextFlags_Password;
- }
-
- ImGui::SetNextItemWidth(-0.50f * ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_hostname", &input_hostname, hostname_flags);
- ImGui::SameLine();
-
- ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_password", &input_password, ImGuiInputTextFlags_Password);
-}
-
-static void layout_servers(void)
-{
- if(ImGui::BeginListBox("###play_menu.servers.listbox", ImVec2(-1.0f, -1.0f))) {
- for(ServerStatusItem* item : servers_deque) {
- if(editing_server && item == selected_server) {
- layout_server_edit(item);
- }
- else {
- layout_server_item(item);
- }
- }
-
- ImGui::EndListBox();
- }
-}
-
-static void layout_servers_buttons(void)
-{
- auto avail_width = ImGui::GetContentRegionAvail().x;
-
- // Can only join when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_join.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) {
- join_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only connect directly when not editing anything
- ImGui::BeginDisabled(editing_server);
-
- if(ImGui::Button(str_connect.c_str(), ImVec2(-1.00f, 0.0f))) {
- globals::gui_screen = GUI_DIRECT_CONNECTION;
- }
-
- ImGui::EndDisabled();
-
- // Can only add when not editing anything
- ImGui::BeginDisabled(editing_server);
-
- if(ImGui::Button(str_add.c_str(), ImVec2(-0.75f * avail_width, 0.0f))) {
- add_new_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only edit when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_edit.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) {
- edit_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only remove when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_remove.c_str(), ImVec2(-0.25f * avail_width, 0.0f))) {
- remove_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- if(ImGui::Button(str_refresh.c_str(), ImVec2(-1.0f, 0.0f))) {
- for(ServerStatusItem* item : servers_deque) {
- if(item->status != item_status::PINGING) {
- if(!editing_server || item != selected_server) {
- item->status = item_status::UNKNOWN;
- gui::bother::cancel(item->identity);
- }
- }
- }
- }
-}
-
-void gui::play_menu::init(void)
-{
- if(auto file = PHYSFS_openRead(std::string(SERVERS_TXT).c_str())) {
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto stream = std::istringstream(source);
- auto line = std::string();
-
- while(std::getline(stream, line)) {
- auto parts = utils::split(line, "%");
-
- auto item = new ServerStatusItem();
- item->port = protocol::PORT;
- item->max_players = UINT16_MAX;
- item->num_players = UINT16_MAX;
- item->identity = next_identity;
- item->status = item_status::UNKNOWN;
- item->game_version_major = version::major;
- item->game_version_minor = version::minor;
- item->game_version_patch = version::patch;
-
- next_identity += 1U;
-
- parse_hostname(item, parts[0]);
-
- if(parts.size() >= 2) {
- item->password = parts[1];
- }
- else {
- item->password = std::string();
- }
-
- if(parts.size() >= 3) {
- item->name = parts[2].substr(0, MAX_SERVER_ITEM_NAME);
- }
- else {
- item->name = DEFAULT_SERVER_NAME;
- }
-
- servers_deque.push_back(item);
- }
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
- globals::dispatcher.sink<BotherResponseEvent>().connect<&on_bother_response>();
-}
-
-void gui::play_menu::shutdown(void)
-{
- std::ostringstream stream;
-
- for(const auto item : servers_deque) {
- stream << std::format("{}:{}%{}%{}", item->hostname, item->port, item->password, item->name) << std::endl;
- }
-
- if(auto file = PHYSFS_openWrite(std::string(SERVERS_TXT).c_str())) {
- auto source = stream.str();
- PHYSFS_writeBytes(file, source.data(), source.size());
- PHYSFS_close(file);
- }
-
- for(auto item : servers_deque)
- delete item;
- servers_deque.clear();
-}
-
-void gui::play_menu::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
- const auto window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###play_menu", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale));
-
- if(ImGui::BeginTabBar("###play_menu.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::TabItemButton("<<")) {
- globals::gui_screen = GUI_MAIN_MENU;
- selected_server = nullptr;
- editing_server = false;
- }
-
- if(ImGui::BeginTabItem(str_tab_servers.c_str())) {
- if(ImGui::BeginChild("###play_menu.servers.child", ImVec2(0.0f, -2.0f * ImGui::GetFrameHeightWithSpacing()))) {
- layout_servers();
- }
-
- ImGui::EndChild();
-
- layout_servers_buttons();
-
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem("debug###play_menu.debug.child")) {
- ImGui::ShowStyleEditor();
- ImGui::EndTabItem();
- }
-
- ImGui::EndTabBar();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::play_menu::update_late(void)
-{
- for(auto item : servers_deque) {
- if(item->status == item_status::UNKNOWN) {
- gui::bother::ping(item->identity, item->hostname.c_str(), item->port);
- item->status = item_status::PINGING;
- continue;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/gui/play_menu.hh" + +#include "core/config/boolean.hh" + +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" + +#include "core/utils/string.hh" + +#include "core/version.hh" + +#include "shared/protocol.hh" + +#include "client/gui/bother.hh" +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" + +#include "client/io/glfw.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; +constexpr static std::string_view DEFAULT_SERVER_NAME = "Voxelius Server"; +constexpr static std::string_view SERVERS_TXT = "servers.txt"; + +constexpr static std::size_t MAX_SERVER_ITEM_NAME = 18; + +enum class item_status : unsigned int { + UNKNOWN = 0x0000U, + PINGING = 0x0001U, + REACHED = 0x0002U, + FAILURE = 0x0003U, +}; + +struct ServerStatusItem final { + std::string name; + std::string password; + std::string hostname; + std::uint16_t port; + + // Things pulled from bother events + std::uint16_t num_players; + std::uint16_t max_players; + std::string motd; + std::uint16_t game_version_major; + std::uint16_t game_version_minor; + std::uint16_t game_version_patch; + + // Unique identifier that monotonically + // grows with each new server added and + // doesn't reset with each server removed + unsigned int identity; + + item_status status; +}; + +static std::string str_tab_servers; + +static std::string str_join; +static std::string str_connect; +static std::string str_add; +static std::string str_edit; +static std::string str_remove; +static std::string str_refresh; + +static std::string str_status_init; +static std::string str_status_ping; +static std::string str_status_fail; + +static std::string input_itemname; +static std::string input_hostname; +static std::string input_password; + +static unsigned int next_identity; +static std::deque<ServerStatusItem*> servers_deque; +static ServerStatusItem* selected_server; +static bool editing_server; +static bool adding_server; +static bool needs_focus; + +static void parse_hostname(ServerStatusItem* item, const std::string& hostname) +{ + auto parts = utils::split(hostname, ":"); + + if(!parts[0].empty()) { + item->hostname = parts[0]; + } + else { + item->hostname = std::string("localhost"); + } + + if(parts.size() >= 2) { + item->port = glm::clamp<std::uint16_t>(static_cast<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10)), 1024, UINT16_MAX); + } + else { + item->port = protocol::PORT; + } +} + +static void add_new_server(void) +{ + auto item = new ServerStatusItem(); + item->port = protocol::PORT; + item->max_players = UINT16_MAX; + item->num_players = UINT16_MAX; + item->identity = next_identity; + item->status = item_status::UNKNOWN; + item->game_version_major = 0U; + item->game_version_minor = 0U; + item->game_version_patch = 0U; + + next_identity += 1U; + + input_itemname = DEFAULT_SERVER_NAME; + input_hostname = std::string(); + input_password = std::string(); + + servers_deque.push_back(item); + selected_server = item; + editing_server = true; + adding_server = true; + needs_focus = true; +} + +static void edit_selected_server(void) +{ + input_itemname = selected_server->name; + + if(selected_server->port != protocol::PORT) { + input_hostname = std::format("{}:{}", selected_server->hostname, selected_server->port); + } + else { + input_hostname = selected_server->hostname; + } + + input_password = selected_server->password; + + editing_server = true; + needs_focus = true; +} + +static void remove_selected_server(void) +{ + gui::bother::cancel(selected_server->identity); + + for(auto it = servers_deque.cbegin(); it != servers_deque.cend(); ++it) { + if(selected_server == (*it)) { + delete selected_server; + selected_server = nullptr; + servers_deque.erase(it); + return; + } + } +} + +static void join_selected_server(void) +{ + if(!session::peer) { + session::connect(selected_server->hostname.c_str(), selected_server->port, selected_server->password.c_str()); + } +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) { + if(globals::gui_screen == GUI_PLAY_MENU) { + if(editing_server) { + if(adding_server) { + remove_selected_server(); + } + else { + input_itemname.clear(); + input_hostname.clear(); + input_password.clear(); + editing_server = false; + adding_server = false; + return; + } + } + + globals::gui_screen = GUI_MAIN_MENU; + selected_server = nullptr; + return; + } + } +} + +static void on_language_set(const gui::LanguageSetEvent& event) +{ + str_tab_servers = gui::language::resolve_gui("play_menu.tab.servers"); + + str_join = gui::language::resolve_gui("play_menu.join"); + str_connect = gui::language::resolve_gui("play_menu.connect"); + str_add = gui::language::resolve_gui("play_menu.add"); + str_edit = gui::language::resolve_gui("play_menu.edit"); + str_remove = gui::language::resolve_gui("play_menu.remove"); + str_refresh = gui::language::resolve_gui("play_menu.refresh"); + + str_status_init = gui::language::resolve("play_menu.status.init"); + str_status_ping = gui::language::resolve("play_menu.status.ping"); + str_status_fail = gui::language::resolve("play_menu.status.fail"); +} + +static void on_bother_response(const gui::BotherResponseEvent& event) +{ + for(auto item : servers_deque) { + if(item->identity == event.identity) { + if(event.is_server_unreachable) { + item->num_players = UINT16_MAX; + item->max_players = UINT16_MAX; + item->motd = str_status_fail; + item->status = item_status::FAILURE; + item->game_version_major = 0U; + item->game_version_minor = 0U; + item->game_version_patch = 0U; + } + else { + item->num_players = event.num_players; + item->max_players = event.max_players; + item->motd = event.motd; + item->status = item_status::REACHED; + item->game_version_major = event.game_version_major; + item->game_version_minor = event.game_version_minor; + item->game_version_patch = event.game_version_patch; + } + + break; + } + } +} + +static void layout_server_item(ServerStatusItem* item) +{ + // Preserve the cursor at which we draw stuff + const ImVec2& cursor = ImGui::GetCursorScreenPos(); + const ImVec2& padding = ImGui::GetStyle().FramePadding; + const ImVec2& spacing = ImGui::GetStyle().ItemSpacing; + + const float item_width = ImGui::GetContentRegionAvail().x; + const float line_height = ImGui::GetTextLineHeightWithSpacing(); + const std::string sid = std::format("###play_menu.servers.{}", static_cast<void*>(item)); + if(ImGui::Selectable(sid.c_str(), (item == selected_server), 0, ImVec2(0.0, 2.0f * (line_height + padding.y + spacing.y)))) { + selected_server = item; + editing_server = false; + } + + if(ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { + // Double clicked - join the selected server + join_selected_server(); + } + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + if(item == selected_server) { + const ImVec2 start = ImVec2(cursor.x, cursor.y); + const ImVec2 end = ImVec2(start.x + item_width, start.y + 2.0f * (line_height + padding.y + spacing.y)); + draw_list->AddRect(start, end, ImGui::GetColorU32(ImGuiCol_Text), 0.0f, 0, static_cast<float>(globals::gui_scale)); + } + + const ImVec2 name_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y); + draw_list->AddText(name_pos, ImGui::GetColorU32(ImGuiCol_Text), item->name.c_str(), item->name.c_str() + item->name.size()); + + if(item->status == item_status::REACHED) { + auto stats = std::format("{}/{}", item->num_players, item->max_players); + auto stats_size = ImGui::CalcTextSize(stats.c_str(), stats.c_str() + stats.size()); + auto stats_pos = ImVec2(cursor.x + item_width - stats_size.x - padding.x, cursor.y + padding.y); + draw_list->AddText(stats_pos, ImGui::GetColorU32(ImGuiCol_TextDisabled), stats.c_str(), stats.c_str() + stats.size()); + + auto major_version_mismatch = item->game_version_major != version::major; + auto minor_version_mismatch = item->game_version_minor != version::minor; + auto patch_version_mismatch = item->game_version_patch != version::patch; + + ImU32 version_color; + + if(major_version_mismatch || minor_version_mismatch || patch_version_mismatch) { + version_color = ImGui::GetColorU32(major_version_mismatch ? ImGuiCol_PlotLinesHovered : ImGuiCol_DragDropTarget); + } + else { + version_color = ImGui::GetColorU32(ImGuiCol_PlotHistogram); + } + + ImGui::PushFont(globals::font_unscii8, 4.0f); + + std::string version_toast; + + if(item->game_version_major < 16U) { + // Pre v16.x.x servers didn't send minor and patch versions + // and also used a different versioning scheme; post v16 the + // major version became the protocol version and the semver lost the tweak part + version_toast = std::string("15.x.x"); + } + else { + version_toast = std::format("{}.{}.{}", item->game_version_major, item->game_version_minor, item->game_version_patch); + } + + auto version_size = ImGui::CalcTextSize(version_toast.c_str(), version_toast.c_str() + version_toast.size()); + auto version_pos = ImVec2(stats_pos.x - version_size.x - padding.x - 4.0f * globals::gui_scale, + cursor.y + padding.y + 0.5f * (stats_size.y - version_size.y)); + auto version_end = ImVec2(version_pos.x + version_size.x, version_pos.y + version_size.y); + + auto outline_pos = ImVec2(version_pos.x - 2U * globals::gui_scale, version_pos.y - 2U * globals::gui_scale); + auto outline_end = ImVec2(version_end.x + 2U * globals::gui_scale, version_end.y + 2U * globals::gui_scale); + auto outline_thickness = glm::max<float>(1.0f, 0.5f * static_cast<float>(globals::gui_scale)); + + draw_list->AddRect(outline_pos, outline_end, version_color, 0.0f, 0, outline_thickness); + draw_list->AddText(version_pos, version_color, version_toast.c_str(), version_toast.c_str() + version_toast.size()); + + ImGui::PopFont(); + } + + ImU32 motd_color = {}; + const std::string* motd_text; + + switch(item->status) { + case item_status::UNKNOWN: + motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled); + motd_text = &str_status_init; + break; + case item_status::PINGING: + motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled); + motd_text = &str_status_ping; + break; + case item_status::REACHED: + motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled); + motd_text = &item->motd; + break; + default: + motd_color = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered); + motd_text = &str_status_fail; + break; + } + + const ImVec2 motd_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y + line_height); + draw_list->AddText(motd_pos, motd_color, motd_text->c_str(), motd_text->c_str() + motd_text->size()); +} + +static void layout_server_edit(ServerStatusItem* item) +{ + if(needs_focus) { + ImGui::SetKeyboardFocusHere(); + needs_focus = false; + } + + ImGui::SetNextItemWidth(-0.25f * ImGui::GetContentRegionAvail().x); + ImGui::InputText("###play_menu.servers.edit_itemname", &input_itemname); + ImGui::SameLine(); + + const bool ignore_input = utils::is_whitespace(input_itemname) || input_hostname.empty(); + + ImGui::BeginDisabled(ignore_input); + + if(ImGui::Button("OK###play_menu.servers.submit_input", ImVec2(-1.0f, 0.0f)) + || (!ignore_input && ImGui::IsKeyPressed(ImGuiKey_Enter))) { + parse_hostname(item, input_hostname); + item->password = input_password; + item->name = input_itemname.substr(0, MAX_SERVER_ITEM_NAME); + item->status = item_status::UNKNOWN; + editing_server = false; + adding_server = false; + + input_itemname.clear(); + input_hostname.clear(); + + gui::bother::cancel(item->identity); + } + + ImGui::EndDisabled(); + + ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank; + + if(client_game::streamer_mode.get_value()) { + // Hide server hostname to avoid things like + // followers flooding the server that is streamed online + hostname_flags |= ImGuiInputTextFlags_Password; + } + + ImGui::SetNextItemWidth(-0.50f * ImGui::GetContentRegionAvail().x); + ImGui::InputText("###play_menu.servers.edit_hostname", &input_hostname, hostname_flags); + ImGui::SameLine(); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + ImGui::InputText("###play_menu.servers.edit_password", &input_password, ImGuiInputTextFlags_Password); +} + +static void layout_servers(void) +{ + if(ImGui::BeginListBox("###play_menu.servers.listbox", ImVec2(-1.0f, -1.0f))) { + for(ServerStatusItem* item : servers_deque) { + if(editing_server && item == selected_server) { + layout_server_edit(item); + } + else { + layout_server_item(item); + } + } + + ImGui::EndListBox(); + } +} + +static void layout_servers_buttons(void) +{ + auto avail_width = ImGui::GetContentRegionAvail().x; + + // Can only join when selected and not editing + ImGui::BeginDisabled(!selected_server || editing_server); + + if(ImGui::Button(str_join.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) { + join_selected_server(); + } + + ImGui::EndDisabled(); + ImGui::SameLine(); + + // Can only connect directly when not editing anything + ImGui::BeginDisabled(editing_server); + + if(ImGui::Button(str_connect.c_str(), ImVec2(-1.00f, 0.0f))) { + globals::gui_screen = GUI_DIRECT_CONNECTION; + } + + ImGui::EndDisabled(); + + // Can only add when not editing anything + ImGui::BeginDisabled(editing_server); + + if(ImGui::Button(str_add.c_str(), ImVec2(-0.75f * avail_width, 0.0f))) { + add_new_server(); + } + + ImGui::EndDisabled(); + ImGui::SameLine(); + + // Can only edit when selected and not editing + ImGui::BeginDisabled(!selected_server || editing_server); + + if(ImGui::Button(str_edit.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) { + edit_selected_server(); + } + + ImGui::EndDisabled(); + ImGui::SameLine(); + + // Can only remove when selected and not editing + ImGui::BeginDisabled(!selected_server || editing_server); + + if(ImGui::Button(str_remove.c_str(), ImVec2(-0.25f * avail_width, 0.0f))) { + remove_selected_server(); + } + + ImGui::EndDisabled(); + ImGui::SameLine(); + + if(ImGui::Button(str_refresh.c_str(), ImVec2(-1.0f, 0.0f))) { + for(ServerStatusItem* item : servers_deque) { + if(item->status != item_status::PINGING) { + if(!editing_server || item != selected_server) { + item->status = item_status::UNKNOWN; + gui::bother::cancel(item->identity); + } + } + } + } +} + +void gui::play_menu::init(void) +{ + if(auto file = PHYSFS_openRead(std::string(SERVERS_TXT).c_str())) { + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + auto stream = std::istringstream(source); + auto line = std::string(); + + while(std::getline(stream, line)) { + auto parts = utils::split(line, "%"); + + auto item = new ServerStatusItem(); + item->port = protocol::PORT; + item->max_players = UINT16_MAX; + item->num_players = UINT16_MAX; + item->identity = next_identity; + item->status = item_status::UNKNOWN; + item->game_version_major = version::major; + item->game_version_minor = version::minor; + item->game_version_patch = version::patch; + + next_identity += 1U; + + parse_hostname(item, parts[0]); + + if(parts.size() >= 2) { + item->password = parts[1]; + } + else { + item->password = std::string(); + } + + if(parts.size() >= 3) { + item->name = parts[2].substr(0, MAX_SERVER_ITEM_NAME); + } + else { + item->name = DEFAULT_SERVER_NAME; + } + + servers_deque.push_back(item); + } + } + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>(); + globals::dispatcher.sink<BotherResponseEvent>().connect<&on_bother_response>(); +} + +void gui::play_menu::shutdown(void) +{ + std::ostringstream stream; + + for(const auto item : servers_deque) { + stream << std::format("{}:{}%{}%{}", item->hostname, item->port, item->password, item->name) << std::endl; + } + + if(auto file = PHYSFS_openWrite(std::string(SERVERS_TXT).c_str())) { + auto source = stream.str(); + PHYSFS_writeBytes(file, source.data(), source.size()); + PHYSFS_close(file); + } + + for(auto item : servers_deque) + delete item; + servers_deque.clear(); +} + +void gui::play_menu::layout(void) +{ + const auto viewport = ImGui::GetMainViewport(); + const auto window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f); + const auto window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###play_menu", nullptr, WINDOW_FLAGS)) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale)); + + if(ImGui::BeginTabBar("###play_menu.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) { + if(ImGui::TabItemButton("<<")) { + globals::gui_screen = GUI_MAIN_MENU; + selected_server = nullptr; + editing_server = false; + } + + if(ImGui::BeginTabItem(str_tab_servers.c_str())) { + if(ImGui::BeginChild("###play_menu.servers.child", ImVec2(0.0f, -2.0f * ImGui::GetFrameHeightWithSpacing()))) { + layout_servers(); + } + + ImGui::EndChild(); + + layout_servers_buttons(); + + ImGui::EndTabItem(); + } + + if(ImGui::BeginTabItem("debug###play_menu.debug.child")) { + ImGui::ShowStyleEditor(); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::PopStyleVar(); + } + + ImGui::End(); +} + +void gui::play_menu::update_late(void) +{ + for(auto item : servers_deque) { + if(item->status == item_status::UNKNOWN) { + gui::bother::ping(item->identity, item->hostname.c_str(), item->port); + item->status = item_status::PINGING; + continue; + } + } +} diff --git a/game/client/gui/play_menu.hh b/src/game/client/gui/play_menu.hh index 15f7c89..1b1f003 100644 --- a/game/client/gui/play_menu.hh +++ b/src/game/client/gui/play_menu.hh @@ -1,9 +1,9 @@ -#pragma once
-
-namespace gui::play_menu
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-void update_late(void);
-} // namespace gui::play_menu
+#pragma once + +namespace gui::play_menu +{ +void init(void); +void shutdown(void); +void layout(void); +void update_late(void); +} // namespace gui::play_menu diff --git a/game/client/gui/progress_bar.cc b/src/game/client/gui/progress_bar.cc index 46277b5..1732f72 100644 --- a/game/client/gui/progress_bar.cc +++ b/src/game/client/gui/progress_bar.cc @@ -1,111 +1,111 @@ -#include "client/pch.hh"
-
-#include "client/gui/progress_bar.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/gui/language.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_title;
-static std::string str_button;
-static gui::progress_bar_action button_action;
-
-void gui::progress_bar::init(void)
-{
- str_title = "Loading";
- str_button = std::string();
- button_action = nullptr;
-}
-
-void gui::progress_bar::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale));
-
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale));
-
- const ImVec2 cursor = ImGui::GetCursorPos();
-
- const std::size_t num_bars = 32;
- const float spinner_width = 0.8f * ImGui::CalcItemWidth();
- const float bar_width = spinner_width / static_cast<float>(num_bars);
- const float bar_height = 0.5f * ImGui::GetFrameHeight();
-
- const float base_xpos = window_start.x + 0.5f * (window_size.x - spinner_width) + 0.5f;
- const float base_ypos = window_start.y + cursor.y;
- const float phase = 2.0f * ImGui::GetTime();
-
- const ImVec4& background = ImGui::GetStyleColorVec4(ImGuiCol_Button);
- const ImVec4& foreground = ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram);
-
- for(std::size_t i = 0; i < num_bars; ++i) {
- const float sinval = std::sin(M_PI * static_cast<float>(i) / static_cast<float>(num_bars) - phase);
- const float modifier = std::exp(-8.0f * (0.5f + 0.5f * sinval));
-
- ImVec4 color = {};
- color.x = glm::mix(background.x, foreground.x, modifier);
- color.y = glm::mix(background.y, foreground.y, modifier);
- color.z = glm::mix(background.z, foreground.z, modifier);
- color.w = glm::mix(background.w, foreground.w, modifier);
-
- const ImVec2 start = ImVec2(base_xpos + bar_width * i, base_ypos);
- const ImVec2 end = ImVec2(start.x + bar_width, start.y + bar_height);
- ImGui::GetWindowDrawList()->AddRectFilled(start, end, ImGui::GetColorU32(color));
- }
-
- // The NewLine call tricks ImGui into correctly padding the
- // next widget that comes after the progress_bar spinner; this
- // is needed to ensure the button is located in the correct place
- ImGui::NewLine();
-
- if(!str_button.empty()) {
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
-
- const float button_width = 0.8f * ImGui::CalcItemWidth();
- ImGui::SetCursorPosX(0.5f * (window_size.x - button_width));
-
- if(ImGui::Button(str_button.c_str(), ImVec2(button_width, 0.0f))) {
- if(button_action) {
- button_action();
- }
- }
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::progress_bar::reset(void)
-{
- str_title.clear();
- str_button.clear();
- button_action = nullptr;
-}
-
-void gui::progress_bar::set_title(std::string_view title)
-{
- str_title = gui::language::resolve(title);
-}
-
-void gui::progress_bar::set_button(std::string_view text, const progress_bar_action& action)
-{
- str_button = std::format("{}###ProgressBar_Button", gui::language::resolve(text));
- button_action = action;
-}
+#include "client/pch.hh" + +#include "client/gui/progress_bar.hh" + +#include "core/math/constexpr.hh" + +#include "client/gui/language.hh" + +#include "client/globals.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +static std::string str_title; +static std::string str_button; +static gui::progress_bar_action button_action; + +void gui::progress_bar::init(void) +{ + str_title = "Loading"; + str_button = std::string(); + button_action = nullptr; +} + +void gui::progress_bar::layout(void) +{ + const auto viewport = ImGui::GetMainViewport(); + const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f); + const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale)); + + const float title_width = ImGui::CalcTextSize(str_title.c_str()).x; + ImGui::SetCursorPosX(0.5f * (window_size.x - title_width)); + ImGui::TextUnformatted(str_title.c_str()); + + ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale)); + + const ImVec2 cursor = ImGui::GetCursorPos(); + + const std::size_t num_bars = 32; + const float spinner_width = 0.8f * ImGui::CalcItemWidth(); + const float bar_width = spinner_width / static_cast<float>(num_bars); + const float bar_height = 0.5f * ImGui::GetFrameHeight(); + + const float base_xpos = window_start.x + 0.5f * (window_size.x - spinner_width) + 0.5f; + const float base_ypos = window_start.y + cursor.y; + const float phase = 2.0f * static_cast<float>(ImGui::GetTime()); + + const ImVec4& background = ImGui::GetStyleColorVec4(ImGuiCol_Button); + const ImVec4& foreground = ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram); + + for(std::size_t i = 0; i < num_bars; ++i) { + const float sinval = std::sinf(float(M_PI) * static_cast<float>(i) / static_cast<float>(num_bars) - phase); + const float modifier = std::exp(-8.0f * (0.5f + 0.5f * sinval)); + + ImVec4 color = {}; + color.x = glm::mix(background.x, foreground.x, modifier); + color.y = glm::mix(background.y, foreground.y, modifier); + color.z = glm::mix(background.z, foreground.z, modifier); + color.w = glm::mix(background.w, foreground.w, modifier); + + const ImVec2 start = ImVec2(base_xpos + bar_width * i, base_ypos); + const ImVec2 end = ImVec2(start.x + bar_width, start.y + bar_height); + ImGui::GetWindowDrawList()->AddRectFilled(start, end, ImGui::GetColorU32(color)); + } + + // The NewLine call tricks ImGui into correctly padding the + // next widget that comes after the progress_bar spinner; this + // is needed to ensure the button is located in the correct place + ImGui::NewLine(); + + if(!str_button.empty()) { + ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale)); + + const float button_width = 0.8f * ImGui::CalcItemWidth(); + ImGui::SetCursorPosX(0.5f * (window_size.x - button_width)); + + if(ImGui::Button(str_button.c_str(), ImVec2(button_width, 0.0f))) { + if(button_action) { + button_action(); + } + } + } + + ImGui::PopStyleVar(); + } + + ImGui::End(); +} + +void gui::progress_bar::reset(void) +{ + str_title.clear(); + str_button.clear(); + button_action = nullptr; +} + +void gui::progress_bar::set_title(std::string_view title) +{ + str_title = gui::language::resolve(title); +} + +void gui::progress_bar::set_button(std::string_view text, const progress_bar_action& action) +{ + str_button = std::format("{}###ProgressBar_Button", gui::language::resolve(text)); + button_action = action; +} diff --git a/game/client/gui/progress_bar.hh b/src/game/client/gui/progress_bar.hh index 5f2e601..7a0581d 100644 --- a/game/client/gui/progress_bar.hh +++ b/src/game/client/gui/progress_bar.hh @@ -1,19 +1,19 @@ -#pragma once
-
-namespace gui
-{
-using progress_bar_action = void (*)(void);
-} // namespace gui
-
-namespace gui::progress_bar
-{
-void init(void);
-void layout(void);
-} // namespace gui::progress_bar
-
-namespace gui::progress_bar
-{
-void reset(void);
-void set_title(std::string_view title);
-void set_button(std::string_view text, const progress_bar_action& action);
-} // namespace gui::progress_bar
+#pragma once + +namespace gui +{ +using progress_bar_action = void (*)(void); +} // namespace gui + +namespace gui::progress_bar +{ +void init(void); +void layout(void); +} // namespace gui::progress_bar + +namespace gui::progress_bar +{ +void reset(void); +void set_title(std::string_view title); +void set_button(std::string_view text, const progress_bar_action& action); +} // namespace gui::progress_bar diff --git a/game/client/gui/scoreboard.cc b/src/game/client/gui/scoreboard.cc index 12a4f41..4f14de8 100644 --- a/game/client/gui/scoreboard.cc +++ b/src/game/client/gui/scoreboard.cc @@ -1,103 +1,103 @@ -#include "client/pch.hh"
-
-#include "client/gui/scoreboard.hh"
-
-#include "core/io/config_map.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/settings.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs
- | ImGuiWindowFlags_NoBackground;
-
-static config::KeyBind list_key(GLFW_KEY_TAB);
-
-static std::vector<std::string> usernames;
-static float max_username_size;
-
-static void on_scoreboard_update_packet(const protocol::ScoreboardUpdate& packet)
-{
- usernames = packet.names;
- max_username_size = 0.0f;
-}
-
-void gui::scoreboard::init(void)
-{
- globals::client_config.add_value("scoreboard.key", list_key);
-
- settings::add_keybind(3, list_key, settings_location::KEYBOARD_MISC, "key.scoreboard");
-
- globals::dispatcher.sink<protocol::ScoreboardUpdate>().connect<&on_scoreboard_update_packet>();
-}
-
-void gui::scoreboard::layout(void)
-{
- if(globals::gui_screen == GUI_SCREEN_NONE && session::is_ingame() && glfwGetKey(globals::window, list_key.get_key()) == GLFW_PRESS) {
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, 0.0f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) {
- ImGui::End();
- return;
- }
-
- ImGui::PushFont(globals::font_unscii16, 8.0f);
-
- const auto& padding = ImGui::GetStyle().FramePadding;
- const auto& spacing = ImGui::GetStyle().ItemSpacing;
- auto font = globals::font_unscii8;
-
- // Figure out the maximum username size
- for(const auto& username : usernames) {
- const ImVec2 size = ImGui::CalcTextSize(username.c_str(), username.c_str() + username.size());
-
- if(size.x > max_username_size) {
- max_username_size = size.x;
- }
- }
-
- // Having a minimum size allows for
- // generally better in-game visibility
- const float true_size = glm::max<float>(0.25f * window_size.x, max_username_size);
-
- // Figure out username rect dimensions
- const float rect_start_x = 0.5f * window_size.x - 0.5f * true_size;
- const float rect_start_y = 0.15f * window_size.y;
- const float rect_size_x = 2.0f * padding.x + true_size;
- const float rect_size_y = 2.0f * padding.y + 0.5f * ImGui::GetFontSize();
-
- // const ImU32 border_col = ImGui::GetColorU32(ImGuiCol_Border, 1.00f);
- const ImU32 rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, 0.80f);
- const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text, 1.00f);
-
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
-
- // Slightly space apart individual rows
- const float row_step_y = rect_size_y + 0.5f * spacing.y;
-
- for(std::size_t i = 0; i < usernames.size(); ++i) {
- const ImVec2 rect_a = ImVec2(rect_start_x, rect_start_y + i * row_step_y);
- const ImVec2 rect_b = ImVec2(rect_a.x + rect_size_x, rect_a.y + rect_size_y);
- const ImVec2 text_pos = ImVec2(rect_a.x + padding.x, rect_a.y + padding.y);
-
- // draw_list->AddRect(rect_a, rect_b, border_col, 0.0f, ImDrawFlags_None, globals::gui_scale);
- draw_list->AddRectFilled(rect_a, rect_b, rect_col, 0.0f, ImDrawFlags_None);
- draw_list->AddText(font, 0.5f * ImGui::GetFontSize(), text_pos, text_col, usernames[i].c_str(),
- usernames[i].c_str() + usernames[i].size());
- }
-
- ImGui::PopFont();
- ImGui::End();
- }
-}
+#include "client/pch.hh" + +#include "client/gui/scoreboard.hh" + +#include "core/io/config_map.hh" + +#include "shared/protocol.hh" + +#include "client/config/keybind.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/settings.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs + | ImGuiWindowFlags_NoBackground; + +static config::KeyBind list_key(GLFW_KEY_TAB); + +static std::vector<std::string> usernames; +static float max_username_size; + +static void on_scoreboard_update_packet(const protocol::ScoreboardUpdate& packet) +{ + usernames = packet.names; + max_username_size = 0.0f; +} + +void gui::scoreboard::init(void) +{ + globals::client_config.add_value("scoreboard.key", list_key); + + settings::add_keybind(3, list_key, settings_location::KEYBOARD_MISC, "key.scoreboard"); + + globals::dispatcher.sink<protocol::ScoreboardUpdate>().connect<&on_scoreboard_update_packet>(); +} + +void gui::scoreboard::layout(void) +{ + if(globals::gui_screen == GUI_SCREEN_NONE && session::is_ingame() && glfwGetKey(globals::window, list_key.get_key()) == GLFW_PRESS) { + const auto viewport = ImGui::GetMainViewport(); + const auto window_start = ImVec2(0.0f, 0.0f); + const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) { + ImGui::End(); + return; + } + + ImGui::PushFont(globals::font_unscii16, 8.0f); + + const auto& padding = ImGui::GetStyle().FramePadding; + const auto& spacing = ImGui::GetStyle().ItemSpacing; + auto font = globals::font_unscii8; + + // Figure out the maximum username size + for(const auto& username : usernames) { + const ImVec2 size = ImGui::CalcTextSize(username.c_str(), username.c_str() + username.size()); + + if(size.x > max_username_size) { + max_username_size = size.x; + } + } + + // Having a minimum size allows for + // generally better in-game visibility + const float true_size = glm::max<float>(0.25f * window_size.x, max_username_size); + + // Figure out username rect dimensions + const float rect_start_x = 0.5f * window_size.x - 0.5f * true_size; + const float rect_start_y = 0.15f * window_size.y; + const float rect_size_x = 2.0f * padding.x + true_size; + const float rect_size_y = 2.0f * padding.y + 0.5f * ImGui::GetFontSize(); + + // const ImU32 border_col = ImGui::GetColorU32(ImGuiCol_Border, 1.00f); + const ImU32 rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, 0.80f); + const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text, 1.00f); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Slightly space apart individual rows + const float row_step_y = rect_size_y + 0.5f * spacing.y; + + for(std::size_t i = 0; i < usernames.size(); ++i) { + const ImVec2 rect_a = ImVec2(rect_start_x, rect_start_y + i * row_step_y); + const ImVec2 rect_b = ImVec2(rect_a.x + rect_size_x, rect_a.y + rect_size_y); + const ImVec2 text_pos = ImVec2(rect_a.x + padding.x, rect_a.y + padding.y); + + // draw_list->AddRect(rect_a, rect_b, border_col, 0.0f, ImDrawFlags_None, globals::gui_scale); + draw_list->AddRectFilled(rect_a, rect_b, rect_col, 0.0f, ImDrawFlags_None); + draw_list->AddText(font, 0.5f * ImGui::GetFontSize(), text_pos, text_col, usernames[i].c_str(), + usernames[i].c_str() + usernames[i].size()); + } + + ImGui::PopFont(); + ImGui::End(); + } +} diff --git a/game/client/gui/scoreboard.hh b/src/game/client/gui/scoreboard.hh index 5f1c59d..320e185 100644 --- a/game/client/gui/scoreboard.hh +++ b/src/game/client/gui/scoreboard.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace gui::scoreboard
-{
-void init(void);
-void layout(void);
-} // namespace gui::scoreboard
+#pragma once + +namespace gui::scoreboard +{ +void init(void); +void layout(void); +} // namespace gui::scoreboard diff --git a/game/client/gui/settings.cc b/src/game/client/gui/settings.cc index db26d8c..70852b2 100644 --- a/game/client/gui/settings.cc +++ b/src/game/client/gui/settings.cc @@ -1,1069 +1,1069 @@ -#include "client/pch.hh"
-
-#include "client/gui/settings.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/config/gamepad_axis.hh"
-#include "client/config/gamepad_button.hh"
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static unsigned int NUM_LOCATIONS = static_cast<unsigned int>(settings_location::COUNT);
-
-enum class setting_type : unsigned int {
- CHECKBOX = 0x0000U, ///< config::Boolean
- INPUT_INT = 0x0001U, ///< config::Number<int>
- INPUT_FLOAT = 0x0002U, ///< config::Number<float>
- INPUT_UINT = 0x0003U, ///< config::Number<unsigned int>
- INPUT_STRING = 0x0004U, ///< config::String
- SLIDER_INT = 0x0005U, ///< config::Number<int>
- SLIDER_FLOAT = 0x0006U, ///< config::Number<float>
- SLIDER_UINT = 0x0007U, ///< config::Number<unsigned int>
- STEPPER_INT = 0x0008U, ///< config::Number<int>
- STEPPER_UINT = 0x0009U, ///< config::Number<unsigned int>
- KEYBIND = 0x000AU, ///< config::KeyBind
- GAMEPAD_AXIS = 0x000BU, ///< config::GamepadAxis
- GAMEPAD_BUTTON = 0x000CU, ///< config::GamepadButton
- LANGUAGE_SELECT = 0x000DU, ///< config::String internally
-};
-
-class SettingValue {
-public:
- virtual ~SettingValue(void) = default;
- virtual void layout(void) const = 0;
- void layout_tooltip(void) const;
- void layout_label(void) const;
-
-public:
- setting_type type;
- std::string tooltip;
- std::string title;
- std::string name;
- bool has_tooltip;
- int priority;
-};
-
-class SettingValueWID : public SettingValue {
-public:
- virtual ~SettingValueWID(void) = default;
-
-public:
- std::string wid;
-};
-
-class SettingValue_CheckBox final : public SettingValue {
-public:
- virtual ~SettingValue_CheckBox(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- config::Boolean* value;
- std::string wids[2];
-};
-
-class SettingValue_InputInt final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputInt(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Int* value;
-};
-
-class SettingValue_InputFloat final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputFloat(void) = default;
- virtual void layout(void) const override;
-
-public:
- std::string format;
- config::Float* value;
-};
-
-class SettingValue_InputUnsigned final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputUnsigned(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Unsigned* value;
-};
-
-class SettingValue_InputString final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputString(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::String* value;
- bool allow_whitespace;
-};
-
-class SettingValue_SliderInt final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderInt(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Int* value;
-};
-
-class SettingValue_SliderFloat final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderFloat(void) = default;
- virtual void layout(void) const override;
-
-public:
- std::string format;
- config::Float* value;
-};
-
-class SettingValue_SliderUnsigned final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderUnsigned(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Unsigned* value;
-};
-
-class SettingValue_StepperInt final : public SettingValue {
-public:
- virtual ~SettingValue_StepperInt(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::vector<std::string> wids;
- config::Int* value;
-};
-
-class SettingValue_StepperUnsigned final : public SettingValue {
-public:
- virtual ~SettingValue_StepperUnsigned(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::vector<std::string> wids;
- config::Unsigned* value;
-};
-
-class SettingValue_KeyBind final : public SettingValue {
-public:
- virtual ~SettingValue_KeyBind(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- config::KeyBind* value;
-};
-
-class SettingValue_GamepadAxis final : public SettingValue {
-public:
- virtual ~SettingValue_GamepadAxis(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- std::string wid_checkbox;
- config::GamepadAxis* value;
-};
-
-class SettingValue_GamepadButton final : public SettingValue {
-public:
- virtual ~SettingValue_GamepadButton(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- config::GamepadButton* value;
-};
-
-class SettingValue_Language final : public SettingValueWID {
-public:
- virtual ~SettingValue_Language(void) = default;
- virtual void layout(void) const override;
-};
-
-static std::string str_checkbox_false;
-static std::string str_checkbox_true;
-
-static std::string str_tab_general;
-static std::string str_tab_input;
-static std::string str_tab_video;
-static std::string str_tab_sound;
-
-static std::string str_input_keyboard;
-static std::string str_input_gamepad;
-static std::string str_input_mouse;
-
-static std::string str_keyboard_movement;
-static std::string str_keyboard_gameplay;
-static std::string str_keyboard_misc;
-
-static std::string str_gamepad_movement;
-static std::string str_gamepad_gameplay;
-static std::string str_gamepad_misc;
-
-static std::string str_gamepad_axis_prefix;
-static std::string str_gamepad_button_prefix;
-static std::string str_gamepad_checkbox_tooltip;
-
-static std::string str_video_gui;
-
-static std::string str_sound_levels;
-
-static std::vector<SettingValue*> values_all;
-static std::vector<SettingValue*> values[NUM_LOCATIONS];
-
-void SettingValue::layout_tooltip(void) const
-{
- if(has_tooltip) {
- ImGui::SameLine();
- ImGui::TextDisabled("[?]");
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(tooltip.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
- }
-}
-
-void SettingValue::layout_label(void) const
-{
- ImGui::SameLine();
- ImGui::TextUnformatted(title.c_str());
-}
-
-void SettingValue_CheckBox::refresh_wids(void)
-{
- wids[0] = std::format("{}###{}", str_checkbox_false, static_cast<void*>(value));
- wids[1] = std::format("{}###{}", str_checkbox_true, static_cast<void*>(value));
-}
-
-void SettingValue_CheckBox::layout(void) const
-{
- const auto& wid = value->get_value() ? wids[1] : wids[0];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- value->set_value(!value->get_value());
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputInt::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::InputInt(wid.c_str(), ¤t_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputFloat::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::InputFloat(wid.c_str(), ¤t_value, 0.0f, 0.0f, format.c_str())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputUnsigned::layout(void) const
-{
- auto current_value = static_cast<std::uint32_t>(value->get_value());
-
- if(ImGui::InputScalar(wid.c_str(), ImGuiDataType_U32, ¤t_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputString::layout(void) const
-{
- ImGuiInputTextFlags flags;
- std::string current_value(value->get_value());
-
- if(allow_whitespace) {
- flags = ImGuiInputTextFlags_AllowTabInput;
- }
- else {
- flags = 0;
- }
-
- if(ImGui::InputText(wid.c_str(), ¤t_value, flags)) {
- value->set(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderInt::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::SliderInt(wid.c_str(), ¤t_value, value->get_min_value(), value->get_max_value())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderFloat::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::SliderFloat(wid.c_str(), ¤t_value, value->get_min_value(), value->get_max_value(), format.c_str())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderUnsigned::layout(void) const
-{
- auto current_value = static_cast<std::uint32_t>(value->get_value());
- auto min_value = static_cast<std::uint32_t>(value->get_min_value());
- auto max_value = static_cast<std::uint32_t>(value->get_max_value());
-
- if(ImGui::SliderScalar(wid.c_str(), ImGuiDataType_U32, ¤t_value, &min_value, &max_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperInt::layout(void) const
-{
- auto current_value = value->get_value();
- auto min_value = value->get_min_value();
- auto max_value = value->get_max_value();
-
- auto current_wid = current_value - min_value;
-
- if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- current_value += 1;
- }
-
- if(current_value > max_value) {
- value->set_value(min_value);
- }
- else {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperInt::refresh_wids(void)
-{
- for(std::size_t i = 0; i < wids.size(); ++i) {
- auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
- }
-}
-
-void SettingValue_StepperUnsigned::layout(void) const
-{
- auto current_value = value->get_value();
- auto min_value = value->get_min_value();
- auto max_value = value->get_max_value();
-
- auto current_wid = current_value - min_value;
-
- if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- current_value += 1U;
- }
-
- if(current_value > max_value) {
- value->set_value(min_value);
- }
- else {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperUnsigned::refresh_wids(void)
-{
- for(std::size_t i = 0; i < wids.size(); ++i) {
- auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
- }
-}
-
-void SettingValue_KeyBind::layout(void) const
-{
- const auto is_active = ((globals::gui_keybind_ptr == value) && !globals::gui_gamepad_axis_ptr && !globals::gui_gamepad_button_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_keybind_ptr = value;
- }
-
- layout_label();
-}
-
-void SettingValue_KeyBind::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value));
-}
-
-void SettingValue_GamepadAxis::layout(void) const
-{
- const auto is_active = ((globals::gui_gamepad_axis_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_button_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
- auto is_inverted = value->is_inverted();
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth() - ImGui::GetFrameHeight() - ImGui::GetStyle().ItemSpacing.x, 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_axis_ptr = value;
- }
-
- ImGui::SameLine();
-
- if(ImGui::Checkbox(wid_checkbox.c_str(), &is_inverted)) {
- value->set_inverted(is_inverted);
- }
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_gamepad_checkbox_tooltip.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- layout_label();
-}
-
-void SettingValue_GamepadAxis::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get_name(), static_cast<const void*>(value));
- wid_checkbox = std::format("###CHECKBOX_{}", static_cast<const void*>(value));
-}
-
-void SettingValue_GamepadButton::layout(void) const
-{
- const auto is_active = ((globals::gui_gamepad_button_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_axis_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_button_ptr = value;
- }
-
- layout_label();
-}
-
-void SettingValue_GamepadButton::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value));
-}
-
-void SettingValue_Language::layout(void) const
-{
- auto current_language = gui::language::get_current();
-
- if(ImGui::BeginCombo(wid.c_str(), current_language->endonym.c_str())) {
- for(auto it = gui::language::cbegin(); it != gui::language::cend(); ++it) {
- if(ImGui::Selectable(it->display.c_str(), it == current_language)) {
- gui::language::set(it);
- continue;
- }
- }
-
- ImGui::EndCombo();
- }
-
- layout_label();
- layout_tooltip();
-}
-
-static void refresh_input_wids(void)
-{
- for(SettingValue* value : values_all) {
- if(value->type == setting_type::KEYBIND) {
- auto keybind = static_cast<SettingValue_KeyBind*>(value);
- keybind->refresh_wids();
- continue;
- }
-
- if(value->type == setting_type::GAMEPAD_AXIS) {
- auto gamepad_axis = static_cast<SettingValue_GamepadAxis*>(value);
- gamepad_axis->refresh_wids();
- continue;
- }
-
- if(value->type == setting_type::GAMEPAD_BUTTON) {
- auto gamepad_button = static_cast<SettingValue_GamepadButton*>(value);
- gamepad_button->refresh_wids();
- }
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.action == GLFW_PRESS) && (event.key != DEBUG_KEY)) {
- if(globals::gui_keybind_ptr || globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr) {
- if(event.key == GLFW_KEY_ESCAPE) {
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_keybind_ptr = nullptr;
- globals::gui_gamepad_axis_ptr = nullptr;
- globals::gui_gamepad_button_ptr = nullptr;
-
- return;
- }
-
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_keybind_ptr->set_key(event.key);
- globals::gui_keybind_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_SETTINGS)) {
- globals::gui_screen = GUI_MAIN_MENU;
- return;
- }
- }
-}
-
-static void on_gamepad_axis(const io::GamepadAxisEvent& event)
-{
- if(globals::gui_gamepad_axis_ptr) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_gamepad_axis_ptr->set_axis(event.axis);
- globals::gui_gamepad_axis_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-}
-
-static void on_gamepad_button(const io::GamepadButtonEvent& event)
-{
- if(globals::gui_gamepad_button_ptr) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_gamepad_button_ptr->set_button(event.button);
- globals::gui_gamepad_button_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_checkbox_false = gui::language::resolve("settings.checkbox.false");
- str_checkbox_true = gui::language::resolve("settings.checkbox.true");
-
- str_tab_general = gui::language::resolve("settings.tab.general");
- str_tab_input = gui::language::resolve("settings.tab.input");
- str_tab_video = gui::language::resolve("settings.tab.video");
- str_tab_sound = gui::language::resolve("settings.tab.sound");
-
- str_input_keyboard = gui::language::resolve("settings.input.keyboard");
- str_input_gamepad = gui::language::resolve("settings.input.gamepad");
- str_input_mouse = gui::language::resolve("settings.input.mouse");
-
- str_keyboard_movement = gui::language::resolve("settings.keyboard.movement");
- str_keyboard_gameplay = gui::language::resolve("settings.keyboard.gameplay");
- str_keyboard_misc = gui::language::resolve("settings.keyboard.misc");
-
- str_gamepad_movement = gui::language::resolve("settings.gamepad.movement");
- str_gamepad_gameplay = gui::language::resolve("settings.gamepad.gameplay");
- str_gamepad_misc = gui::language::resolve("settings.gamepad.misc");
-
- str_gamepad_axis_prefix = gui::language::resolve("settings.gamepad.axis");
- str_gamepad_button_prefix = gui::language::resolve("settings.gamepad.button");
- str_gamepad_checkbox_tooltip = gui::language::resolve("settings.gamepad.checkbox_tooltip");
-
- str_video_gui = gui::language::resolve("settings.video.gui");
-
- str_sound_levels = gui::language::resolve("settings.sound.levels");
-
- for(SettingValue* value : values_all) {
- if(value->type == setting_type::CHECKBOX) {
- auto checkbox = static_cast<SettingValue_CheckBox*>(value);
- checkbox->refresh_wids();
- }
-
- if(value->type == setting_type::STEPPER_INT) {
- auto stepper = static_cast<SettingValue_StepperInt*>(value);
- stepper->refresh_wids();
- }
-
- if(value->type == setting_type::STEPPER_UINT) {
- auto stepper = static_cast<SettingValue_StepperUnsigned*>(value);
- stepper->refresh_wids();
- }
-
- value->title = gui::language::resolve(std::format("settings.value.{}", value->name).c_str());
-
- if(value->has_tooltip) {
- value->tooltip = gui::language::resolve(std::format("settings.tooltip.{}", value->name).c_str());
- }
- }
-}
-
-static void layout_values(settings_location location)
-{
- ImGui::PushItemWidth(ImGui::CalcItemWidth() * 0.70f);
-
- for(const SettingValue* value : values[static_cast<unsigned int>(location)]) {
- value->layout();
- }
-
- ImGui::PopItemWidth();
-}
-
-static void layout_general(void)
-{
- if(ImGui::BeginChild("###settings.general.child")) {
- layout_values(settings_location::GENERAL);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_keyboard(void)
-{
- if(ImGui::BeginChild("###settings.input.keyboard.child")) {
- ImGui::SeparatorText(str_keyboard_movement.c_str());
- layout_values(settings_location::KEYBOARD_MOVEMENT);
- ImGui::SeparatorText(str_keyboard_gameplay.c_str());
- layout_values(settings_location::KEYBOARD_GAMEPLAY);
- ImGui::SeparatorText(str_keyboard_misc.c_str());
- layout_values(settings_location::KEYBOARD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_gamepad(void)
-{
- if(ImGui::BeginChild("###settings.input.gamepad.child")) {
- layout_values(settings_location::GAMEPAD);
- ImGui::SeparatorText(str_gamepad_movement.c_str());
- layout_values(settings_location::GAMEPAD_MOVEMENT);
- ImGui::SeparatorText(str_gamepad_gameplay.c_str());
- layout_values(settings_location::GAMEPAD_GAMEPLAY);
- ImGui::SeparatorText(str_gamepad_misc.c_str());
- layout_values(settings_location::GAMEPAD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_mouse(void)
-{
- if(ImGui::BeginChild("###settings.input.mouse.child")) {
- layout_values(settings_location::MOUSE);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input(void)
-{
- if(ImGui::BeginTabBar("###settings.input.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::BeginTabItem(str_input_keyboard.c_str())) {
- layout_input_keyboard();
- ImGui::EndTabItem();
- }
-
- if(io::gamepad::available) {
- if(ImGui::BeginTabItem(str_input_gamepad.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_gamepad();
- ImGui::EndTabItem();
- }
- }
-
- if(ImGui::BeginTabItem(str_input_mouse.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_mouse();
- ImGui::EndTabItem();
- }
-
- ImGui::EndTabBar();
- }
-}
-
-static void layout_video(void)
-{
- if(ImGui::BeginChild("###settings.video.child")) {
- layout_values(settings_location::VIDEO);
- ImGui::SeparatorText(str_video_gui.c_str());
- layout_values(settings_location::VIDEO_GUI);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_sound(void)
-{
- if(ImGui::BeginChild("###settings.sound.child")) {
- layout_values(settings_location::SOUND);
- ImGui::SeparatorText(str_sound_levels.c_str());
- layout_values(settings_location::SOUND_LEVELS);
- }
-
- ImGui::EndChild();
-}
-
-void settings::init(void)
-{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GamepadAxisEvent>().connect<&on_gamepad_axis>();
- globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>();
- globals::dispatcher.sink<gui::LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void settings::init_late(void)
-{
- for(std::size_t i = 0; i < NUM_LOCATIONS; ++i) {
- std::sort(values[i].begin(), values[i].end(), [](const SettingValue* a, const SettingValue* b) {
- return a->priority < b->priority;
- });
- }
-
- refresh_input_wids();
-}
-
-void settings::shutdown(void)
-{
- for(const SettingValue* value : values_all)
- delete value;
- for(std::size_t i = 0; i < NUM_LOCATIONS; values[i++].clear())
- ;
- values_all.clear();
-}
-
-void settings::layout(void)
-{
- const ImGuiViewport* viewport = ImGui::GetMainViewport();
- const ImVec2 window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
- const ImVec2 window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###settings", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale));
-
- if(ImGui::BeginTabBar("###settings.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::TabItemButton("<<")) {
- globals::gui_screen = GUI_MAIN_MENU;
- globals::gui_keybind_ptr = nullptr;
- }
-
- if(ImGui::BeginTabItem(str_tab_general.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_general();
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem(str_tab_input.c_str())) {
- layout_input();
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem(str_tab_video.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_video();
- ImGui::EndTabItem();
- }
-
- if(globals::sound_ctx && globals::sound_dev) {
- if(ImGui::BeginTabItem(str_tab_sound.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_sound();
- ImGui::EndTabItem();
- }
- }
-
- ImGui::EndTabBar();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void settings::add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_CheckBox;
- setting_value->type = setting_type::CHECKBOX;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_InputInt;
- setting_value->type = setting_type::INPUT_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt)
-{
- auto setting_value = new SettingValue_InputFloat;
- setting_value->type = setting_type::INPUT_FLOAT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->format = fmt;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_InputUnsigned;
- setting_value->type = setting_type::INPUT_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip,
- bool allow_whitespace)
-{
- auto setting_value = new SettingValue_InputString;
- setting_value->type = setting_type::INPUT_STRING;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->allow_whitespace = allow_whitespace;
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_SliderInt;
- setting_value->type = setting_type::SLIDER_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt)
-{
- auto setting_value = new SettingValue_SliderFloat;
- setting_value->type = setting_type::SLIDER_FLOAT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->format = fmt;
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_SliderUnsigned;
- setting_value->type = setting_type::SLIDER_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_StepperInt;
- setting_value->type = setting_type::STEPPER_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1);
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_StepperUnsigned;
- setting_value->type = setting_type::STEPPER_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1);
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_KeyBind;
- setting_value->type = setting_type::KEYBIND;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_GamepadAxis;
- setting_value->type = setting_type::GAMEPAD_AXIS;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_GamepadButton;
- setting_value->type = setting_type::GAMEPAD_BUTTON;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_language_select(int priority, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_Language;
- setting_value->type = setting_type::LANGUAGE_SELECT;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
+#include "client/pch.hh" + +#include "client/gui/settings.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" +#include "core/config/string.hh" + +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" + +#include "client/config/gamepad_axis.hh" +#include "client/config/gamepad_button.hh" +#include "client/config/keybind.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" + +#include "client/io/gamepad.hh" +#include "client/io/glfw.hh" + +#include "client/const.hh" +#include "client/globals.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; +constexpr static unsigned int NUM_LOCATIONS = static_cast<unsigned int>(settings_location::COUNT); + +enum class setting_type : unsigned int { + CHECKBOX = 0x0000U, ///< config::Boolean + INPUT_INT = 0x0001U, ///< config::Number<int> + INPUT_FLOAT = 0x0002U, ///< config::Number<float> + INPUT_UINT = 0x0003U, ///< config::Number<unsigned int> + INPUT_STRING = 0x0004U, ///< config::String + SLIDER_INT = 0x0005U, ///< config::Number<int> + SLIDER_FLOAT = 0x0006U, ///< config::Number<float> + SLIDER_UINT = 0x0007U, ///< config::Number<unsigned int> + STEPPER_INT = 0x0008U, ///< config::Number<int> + STEPPER_UINT = 0x0009U, ///< config::Number<unsigned int> + KEYBIND = 0x000AU, ///< config::KeyBind + GAMEPAD_AXIS = 0x000BU, ///< config::GamepadAxis + GAMEPAD_BUTTON = 0x000CU, ///< config::GamepadButton + LANGUAGE_SELECT = 0x000DU, ///< config::String internally +}; + +class SettingValue { +public: + virtual ~SettingValue(void) = default; + virtual void layout(void) const = 0; + void layout_tooltip(void) const; + void layout_label(void) const; + +public: + setting_type type; + std::string tooltip; + std::string title; + std::string name; + bool has_tooltip; + int priority; +}; + +class SettingValueWID : public SettingValue { +public: + virtual ~SettingValueWID(void) = default; + +public: + std::string wid; +}; + +class SettingValue_CheckBox final : public SettingValue { +public: + virtual ~SettingValue_CheckBox(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + config::Boolean* value; + std::string wids[2]; +}; + +class SettingValue_InputInt final : public SettingValueWID { +public: + virtual ~SettingValue_InputInt(void) = default; + virtual void layout(void) const override; + +public: + config::Int* value; +}; + +class SettingValue_InputFloat final : public SettingValueWID { +public: + virtual ~SettingValue_InputFloat(void) = default; + virtual void layout(void) const override; + +public: + std::string format; + config::Float* value; +}; + +class SettingValue_InputUnsigned final : public SettingValueWID { +public: + virtual ~SettingValue_InputUnsigned(void) = default; + virtual void layout(void) const override; + +public: + config::Unsigned* value; +}; + +class SettingValue_InputString final : public SettingValueWID { +public: + virtual ~SettingValue_InputString(void) = default; + virtual void layout(void) const override; + +public: + config::String* value; + bool allow_whitespace; +}; + +class SettingValue_SliderInt final : public SettingValueWID { +public: + virtual ~SettingValue_SliderInt(void) = default; + virtual void layout(void) const override; + +public: + config::Int* value; +}; + +class SettingValue_SliderFloat final : public SettingValueWID { +public: + virtual ~SettingValue_SliderFloat(void) = default; + virtual void layout(void) const override; + +public: + std::string format; + config::Float* value; +}; + +class SettingValue_SliderUnsigned final : public SettingValueWID { +public: + virtual ~SettingValue_SliderUnsigned(void) = default; + virtual void layout(void) const override; + +public: + config::Unsigned* value; +}; + +class SettingValue_StepperInt final : public SettingValue { +public: + virtual ~SettingValue_StepperInt(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + std::vector<std::string> wids; + config::Int* value; +}; + +class SettingValue_StepperUnsigned final : public SettingValue { +public: + virtual ~SettingValue_StepperUnsigned(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + std::vector<std::string> wids; + config::Unsigned* value; +}; + +class SettingValue_KeyBind final : public SettingValue { +public: + virtual ~SettingValue_KeyBind(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + std::string wids[2]; + config::KeyBind* value; +}; + +class SettingValue_GamepadAxis final : public SettingValue { +public: + virtual ~SettingValue_GamepadAxis(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + std::string wids[2]; + std::string wid_checkbox; + config::GamepadAxis* value; +}; + +class SettingValue_GamepadButton final : public SettingValue { +public: + virtual ~SettingValue_GamepadButton(void) = default; + virtual void layout(void) const override; + void refresh_wids(void); + +public: + std::string wids[2]; + config::GamepadButton* value; +}; + +class SettingValue_Language final : public SettingValueWID { +public: + virtual ~SettingValue_Language(void) = default; + virtual void layout(void) const override; +}; + +static std::string str_checkbox_false; +static std::string str_checkbox_true; + +static std::string str_tab_general; +static std::string str_tab_input; +static std::string str_tab_video; +static std::string str_tab_sound; + +static std::string str_input_keyboard; +static std::string str_input_gamepad; +static std::string str_input_mouse; + +static std::string str_keyboard_movement; +static std::string str_keyboard_gameplay; +static std::string str_keyboard_misc; + +static std::string str_gamepad_movement; +static std::string str_gamepad_gameplay; +static std::string str_gamepad_misc; + +static std::string str_gamepad_axis_prefix; +static std::string str_gamepad_button_prefix; +static std::string str_gamepad_checkbox_tooltip; + +static std::string str_video_gui; + +static std::string str_sound_levels; + +static std::vector<SettingValue*> values_all; +static std::vector<SettingValue*> values[NUM_LOCATIONS]; + +void SettingValue::layout_tooltip(void) const +{ + if(has_tooltip) { + ImGui::SameLine(); + ImGui::TextDisabled("[?]"); + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(tooltip.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + } +} + +void SettingValue::layout_label(void) const +{ + ImGui::SameLine(); + ImGui::TextUnformatted(title.c_str()); +} + +void SettingValue_CheckBox::refresh_wids(void) +{ + wids[0] = std::format("{}###{}", str_checkbox_false, static_cast<void*>(value)); + wids[1] = std::format("{}###{}", str_checkbox_true, static_cast<void*>(value)); +} + +void SettingValue_CheckBox::layout(void) const +{ + const auto& wid = value->get_value() ? wids[1] : wids[0]; + + if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) { + value->set_value(!value->get_value()); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_InputInt::layout(void) const +{ + auto current_value = value->get_value(); + + if(ImGui::InputInt(wid.c_str(), ¤t_value)) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_InputFloat::layout(void) const +{ + auto current_value = value->get_value(); + + if(ImGui::InputFloat(wid.c_str(), ¤t_value, 0.0f, 0.0f, format.c_str())) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_InputUnsigned::layout(void) const +{ + auto current_value = static_cast<std::uint32_t>(value->get_value()); + + if(ImGui::InputScalar(wid.c_str(), ImGuiDataType_U32, ¤t_value)) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_InputString::layout(void) const +{ + ImGuiInputTextFlags flags; + std::string current_value(value->get_value()); + + if(allow_whitespace) { + flags = ImGuiInputTextFlags_AllowTabInput; + } + else { + flags = 0; + } + + if(ImGui::InputText(wid.c_str(), ¤t_value, flags)) { + value->set(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_SliderInt::layout(void) const +{ + auto current_value = value->get_value(); + + if(ImGui::SliderInt(wid.c_str(), ¤t_value, value->get_min_value(), value->get_max_value())) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_SliderFloat::layout(void) const +{ + auto current_value = value->get_value(); + + if(ImGui::SliderFloat(wid.c_str(), ¤t_value, value->get_min_value(), value->get_max_value(), format.c_str())) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_SliderUnsigned::layout(void) const +{ + auto current_value = static_cast<std::uint32_t>(value->get_value()); + auto min_value = static_cast<std::uint32_t>(value->get_min_value()); + auto max_value = static_cast<std::uint32_t>(value->get_max_value()); + + if(ImGui::SliderScalar(wid.c_str(), ImGuiDataType_U32, ¤t_value, &min_value, &max_value)) { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_StepperInt::layout(void) const +{ + auto current_value = value->get_value(); + auto min_value = value->get_min_value(); + auto max_value = value->get_max_value(); + + auto current_wid = current_value - min_value; + + if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) { + current_value += 1; + } + + if(current_value > max_value) { + value->set_value(min_value); + } + else { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_StepperInt::refresh_wids(void) +{ + for(std::size_t i = 0; i < wids.size(); ++i) { + auto key = std::format("settings.value.{}.{}", name, i); + wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value)); + } +} + +void SettingValue_StepperUnsigned::layout(void) const +{ + auto current_value = value->get_value(); + auto min_value = value->get_min_value(); + auto max_value = value->get_max_value(); + + auto current_wid = current_value - min_value; + + if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) { + current_value += 1U; + } + + if(current_value > max_value) { + value->set_value(min_value); + } + else { + value->set_value(current_value); + } + + layout_label(); + layout_tooltip(); +} + +void SettingValue_StepperUnsigned::refresh_wids(void) +{ + for(std::size_t i = 0; i < wids.size(); ++i) { + auto key = std::format("settings.value.{}.{}", name, i); + wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value)); + } +} + +void SettingValue_KeyBind::layout(void) const +{ + const auto is_active = ((globals::gui_keybind_ptr == value) && !globals::gui_gamepad_axis_ptr && !globals::gui_gamepad_button_ptr); + const auto& wid = is_active ? wids[0] : wids[1]; + + if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) { + auto& io = ImGui::GetIO(); + io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; + globals::gui_keybind_ptr = value; + } + + layout_label(); +} + +void SettingValue_KeyBind::refresh_wids(void) +{ + wids[0] = std::format("...###{}", static_cast<const void*>(value)); + wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value)); +} + +void SettingValue_GamepadAxis::layout(void) const +{ + const auto is_active = ((globals::gui_gamepad_axis_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_button_ptr); + const auto& wid = is_active ? wids[0] : wids[1]; + auto is_inverted = value->is_inverted(); + + if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth() - ImGui::GetFrameHeight() - ImGui::GetStyle().ItemSpacing.x, 0.0f))) { + auto& io = ImGui::GetIO(); + io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; + globals::gui_gamepad_axis_ptr = value; + } + + ImGui::SameLine(); + + if(ImGui::Checkbox(wid_checkbox.c_str(), &is_inverted)) { + value->set_inverted(is_inverted); + } + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(str_gamepad_checkbox_tooltip.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + layout_label(); +} + +void SettingValue_GamepadAxis::refresh_wids(void) +{ + wids[0] = std::format("...###{}", static_cast<const void*>(value)); + wids[1] = std::format("{}###{}", value->get_name(), static_cast<const void*>(value)); + wid_checkbox = std::format("###CHECKBOX_{}", static_cast<const void*>(value)); +} + +void SettingValue_GamepadButton::layout(void) const +{ + const auto is_active = ((globals::gui_gamepad_button_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_axis_ptr); + const auto& wid = is_active ? wids[0] : wids[1]; + + if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) { + auto& io = ImGui::GetIO(); + io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; + globals::gui_gamepad_button_ptr = value; + } + + layout_label(); +} + +void SettingValue_GamepadButton::refresh_wids(void) +{ + wids[0] = std::format("...###{}", static_cast<const void*>(value)); + wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value)); +} + +void SettingValue_Language::layout(void) const +{ + auto current_language = gui::language::get_current(); + + if(ImGui::BeginCombo(wid.c_str(), current_language->endonym.c_str())) { + for(auto it = gui::language::cbegin(); it != gui::language::cend(); ++it) { + if(ImGui::Selectable(it->display.c_str(), it == current_language)) { + gui::language::set(it); + continue; + } + } + + ImGui::EndCombo(); + } + + layout_label(); + layout_tooltip(); +} + +static void refresh_input_wids(void) +{ + for(SettingValue* value : values_all) { + if(value->type == setting_type::KEYBIND) { + auto keybind = static_cast<SettingValue_KeyBind*>(value); + keybind->refresh_wids(); + continue; + } + + if(value->type == setting_type::GAMEPAD_AXIS) { + auto gamepad_axis = static_cast<SettingValue_GamepadAxis*>(value); + gamepad_axis->refresh_wids(); + continue; + } + + if(value->type == setting_type::GAMEPAD_BUTTON) { + auto gamepad_button = static_cast<SettingValue_GamepadButton*>(value); + gamepad_button->refresh_wids(); + } + } +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if((event.action == GLFW_PRESS) && (event.key != DEBUG_KEY)) { + if(globals::gui_keybind_ptr || globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr) { + if(event.key == GLFW_KEY_ESCAPE) { + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + globals::gui_keybind_ptr = nullptr; + globals::gui_gamepad_axis_ptr = nullptr; + globals::gui_gamepad_button_ptr = nullptr; + + return; + } + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + globals::gui_keybind_ptr->set_key(event.key); + globals::gui_keybind_ptr = nullptr; + + refresh_input_wids(); + + return; + } + + if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_SETTINGS)) { + globals::gui_screen = GUI_MAIN_MENU; + return; + } + } +} + +static void on_gamepad_axis(const io::GamepadAxisEvent& event) +{ + if(globals::gui_gamepad_axis_ptr) { + auto& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + globals::gui_gamepad_axis_ptr->set_axis(event.axis); + globals::gui_gamepad_axis_ptr = nullptr; + + refresh_input_wids(); + + return; + } +} + +static void on_gamepad_button(const io::GamepadButtonEvent& event) +{ + if(globals::gui_gamepad_button_ptr) { + auto& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + globals::gui_gamepad_button_ptr->set_button(event.button); + globals::gui_gamepad_button_ptr = nullptr; + + refresh_input_wids(); + + return; + } +} + +static void on_language_set(const gui::LanguageSetEvent& event) +{ + str_checkbox_false = gui::language::resolve("settings.checkbox.false"); + str_checkbox_true = gui::language::resolve("settings.checkbox.true"); + + str_tab_general = gui::language::resolve("settings.tab.general"); + str_tab_input = gui::language::resolve("settings.tab.input"); + str_tab_video = gui::language::resolve("settings.tab.video"); + str_tab_sound = gui::language::resolve("settings.tab.sound"); + + str_input_keyboard = gui::language::resolve("settings.input.keyboard"); + str_input_gamepad = gui::language::resolve("settings.input.gamepad"); + str_input_mouse = gui::language::resolve("settings.input.mouse"); + + str_keyboard_movement = gui::language::resolve("settings.keyboard.movement"); + str_keyboard_gameplay = gui::language::resolve("settings.keyboard.gameplay"); + str_keyboard_misc = gui::language::resolve("settings.keyboard.misc"); + + str_gamepad_movement = gui::language::resolve("settings.gamepad.movement"); + str_gamepad_gameplay = gui::language::resolve("settings.gamepad.gameplay"); + str_gamepad_misc = gui::language::resolve("settings.gamepad.misc"); + + str_gamepad_axis_prefix = gui::language::resolve("settings.gamepad.axis"); + str_gamepad_button_prefix = gui::language::resolve("settings.gamepad.button"); + str_gamepad_checkbox_tooltip = gui::language::resolve("settings.gamepad.checkbox_tooltip"); + + str_video_gui = gui::language::resolve("settings.video.gui"); + + str_sound_levels = gui::language::resolve("settings.sound.levels"); + + for(SettingValue* value : values_all) { + if(value->type == setting_type::CHECKBOX) { + auto checkbox = static_cast<SettingValue_CheckBox*>(value); + checkbox->refresh_wids(); + } + + if(value->type == setting_type::STEPPER_INT) { + auto stepper = static_cast<SettingValue_StepperInt*>(value); + stepper->refresh_wids(); + } + + if(value->type == setting_type::STEPPER_UINT) { + auto stepper = static_cast<SettingValue_StepperUnsigned*>(value); + stepper->refresh_wids(); + } + + value->title = gui::language::resolve(std::format("settings.value.{}", value->name).c_str()); + + if(value->has_tooltip) { + value->tooltip = gui::language::resolve(std::format("settings.tooltip.{}", value->name).c_str()); + } + } +} + +static void layout_values(settings_location location) +{ + ImGui::PushItemWidth(ImGui::CalcItemWidth() * 0.70f); + + for(const SettingValue* value : values[static_cast<unsigned int>(location)]) { + value->layout(); + } + + ImGui::PopItemWidth(); +} + +static void layout_general(void) +{ + if(ImGui::BeginChild("###settings.general.child")) { + layout_values(settings_location::GENERAL); + } + + ImGui::EndChild(); +} + +static void layout_input_keyboard(void) +{ + if(ImGui::BeginChild("###settings.input.keyboard.child")) { + ImGui::SeparatorText(str_keyboard_movement.c_str()); + layout_values(settings_location::KEYBOARD_MOVEMENT); + ImGui::SeparatorText(str_keyboard_gameplay.c_str()); + layout_values(settings_location::KEYBOARD_GAMEPLAY); + ImGui::SeparatorText(str_keyboard_misc.c_str()); + layout_values(settings_location::KEYBOARD_MISC); + } + + ImGui::EndChild(); +} + +static void layout_input_gamepad(void) +{ + if(ImGui::BeginChild("###settings.input.gamepad.child")) { + layout_values(settings_location::GAMEPAD); + ImGui::SeparatorText(str_gamepad_movement.c_str()); + layout_values(settings_location::GAMEPAD_MOVEMENT); + ImGui::SeparatorText(str_gamepad_gameplay.c_str()); + layout_values(settings_location::GAMEPAD_GAMEPLAY); + ImGui::SeparatorText(str_gamepad_misc.c_str()); + layout_values(settings_location::GAMEPAD_MISC); + } + + ImGui::EndChild(); +} + +static void layout_input_mouse(void) +{ + if(ImGui::BeginChild("###settings.input.mouse.child")) { + layout_values(settings_location::MOUSE); + } + + ImGui::EndChild(); +} + +static void layout_input(void) +{ + if(ImGui::BeginTabBar("###settings.input.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) { + if(ImGui::BeginTabItem(str_input_keyboard.c_str())) { + layout_input_keyboard(); + ImGui::EndTabItem(); + } + + if(io::gamepad::available) { + if(ImGui::BeginTabItem(str_input_gamepad.c_str())) { + globals::gui_keybind_ptr = nullptr; + layout_input_gamepad(); + ImGui::EndTabItem(); + } + } + + if(ImGui::BeginTabItem(str_input_mouse.c_str())) { + globals::gui_keybind_ptr = nullptr; + layout_input_mouse(); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } +} + +static void layout_video(void) +{ + if(ImGui::BeginChild("###settings.video.child")) { + layout_values(settings_location::VIDEO); + ImGui::SeparatorText(str_video_gui.c_str()); + layout_values(settings_location::VIDEO_GUI); + } + + ImGui::EndChild(); +} + +static void layout_sound(void) +{ + if(ImGui::BeginChild("###settings.sound.child")) { + layout_values(settings_location::SOUND); + ImGui::SeparatorText(str_sound_levels.c_str()); + layout_values(settings_location::SOUND_LEVELS); + } + + ImGui::EndChild(); +} + +void settings::init(void) +{ + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<io::GamepadAxisEvent>().connect<&on_gamepad_axis>(); + globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>(); + globals::dispatcher.sink<gui::LanguageSetEvent>().connect<&on_language_set>(); +} + +void settings::init_late(void) +{ + for(std::size_t i = 0; i < NUM_LOCATIONS; ++i) { + std::sort(values[i].begin(), values[i].end(), [](const SettingValue* a, const SettingValue* b) { + return a->priority < b->priority; + }); + } + + refresh_input_wids(); +} + +void settings::shutdown(void) +{ + for(const SettingValue* value : values_all) + delete value; + for(std::size_t i = 0; i < NUM_LOCATIONS; values[i++].clear()) + ; + values_all.clear(); +} + +void settings::layout(void) +{ + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + const ImVec2 window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f); + const ImVec2 window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###settings", nullptr, WINDOW_FLAGS)) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale)); + + if(ImGui::BeginTabBar("###settings.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) { + if(ImGui::TabItemButton("<<")) { + globals::gui_screen = GUI_MAIN_MENU; + globals::gui_keybind_ptr = nullptr; + } + + if(ImGui::BeginTabItem(str_tab_general.c_str())) { + globals::gui_keybind_ptr = nullptr; + layout_general(); + ImGui::EndTabItem(); + } + + if(ImGui::BeginTabItem(str_tab_input.c_str())) { + layout_input(); + ImGui::EndTabItem(); + } + + if(ImGui::BeginTabItem(str_tab_video.c_str())) { + globals::gui_keybind_ptr = nullptr; + layout_video(); + ImGui::EndTabItem(); + } + + if(globals::sound_ctx && globals::sound_dev) { + if(ImGui::BeginTabItem(str_tab_sound.c_str())) { + globals::gui_keybind_ptr = nullptr; + layout_sound(); + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + } + + ImGui::PopStyleVar(); + } + + ImGui::End(); +} + +void settings::add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_CheckBox; + setting_value->type = setting_type::CHECKBOX; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_InputInt; + setting_value->type = setting_type::INPUT_INT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip, + std::string_view fmt) +{ + auto setting_value = new SettingValue_InputFloat; + setting_value->type = setting_type::INPUT_FLOAT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->format = fmt; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_InputUnsigned; + setting_value->type = setting_type::INPUT_UINT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip, + bool allow_whitespace) +{ + auto setting_value = new SettingValue_InputString; + setting_value->type = setting_type::INPUT_STRING; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->allow_whitespace = allow_whitespace; + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_SliderInt; + setting_value->type = setting_type::SLIDER_INT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip, + std::string_view fmt) +{ + auto setting_value = new SettingValue_SliderFloat; + setting_value->type = setting_type::SLIDER_FLOAT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->format = fmt; + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_SliderUnsigned; + setting_value->type = setting_type::SLIDER_UINT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_StepperInt; + setting_value->type = setting_type::STEPPER_INT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1); + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip) +{ + auto setting_value = new SettingValue_StepperUnsigned; + setting_value->type = setting_type::STEPPER_UINT; + setting_value->priority = priority; + setting_value->has_tooltip = tooltip; + setting_value->value = &value; + setting_value->name = name; + + setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1); + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name) +{ + auto setting_value = new SettingValue_KeyBind; + setting_value->type = setting_type::KEYBIND; + setting_value->priority = priority; + setting_value->has_tooltip = false; + setting_value->value = &value; + setting_value->name = name; + + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name) +{ + auto setting_value = new SettingValue_GamepadAxis; + setting_value->type = setting_type::GAMEPAD_AXIS; + setting_value->priority = priority; + setting_value->has_tooltip = false; + setting_value->value = &value; + setting_value->name = name; + + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name) +{ + auto setting_value = new SettingValue_GamepadButton; + setting_value->type = setting_type::GAMEPAD_BUTTON; + setting_value->priority = priority; + setting_value->has_tooltip = false; + setting_value->value = &value; + setting_value->name = name; + + setting_value->refresh_wids(); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} + +void settings::add_language_select(int priority, settings_location location, std::string_view name) +{ + auto setting_value = new SettingValue_Language; + setting_value->type = setting_type::LANGUAGE_SELECT; + setting_value->priority = priority; + setting_value->has_tooltip = false; + setting_value->name = name; + + setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value)); + + values[static_cast<unsigned int>(location)].push_back(setting_value); + values_all.push_back(setting_value); +} diff --git a/game/client/gui/settings.hh b/src/game/client/gui/settings.hh index 472a61d..efb8ca4 100644 --- a/game/client/gui/settings.hh +++ b/src/game/client/gui/settings.hh @@ -1,90 +1,90 @@ -#pragma once
-
-namespace config
-{
-class Boolean;
-class String;
-} // namespace config
-
-namespace config
-{
-class Int;
-class Float;
-class Unsigned;
-} // namespace config
-
-namespace config
-{
-class KeyBind;
-class GamepadAxis;
-class GamepadButton;
-} // namespace config
-
-enum class settings_location : unsigned int {
- GENERAL = 0x0000U,
- KEYBOARD_MOVEMENT = 0x0001U,
- KEYBOARD_GAMEPLAY = 0x0002U,
- KEYBOARD_MISC = 0x0003U,
- GAMEPAD = 0x0004U,
- GAMEPAD_MOVEMENT = 0x0005U,
- GAMEPAD_GAMEPLAY = 0x0006U,
- GAMEPAD_MISC = 0x0007U,
- MOUSE = 0x0008U,
- VIDEO = 0x0009U,
- VIDEO_GUI = 0x000AU,
- SOUND = 0x000BU,
- SOUND_LEVELS = 0x000CU,
- COUNT = 0x000DU,
-};
-
-namespace settings
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void layout(void);
-} // namespace settings
-
-namespace settings
-{
-void add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt = "%.3f");
-void add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-void add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip, bool allow_whitespace);
-} // namespace settings
-
-namespace settings
-{
-void add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view format = "%.3f");
-void add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name);
-} // namespace settings
-
-namespace settings
-{
-void add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name);
-void add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name);
-} // namespace settings
-
-namespace settings
-{
-void add_language_select(int priority, settings_location location, std::string_view name);
-} // namespace settings
+#pragma once + +namespace config +{ +class Boolean; +class String; +} // namespace config + +namespace config +{ +class Int; +class Float; +class Unsigned; +} // namespace config + +namespace config +{ +class KeyBind; +class GamepadAxis; +class GamepadButton; +} // namespace config + +enum class settings_location : unsigned int { + GENERAL = 0x0000U, + KEYBOARD_MOVEMENT = 0x0001U, + KEYBOARD_GAMEPLAY = 0x0002U, + KEYBOARD_MISC = 0x0003U, + GAMEPAD = 0x0004U, + GAMEPAD_MOVEMENT = 0x0005U, + GAMEPAD_GAMEPLAY = 0x0006U, + GAMEPAD_MISC = 0x0007U, + MOUSE = 0x0008U, + VIDEO = 0x0009U, + VIDEO_GUI = 0x000AU, + SOUND = 0x000BU, + SOUND_LEVELS = 0x000CU, + COUNT = 0x000DU, +}; + +namespace settings +{ +void init(void); +void init_late(void); +void shutdown(void); +void layout(void); +} // namespace settings + +namespace settings +{ +void add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip); +} // namespace settings + +namespace settings +{ +void add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip); +void add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip, + std::string_view fmt = "%.3f"); +void add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip); +void add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip, bool allow_whitespace); +} // namespace settings + +namespace settings +{ +void add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip); +void add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip, + std::string_view format = "%.3f"); +void add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip); +} // namespace settings + +namespace settings +{ +void add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip); +void add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip); +} // namespace settings + +namespace settings +{ +void add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name); +} // namespace settings + +namespace settings +{ +void add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name); +void add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name); +} // namespace settings + +namespace settings +{ +void add_language_select(int priority, settings_location location, std::string_view name); +} // namespace settings diff --git a/game/client/gui/splash.cc b/src/game/client/gui/splash.cc index 5eae0f2..fab3ad8 100644 --- a/game/client/gui/splash.cc +++ b/src/game/client/gui/splash.cc @@ -1,178 +1,177 @@ -#include "client/pch.hh"
-
-#include "client/gui/splash.hh"
-
-#include "core/io/cmdline.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-constexpr static int SPLASH_COUNT = 4;
-constexpr static std::size_t DELAY_MICROSECONDS = 2000000;
-constexpr static std::string_view SPLASH_PATH = "textures/gui/client_splash.png";
-
-static resource_ptr<TextureGUI> texture;
-static float texture_aspect;
-static float texture_alpha;
-
-static std::uint64_t end_time;
-static std::string current_text;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-void gui::client_splash::init(void)
-{
- if(io::cmdline::contains("nosplash")) {
- texture = nullptr;
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
- return;
- }
-
- std::random_device randev;
- std::uniform_int_distribution<int> dist(0, SPLASH_COUNT - 1);
-
- texture = resource::load<TextureGUI>(SPLASH_PATH, TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
-
- if(texture) {
- if(texture->size.x > texture->size.y) {
- texture_aspect = static_cast<float>(texture->size.x) / static_cast<float>(texture->size.y);
- }
- else {
- texture_aspect = static_cast<float>(texture->size.y) / static_cast<float>(texture->size.x);
- }
-
- texture_alpha = 1.0f;
- }
-}
-
-void gui::client_splash::init_late(void)
-{
- if(!texture) {
- // We don't have to waste time
- // rendering the missing client_splash texture
- return;
- }
-
- end_time = utils::unix_microseconds() + DELAY_MICROSECONDS;
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
-
- current_text = gui::language::resolve("splash.skip_prompt");
-
- while(!glfwWindowShouldClose(globals::window)) {
- const std::uint64_t curtime = utils::unix_microseconds();
- const std::uint64_t remains = end_time - curtime;
-
- if(curtime >= end_time) {
- break;
- }
-
- texture_alpha = glm::smoothstep(0.25f, 0.6f, static_cast<float>(remains) / static_cast<float>(DELAY_MICROSECONDS));
-
- gui::client_splash::render();
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().disconnect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().disconnect<&on_glfw_scroll>();
-
- texture = nullptr;
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
- end_time = UINT64_C(0);
-}
-
-void gui::client_splash::render(void)
-{
- if(!texture) {
- // We don't have to waste time
- // rendering the missing client_splash texture
- return;
- }
-
- // The client_splash is rendered outside the main
- // render loop, so we have to manually begin
- // and render both window and ImGui frames
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
-
- glDisable(GL_DEPTH_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glViewport(0, 0, globals::width, globals::height);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.0f, 0.0f);
- auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###client_splash", nullptr, WINDOW_FLAGS)) {
- const float image_width = 0.60f * viewport->Size.x;
- const float image_height = image_width / texture_aspect;
- const ImVec2 image_size = ImVec2(image_width, image_height);
-
- const float image_x = 0.5f * (viewport->Size.x - image_width);
- const float image_y = 0.5f * (viewport->Size.y - image_height);
- const ImVec2 image_pos = ImVec2(image_x, image_y);
-
- if(!current_text.empty()) {
- ImGui::PushFont(globals::font_unscii8, 16.0f);
- ImGui::SetCursorPos(ImVec2(16.0f, 16.0f));
- ImGui::TextDisabled("%s", current_text.c_str());
- ImGui::PopFont();
- }
-
- const ImVec2 uv_a = ImVec2(0.0f, 0.0f);
- const ImVec2 uv_b = ImVec2(1.0f, 1.0f);
- const ImVec4 tint = ImVec4(1.0f, 1.0f, 1.0f, texture_alpha);
-
- ImGui::SetCursorPos(image_pos);
- ImGui::ImageWithBg(texture->handle, image_size, uv_a, uv_b, ImVec4(0.0f, 0.0f, 0.0f, 0.0f), tint);
- }
-
- ImGui::End();
-
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
- glfwSwapBuffers(globals::window);
-
- glfwPollEvents();
-}
+#include "client/pch.hh" + +#include "client/gui/splash.hh" + +#include "core/io/cmdline.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/resource.hh" + +#include "core/utils/epoch.hh" + +#include "client/gui/gui_screen.hh" +#include "client/gui/language.hh" + +#include "client/io/glfw.hh" + +#include "client/resource/texture_gui.hh" + +#include "client/globals.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +constexpr static int SPLASH_COUNT = 4; +constexpr static std::size_t DELAY_MICROSECONDS = 2000000; +constexpr static std::string_view SPLASH_PATH = "textures/gui/client_splash.png"; + +static resource_ptr<TextureGUI> texture; +static float texture_aspect; +static float texture_alpha; + +static std::uint64_t end_time; +static std::string current_text; + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + end_time = UINT64_C(0); +} + +static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event) +{ + end_time = UINT64_C(0); +} + +static void on_glfw_scroll(const io::GlfwScrollEvent& event) +{ + end_time = UINT64_C(0); +} + +void gui::client_splash::init(void) +{ + if(io::cmdline::contains("nosplash")) { + texture = nullptr; + texture_aspect = 0.0f; + texture_alpha = 0.0f; + return; + } + + std::uniform_int_distribution<int> dist(0, SPLASH_COUNT - 1); + + texture = resource::load<TextureGUI>(SPLASH_PATH, TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T); + texture_aspect = 0.0f; + texture_alpha = 0.0f; + + if(texture) { + if(texture->size.x > texture->size.y) { + texture_aspect = static_cast<float>(texture->size.x) / static_cast<float>(texture->size.y); + } + else { + texture_aspect = static_cast<float>(texture->size.y) / static_cast<float>(texture->size.x); + } + + texture_alpha = 1.0f; + } +} + +void gui::client_splash::init_late(void) +{ + if(!texture) { + // We don't have to waste time + // rendering the missing client_splash texture + return; + } + + end_time = utils::unix_microseconds() + DELAY_MICROSECONDS; + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>(); + globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>(); + + current_text = gui::language::resolve("splash.skip_prompt"); + + while(!glfwWindowShouldClose(globals::window)) { + const std::uint64_t curtime = utils::unix_microseconds(); + const std::uint64_t remains = end_time - curtime; + + if(curtime >= end_time) { + break; + } + + texture_alpha = glm::smoothstep(0.25f, 0.6f, static_cast<float>(remains) / static_cast<float>(DELAY_MICROSECONDS)); + + gui::client_splash::render(); + } + + globals::dispatcher.sink<io::GlfwKeyEvent>().disconnect<&on_glfw_key>(); + globals::dispatcher.sink<io::GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>(); + globals::dispatcher.sink<io::GlfwScrollEvent>().disconnect<&on_glfw_scroll>(); + + texture = nullptr; + texture_aspect = 0.0f; + texture_alpha = 0.0f; + end_time = UINT64_C(0); +} + +void gui::client_splash::render(void) +{ + if(!texture) { + // We don't have to waste time + // rendering the missing client_splash texture + return; + } + + // The client_splash is rendered outside the main + // render loop, so we have to manually begin + // and render both window and ImGui frames + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + glDisable(GL_DEPTH_TEST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, globals::width, globals::height); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + auto viewport = ImGui::GetMainViewport(); + auto window_start = ImVec2(0.0f, 0.0f); + auto window_size = ImVec2(viewport->Size.x, viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###client_splash", nullptr, WINDOW_FLAGS)) { + const float image_width = 0.60f * viewport->Size.x; + const float image_height = image_width / texture_aspect; + const ImVec2 image_size = ImVec2(image_width, image_height); + + const float image_x = 0.5f * (viewport->Size.x - image_width); + const float image_y = 0.5f * (viewport->Size.y - image_height); + const ImVec2 image_pos = ImVec2(image_x, image_y); + + if(!current_text.empty()) { + ImGui::PushFont(globals::font_unscii8, 16.0f); + ImGui::SetCursorPos(ImVec2(16.0f, 16.0f)); + ImGui::TextDisabled("%s", current_text.c_str()); + ImGui::PopFont(); + } + + const ImVec2 uv_a = ImVec2(0.0f, 0.0f); + const ImVec2 uv_b = ImVec2(1.0f, 1.0f); + const ImVec4 tint = ImVec4(1.0f, 1.0f, 1.0f, texture_alpha); + + ImGui::SetCursorPos(image_pos); + ImGui::ImageWithBg(texture->handle, image_size, uv_a, uv_b, ImVec4(0.0f, 0.0f, 0.0f, 0.0f), tint); + } + + ImGui::End(); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(globals::window); + + glfwPollEvents(); +} diff --git a/game/client/gui/splash.hh b/src/game/client/gui/splash.hh index a28a9ad..3ce63e4 100644 --- a/game/client/gui/splash.hh +++ b/src/game/client/gui/splash.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace gui::client_splash
-{
-void init(void);
-void init_late(void);
-void render(void);
-} // namespace gui::client_splash
+#pragma once + +namespace gui::client_splash +{ +void init(void); +void init_late(void); +void render(void); +} // namespace gui::client_splash diff --git a/game/client/gui/status_lines.cc b/src/game/client/gui/status_lines.cc index c146478..74d0dbe 100644 --- a/game/client/gui/status_lines.cc +++ b/src/game/client/gui/status_lines.cc @@ -1,84 +1,84 @@ -#include "client/pch.hh"
-
-#include "client/gui/status_lines.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/globals.hh"
-
-static float line_offsets[gui::STATUS_COUNT];
-static ImFont* line_fonts[gui::STATUS_COUNT];
-static float line_sizes[gui::STATUS_COUNT];
-
-static ImVec4 line_text_colors[gui::STATUS_COUNT];
-static ImVec4 line_shadow_colors[gui::STATUS_COUNT];
-static std::string line_strings[gui::STATUS_COUNT];
-static std::uint64_t line_spawns[gui::STATUS_COUNT];
-static float line_fadeouts[gui::STATUS_COUNT];
-
-void gui::status_lines::init(void)
-{
- for(unsigned int i = 0U; i < STATUS_COUNT; ++i) {
- line_text_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_shadow_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_strings[i] = std::string();
- line_spawns[i] = UINT64_MAX;
- line_fadeouts[i] = 0.0f;
- }
-}
-
-void gui::status_lines::init_late(void)
-{
- line_offsets[STATUS_DEBUG] = 64.0f;
- line_offsets[STATUS_HOTBAR] = 40.0f;
-}
-
-void gui::status_lines::layout(void)
-{
- line_fonts[STATUS_DEBUG] = globals::font_unscii8;
- line_sizes[STATUS_DEBUG] = 4.0f;
-
- line_fonts[STATUS_HOTBAR] = globals::font_unscii16;
- line_sizes[STATUS_HOTBAR] = 8.0f;
-
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- for(unsigned int i = 0U; i < STATUS_COUNT; ++i) {
- auto offset = line_offsets[i] * globals::gui_scale;
- auto& text = line_strings[i];
- auto* font = line_fonts[i];
-
- auto size = font->CalcTextSizeA(line_sizes[i] * globals::gui_scale, FLT_MAX, 0.0f, text.c_str(), text.c_str() + text.size());
- auto pos = ImVec2(0.5f * (viewport->Size.x - size.x), viewport->Size.y - offset);
-
- auto spawn = line_spawns[i];
- auto fadeout = line_fadeouts[i];
- auto alpha = std::exp(-1.0f * std::pow(1.0e-6f * static_cast<float>(globals::curtime - spawn) / fadeout, 10.0f));
-
- auto& color = line_text_colors[i];
- auto& shadow = line_shadow_colors[i];
- auto color_U32 = ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, color.w * alpha));
- auto shadow_U32 = ImGui::GetColorU32(ImVec4(shadow.x, shadow.y, shadow.z, color.w * alpha));
-
- gui::imdraw_ext::text_shadow(text, pos, color_U32, shadow_U32, font, draw_list, line_sizes[i]);
- }
-}
-
-void gui::status_lines::set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout)
-{
- line_text_colors[line] = ImVec4(color.x, color.y, color.z, color.w);
- line_shadow_colors[line] = ImVec4(color.x * 0.1f, color.y * 0.1f, color.z * 0.1f, color.w);
- line_strings[line] = text;
- line_spawns[line] = globals::curtime;
- line_fadeouts[line] = fadeout;
-}
-
-void gui::status_lines::unset(unsigned int line)
-{
- line_text_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_shadow_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_strings[line] = std::string();
- line_spawns[line] = UINT64_C(0);
- line_fadeouts[line] = 0.0f;
-}
+#include "client/pch.hh" + +#include "client/gui/status_lines.hh" + +#include "client/gui/imdraw_ext.hh" + +#include "client/globals.hh" + +static float line_offsets[gui::STATUS_COUNT]; +static ImFont* line_fonts[gui::STATUS_COUNT]; +static float line_sizes[gui::STATUS_COUNT]; + +static ImVec4 line_text_colors[gui::STATUS_COUNT]; +static ImVec4 line_shadow_colors[gui::STATUS_COUNT]; +static std::string line_strings[gui::STATUS_COUNT]; +static std::uint64_t line_spawns[gui::STATUS_COUNT]; +static float line_fadeouts[gui::STATUS_COUNT]; + +void gui::status_lines::init(void) +{ + for(unsigned int i = 0U; i < STATUS_COUNT; ++i) { + line_text_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); + line_shadow_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); + line_strings[i] = std::string(); + line_spawns[i] = UINT64_MAX; + line_fadeouts[i] = 0.0f; + } +} + +void gui::status_lines::init_late(void) +{ + line_offsets[STATUS_DEBUG] = 64.0f; + line_offsets[STATUS_HOTBAR] = 40.0f; +} + +void gui::status_lines::layout(void) +{ + line_fonts[STATUS_DEBUG] = globals::font_unscii8; + line_sizes[STATUS_DEBUG] = 4.0f; + + line_fonts[STATUS_HOTBAR] = globals::font_unscii16; + line_sizes[STATUS_HOTBAR] = 8.0f; + + auto viewport = ImGui::GetMainViewport(); + auto draw_list = ImGui::GetForegroundDrawList(); + + for(unsigned int i = 0U; i < STATUS_COUNT; ++i) { + auto offset = line_offsets[i] * globals::gui_scale; + auto& text = line_strings[i]; + auto* font = line_fonts[i]; + + auto size = font->CalcTextSizeA(line_sizes[i] * globals::gui_scale, FLT_MAX, 0.0f, text.c_str(), text.c_str() + text.size()); + auto pos = ImVec2(0.5f * (viewport->Size.x - size.x), viewport->Size.y - offset); + + auto spawn = line_spawns[i]; + auto fadeout = line_fadeouts[i]; + auto alpha = std::exp(-1.0f * std::pow(1.0e-6f * static_cast<float>(globals::curtime - spawn) / fadeout, 10.0f)); + + auto& color = line_text_colors[i]; + auto& shadow = line_shadow_colors[i]; + auto color_U32 = ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, color.w * alpha)); + auto shadow_U32 = ImGui::GetColorU32(ImVec4(shadow.x, shadow.y, shadow.z, color.w * alpha)); + + gui::imdraw_ext::text_shadow(text, pos, color_U32, shadow_U32, font, draw_list, line_sizes[i]); + } +} + +void gui::status_lines::set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout) +{ + line_text_colors[line] = ImVec4(color.x, color.y, color.z, color.w); + line_shadow_colors[line] = ImVec4(color.x * 0.1f, color.y * 0.1f, color.z * 0.1f, color.w); + line_strings[line] = text; + line_spawns[line] = globals::curtime; + line_fadeouts[line] = fadeout; +} + +void gui::status_lines::unset(unsigned int line) +{ + line_text_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); + line_shadow_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); + line_strings[line] = std::string(); + line_spawns[line] = UINT64_C(0); + line_fadeouts[line] = 0.0f; +} diff --git a/game/client/gui/status_lines.hh b/src/game/client/gui/status_lines.hh index f694fd3..98cbde1 100644 --- a/game/client/gui/status_lines.hh +++ b/src/game/client/gui/status_lines.hh @@ -1,21 +1,21 @@ -#pragma once
-
-namespace gui
-{
-constexpr static unsigned int STATUS_DEBUG = 0x0000; // generic debug line
-constexpr static unsigned int STATUS_HOTBAR = 0x0001; // hotbar item line
-constexpr static unsigned int STATUS_COUNT = 0x0002;
-} // namespace gui
-
-namespace gui::status_lines
-{
-void init(void);
-void init_late(void);
-void layout(void);
-} // namespace gui::status_lines
-
-namespace gui::status_lines
-{
-void set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout);
-void unset(unsigned int line);
-} // namespace gui::status_lines
+#pragma once + +namespace gui +{ +constexpr static unsigned int STATUS_DEBUG = 0x0000; // generic debug line +constexpr static unsigned int STATUS_HOTBAR = 0x0001; // hotbar item line +constexpr static unsigned int STATUS_COUNT = 0x0002; +} // namespace gui + +namespace gui::status_lines +{ +void init(void); +void init_late(void); +void layout(void); +} // namespace gui::status_lines + +namespace gui::status_lines +{ +void set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout); +void unset(unsigned int line); +} // namespace gui::status_lines diff --git a/game/client/gui/window_title.cc b/src/game/client/gui/window_title.cc index 2f96205..787a7fa 100644 --- a/game/client/gui/window_title.cc +++ b/src/game/client/gui/window_title.cc @@ -1,14 +1,14 @@ -#include "client/pch.hh"
-
-#include "client/gui/window_title.hh"
-
-#include "core/version.hh"
-
-#include "shared/splash.hh"
-
-#include "client/globals.hh"
-
-void gui::window_title::update(void)
-{
- glfwSetWindowTitle(globals::window, std::format("Voxelius {}: {}", version::semver, splash::get()).c_str());
-}
+#include "client/pch.hh" + +#include "client/gui/window_title.hh" + +#include "core/version.hh" + +#include "shared/splash.hh" + +#include "client/globals.hh" + +void gui::window_title::update(void) +{ + glfwSetWindowTitle(globals::window, std::format("Voxelius {}: {}", version::triplet, splash::get()).c_str()); +} diff --git a/game/client/gui/window_title.hh b/src/game/client/gui/window_title.hh index 86e6a86..af1ab7c 100644 --- a/game/client/gui/window_title.hh +++ b/src/game/client/gui/window_title.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace gui::window_title
-{
-void update(void);
-} // namespace gui::window_title
+#pragma once + +namespace gui::window_title +{ +void update(void); +} // namespace gui::window_title diff --git a/game/client/io/CMakeLists.txt b/src/game/client/io/CMakeLists.txt index 82bc422..82bc422 100644 --- a/game/client/io/CMakeLists.txt +++ b/src/game/client/io/CMakeLists.txt diff --git a/game/client/io/gamepad.cc b/src/game/client/io/gamepad.cc index f19f04a..3661769 100644 --- a/game/client/io/gamepad.cc +++ b/src/game/client/io/gamepad.cc @@ -1,183 +1,183 @@ -#include "client/pch.hh"
-
-#include "client/io/gamepad.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-#include "core/io/cmdline.hh"
-#include "core/io/config_map.hh"
-#include "core/math/constexpr.hh"
-
-#include "client/gui/settings.hh"
-#include "client/io/glfw.hh"
-
-#include "client/globals.hh"
-#include "client/toggles.hh"
-
-constexpr static int INVALID_GAMEPAD_ID = INT_MAX;
-constexpr static std::size_t NUM_AXES = static_cast<std::size_t>(GLFW_GAMEPAD_AXIS_LAST + 1);
-constexpr static std::size_t NUM_BUTTONS = static_cast<std::size_t>(GLFW_GAMEPAD_BUTTON_LAST + 1);
-constexpr static float GAMEPAD_AXIS_EVENT_THRESHOLD = 0.5f;
-
-static int active_gamepad_id;
-
-bool io::gamepad::available = false;
-config::Float io::gamepad::deadzone(0.00f, 0.00f, 0.66f);
-config::Boolean io::gamepad::active(false);
-GLFWgamepadstate io::gamepad::state;
-GLFWgamepadstate io::gamepad::last_state;
-
-static void on_toggle_enable(const ToggleEnabledEvent& event)
-{
- if(event.type == TOGGLE_USE_GAMEPAD) {
- io::gamepad::active.set_value(true);
- return;
- }
-}
-
-static void on_toggle_disable(const ToggleDisabledEvent& event)
-{
- if(event.type == TOGGLE_USE_GAMEPAD) {
- io::gamepad::active.set_value(false);
- return;
- }
-}
-
-static void on_glfw_joystick_event(const io::GlfwJoystickEvent& event)
-{
- if((event.event_type == GLFW_CONNECTED) && glfwJoystickIsGamepad(event.joystick_id) && (active_gamepad_id == INVALID_GAMEPAD_ID)) {
- io::gamepad::available = true;
-
- active_gamepad_id = event.joystick_id;
-
- for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) {
- // empty
- }
-
- for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) {
- // empty
- }
-
- spdlog::info("gamepad: detected gamepad: {}", glfwGetGamepadName(event.joystick_id));
-
- return;
- }
-
- if((event.event_type == GLFW_DISCONNECTED) && (active_gamepad_id == event.joystick_id)) {
- io::gamepad::available = false;
-
- active_gamepad_id = INVALID_GAMEPAD_ID;
-
- for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) {
- // empty
- }
-
- for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) {
- // empty
- }
-
- spdlog::warn("gamepad: disconnected");
-
- return;
- }
-}
-
-void io::gamepad::init(void)
-{
- io::gamepad::available = false;
-
- active_gamepad_id = INVALID_GAMEPAD_ID;
-
- globals::client_config.add_value("gamepad.deadzone", io::gamepad::deadzone);
- globals::client_config.add_value("gamepad.active", io::gamepad::active);
-
- settings::add_checkbox(0, io::gamepad::active, settings_location::GAMEPAD, "gamepad.active", true);
- settings::add_slider(1, io::gamepad::deadzone, settings_location::GAMEPAD, "gamepad.deadzone", true, "%.03f");
-
- auto mappings_path = io::cmdline::get_cstr("gpmap", "misc/gamecontrollerdb.txt");
- auto mappings_file = PHYSFS_openRead(mappings_path);
-
- if(mappings_file) {
- spdlog::info("gamepad: using mappings from {}", mappings_path);
- auto mappings_string = std::string(PHYSFS_fileLength(mappings_file), char(0x00));
- PHYSFS_readBytes(mappings_file, mappings_string.data(), mappings_string.size());
- glfwUpdateGamepadMappings(mappings_string.c_str());
- PHYSFS_close(mappings_file);
- }
-
- for(int joystick = 0; joystick <= GLFW_JOYSTICK_LAST; joystick += 1) {
- if(glfwJoystickIsGamepad(joystick)) {
- io::gamepad::available = true;
-
- active_gamepad_id = joystick;
-
- for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) {
- // empty
- }
-
- for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) {
- // empty
- }
-
- spdlog::info("gamepad: detected gamepad: {}", glfwGetGamepadName(joystick));
-
- break;
- }
- }
-
- for(int i = 0; i < NUM_AXES; io::gamepad::state.axes[i++] = 0.0f) {
- // empty
- }
-
- for(int i = 0; i < NUM_BUTTONS; io::gamepad::state.buttons[i++] = GLFW_RELEASE) {
- // empty
- }
-
- globals::dispatcher.sink<ToggleEnabledEvent>().connect<&on_toggle_enable>();
- globals::dispatcher.sink<ToggleDisabledEvent>().connect<&on_toggle_disable>();
- globals::dispatcher.sink<GlfwJoystickEvent>().connect<&on_glfw_joystick_event>();
-}
-
-void io::gamepad::update_late(void)
-{
- if(active_gamepad_id == INVALID_GAMEPAD_ID) {
- // No active gamepad found
- return;
- }
-
- if(glfwGetGamepadState(active_gamepad_id, &io::gamepad::state)) {
- for(int i = 0; i < NUM_AXES; ++i) {
- if((glm::abs(io::gamepad::state.axes[i]) > GAMEPAD_AXIS_EVENT_THRESHOLD)
- && (glm::abs(io::gamepad::last_state.axes[i]) <= GAMEPAD_AXIS_EVENT_THRESHOLD)) {
- GamepadAxisEvent event;
- event.action = GLFW_PRESS;
- event.axis = i;
- globals::dispatcher.enqueue(event);
- continue;
- }
-
- if((glm::abs(io::gamepad::state.axes[i]) <= GAMEPAD_AXIS_EVENT_THRESHOLD)
- && (glm::abs(io::gamepad::last_state.axes[i]) > GAMEPAD_AXIS_EVENT_THRESHOLD)) {
- GamepadAxisEvent event;
- event.action = GLFW_RELEASE;
- event.axis = i;
- globals::dispatcher.enqueue(event);
- continue;
- }
- }
-
- for(int i = 0; i < NUM_BUTTONS; ++i) {
- if(io::gamepad::state.buttons[i] == io::gamepad::last_state.buttons[i]) {
- // Nothing happens
- continue;
- }
-
- GamepadButtonEvent event;
- event.action = io::gamepad::state.buttons[i];
- event.button = i;
- globals::dispatcher.enqueue(event);
- }
- }
-
- io::gamepad::last_state = io::gamepad::state;
-}
+#include "client/pch.hh" + +#include "client/io/gamepad.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" +#include "core/io/cmdline.hh" +#include "core/io/config_map.hh" +#include "core/math/constexpr.hh" + +#include "client/gui/settings.hh" +#include "client/io/glfw.hh" + +#include "client/globals.hh" +#include "client/toggles.hh" + +constexpr static int INVALID_GAMEPAD_ID = INT_MAX; +constexpr static std::size_t NUM_AXES = static_cast<std::size_t>(GLFW_GAMEPAD_AXIS_LAST + 1); +constexpr static std::size_t NUM_BUTTONS = static_cast<std::size_t>(GLFW_GAMEPAD_BUTTON_LAST + 1); +constexpr static float GAMEPAD_AXIS_EVENT_THRESHOLD = 0.5f; + +static int active_gamepad_id; + +bool io::gamepad::available = false; +config::Float io::gamepad::deadzone(0.00f, 0.00f, 0.66f); +config::Boolean io::gamepad::active(false); +GLFWgamepadstate io::gamepad::state; +GLFWgamepadstate io::gamepad::last_state; + +static void on_toggle_enable(const ToggleEnabledEvent& event) +{ + if(event.type == TOGGLE_USE_GAMEPAD) { + io::gamepad::active.set_value(true); + return; + } +} + +static void on_toggle_disable(const ToggleDisabledEvent& event) +{ + if(event.type == TOGGLE_USE_GAMEPAD) { + io::gamepad::active.set_value(false); + return; + } +} + +static void on_glfw_joystick_event(const io::GlfwJoystickEvent& event) +{ + if((event.event_type == GLFW_CONNECTED) && glfwJoystickIsGamepad(event.joystick_id) && (active_gamepad_id == INVALID_GAMEPAD_ID)) { + io::gamepad::available = true; + + active_gamepad_id = event.joystick_id; + + for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) { + // empty + } + + for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) { + // empty + } + + spdlog::info("gamepad: detected gamepad: {}", glfwGetGamepadName(event.joystick_id)); + + return; + } + + if((event.event_type == GLFW_DISCONNECTED) && (active_gamepad_id == event.joystick_id)) { + io::gamepad::available = false; + + active_gamepad_id = INVALID_GAMEPAD_ID; + + for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) { + // empty + } + + for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) { + // empty + } + + spdlog::warn("gamepad: disconnected"); + + return; + } +} + +void io::gamepad::init(void) +{ + io::gamepad::available = false; + + active_gamepad_id = INVALID_GAMEPAD_ID; + + globals::client_config.add_value("gamepad.deadzone", io::gamepad::deadzone); + globals::client_config.add_value("gamepad.active", io::gamepad::active); + + settings::add_checkbox(0, io::gamepad::active, settings_location::GAMEPAD, "gamepad.active", true); + settings::add_slider(1, io::gamepad::deadzone, settings_location::GAMEPAD, "gamepad.deadzone", true, "%.03f"); + + auto mappings_path = io::cmdline::get_cstr("gpmap", "misc/gamecontrollerdb.txt"); + auto mappings_file = PHYSFS_openRead(mappings_path); + + if(mappings_file) { + spdlog::info("gamepad: using mappings from {}", mappings_path); + auto mappings_string = std::string(PHYSFS_fileLength(mappings_file), char(0x00)); + PHYSFS_readBytes(mappings_file, mappings_string.data(), mappings_string.size()); + glfwUpdateGamepadMappings(mappings_string.c_str()); + PHYSFS_close(mappings_file); + } + + for(int joystick = 0; joystick <= GLFW_JOYSTICK_LAST; joystick += 1) { + if(glfwJoystickIsGamepad(joystick)) { + io::gamepad::available = true; + + active_gamepad_id = joystick; + + for(int i = 0; i < NUM_AXES; io::gamepad::last_state.axes[i++] = 0.0f) { + // empty + } + + for(int i = 0; i < NUM_BUTTONS; io::gamepad::last_state.buttons[i++] = GLFW_RELEASE) { + // empty + } + + spdlog::info("gamepad: detected gamepad: {}", glfwGetGamepadName(joystick)); + + break; + } + } + + for(int i = 0; i < NUM_AXES; io::gamepad::state.axes[i++] = 0.0f) { + // empty + } + + for(int i = 0; i < NUM_BUTTONS; io::gamepad::state.buttons[i++] = GLFW_RELEASE) { + // empty + } + + globals::dispatcher.sink<ToggleEnabledEvent>().connect<&on_toggle_enable>(); + globals::dispatcher.sink<ToggleDisabledEvent>().connect<&on_toggle_disable>(); + globals::dispatcher.sink<GlfwJoystickEvent>().connect<&on_glfw_joystick_event>(); +} + +void io::gamepad::update_late(void) +{ + if(active_gamepad_id == INVALID_GAMEPAD_ID) { + // No active gamepad found + return; + } + + if(glfwGetGamepadState(active_gamepad_id, &io::gamepad::state)) { + for(int i = 0; i < NUM_AXES; ++i) { + if((glm::abs(io::gamepad::state.axes[i]) > GAMEPAD_AXIS_EVENT_THRESHOLD) + && (glm::abs(io::gamepad::last_state.axes[i]) <= GAMEPAD_AXIS_EVENT_THRESHOLD)) { + GamepadAxisEvent event; + event.action = GLFW_PRESS; + event.axis = i; + globals::dispatcher.enqueue(event); + continue; + } + + if((glm::abs(io::gamepad::state.axes[i]) <= GAMEPAD_AXIS_EVENT_THRESHOLD) + && (glm::abs(io::gamepad::last_state.axes[i]) > GAMEPAD_AXIS_EVENT_THRESHOLD)) { + GamepadAxisEvent event; + event.action = GLFW_RELEASE; + event.axis = i; + globals::dispatcher.enqueue(event); + continue; + } + } + + for(int i = 0; i < NUM_BUTTONS; ++i) { + if(io::gamepad::state.buttons[i] == io::gamepad::last_state.buttons[i]) { + // Nothing happens + continue; + } + + GamepadButtonEvent event; + event.action = io::gamepad::state.buttons[i]; + event.button = i; + globals::dispatcher.enqueue(event); + } + } + + io::gamepad::last_state = io::gamepad::state; +} diff --git a/game/client/io/gamepad.hh b/src/game/client/io/gamepad.hh index ff38127..9c56894 100644 --- a/game/client/io/gamepad.hh +++ b/src/game/client/io/gamepad.hh @@ -1,50 +1,50 @@ -#pragma once
-
-namespace io
-{
-constexpr static int INVALID_GAMEPAD_AXIS = INT_MAX;
-constexpr static int INVALID_GAMEPAD_BUTTON = INT_MAX;
-} // namespace io
-
-namespace config
-{
-class Boolean;
-class Float;
-} // namespace config
-
-struct GLFWgamepadstate;
-
-namespace io::gamepad
-{
-extern bool available;
-extern config::Float deadzone;
-extern config::Boolean active;
-extern GLFWgamepadstate state;
-extern GLFWgamepadstate last_state;
-} // namespace io::gamepad
-
-namespace io::gamepad
-{
-void init(void);
-void update_late(void);
-} // namespace io::gamepad
-
-namespace io
-{
-// This simulates buttons using axes. When an axis
-// value exceeds 1.5 times the deadzone, the event is
-// queued with a GLFW_PRESS action, when it falls back
-// below the threshold, the event is queued with GLFW_RELEASE action
-struct GamepadAxisEvent final {
- int action;
- int axis;
-};
-
-// This smears GLFW event sugar over gamepad polling
-// system. Whenever it detects a state change, the event
-// is queued with an appropriate action
-struct GamepadButtonEvent final {
- int action;
- int button;
-};
-} // namespace io
+#pragma once + +namespace io +{ +constexpr static int INVALID_GAMEPAD_AXIS = INT_MAX; +constexpr static int INVALID_GAMEPAD_BUTTON = INT_MAX; +} // namespace io + +namespace config +{ +class Boolean; +class Float; +} // namespace config + +struct GLFWgamepadstate; + +namespace io::gamepad +{ +extern bool available; +extern config::Float deadzone; +extern config::Boolean active; +extern GLFWgamepadstate state; +extern GLFWgamepadstate last_state; +} // namespace io::gamepad + +namespace io::gamepad +{ +void init(void); +void update_late(void); +} // namespace io::gamepad + +namespace io +{ +// This simulates buttons using axes. When an axis +// value exceeds 1.5 times the deadzone, the event is +// queued with a GLFW_PRESS action, when it falls back +// below the threshold, the event is queued with GLFW_RELEASE action +struct GamepadAxisEvent final { + int action; + int axis; +}; + +// This smears GLFW event sugar over gamepad polling +// system. Whenever it detects a state change, the event +// is queued with an appropriate action +struct GamepadButtonEvent final { + int action; + int button; +}; +} // namespace io diff --git a/game/client/io/glfw.hh b/src/game/client/io/glfw.hh index 7697d97..cd6d882 100644 --- a/game/client/io/glfw.hh +++ b/src/game/client/io/glfw.hh @@ -1,36 +1,36 @@ -#pragma once
-
-namespace io
-{
-struct GlfwCursorPosEvent final {
- glm::fvec2 pos;
-};
-
-struct GlfwFramebufferSizeEvent final {
- glm::ivec2 size;
- float aspect;
-};
-
-struct GlfwJoystickEvent final {
- int joystick_id;
- int event_type;
-};
-
-struct GlfwKeyEvent final {
- int key { GLFW_KEY_UNKNOWN };
- int scancode;
- int action;
- int mods;
-};
-
-struct GlfwMouseButtonEvent final {
- int button { GLFW_KEY_UNKNOWN };
- int action;
- int mods;
-};
-
-struct GlfwScrollEvent final {
- float dx;
- float dy;
-};
-} // namespace io
+#pragma once + +namespace io +{ +struct GlfwCursorPosEvent final { + glm::fvec2 pos; +}; + +struct GlfwFramebufferSizeEvent final { + glm::ivec2 size; + float aspect; +}; + +struct GlfwJoystickEvent final { + int joystick_id; + int event_type; +}; + +struct GlfwKeyEvent final { + int key { GLFW_KEY_UNKNOWN }; + int scancode; + int action; + int mods; +}; + +struct GlfwMouseButtonEvent final { + int button { GLFW_KEY_UNKNOWN }; + int action; + int mods; +}; + +struct GlfwScrollEvent final { + float dx; + float dy; +}; +} // namespace io diff --git a/game/client/main.cc b/src/game/client/main.cc index b2a6a01..c96d4a4 100644 --- a/game/client/main.cc +++ b/src/game/client/main.cc @@ -1,449 +1,449 @@ -#include "client/pch.hh"
-
-#include "core/io/cmdline.hh"
-#include "core/io/config_map.hh"
-
-#include "core/resource/image.hh"
-#include "core/resource/resource.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "core/threading.hh"
-#include "core/version.hh"
-
-#include "shared/game.hh"
-#include "shared/splash.hh"
-
-#include "client/gui/window_title.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/sound_effect.hh"
-#include "client/resource/texture_gui.hh"
-
-#include "client/const.hh"
-#include "client/game.hh"
-#include "client/globals.hh"
-
-#if defined(_WIN32)
-extern "C" __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
-extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
-#endif
-
-static void on_glfw_error(int code, const char* message)
-{
- spdlog::error("glfw: {}", message);
-}
-
-static void on_glfw_char(GLFWwindow* window, unsigned int codepoint)
-{
- ImGui_ImplGlfw_CharCallback(window, codepoint);
-}
-
-static void on_glfw_cursor_enter(GLFWwindow* window, int entered)
-{
- ImGui_ImplGlfw_CursorEnterCallback(window, entered);
-}
-
-static void on_glfw_cursor_pos(GLFWwindow* window, double xpos, double ypos)
-{
- io::GlfwCursorPosEvent event;
- event.pos.x = static_cast<float>(xpos);
- event.pos.y = static_cast<float>(ypos);
- globals::dispatcher.trigger(event);
-
- ImGui_ImplGlfw_CursorPosCallback(window, xpos, ypos);
-}
-
-static void on_glfw_framebuffer_size(GLFWwindow* window, int width, int height)
-{
- if(glfwGetWindowAttrib(window, GLFW_ICONIFIED)) {
- // Don't do anything if the window was just
- // iconified (minimized); as it turns out minimized
- // windows on WIN32 seem to be forced into 0x0
- return;
- }
-
- globals::width = width;
- globals::height = height;
- globals::aspect = static_cast<float>(width) / static_cast<float>(height);
-
- io::GlfwFramebufferSizeEvent fb_event;
- fb_event.size.x = globals::width;
- fb_event.size.y = globals::height;
- fb_event.aspect = globals::aspect;
- globals::dispatcher.trigger(fb_event);
-}
-
-static void on_glfw_key(GLFWwindow* window, int key, int scancode, int action, int mods)
-{
- io::GlfwKeyEvent event;
- event.key = key;
- event.scancode = scancode;
- event.action = action;
- event.mods = mods;
- globals::dispatcher.trigger(event);
-
- ImGui_ImplGlfw_KeyCallback(window, key, scancode, action, mods);
-}
-
-static void on_glfw_joystick(int joystick_id, int event_type)
-{
- io::GlfwJoystickEvent event;
- event.joystick_id = joystick_id;
- event.event_type = event_type;
- globals::dispatcher.trigger(event);
-}
-
-static void on_glfw_monitor_event(GLFWmonitor* monitor, int event)
-{
- ImGui_ImplGlfw_MonitorCallback(monitor, event);
-}
-
-static void on_glfw_mouse_button(GLFWwindow* window, int button, int action, int mods)
-{
- io::GlfwMouseButtonEvent event;
- event.button = button;
- event.action = action;
- event.mods = mods;
- globals::dispatcher.trigger(event);
-
- ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods);
-}
-
-static void on_glfw_scroll(GLFWwindow* window, double dx, double dy)
-{
- io::GlfwScrollEvent event;
- event.dx = static_cast<float>(dx);
- event.dy = static_cast<float>(dy);
- globals::dispatcher.trigger(event);
-
- ImGui_ImplGlfw_ScrollCallback(window, dx, dy);
-}
-
-static void on_glfw_window_focus(GLFWwindow* window, int focused)
-{
- ImGui_ImplGlfw_WindowFocusCallback(window, focused);
-}
-
-static void GLAD_API_PTR on_opengl_message(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message,
- const void* param)
-{
- spdlog::info("opengl: {}", reinterpret_cast<const char*>(message));
-}
-
-static void on_termination_signal(int)
-{
- spdlog::warn("client: received termination signal");
- glfwSetWindowShouldClose(globals::window, true);
-}
-
-int main(int argc, char** argv)
-{
- io::cmdline::create(argc, argv);
-
-#if defined(_WIN32)
-#if defined(NDEBUG)
- if(GetConsoleWindow() && !io::cmdline::contains("debug")) {
- // Hide the console window on release builds
- // unless explicitly specified to preserve it instead
- FreeConsole();
- }
-#else
- if(GetConsoleWindow() && io::cmdline::contains("nodebug")) {
- // Hide the console window on debug builds when
- // explicitly specified by the user to hide it
- FreeConsole();
- }
-#endif
-#endif
-
- shared_game::init(argc, argv);
-
- spdlog::info("Voxelius Client {}", version::semver);
-
- glfwSetErrorCallback(&on_glfw_error);
-
-#if defined(__unix__)
- // Wayland constantly throws random bullshit at me
- // when I'm dealing with pretty much anything cross-platform
- // on pretty much any kind of UNIX and Linux distribution
- glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
-#endif
-
- if(!glfwInit()) {
- spdlog::critical("glfw: init failed");
- std::terminate();
- }
-
- glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_SAMPLES, 0);
-
- globals::window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, "Client", nullptr, nullptr);
-
- if(!globals::window) {
- spdlog::critical("glfw: failed to open a window");
- std::terminate();
- }
-
- std::signal(SIGINT, &on_termination_signal);
- std::signal(SIGTERM, &on_termination_signal);
-
- glfwMakeContextCurrent(globals::window);
- glfwSwapInterval(1);
-
- if(!gladLoadGL(&glfwGetProcAddress)) {
- spdlog::critical("glad: failed to load function pointers");
- std::terminate();
- }
-
- if(GLAD_GL_KHR_debug) {
- if(!io::cmdline::contains("nodebug")) {
- glEnable(GL_DEBUG_OUTPUT);
- glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- glDebugMessageCallback(&on_opengl_message, nullptr);
-
- // NVIDIA drivers tend to spam quote-unquote "useful"
- // information about buffer usage into the debug callback
- static const std::uint32_t ignore_nvidia_131185 = 131185;
- glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 1, &ignore_nvidia_131185, GL_FALSE);
- }
- else {
- spdlog::warn("glad: nodebug command line parameter found");
- spdlog::warn("glad: OpenGL errors will not be logged");
- }
- }
- else {
- spdlog::warn("glad: KHR_debug extension not supported");
- spdlog::warn("glad: OpenGL errors will not be logged");
- }
-
- spdlog::info("opengl: version: {}", reinterpret_cast<const char*>(glGetString(GL_VERSION)));
- spdlog::info("opengl: renderer: {}", reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
-
- Image::register_resource();
- TextureGUI::register_resource();
- SoundEffect::register_resource();
-
- glDisable(GL_MULTISAMPLE);
-
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGui::StyleColorsDark();
- ImGui_ImplGlfw_InitForOpenGL(globals::window, false);
- ImGui_ImplOpenGL3_Init(nullptr);
-
- // The UI is scaled against a resolution defined by BASE_WIDTH and BASE_HEIGHT
- // constants. However, UI scale of 1 doesn't look that good, so the window size is
- // limited to a resolution that allows at least UI scale of 2 and is defined by MIN_WIDTH and MIN_HEIGHT.
- glfwSetWindowSizeLimits(globals::window, MIN_WIDTH, MIN_HEIGHT, GLFW_DONT_CARE, GLFW_DONT_CARE);
-
- glfwSetCharCallback(globals::window, &on_glfw_char);
- glfwSetCursorEnterCallback(globals::window, &on_glfw_cursor_enter);
- glfwSetCursorPosCallback(globals::window, &on_glfw_cursor_pos);
- glfwSetFramebufferSizeCallback(globals::window, &on_glfw_framebuffer_size);
- glfwSetKeyCallback(globals::window, &on_glfw_key);
- glfwSetMouseButtonCallback(globals::window, &on_glfw_mouse_button);
- glfwSetScrollCallback(globals::window, &on_glfw_scroll);
- glfwSetWindowFocusCallback(globals::window, &on_glfw_window_focus);
-
- glfwSetJoystickCallback(&on_glfw_joystick);
- glfwSetMonitorCallback(&on_glfw_monitor_event);
-
- if(auto image = resource::load<Image>("textures/gui/window_icon.png")) {
- GLFWimage icon_image;
- icon_image.width = image->size.x;
- icon_image.height = image->size.y;
- icon_image.pixels = reinterpret_cast<unsigned char*>(image->pixels);
- glfwSetWindowIcon(globals::window, 1, &icon_image);
- }
-
- if(io::cmdline::contains("nosound")) {
- spdlog::warn("client: sound disabled [per command line]");
- globals::sound_dev = nullptr;
- globals::sound_ctx = nullptr;
- }
- else {
- if(!saladLoadALdefault()) {
- spdlog::warn("client: sound disabled [openal loading failed]");
- globals::sound_dev = nullptr;
- globals::sound_ctx = nullptr;
- }
- else {
- globals::sound_dev = alcOpenDevice(nullptr);
-
- if(globals::sound_dev == nullptr) {
- spdlog::warn("client: sound disabled [no device]");
- globals::sound_ctx = nullptr;
- }
- else {
- spdlog::info("sound: {}", reinterpret_cast<const char*>(alcGetString(globals::sound_dev, ALC_DEVICE_SPECIFIER)));
-
- globals::sound_ctx = alcCreateContext(globals::sound_dev, nullptr);
-
- if(globals::sound_ctx == nullptr) {
- spdlog::warn("client: sound disabled [context creation failed]");
- alcCloseDevice(globals::sound_dev);
- globals::sound_dev = nullptr;
- }
- else {
- alcMakeContextCurrent(globals::sound_ctx);
- }
- }
- }
- }
-
- splash::init_client();
-
- gui::window_title::update();
-
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::fixed_frametime = 0.0f;
- globals::fixed_frametime_avg = 0.0f;
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_framecount = 0;
-
- globals::curtime = utils::unix_microseconds();
-
- globals::window_frametime = 0.0f;
- globals::window_frametime_avg = 0.0f;
- globals::window_frametime_us = 0;
- globals::window_framecount = 0;
-
- int vmode_width = DEFAULT_WIDTH;
- int vmode_height = DEFAULT_HEIGHT;
-
- if(auto vmode = io::cmdline::get_cstr("mode")) {
- std::sscanf(vmode, "%dx%d", &vmode_width, &vmode_height);
- vmode_height = glm::max(vmode_height, MIN_HEIGHT);
- vmode_width = glm::max(vmode_width, MIN_WIDTH);
- }
-
- glfwSetWindowSize(globals::window, vmode_width, vmode_height);
-
- client_game::init();
-
- int wwidth, wheight;
- glfwGetFramebufferSize(globals::window, &wwidth, &wheight);
- on_glfw_framebuffer_size(globals::window, wwidth, wheight);
-
- threading::init();
-
- globals::client_config.load_file("client.conf");
- globals::client_config.load_cmdline();
-
- client_game::init_late();
-
- auto last_curtime = globals::curtime;
-
- while(!glfwWindowShouldClose(globals::window)) {
- globals::curtime = utils::unix_microseconds();
-
- globals::window_frametime_us = globals::curtime - last_curtime;
- globals::window_frametime = static_cast<float>(globals::window_frametime_us) / 1000000.0f;
- globals::window_frametime_avg += globals::window_frametime;
- globals::window_frametime_avg *= 0.5f;
-
- if(globals::fixed_frametime_us == UINT64_MAX) {
- globals::fixed_framecount = 0;
- globals::fixed_accumulator = 0;
- }
- else {
- globals::fixed_accumulator += globals::window_frametime_us;
- globals::fixed_framecount = globals::fixed_accumulator / globals::fixed_frametime_us;
- globals::fixed_accumulator %= globals::fixed_frametime_us;
- }
-
- globals::num_drawcalls = 0;
- globals::num_triangles = 0;
-
- last_curtime = globals::curtime;
-
- for(std::uint64_t i = 0; i < globals::fixed_framecount; ++i)
- client_game::fixed_update();
- client_game::update();
-
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
-
- glDisable(GL_BLEND);
-
- glDisable(GL_DEPTH_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glViewport(0, 0, globals::width, globals::height);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // Make sure there is no stray program object
- // being bound to the context. Usually third-party
- // overlay software (such as RivaTuner) injects itself
- // into the rendering loop and binds internal objects,
- // which creates an incomprehensible visual mess
- glUseProgram(0);
-
- client_game::render();
-
- client_game::layout();
-
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
- glfwSwapBuffers(globals::window);
-
- for(std::uint64_t i = 0; i < globals::fixed_framecount; ++i)
- client_game::fixed_update_late();
- client_game::update_late();
-
- glfwPollEvents();
-
- // EnTT provides two ways of dispatching events:
- // queued and immediate. When glfwPollEvents() is
- // called, immediate events are triggered across
- // the application, whilst queued ones are triggered
- // later by calling entt::dispatcher::update()
- globals::dispatcher.update();
-
- globals::window_framecount += 1;
-
- resource::soft_cleanup();
-
- threading::update();
- }
-
- client_game::shutdown();
-
- resource::hard_cleanup();
-
- spdlog::info("client: shutdown after {} frames", globals::window_framecount);
- spdlog::info("client: average framerate: {:.03f} FPS", 1.0f / globals::window_frametime_avg);
- spdlog::info("client: average frametime: {:.03f} ms", 1000.0f * globals::window_frametime_avg);
-
- ImGui_ImplOpenGL3_Shutdown();
- ImGui_ImplGlfw_Shutdown();
- ImGui::DestroyContext();
-
- if(globals::sound_ctx) {
- alcMakeContextCurrent(nullptr);
- alcDestroyContext(globals::sound_ctx);
- alcCloseDevice(globals::sound_dev);
- }
-
- glfwDestroyWindow(globals::window);
- glfwTerminate();
-
- globals::client_config.save_file("client.conf");
-
- threading::shutdown();
-
- shared_game::shutdown();
-
- return EXIT_SUCCESS;
-}
+#include "client/pch.hh" + +#include "core/io/cmdline.hh" +#include "core/io/config_map.hh" + +#include "core/resource/image.hh" +#include "core/resource/resource.hh" + +#include "core/utils/epoch.hh" + +#include "core/threading.hh" +#include "core/version.hh" + +#include "shared/game.hh" +#include "shared/splash.hh" + +#include "client/gui/window_title.hh" + +#include "client/io/glfw.hh" + +#include "client/resource/sound_effect.hh" +#include "client/resource/texture_gui.hh" + +#include "client/const.hh" +#include "client/game.hh" +#include "client/globals.hh" + +#if defined(_WIN32) +extern "C" __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; +extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +#endif + +static void on_glfw_error(int code, const char* message) +{ + spdlog::error("glfw: {}", message); +} + +static void on_glfw_char(GLFWwindow* window, unsigned int codepoint) +{ + ImGui_ImplGlfw_CharCallback(window, codepoint); +} + +static void on_glfw_cursor_enter(GLFWwindow* window, int entered) +{ + ImGui_ImplGlfw_CursorEnterCallback(window, entered); +} + +static void on_glfw_cursor_pos(GLFWwindow* window, double xpos, double ypos) +{ + io::GlfwCursorPosEvent event; + event.pos.x = static_cast<float>(xpos); + event.pos.y = static_cast<float>(ypos); + globals::dispatcher.trigger(event); + + ImGui_ImplGlfw_CursorPosCallback(window, xpos, ypos); +} + +static void on_glfw_framebuffer_size(GLFWwindow* window, int width, int height) +{ + if(glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { + // Don't do anything if the window was just + // iconified (minimized); as it turns out minimized + // windows on WIN32 seem to be forced into 0x0 + return; + } + + globals::width = width; + globals::height = height; + globals::aspect = static_cast<float>(width) / static_cast<float>(height); + + io::GlfwFramebufferSizeEvent fb_event; + fb_event.size.x = globals::width; + fb_event.size.y = globals::height; + fb_event.aspect = globals::aspect; + globals::dispatcher.trigger(fb_event); +} + +static void on_glfw_key(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + io::GlfwKeyEvent event; + event.key = key; + event.scancode = scancode; + event.action = action; + event.mods = mods; + globals::dispatcher.trigger(event); + + ImGui_ImplGlfw_KeyCallback(window, key, scancode, action, mods); +} + +static void on_glfw_joystick(int joystick_id, int event_type) +{ + io::GlfwJoystickEvent event; + event.joystick_id = joystick_id; + event.event_type = event_type; + globals::dispatcher.trigger(event); +} + +static void on_glfw_monitor_event(GLFWmonitor* monitor, int event) +{ + ImGui_ImplGlfw_MonitorCallback(monitor, event); +} + +static void on_glfw_mouse_button(GLFWwindow* window, int button, int action, int mods) +{ + io::GlfwMouseButtonEvent event; + event.button = button; + event.action = action; + event.mods = mods; + globals::dispatcher.trigger(event); + + ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods); +} + +static void on_glfw_scroll(GLFWwindow* window, double dx, double dy) +{ + io::GlfwScrollEvent event; + event.dx = static_cast<float>(dx); + event.dy = static_cast<float>(dy); + globals::dispatcher.trigger(event); + + ImGui_ImplGlfw_ScrollCallback(window, dx, dy); +} + +static void on_glfw_window_focus(GLFWwindow* window, int focused) +{ + ImGui_ImplGlfw_WindowFocusCallback(window, focused); +} + +static void GLAD_API_PTR on_opengl_message(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, + const void* param) +{ + spdlog::info("opengl: {}", reinterpret_cast<const char*>(message)); +} + +static void on_termination_signal(int) +{ + spdlog::warn("client: received termination signal"); + glfwSetWindowShouldClose(globals::window, true); +} + +int main(int argc, char** argv) +{ + io::cmdline::create(argc, argv); + +#if defined(_WIN32) +#if defined(NDEBUG) + if(GetConsoleWindow() && !io::cmdline::contains("debug")) { + // Hide the console window on release builds + // unless explicitly specified to preserve it instead + FreeConsole(); + } +#else + if(GetConsoleWindow() && io::cmdline::contains("nodebug")) { + // Hide the console window on debug builds when + // explicitly specified by the user to hide it + FreeConsole(); + } +#endif +#endif + + shared_game::init(argc, argv); + + spdlog::info("Voxelius Client {}", version::full); + + glfwSetErrorCallback(&on_glfw_error); + +#if defined(__unix__) + // Wayland constantly throws random bullshit at me + // when I'm dealing with pretty much anything cross-platform + // on pretty much any kind of UNIX and Linux distribution + glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11); +#endif + + if(!glfwInit()) { + spdlog::critical("glfw: init failed"); + std::terminate(); + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 0); + + globals::window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, "Client", nullptr, nullptr); + + if(!globals::window) { + spdlog::critical("glfw: failed to open a window"); + std::terminate(); + } + + std::signal(SIGINT, &on_termination_signal); + std::signal(SIGTERM, &on_termination_signal); + + glfwMakeContextCurrent(globals::window); + glfwSwapInterval(1); + + if(!gladLoadGL(&glfwGetProcAddress)) { + spdlog::critical("glad: failed to load function pointers"); + std::terminate(); + } + + if(GLAD_GL_KHR_debug) { + if(!io::cmdline::contains("nodebug")) { + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(&on_opengl_message, nullptr); + + // NVIDIA drivers tend to spam quote-unquote "useful" + // information about buffer usage into the debug callback + static const std::uint32_t ignore_nvidia_131185 = 131185; + glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 1, &ignore_nvidia_131185, GL_FALSE); + } + else { + spdlog::warn("glad: nodebug command line parameter found"); + spdlog::warn("glad: OpenGL errors will not be logged"); + } + } + else { + spdlog::warn("glad: KHR_debug extension not supported"); + spdlog::warn("glad: OpenGL errors will not be logged"); + } + + spdlog::info("opengl: version: {}", reinterpret_cast<const char*>(glGetString(GL_VERSION))); + spdlog::info("opengl: renderer: {}", reinterpret_cast<const char*>(glGetString(GL_RENDERER))); + + Image::register_resource(); + TextureGUI::register_resource(); + SoundEffect::register_resource(); + + glDisable(GL_MULTISAMPLE); + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGui::StyleColorsDark(); + ImGui_ImplGlfw_InitForOpenGL(globals::window, false); + ImGui_ImplOpenGL3_Init(nullptr); + + // The UI is scaled against a resolution defined by BASE_WIDTH and BASE_HEIGHT + // constants. However, UI scale of 1 doesn't look that good, so the window size is + // limited to a resolution that allows at least UI scale of 2 and is defined by MIN_WIDTH and MIN_HEIGHT. + glfwSetWindowSizeLimits(globals::window, MIN_WIDTH, MIN_HEIGHT, GLFW_DONT_CARE, GLFW_DONT_CARE); + + glfwSetCharCallback(globals::window, &on_glfw_char); + glfwSetCursorEnterCallback(globals::window, &on_glfw_cursor_enter); + glfwSetCursorPosCallback(globals::window, &on_glfw_cursor_pos); + glfwSetFramebufferSizeCallback(globals::window, &on_glfw_framebuffer_size); + glfwSetKeyCallback(globals::window, &on_glfw_key); + glfwSetMouseButtonCallback(globals::window, &on_glfw_mouse_button); + glfwSetScrollCallback(globals::window, &on_glfw_scroll); + glfwSetWindowFocusCallback(globals::window, &on_glfw_window_focus); + + glfwSetJoystickCallback(&on_glfw_joystick); + glfwSetMonitorCallback(&on_glfw_monitor_event); + + if(auto image = resource::load<Image>("textures/gui/window_icon.png")) { + GLFWimage icon_image; + icon_image.width = image->size.x; + icon_image.height = image->size.y; + icon_image.pixels = reinterpret_cast<unsigned char*>(image->pixels); + glfwSetWindowIcon(globals::window, 1, &icon_image); + } + + if(io::cmdline::contains("nosound")) { + spdlog::warn("client: sound disabled [per command line]"); + globals::sound_dev = nullptr; + globals::sound_ctx = nullptr; + } + else { + if(!saladLoadALdefault()) { + spdlog::warn("client: sound disabled [openal loading failed]"); + globals::sound_dev = nullptr; + globals::sound_ctx = nullptr; + } + else { + globals::sound_dev = alcOpenDevice(nullptr); + + if(globals::sound_dev == nullptr) { + spdlog::warn("client: sound disabled [no device]"); + globals::sound_ctx = nullptr; + } + else { + spdlog::info("sound: {}", reinterpret_cast<const char*>(alcGetString(globals::sound_dev, ALC_DEVICE_SPECIFIER))); + + globals::sound_ctx = alcCreateContext(globals::sound_dev, nullptr); + + if(globals::sound_ctx == nullptr) { + spdlog::warn("client: sound disabled [context creation failed]"); + alcCloseDevice(globals::sound_dev); + globals::sound_dev = nullptr; + } + else { + alcMakeContextCurrent(globals::sound_ctx); + } + } + } + } + + splash::init_client(); + + gui::window_title::update(); + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + globals::fixed_frametime = 0.0f; + globals::fixed_frametime_avg = 0.0f; + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_framecount = 0; + + globals::curtime = utils::unix_microseconds(); + + globals::window_frametime = 0.0f; + globals::window_frametime_avg = 0.0f; + globals::window_frametime_us = 0; + globals::window_framecount = 0; + + int vmode_width = DEFAULT_WIDTH; + int vmode_height = DEFAULT_HEIGHT; + + if(auto vmode = io::cmdline::get_cstr("mode")) { + std::sscanf(vmode, "%dx%d", &vmode_width, &vmode_height); + vmode_height = glm::max(vmode_height, MIN_HEIGHT); + vmode_width = glm::max(vmode_width, MIN_WIDTH); + } + + glfwSetWindowSize(globals::window, vmode_width, vmode_height); + + client_game::init(); + + int wwidth, wheight; + glfwGetFramebufferSize(globals::window, &wwidth, &wheight); + on_glfw_framebuffer_size(globals::window, wwidth, wheight); + + threading::init(); + + globals::client_config.load_file("client.conf"); + globals::client_config.load_cmdline(); + + client_game::init_late(); + + auto last_curtime = globals::curtime; + + while(!glfwWindowShouldClose(globals::window)) { + globals::curtime = utils::unix_microseconds(); + + globals::window_frametime_us = globals::curtime - last_curtime; + globals::window_frametime = static_cast<float>(globals::window_frametime_us) / 1000000.0f; + globals::window_frametime_avg += globals::window_frametime; + globals::window_frametime_avg *= 0.5f; + + if(globals::fixed_frametime_us == UINT64_MAX) { + globals::fixed_framecount = 0; + globals::fixed_accumulator = 0; + } + else { + globals::fixed_accumulator += globals::window_frametime_us; + globals::fixed_framecount = globals::fixed_accumulator / globals::fixed_frametime_us; + globals::fixed_accumulator %= globals::fixed_frametime_us; + } + + globals::num_drawcalls = 0; + globals::num_triangles = 0; + + last_curtime = globals::curtime; + + for(std::uint64_t i = 0; i < globals::fixed_framecount; ++i) + client_game::fixed_update(); + client_game::update(); + + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + glDisable(GL_BLEND); + + glDisable(GL_DEPTH_TEST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, globals::width, globals::height); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Make sure there is no stray program object + // being bound to the context. Usually third-party + // overlay software (such as RivaTuner) injects itself + // into the rendering loop and binds internal objects, + // which creates an incomprehensible visual mess + glUseProgram(0); + + client_game::render(); + + client_game::layout(); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(globals::window); + + for(std::uint64_t i = 0; i < globals::fixed_framecount; ++i) + client_game::fixed_update_late(); + client_game::update_late(); + + glfwPollEvents(); + + // EnTT provides two ways of dispatching events: + // queued and immediate. When glfwPollEvents() is + // called, immediate events are triggered across + // the application, whilst queued ones are triggered + // later by calling entt::dispatcher::update() + globals::dispatcher.update(); + + globals::window_framecount += 1; + + resource::soft_cleanup(); + + threading::update(); + } + + client_game::shutdown(); + + resource::hard_cleanup(); + + spdlog::info("client: shutdown after {} frames", globals::window_framecount); + spdlog::info("client: average framerate: {:.03f} FPS", 1.0f / globals::window_frametime_avg); + spdlog::info("client: average frametime: {:.03f} ms", 1000.0f * globals::window_frametime_avg); + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + if(globals::sound_ctx) { + alcMakeContextCurrent(nullptr); + alcDestroyContext(globals::sound_ctx); + alcCloseDevice(globals::sound_dev); + } + + glfwDestroyWindow(globals::window); + glfwTerminate(); + + globals::client_config.save_file("client.conf"); + + threading::shutdown(); + + shared_game::shutdown(); + + return EXIT_SUCCESS; +} diff --git a/game/client/pch.hh b/src/game/client/pch.hh index e6d5681..3832081 100644 --- a/game/client/pch.hh +++ b/src/game/client/pch.hh @@ -1,28 +1,28 @@ -#pragma once
-
-#include <shared/pch.hh>
-
-#include <AL/al.h>
-#include <AL/alc.h>
-#include <AL/salad.h>
-
-#include <dr_mp3.h>
-#include <dr_wav.h>
-
-#include <GLFW/glfw3.h>
-
-#include <glad/gl.h>
-
-#include <imgui.h>
-#include <imgui_impl_glfw.h>
-#include <imgui_impl_opengl3.h>
-#include <imgui_stdlib.h>
-
-#if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#if defined(__unix__)
-#include <dlfcn.h>
-#endif
+#pragma once + +#include <shared/pch.hh> + +#include <AL/al.h> +#include <AL/alc.h> +#include <AL/salad.h> + +#include <dr_mp3.h> +#include <dr_wav.h> + +#include <GLFW/glfw3.h> + +#include <glad/gl.h> + +#include <imgui.h> +#include <imgui_impl_glfw.h> +#include <imgui_impl_opengl3.h> +#include <imgui_stdlib.h> + +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +#if defined(__unix__) +#include <dlfcn.h> +#endif diff --git a/game/client/program.cc b/src/game/client/program.cc index 6a2dfa0..88cbe28 100644 --- a/game/client/program.cc +++ b/src/game/client/program.cc @@ -1,226 +1,226 @@ -#include "client/pch.hh"
-
-#include "client/program.hh"
-
-#include "core/io/physfs.hh"
-
-#include "core/utils/string.hh"
-
-// This fills up the array of source lines and figures out
-// which lines are to be dynamically resolved as variant macros
-static void parse_source(std::string_view source, std::vector<std::string>& out_lines, std::vector<GL_VariedMacro>& out_variants)
-{
- std::string line;
- std::istringstream stream = std::istringstream(std::string(source));
- unsigned long line_number = 0UL;
-
- out_lines.clear();
- out_variants.clear();
-
- while(std::getline(stream, line)) {
- unsigned int macro_index = {};
- char macro_name[128] = {};
-
- if(std::sscanf(line.c_str(), " # pragma variant [ %u ] %127[^, \"\t\r\n]", ¯o_index, ¯o_name) == 2) {
- if(out_variants.size() <= macro_index) {
- out_variants.resize(macro_index + 1U);
- }
-
- out_variants[macro_index].name = macro_name;
- out_variants[macro_index].line = line_number;
- out_variants[macro_index].value = std::numeric_limits<unsigned int>::max();
-
- out_lines.push_back(std::string());
- line_number += 1UL;
- }
- else {
- out_lines.push_back(line);
- line_number += 1UL;
- }
- }
-}
-
-static GLuint compile_shader(std::string_view path, const char* source, GLenum shader_stage)
-{
- GLuint shader = glCreateShader(shader_stage);
- glShaderSource(shader, 1, &source, nullptr);
- glCompileShader(shader);
-
- GLint info_log_length;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
-
- if(info_log_length >= 2) {
- std::basic_string<GLchar> info_log;
- info_log.resize(info_log_length);
- glGetShaderInfoLog(shader, info_log_length, nullptr, info_log.data());
- spdlog::info("gl_program: {}: shader information:", path);
- spdlog::info(info_log);
- }
-
- GLint compile_status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
-
- if(!compile_status) {
- glDeleteShader(shader);
- return 0;
- }
-
- return shader;
-}
-
-bool GL_Program::setup(std::string_view vpath, std::string_view fpath)
-{
- destroy();
-
- vert_path = std::string(vpath);
- frag_path = std::string(fpath);
-
- auto vfile = PHYSFS_openRead(vert_path.c_str());
-
- if(vfile == nullptr) {
- spdlog::warn("gl_program: {}: {}", vpath, io::physfs_error());
- return false;
- }
-
- auto vsource = std::string(PHYSFS_fileLength(vfile), char(0x00));
- PHYSFS_readBytes(vfile, vsource.data(), vsource.size());
- PHYSFS_close(vfile);
-
- auto ffile = PHYSFS_openRead(frag_path.c_str());
-
- if(ffile == nullptr) {
- spdlog::warn("gl_program: {}: {}", fpath, io::physfs_error());
- return false;
- }
-
- auto fsource = std::string(PHYSFS_fileLength(ffile), char(0x00));
- PHYSFS_readBytes(ffile, fsource.data(), fsource.size());
- PHYSFS_close(ffile);
-
- parse_source(vsource.c_str(), vert_source, vert_variants);
- parse_source(fsource.c_str(), frag_source, frag_variants);
-
- needs_update = true;
- handle = 0;
-
- return true;
-}
-
-bool GL_Program::update(void)
-{
- if(!needs_update) {
- // The program is already up to
- // date with the internal state
- return true;
- }
-
- for(const auto& macro : vert_variants)
- vert_source[macro.line] = std::format("#define {} {}", macro.name, macro.value);
- for(const auto& macro : frag_variants)
- frag_source[macro.line] = std::format("#define {} {}", macro.name, macro.value);
-
- std::string vsource(utils::join(vert_source, "\r\n"));
- std::string fsource(utils::join(frag_source, "\r\n"));
-
- GLuint vert = compile_shader(vert_path.c_str(), vsource.c_str(), GL_VERTEX_SHADER);
- GLuint frag = compile_shader(frag_path.c_str(), fsource.c_str(), GL_FRAGMENT_SHADER);
-
- if(!vert || !frag) {
- // needs_update = false;
- glDeleteShader(frag);
- glDeleteShader(vert);
- return false;
- }
-
- handle = glCreateProgram();
- glAttachShader(handle, vert);
- glAttachShader(handle, frag);
- glLinkProgram(handle);
-
- GLint info_log_length;
- glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &info_log_length);
-
- if(info_log_length >= 2) {
- std::basic_string<GLchar> info_log;
- info_log.resize(info_log_length);
- glGetProgramInfoLog(handle, info_log_length, nullptr, info_log.data());
- spdlog::info("gl_program: [{}; {}]: program information", vert, frag);
- spdlog::info(info_log);
- }
-
- glDeleteShader(frag);
- glDeleteShader(vert);
-
- GLint link_status;
- glGetProgramiv(handle, GL_LINK_STATUS, &link_status);
-
- if(!link_status) {
- // needs_update = false;
- glDeleteProgram(handle);
- return false;
- }
-
- for(auto& uniform : uniforms) {
- // NOTE: GL seems to silently ignore invalid uniform
- // locations (-1); should we write something into logs about this?
- uniform.location = glGetUniformLocation(handle, uniform.name.c_str());
- }
-
- needs_update = false;
- return true;
-}
-
-void GL_Program::destroy(void)
-{
- if(handle) {
- glDeleteProgram(handle);
- handle = 0;
- }
-
- uniforms.clear();
-
- frag_variants.clear();
- frag_source.clear();
- frag_path = std::string();
-
- vert_variants.clear();
- vert_source.clear();
- vert_path = std::string();
-
- needs_update = false;
-}
-
-std::size_t GL_Program::add_uniform(std::string_view name)
-{
- for(std::size_t i = 0; i < uniforms.size(); ++i) {
- if(0 == uniforms[i].name.compare(name)) {
- return i;
- }
- }
-
- const std::size_t index = uniforms.size();
- uniforms.push_back(GL_Uniform());
- uniforms[index].location = -1;
- uniforms[index].name = name;
- return index;
-}
-
-void GL_Program::set_variant_vert(unsigned int variant, unsigned int value)
-{
- if(variant < vert_variants.size()) {
- if(value != vert_variants[variant].value) {
- vert_variants[variant].value = value;
- needs_update = true;
- }
- }
-}
-
-void GL_Program::set_variant_frag(unsigned int variant, unsigned int value)
-{
- if(variant < frag_variants.size()) {
- if(value != frag_variants[variant].value) {
- frag_variants[variant].value = value;
- needs_update = true;
- }
- }
-}
+#include "client/pch.hh" + +#include "client/program.hh" + +#include "core/io/physfs.hh" + +#include "core/utils/string.hh" + +// This fills up the array of source lines and figures out +// which lines are to be dynamically resolved as variant macros +static void parse_source(std::string_view source, std::vector<std::string>& out_lines, std::vector<GL_VariedMacro>& out_variants) +{ + std::string line; + std::istringstream stream = std::istringstream(std::string(source)); + unsigned long line_number = 0UL; + + out_lines.clear(); + out_variants.clear(); + + while(std::getline(stream, line)) { + unsigned int macro_index = {}; + char macro_name[128] = {}; + + if(std::sscanf(line.c_str(), " # pragma variant [ %u ] %127[^, \"\t\r\n]", ¯o_index, ¯o_name) == 2) { + if(out_variants.size() <= macro_index) { + out_variants.resize(macro_index + 1U); + } + + out_variants[macro_index].name = macro_name; + out_variants[macro_index].line = line_number; + out_variants[macro_index].value = std::numeric_limits<unsigned int>::max(); + + out_lines.push_back(std::string()); + line_number += 1UL; + } + else { + out_lines.push_back(line); + line_number += 1UL; + } + } +} + +static GLuint compile_shader(std::string_view path, const char* source, GLenum shader_stage) +{ + GLuint shader = glCreateShader(shader_stage); + glShaderSource(shader, 1, &source, nullptr); + glCompileShader(shader); + + GLint info_log_length; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length); + + if(info_log_length >= 2) { + std::basic_string<GLchar> info_log; + info_log.resize(info_log_length); + glGetShaderInfoLog(shader, info_log_length, nullptr, info_log.data()); + spdlog::info("gl_program: {}: shader information:", path); + spdlog::info(info_log); + } + + GLint compile_status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); + + if(!compile_status) { + glDeleteShader(shader); + return 0; + } + + return shader; +} + +bool GL_Program::setup(std::string_view vpath, std::string_view fpath) +{ + destroy(); + + vert_path = std::string(vpath); + frag_path = std::string(fpath); + + auto vfile = PHYSFS_openRead(vert_path.c_str()); + + if(vfile == nullptr) { + spdlog::warn("gl_program: {}: {}", vpath, io::physfs_error()); + return false; + } + + auto vsource = std::string(PHYSFS_fileLength(vfile), char(0x00)); + PHYSFS_readBytes(vfile, vsource.data(), vsource.size()); + PHYSFS_close(vfile); + + auto ffile = PHYSFS_openRead(frag_path.c_str()); + + if(ffile == nullptr) { + spdlog::warn("gl_program: {}: {}", fpath, io::physfs_error()); + return false; + } + + auto fsource = std::string(PHYSFS_fileLength(ffile), char(0x00)); + PHYSFS_readBytes(ffile, fsource.data(), fsource.size()); + PHYSFS_close(ffile); + + parse_source(vsource.c_str(), vert_source, vert_variants); + parse_source(fsource.c_str(), frag_source, frag_variants); + + needs_update = true; + handle = 0; + + return true; +} + +bool GL_Program::update(void) +{ + if(!needs_update) { + // The program is already up to + // date with the internal state + return true; + } + + for(const auto& macro : vert_variants) + vert_source[macro.line] = std::format("#define {} {}", macro.name, macro.value); + for(const auto& macro : frag_variants) + frag_source[macro.line] = std::format("#define {} {}", macro.name, macro.value); + + std::string vsource(utils::join(vert_source, "\r\n")); + std::string fsource(utils::join(frag_source, "\r\n")); + + GLuint vert = compile_shader(vert_path.c_str(), vsource.c_str(), GL_VERTEX_SHADER); + GLuint frag = compile_shader(frag_path.c_str(), fsource.c_str(), GL_FRAGMENT_SHADER); + + if(!vert || !frag) { + // needs_update = false; + glDeleteShader(frag); + glDeleteShader(vert); + return false; + } + + handle = glCreateProgram(); + glAttachShader(handle, vert); + glAttachShader(handle, frag); + glLinkProgram(handle); + + GLint info_log_length; + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &info_log_length); + + if(info_log_length >= 2) { + std::basic_string<GLchar> info_log; + info_log.resize(info_log_length); + glGetProgramInfoLog(handle, info_log_length, nullptr, info_log.data()); + spdlog::info("gl_program: [{}; {}]: program information", vert, frag); + spdlog::info(info_log); + } + + glDeleteShader(frag); + glDeleteShader(vert); + + GLint link_status; + glGetProgramiv(handle, GL_LINK_STATUS, &link_status); + + if(!link_status) { + // needs_update = false; + glDeleteProgram(handle); + return false; + } + + for(auto& uniform : uniforms) { + // NOTE: GL seems to silently ignore invalid uniform + // locations (-1); should we write something into logs about this? + uniform.location = glGetUniformLocation(handle, uniform.name.c_str()); + } + + needs_update = false; + return true; +} + +void GL_Program::destroy(void) +{ + if(handle) { + glDeleteProgram(handle); + handle = 0; + } + + uniforms.clear(); + + frag_variants.clear(); + frag_source.clear(); + frag_path = std::string(); + + vert_variants.clear(); + vert_source.clear(); + vert_path = std::string(); + + needs_update = false; +} + +std::size_t GL_Program::add_uniform(std::string_view name) +{ + for(std::size_t i = 0; i < uniforms.size(); ++i) { + if(0 == uniforms[i].name.compare(name)) { + return i; + } + } + + const std::size_t index = uniforms.size(); + uniforms.push_back(GL_Uniform()); + uniforms[index].location = -1; + uniforms[index].name = name; + return index; +} + +void GL_Program::set_variant_vert(unsigned int variant, unsigned int value) +{ + if(variant < vert_variants.size()) { + if(value != vert_variants[variant].value) { + vert_variants[variant].value = value; + needs_update = true; + } + } +} + +void GL_Program::set_variant_frag(unsigned int variant, unsigned int value) +{ + if(variant < frag_variants.size()) { + if(value != frag_variants[variant].value) { + frag_variants[variant].value = value; + needs_update = true; + } + } +} diff --git a/game/client/program.hh b/src/game/client/program.hh index bf35417..af78513 100644 --- a/game/client/program.hh +++ b/src/game/client/program.hh @@ -1,34 +1,34 @@ -#pragma once
-
-struct GL_VariedMacro final {
- std::string name;
- unsigned long line;
- unsigned int value;
-};
-
-struct GL_Uniform final {
- std::string name;
- GLint location;
-};
-
-class GL_Program final {
-public:
- bool setup(std::string_view vpath, std::string_view fpath);
- void destroy(void);
- bool update(void);
-
- std::size_t add_uniform(std::string_view name);
- void set_variant_vert(unsigned int variant, unsigned int value);
- void set_variant_frag(unsigned int variant, unsigned int value);
-
-public:
- std::string vert_path;
- std::string frag_path;
- std::vector<std::string> vert_source;
- std::vector<std::string> frag_source;
- std::vector<GL_VariedMacro> vert_variants;
- std::vector<GL_VariedMacro> frag_variants;
- std::vector<GL_Uniform> uniforms;
- bool needs_update;
- GLuint handle;
-};
+#pragma once + +struct GL_VariedMacro final { + std::string name; + unsigned long line; + unsigned int value; +}; + +struct GL_Uniform final { + std::string name; + GLint location; +}; + +class GL_Program final { +public: + bool setup(std::string_view vpath, std::string_view fpath); + void destroy(void); + bool update(void); + + std::size_t add_uniform(std::string_view name); + void set_variant_vert(unsigned int variant, unsigned int value); + void set_variant_frag(unsigned int variant, unsigned int value); + +public: + std::string vert_path; + std::string frag_path; + std::vector<std::string> vert_source; + std::vector<std::string> frag_source; + std::vector<GL_VariedMacro> vert_variants; + std::vector<GL_VariedMacro> frag_variants; + std::vector<GL_Uniform> uniforms; + bool needs_update; + GLuint handle; +}; diff --git a/game/client/receive.cc b/src/game/client/receive.cc index d6dcac0..a253911 100644 --- a/game/client/receive.cc +++ b/src/game/client/receive.cc @@ -1,192 +1,192 @@ -#include "client/pch.hh"
-
-#include "client/receive.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/entity/factory.hh"
-
-#include "client/gui/chat.hh"
-#include "client/gui/gui_screen.hh"
-#include "client/gui/message_box.hh"
-#include "client/gui/window_title.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-static bool synchronize_entity_id(world::Dimension* dimension, entt::entity entity)
-{
- if(dimension->entities.valid(entity)) {
- // Entity ID already exists
- return true;
- }
-
- auto created = dimension->entities.create(entity);
-
- if(created == entity) {
- // Synchronized successfully
- return true;
- }
-
- session::disconnect("protocol.entity_id_desync");
- spdlog::critical("receive: entity desync: network {} resolved as client {}", static_cast<std::uint64_t>(entity),
- static_cast<std::uint64_t>(created));
-
- gui::message_box::reset();
- gui::message_box::set_title("disconnected.disconnected");
- gui::message_box::set_subtitle("protocol.entity_id_desync");
- gui::message_box::add_button("disconnected.back", [](void) {
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- });
-
- globals::gui_screen = GUI_MESSAGE_BOX;
-
- return false;
-}
-
-static void on_dimension_info_packet(const protocol::DimensionInfo& packet)
-{
- if(session::peer) {
- if(globals::dimension) {
- delete globals::dimension;
- globals::dimension = nullptr;
- globals::player = entt::null;
- }
-
- globals::dimension = new world::Dimension(packet.name.c_str(), packet.gravity);
- }
-}
-
-static void on_chunk_voxels_packet(const protocol::ChunkVoxels& packet)
-{
- if(session::peer && globals::dimension) {
- auto chunk = globals::dimension->create_chunk(packet.chunk);
- chunk->set_voxels(packet.voxels);
-
- world::ChunkUpdateEvent event;
- event.dimension = globals::dimension;
- event.cpos = packet.chunk;
- event.chunk = chunk;
-
- globals::dispatcher.trigger(event);
-
- return;
- }
-}
-
-static void on_entity_head_packet(const protocol::EntityHead& packet)
-{
- if(session::peer && globals::dimension) {
- if(synchronize_entity_id(globals::dimension, packet.entity)) {
- auto& component = globals::dimension->entities.get_or_emplace<entity::Head>(packet.entity);
- auto& prevcomp = globals::dimension->entities.get_or_emplace<entity::client::HeadPrev>(packet.entity);
-
- // Store the previous component state
- prevcomp.angles = component.angles;
- prevcomp.offset = component.offset;
-
- // Assign the new component state
- component.angles = packet.angles;
- }
- }
-}
-
-static void on_entity_transform_packet(const protocol::EntityTransform& packet)
-{
- if(session::peer && globals::dimension) {
- if(synchronize_entity_id(globals::dimension, packet.entity)) {
- auto& component = globals::dimension->entities.get_or_emplace<entity::Transform>(packet.entity);
- auto& prevcomp = globals::dimension->entities.get_or_emplace<entity::client::TransformPrev>(packet.entity);
-
- // Store the previous component state
- prevcomp.angles = component.angles;
- prevcomp.chunk = component.chunk;
- prevcomp.local = component.local;
-
- // Assign the new component state
- component.angles = packet.angles;
- component.chunk = packet.chunk;
- component.local = packet.local;
- }
- }
-}
-
-static void on_entity_velocity_packet(const protocol::EntityVelocity& packet)
-{
- if(session::peer && globals::dimension) {
- if(synchronize_entity_id(globals::dimension, packet.entity)) {
- auto& component = globals::dimension->entities.get_or_emplace<entity::Velocity>(packet.entity);
- component.value = packet.value;
- }
- }
-}
-
-static void on_entity_player_packet(const protocol::EntityPlayer& packet)
-{
- if(session::peer && globals::dimension) {
- if(synchronize_entity_id(globals::dimension, packet.entity)) {
- entity::client::create_player(globals::dimension, packet.entity);
- }
- }
-}
-
-static void on_spawn_player_packet(const protocol::SpawnPlayer& packet)
-{
- if(session::peer && globals::dimension) {
- if(synchronize_entity_id(globals::dimension, packet.entity)) {
- entity::client::create_player(globals::dimension, packet.entity);
-
- globals::player = packet.entity;
- globals::gui_screen = GUI_SCREEN_NONE;
-
- gui::client_chat::refresh_timings();
-
- gui::window_title::update();
- }
- }
-}
-
-static void on_remove_entity_packet(const protocol::RemoveEntity& packet)
-{
- if(globals::dimension) {
- if(packet.entity == globals::player) {
- globals::player = entt::null;
- }
-
- globals::dimension->entities.destroy(packet.entity);
- }
-}
-
-static void on_generic_sound_packet(const protocol::GenericSound& packet)
-{
- sound::play_generic(packet.sound.c_str(), packet.looping, packet.pitch);
-}
-
-static void on_entity_sound_packet(const protocol::EntitySound& packet)
-{
- sound::play_entity(packet.entity, packet.sound.c_str(), packet.looping, packet.pitch);
-}
-
-void client_receive::init(void)
-{
- globals::dispatcher.sink<protocol::DimensionInfo>().connect<&on_dimension_info_packet>();
- globals::dispatcher.sink<protocol::ChunkVoxels>().connect<&on_chunk_voxels_packet>();
- globals::dispatcher.sink<protocol::EntityHead>().connect<&on_entity_head_packet>();
- globals::dispatcher.sink<protocol::EntityTransform>().connect<&on_entity_transform_packet>();
- globals::dispatcher.sink<protocol::EntityVelocity>().connect<&on_entity_velocity_packet>();
- globals::dispatcher.sink<protocol::EntityPlayer>().connect<&on_entity_player_packet>();
- globals::dispatcher.sink<protocol::SpawnPlayer>().connect<&on_spawn_player_packet>();
- globals::dispatcher.sink<protocol::RemoveEntity>().connect<&on_remove_entity_packet>();
- globals::dispatcher.sink<protocol::GenericSound>().connect<&on_generic_sound_packet>();
- globals::dispatcher.sink<protocol::EntitySound>().connect<&on_entity_sound_packet>();
-}
+#include "client/pch.hh" + +#include "client/receive.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/protocol.hh" + +#include "client/entity/factory.hh" + +#include "client/gui/chat.hh" +#include "client/gui/gui_screen.hh" +#include "client/gui/message_box.hh" +#include "client/gui/window_title.hh" + +#include "client/sound/sound.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +static bool synchronize_entity_id(world::Dimension* dimension, entt::entity entity) +{ + if(dimension->entities.valid(entity)) { + // Entity ID already exists + return true; + } + + auto created = dimension->entities.create(entity); + + if(created == entity) { + // Synchronized successfully + return true; + } + + session::disconnect("protocol.entity_id_desync"); + spdlog::critical("receive: entity desync: network {} resolved as client {}", static_cast<std::uint64_t>(entity), + static_cast<std::uint64_t>(created)); + + gui::message_box::reset(); + gui::message_box::set_title("disconnected.disconnected"); + gui::message_box::set_subtitle("protocol.entity_id_desync"); + gui::message_box::add_button("disconnected.back", [](void) { + globals::gui_screen = GUI_PLAY_MENU; + gui::window_title::update(); + }); + + globals::gui_screen = GUI_MESSAGE_BOX; + + return false; +} + +static void on_dimension_info_packet(const protocol::DimensionInfo& packet) +{ + if(session::peer) { + if(globals::dimension) { + delete globals::dimension; + globals::dimension = nullptr; + globals::player = entt::null; + } + + globals::dimension = new world::Dimension(packet.name.c_str(), packet.gravity); + } +} + +static void on_chunk_voxels_packet(const protocol::ChunkVoxels& packet) +{ + if(session::peer && globals::dimension) { + auto chunk = globals::dimension->create_chunk(packet.chunk); + chunk->set_voxels(packet.voxels); + + world::ChunkUpdateEvent event; + event.dimension = globals::dimension; + event.cpos = packet.chunk; + event.chunk = chunk; + + globals::dispatcher.trigger(event); + + return; + } +} + +static void on_entity_head_packet(const protocol::EntityHead& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace<entity::Head>(packet.entity); + auto& prevcomp = globals::dimension->entities.get_or_emplace<entity::client::HeadPrev>(packet.entity); + + // Store the previous component state + prevcomp.angles = component.angles; + prevcomp.offset = component.offset; + + // Assign the new component state + component.angles = packet.angles; + } + } +} + +static void on_entity_transform_packet(const protocol::EntityTransform& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace<entity::Transform>(packet.entity); + auto& prevcomp = globals::dimension->entities.get_or_emplace<entity::client::TransformPrev>(packet.entity); + + // Store the previous component state + prevcomp.angles = component.angles; + prevcomp.chunk = component.chunk; + prevcomp.local = component.local; + + // Assign the new component state + component.angles = packet.angles; + component.chunk = packet.chunk; + component.local = packet.local; + } + } +} + +static void on_entity_velocity_packet(const protocol::EntityVelocity& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace<entity::Velocity>(packet.entity); + component.value = packet.value; + } + } +} + +static void on_entity_player_packet(const protocol::EntityPlayer& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + entity::client::create_player(globals::dimension, packet.entity); + } + } +} + +static void on_spawn_player_packet(const protocol::SpawnPlayer& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + entity::client::create_player(globals::dimension, packet.entity); + + globals::player = packet.entity; + globals::gui_screen = GUI_SCREEN_NONE; + + gui::client_chat::refresh_timings(); + + gui::window_title::update(); + } + } +} + +static void on_remove_entity_packet(const protocol::RemoveEntity& packet) +{ + if(globals::dimension) { + if(packet.entity == globals::player) { + globals::player = entt::null; + } + + globals::dimension->entities.destroy(packet.entity); + } +} + +static void on_generic_sound_packet(const protocol::GenericSound& packet) +{ + sound::play_generic(packet.sound.c_str(), packet.looping, packet.pitch); +} + +static void on_entity_sound_packet(const protocol::EntitySound& packet) +{ + sound::play_entity(packet.entity, packet.sound.c_str(), packet.looping, packet.pitch); +} + +void client_receive::init(void) +{ + globals::dispatcher.sink<protocol::DimensionInfo>().connect<&on_dimension_info_packet>(); + globals::dispatcher.sink<protocol::ChunkVoxels>().connect<&on_chunk_voxels_packet>(); + globals::dispatcher.sink<protocol::EntityHead>().connect<&on_entity_head_packet>(); + globals::dispatcher.sink<protocol::EntityTransform>().connect<&on_entity_transform_packet>(); + globals::dispatcher.sink<protocol::EntityVelocity>().connect<&on_entity_velocity_packet>(); + globals::dispatcher.sink<protocol::EntityPlayer>().connect<&on_entity_player_packet>(); + globals::dispatcher.sink<protocol::SpawnPlayer>().connect<&on_spawn_player_packet>(); + globals::dispatcher.sink<protocol::RemoveEntity>().connect<&on_remove_entity_packet>(); + globals::dispatcher.sink<protocol::GenericSound>().connect<&on_generic_sound_packet>(); + globals::dispatcher.sink<protocol::EntitySound>().connect<&on_entity_sound_packet>(); +} diff --git a/game/client/receive.hh b/src/game/client/receive.hh index d958581..d675392 100644 --- a/game/client/receive.hh +++ b/src/game/client/receive.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace client_receive
-{
-void init(void);
-} // namespace client_receive
+#pragma once + +namespace client_receive +{ +void init(void); +} // namespace client_receive diff --git a/game/client/resource/CMakeLists.txt b/src/game/client/resource/CMakeLists.txt index baf2311..baf2311 100644 --- a/game/client/resource/CMakeLists.txt +++ b/src/game/client/resource/CMakeLists.txt diff --git a/game/client/resource/sound_effect.cc b/src/game/client/resource/sound_effect.cc index 9d5d8a9..5bbb949 100644 --- a/game/client/resource/sound_effect.cc +++ b/src/game/client/resource/sound_effect.cc @@ -1,90 +1,90 @@ -#include "client/pch.hh"
-
-#include "client/resource/sound_effect.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/io/physfs.hh"
-
-#include "client/globals.hh"
-
-static std::size_t drwav_read_physfs(void* file, void* output, std::size_t count)
-{
- return static_cast<std::size_t>(PHYSFS_readBytes(reinterpret_cast<PHYSFS_File*>(file), output, count));
-}
-
-static drwav_bool32 drwav_seek_physfs(void* file, int offset, drwav_seek_origin origin)
-{
- if(origin == drwav_seek_origin_current) {
- return PHYSFS_seek(reinterpret_cast<PHYSFS_File*>(file), PHYSFS_tell(reinterpret_cast<PHYSFS_File*>(file)) + offset);
- }
- else {
- return PHYSFS_seek(reinterpret_cast<PHYSFS_File*>(file), offset);
- }
-}
-
-static const void* sound_effect_load_func(const char* name, std::uint32_t flags)
-{
- assert(name);
-
- if(globals::sound_ctx == nullptr) {
- // Sound is disabled
- return nullptr;
- }
-
- auto file = PHYSFS_openRead(name);
-
- if(file == nullptr) {
- spdlog::warn("sfx: {}: {}", name, io::physfs_error());
- return nullptr;
- }
-
- drwav wav_info;
-
- if(!drwav_init(&wav_info, &drwav_read_physfs, &drwav_seek_physfs, file, nullptr)) {
- spdlog::warn("sfx: {}: drwav_init failed", name);
- PHYSFS_close(file);
- return nullptr;
- }
-
- if(wav_info.channels != 1) {
- spdlog::warn("sfx: {}: only mono sound files are allowed", name);
- drwav_uninit(&wav_info);
- PHYSFS_close(file);
- return nullptr;
- }
-
- auto samples = new ALshort[wav_info.totalPCMFrameCount];
- auto count = drwav_read_pcm_frames_s16(&wav_info, wav_info.totalPCMFrameCount, reinterpret_cast<drwav_int16*>(samples));
- auto sample_rate = static_cast<ALsizei>(wav_info.sampleRate);
- auto length = static_cast<ALsizei>(count * sizeof(ALshort));
-
- drwav_uninit(&wav_info);
- PHYSFS_close(file);
-
- auto new_resource = new SoundEffect();
- new_resource->name = std::string(name);
-
- alGenBuffers(1, &new_resource->buffer);
- alBufferData(new_resource->buffer, AL_FORMAT_MONO16, samples, length, sample_rate);
-
- delete[] samples;
-
- return new_resource;
-}
-
-static void sound_effect_free_func(const void* resource)
-{
- assert(resource);
-
- auto sound_effect = reinterpret_cast<const SoundEffect*>(resource);
-
- alDeleteBuffers(1, &sound_effect->buffer);
-
- delete sound_effect;
-}
-
-void SoundEffect::register_resource(void)
-{
- resource::register_loader<SoundEffect>(&sound_effect_load_func, &sound_effect_free_func);
-}
+#include "client/pch.hh" + +#include "client/resource/sound_effect.hh" + +#include "core/resource/resource.hh" + +#include "core/io/physfs.hh" + +#include "client/globals.hh" + +static std::size_t drwav_read_physfs(void* file, void* output, std::size_t count) +{ + return static_cast<std::size_t>(PHYSFS_readBytes(reinterpret_cast<PHYSFS_File*>(file), output, count)); +} + +static drwav_bool32 drwav_seek_physfs(void* file, int offset, drwav_seek_origin origin) +{ + if(origin == drwav_seek_origin_current) { + return PHYSFS_seek(reinterpret_cast<PHYSFS_File*>(file), PHYSFS_tell(reinterpret_cast<PHYSFS_File*>(file)) + offset); + } + else { + return PHYSFS_seek(reinterpret_cast<PHYSFS_File*>(file), offset); + } +} + +static const void* sound_effect_load_func(const char* name, std::uint32_t flags) +{ + assert(name); + + if(globals::sound_ctx == nullptr) { + // Sound is disabled + return nullptr; + } + + auto file = PHYSFS_openRead(name); + + if(file == nullptr) { + spdlog::warn("sfx: {}: {}", name, io::physfs_error()); + return nullptr; + } + + drwav wav_info; + + if(!drwav_init(&wav_info, &drwav_read_physfs, &drwav_seek_physfs, file, nullptr)) { + spdlog::warn("sfx: {}: drwav_init failed", name); + PHYSFS_close(file); + return nullptr; + } + + if(wav_info.channels != 1) { + spdlog::warn("sfx: {}: only mono sound files are allowed", name); + drwav_uninit(&wav_info); + PHYSFS_close(file); + return nullptr; + } + + auto samples = new ALshort[wav_info.totalPCMFrameCount]; + auto count = drwav_read_pcm_frames_s16(&wav_info, wav_info.totalPCMFrameCount, reinterpret_cast<drwav_int16*>(samples)); + auto sample_rate = static_cast<ALsizei>(wav_info.sampleRate); + auto length = static_cast<ALsizei>(count * sizeof(ALshort)); + + drwav_uninit(&wav_info); + PHYSFS_close(file); + + auto new_resource = new SoundEffect(); + new_resource->name = std::string(name); + + alGenBuffers(1, &new_resource->buffer); + alBufferData(new_resource->buffer, AL_FORMAT_MONO16, samples, length, sample_rate); + + delete[] samples; + + return new_resource; +} + +static void sound_effect_free_func(const void* resource) +{ + assert(resource); + + auto sound_effect = reinterpret_cast<const SoundEffect*>(resource); + + alDeleteBuffers(1, &sound_effect->buffer); + + delete sound_effect; +} + +void SoundEffect::register_resource(void) +{ + resource::register_loader<SoundEffect>(&sound_effect_load_func, &sound_effect_free_func); +} diff --git a/game/client/resource/sound_effect.hh b/src/game/client/resource/sound_effect.hh index ab68ed2..f2db33b 100644 --- a/game/client/resource/sound_effect.hh +++ b/src/game/client/resource/sound_effect.hh @@ -1,8 +1,8 @@ -#pragma once
-
-struct SoundEffect final {
- static void register_resource(void);
-
- std::string name;
- ALuint buffer;
-};
+#pragma once + +struct SoundEffect final { + static void register_resource(void); + + std::string name; + ALuint buffer; +}; diff --git a/game/client/resource/texture_gui.cc b/src/game/client/resource/texture_gui.cc index be8a6ed..beb2f54 100644 --- a/game/client/resource/texture_gui.cc +++ b/src/game/client/resource/texture_gui.cc @@ -1,83 +1,83 @@ -#include "client/pch.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "core/resource/image.hh"
-#include "core/resource/resource.hh"
-
-static const void* texture_gui_load_func(const char* name, std::uint32_t flags)
-{
- assert(name);
-
- unsigned int image_load_flags = 0U;
-
- if(flags & TEXTURE_GUI_LOAD_VFLIP) {
- image_load_flags |= IMAGE_LOAD_FLIP;
- }
-
- if(flags & TEXTURE_GUI_LOAD_GRAYSCALE) {
- image_load_flags |= IMAGE_LOAD_GRAY;
- }
-
- if(auto image = resource::load<Image>(name, image_load_flags)) {
- GLuint gl_texture;
-
- glGenTextures(1, &gl_texture);
- glBindTexture(GL_TEXTURE_2D, gl_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image->size.x, image->size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
-
- if(flags & TEXTURE_GUI_LOAD_CLAMP_S) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- }
-
- if(flags & TEXTURE_GUI_LOAD_CLAMP_T) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
-
- if(flags & TEXTURE_GUI_LOAD_LINEAR_MAG) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
-
- if(flags & TEXTURE_GUI_LOAD_LINEAR_MIN) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
-
- auto new_resource = new TextureGUI();
- new_resource->handle = static_cast<ImTextureID>(gl_texture);
- new_resource->size.x = image->size.x;
- new_resource->size.y = image->size.y;
-
- return new_resource;
- }
-
- return nullptr;
-}
-
-static void texture_gui_free_func(const void* resource)
-{
- assert(resource);
-
- auto texture_gui = reinterpret_cast<const TextureGUI*>(resource);
- auto gl_texture = static_cast<GLuint>(texture_gui->handle);
-
- glDeleteTextures(1, &gl_texture);
-
- delete texture_gui;
-}
-
-void TextureGUI::register_resource(void)
-{
- resource::register_loader<TextureGUI>(&texture_gui_load_func, &texture_gui_free_func);
-}
+#include "client/pch.hh" + +#include "client/resource/texture_gui.hh" + +#include "core/resource/image.hh" +#include "core/resource/resource.hh" + +static const void* texture_gui_load_func(const char* name, std::uint32_t flags) +{ + assert(name); + + unsigned int image_load_flags = 0U; + + if(flags & TEXTURE_GUI_LOAD_VFLIP) { + image_load_flags |= IMAGE_LOAD_FLIP; + } + + if(flags & TEXTURE_GUI_LOAD_GRAYSCALE) { + image_load_flags |= IMAGE_LOAD_GRAY; + } + + if(auto image = resource::load<Image>(name, image_load_flags)) { + GLuint gl_texture; + + glGenTextures(1, &gl_texture); + glBindTexture(GL_TEXTURE_2D, gl_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image->size.x, image->size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); + + if(flags & TEXTURE_GUI_LOAD_CLAMP_S) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + } + + if(flags & TEXTURE_GUI_LOAD_CLAMP_T) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + if(flags & TEXTURE_GUI_LOAD_LINEAR_MAG) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + if(flags & TEXTURE_GUI_LOAD_LINEAR_MIN) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + auto new_resource = new TextureGUI(); + new_resource->handle = static_cast<ImTextureID>(gl_texture); + new_resource->size.x = image->size.x; + new_resource->size.y = image->size.y; + + return new_resource; + } + + return nullptr; +} + +static void texture_gui_free_func(const void* resource) +{ + assert(resource); + + auto texture_gui = reinterpret_cast<const TextureGUI*>(resource); + auto gl_texture = static_cast<GLuint>(texture_gui->handle); + + glDeleteTextures(1, &gl_texture); + + delete texture_gui; +} + +void TextureGUI::register_resource(void) +{ + resource::register_loader<TextureGUI>(&texture_gui_load_func, &texture_gui_free_func); +} diff --git a/game/client/resource/texture_gui.hh b/src/game/client/resource/texture_gui.hh index 9ce0535..2d42c83 100644 --- a/game/client/resource/texture_gui.hh +++ b/src/game/client/resource/texture_gui.hh @@ -1,15 +1,15 @@ -#pragma once
-
-constexpr static unsigned int TEXTURE_GUI_LOAD_CLAMP_S = 0x0001;
-constexpr static unsigned int TEXTURE_GUI_LOAD_CLAMP_T = 0x0002;
-constexpr static unsigned int TEXTURE_GUI_LOAD_LINEAR_MAG = 0x0004;
-constexpr static unsigned int TEXTURE_GUI_LOAD_LINEAR_MIN = 0x0008;
-constexpr static unsigned int TEXTURE_GUI_LOAD_VFLIP = 0x0010;
-constexpr static unsigned int TEXTURE_GUI_LOAD_GRAYSCALE = 0x0020;
-
-struct TextureGUI final {
- static void register_resource(void);
-
- ImTextureID handle;
- glm::ivec2 size;
-};
+#pragma once + +constexpr static unsigned int TEXTURE_GUI_LOAD_CLAMP_S = 0x0001; +constexpr static unsigned int TEXTURE_GUI_LOAD_CLAMP_T = 0x0002; +constexpr static unsigned int TEXTURE_GUI_LOAD_LINEAR_MAG = 0x0004; +constexpr static unsigned int TEXTURE_GUI_LOAD_LINEAR_MIN = 0x0008; +constexpr static unsigned int TEXTURE_GUI_LOAD_VFLIP = 0x0010; +constexpr static unsigned int TEXTURE_GUI_LOAD_GRAYSCALE = 0x0020; + +struct TextureGUI final { + static void register_resource(void); + + ImTextureID handle; + glm::ivec2 size; +}; diff --git a/game/client/screenshot.cc b/src/game/client/screenshot.cc index 87ab5e7..9b573ef 100644 --- a/game/client/screenshot.cc +++ b/src/game/client/screenshot.cc @@ -1,86 +1,86 @@ -#include "client/pch.hh"
-
-#include "client/screenshot.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/chat.hh"
-#include "client/gui/language.hh"
-#include "client/gui/settings.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/globals.hh"
-#include "client/toggles.hh"
-
-static config::KeyBind screenshot_key(GLFW_KEY_F2);
-
-static void stbi_png_physfs_callback(void* context, void* data, int size)
-{
- PHYSFS_writeBytes(reinterpret_cast<PHYSFS_File*>(context), data, size);
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(!globals::gui_keybind_ptr && !toggles::is_sequence_await) {
- if(screenshot_key.equals(event.key) && (event.action == GLFW_PRESS)) {
- screenshot::take();
- return;
- }
- }
-}
-
-void screenshot::init(void)
-{
- globals::client_config.add_value("screenshot.key", screenshot_key);
-
- settings::add_keybind(0, screenshot_key, settings_location::KEYBOARD_MISC, "key.screenshot");
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
-}
-
-void screenshot::take(void)
-{
- auto stride = 3 * globals::width;
- auto length = 3 * globals::width * globals::height;
- auto pixels = new std::byte[length];
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- GLint old_pack_alignment;
- glGetIntegerv(GL_PACK_ALIGNMENT, &old_pack_alignment);
-
- // The window can be of any size, including irregular
- // values such as, say 641x480, while there is a default
- // alignment value of sorts that might result in a corrupted
- // image; we set GL_PACK_ALIGNMENT to 1, enabling byte-alignment
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- glReadPixels(0, 0, globals::width, globals::height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
- // Restore the old pack alignment value
- glPixelStorei(GL_PACK_ALIGNMENT, old_pack_alignment);
-
- const auto directory = std::string("screenshots");
- const auto filename = std::format("{}.png", utils::unix_microseconds());
- const auto filepath = std::format("{}/{}", directory, filename);
-
- PHYSFS_mkdir(directory.c_str());
-
- if(auto file = PHYSFS_openWrite(filepath.c_str())) {
- stbi_flip_vertically_on_write(true);
- stbi_write_png_to_func(&stbi_png_physfs_callback, file, globals::width, globals::height, 3, pixels, stride);
-
- spdlog::info("screenshot: wrote {}", filepath);
-
- gui::client_chat::print(std::format("{} {}", gui::language::resolve("chat.screenshot_message"), filename));
-
- PHYSFS_close(file);
- }
-
- delete[] pixels;
-}
+#include "client/pch.hh" + +#include "client/screenshot.hh" + +#include "core/io/config_map.hh" + +#include "core/utils/epoch.hh" + +#include "client/config/keybind.hh" + +#include "client/gui/chat.hh" +#include "client/gui/language.hh" +#include "client/gui/settings.hh" + +#include "client/io/glfw.hh" + +#include "client/globals.hh" +#include "client/toggles.hh" + +static config::KeyBind screenshot_key(GLFW_KEY_F2); + +static void stbi_png_physfs_callback(void* context, void* data, int size) +{ + PHYSFS_writeBytes(reinterpret_cast<PHYSFS_File*>(context), data, size); +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if(!globals::gui_keybind_ptr && !toggles::is_sequence_await) { + if(screenshot_key.equals(event.key) && (event.action == GLFW_PRESS)) { + screenshot::take(); + return; + } + } +} + +void screenshot::init(void) +{ + globals::client_config.add_value("screenshot.key", screenshot_key); + + settings::add_keybind(0, screenshot_key, settings_location::KEYBOARD_MISC, "key.screenshot"); + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); +} + +void screenshot::take(void) +{ + auto stride = 3 * globals::width; + auto length = 3 * globals::width * globals::height; + auto pixels = new std::byte[length]; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + GLint old_pack_alignment; + glGetIntegerv(GL_PACK_ALIGNMENT, &old_pack_alignment); + + // The window can be of any size, including irregular + // values such as, say 641x480, while there is a default + // alignment value of sorts that might result in a corrupted + // image; we set GL_PACK_ALIGNMENT to 1, enabling byte-alignment + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glReadPixels(0, 0, globals::width, globals::height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + // Restore the old pack alignment value + glPixelStorei(GL_PACK_ALIGNMENT, old_pack_alignment); + + const auto directory = std::string("screenshots"); + const auto filename = std::format("{}.png", utils::unix_microseconds()); + const auto filepath = std::format("{}/{}", directory, filename); + + PHYSFS_mkdir(directory.c_str()); + + if(auto file = PHYSFS_openWrite(filepath.c_str())) { + stbi_flip_vertically_on_write(true); + stbi_write_png_to_func(&stbi_png_physfs_callback, file, globals::width, globals::height, 3, pixels, stride); + + spdlog::info("screenshot: wrote {}", filepath); + + gui::client_chat::print(std::format("{} {}", gui::language::resolve("chat.screenshot_message"), filename)); + + PHYSFS_close(file); + } + + delete[] pixels; +} diff --git a/game/client/screenshot.hh b/src/game/client/screenshot.hh index b76507e..fecbd2f 100644 --- a/game/client/screenshot.hh +++ b/src/game/client/screenshot.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace screenshot
-{
-void init(void);
-void take(void);
-} // namespace screenshot
+#pragma once + +namespace screenshot +{ +void init(void); +void take(void); +} // namespace screenshot diff --git a/game/client/session.cc b/src/game/client/session.cc index d8666b9..36acfb4 100644 --- a/game/client/session.cc +++ b/src/game/client/session.cc @@ -1,313 +1,313 @@ -#include "client/pch.hh"
-
-#include "client/session.hh"
-
-#include "core/config/string.hh"
-
-#include "core/math/crc64.hh"
-
-#include "core/version.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/item_registry.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/protocol.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/gui/chat.hh"
-#include "client/gui/gui_screen.hh"
-#include "client/gui/message_box.hh"
-#include "client/gui/progress_bar.hh"
-#include "client/gui/window_title.hh"
-
-#include "client/world/chunk_visibility.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-
-ENetPeer* session::peer = nullptr;
-std::uint16_t session::client_index = UINT16_MAX;
-std::uint64_t session::client_identity = UINT64_MAX;
-
-static std::uint64_t server_password_hash = UINT64_MAX;
-
-static void set_fixed_tickrate(std::uint16_t tickrate)
-{
- globals::fixed_frametime_us = 1000000U / glm::clamp<std::uint64_t>(tickrate, 10U, 300U);
- globals::fixed_frametime = static_cast<float>(globals::fixed_frametime_us) / 1000000.0f;
- globals::fixed_accumulator = 0;
-}
-
-static void on_login_response_packet(const protocol::LoginResponse& packet)
-{
- spdlog::info("session: assigned client_index={}", packet.client_index);
- spdlog::info("session: assigned client_identity={}", packet.client_identity);
- spdlog::info("session: server ticks at {} TPS", packet.server_tickrate);
-
- session::client_index = packet.client_index;
- session::client_identity = packet.client_identity;
-
- set_fixed_tickrate(packet.server_tickrate);
-
- gui::progress_bar::set_title("connecting.loading_world");
-}
-
-static void on_disconnect_packet(const protocol::Disconnect& packet)
-{
- enet_peer_disconnect(session::peer, 0);
-
- spdlog::info("session: disconnected: {}", packet.reason);
-
- gui::client_chat::clear();
-
- session::peer = nullptr;
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = UINT64_MAX;
-
- delete globals::dimension;
- globals::player = entt::null;
- globals::dimension = nullptr;
-
- gui::message_box::reset();
- gui::message_box::set_title("disconnected.disconnected");
- gui::message_box::set_subtitle(packet.reason.c_str());
- gui::message_box::add_button("disconnected.back", [](void) {
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- });
-
- globals::gui_screen = GUI_MESSAGE_BOX;
-}
-
-static void on_set_voxel_packet(const protocol::SetVoxel& packet)
-{
- auto cpos = coord::to_chunk(packet.vpos);
- auto lpos = coord::to_local(packet.vpos);
- auto index = coord::to_index(lpos);
-
- if(auto chunk = globals::dimension->find_chunk(cpos)) {
- auto packet_voxel = world::voxel_registry::find(packet.voxel);
-
- if(chunk->get_voxel(index) != packet_voxel) {
- chunk->set_voxel(packet_voxel, index);
-
- world::ChunkUpdateEvent event;
- event.dimension = globals::dimension;
- event.chunk = chunk;
- event.cpos = cpos;
-
- // Send a generic ChunkUpdate event to shake
- // up the mesher; directly calling world::set_voxel
- // here would result in a networked feedback loop
- // caused by event handler below tripping
- globals::dispatcher.trigger(event);
- }
- }
-}
-
-// NOTE: [session] is a good place for this since [receive]
-// handles entity data sent by the server and [session] handles
-// everything else network related that is not player movement
-static void on_voxel_set(const world::VoxelSetEvent& event)
-{
- if(session::peer) {
- // Propagate changes to the server
- // FIXME: should we also validate things here or wait for the server to do so
- protocol::SetVoxel packet;
- packet.vpos = coord::to_voxel(event.cpos, event.lpos);
- packet.voxel = event.voxel ? event.voxel->get_id() : NULL_VOXEL_ID;
-
- protocol::send(session::peer, protocol::encode(packet));
- }
-}
-
-void session::init(void)
-{
- session::peer = nullptr;
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = UINT64_MAX;
-
- globals::dispatcher.sink<protocol::LoginResponse>().connect<&on_login_response_packet>();
- globals::dispatcher.sink<protocol::Disconnect>().connect<&on_disconnect_packet>();
- globals::dispatcher.sink<protocol::SetVoxel>().connect<&on_set_voxel_packet>();
-
- globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>();
-}
-
-void session::shutdown(void)
-{
- session::disconnect("protocol.client_shutdown");
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-}
-
-void session::invalidate(void)
-{
- if(session::peer) {
- enet_peer_reset(session::peer);
-
- gui::message_box::reset();
- gui::message_box::set_title("disconnected.disconnected");
- gui::message_box::set_subtitle("enet.peer_connection_timeout");
- gui::message_box::add_button("disconnected.back", [](void) {
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- });
-
- globals::gui_screen = GUI_MESSAGE_BOX;
- }
-
- gui::client_chat::clear();
-
- session::peer = nullptr;
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = UINT64_MAX;
-
- delete globals::dimension;
- globals::player = entt::null;
- globals::dimension = nullptr;
-}
-
-void session::connect(std::string_view host, std::uint16_t port, std::string_view password)
-{
- ENetAddress address;
- enet_address_set_host(&address, std::string(host).c_str());
- address.port = port;
-
- session::peer = enet_host_connect(globals::client_host, &address, 1, 0);
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = math::crc64(password.data(), password.size());
-
- if(!session::peer) {
- server_password_hash = UINT64_MAX;
-
- gui::message_box::reset();
- gui::message_box::set_title("disconnected.disconnected");
- gui::message_box::set_subtitle("enet.peer_connection_failed");
- gui::message_box::add_button("disconnected.back", [](void) {
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- });
-
- globals::gui_screen = GUI_MESSAGE_BOX;
-
- return;
- }
-
- gui::progress_bar::reset();
- gui::progress_bar::set_title("connecting.connecting");
- gui::progress_bar::set_button("connecting.cancel_button", [](void) {
- enet_peer_disconnect(session::peer, 0);
-
- session::peer = nullptr;
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = UINT64_MAX;
-
- delete globals::dimension;
- globals::player = entt::null;
- globals::dimension = nullptr;
-
- globals::gui_screen = GUI_PLAY_MENU;
- });
-
- globals::gui_screen = GUI_PROGRESS_BAR;
-}
-
-void session::disconnect(std::string_view reason)
-{
- if(session::peer) {
- protocol::Disconnect packet;
- packet.reason = std::string(reason);
-
- protocol::send(session::peer, protocol::encode(packet));
-
- enet_host_flush(globals::client_host);
- enet_host_service(globals::client_host, nullptr, 50);
- enet_peer_reset(session::peer);
-
- session::peer = nullptr;
- session::client_index = UINT16_MAX;
- session::client_identity = UINT64_MAX;
-
- globals::fixed_frametime_us = UINT64_MAX;
- globals::fixed_frametime = 0.0f;
- globals::fixed_accumulator = 0;
-
- server_password_hash = UINT64_MAX;
-
- delete globals::dimension;
- globals::player = entt::null;
- globals::dimension = nullptr;
-
- gui::client_chat::clear();
- }
-}
-
-void session::send_login_request(void)
-{
- protocol::LoginRequest packet;
- packet.game_version_major = version::major;
- packet.voxel_registry_checksum = world::voxel_registry::get_checksum();
- packet.item_registry_checksum = world::item_registry::get_checksum();
- packet.password_hash = server_password_hash;
- packet.username = client_game::username.get();
- packet.game_version_minor = version::minor;
- packet.game_version_patch = version::patch;
-
- protocol::send(session::peer, protocol::encode(packet));
-
- server_password_hash = UINT64_MAX;
-
- gui::progress_bar::set_title("connecting.logging_in");
- globals::gui_screen = GUI_PROGRESS_BAR;
-}
-
-bool session::is_ingame(void)
-{
- if(globals::dimension) {
- return globals::dimension->entities.valid(globals::player);
- }
- else {
- return false;
- }
-}
+#include "client/pch.hh" + +#include "client/session.hh" + +#include "core/config/string.hh" + +#include "core/math/crc64.hh" + +#include "core/version.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/item_registry.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/protocol.hh" + +#include "client/entity/camera.hh" + +#include "client/gui/chat.hh" +#include "client/gui/gui_screen.hh" +#include "client/gui/message_box.hh" +#include "client/gui/progress_bar.hh" +#include "client/gui/window_title.hh" + +#include "client/world/chunk_visibility.hh" + +#include "client/game.hh" +#include "client/globals.hh" + +ENetPeer* session::peer = nullptr; +std::uint16_t session::client_index = UINT16_MAX; +std::uint64_t session::client_identity = UINT64_MAX; + +static std::uint64_t server_password_hash = UINT64_MAX; + +static void set_fixed_tickrate(std::uint16_t tickrate) +{ + globals::fixed_frametime_us = 1000000U / glm::clamp<std::uint64_t>(tickrate, 10U, 300U); + globals::fixed_frametime = static_cast<float>(globals::fixed_frametime_us) / 1000000.0f; + globals::fixed_accumulator = 0; +} + +static void on_login_response_packet(const protocol::LoginResponse& packet) +{ + spdlog::info("session: assigned client_index={}", packet.client_index); + spdlog::info("session: assigned client_identity={}", packet.client_identity); + spdlog::info("session: server ticks at {} TPS", packet.server_tickrate); + + session::client_index = packet.client_index; + session::client_identity = packet.client_identity; + + set_fixed_tickrate(packet.server_tickrate); + + gui::progress_bar::set_title("connecting.loading_world"); +} + +static void on_disconnect_packet(const protocol::Disconnect& packet) +{ + enet_peer_disconnect(session::peer, 0); + + spdlog::info("session: disconnected: {}", packet.reason); + + gui::client_chat::clear(); + + session::peer = nullptr; + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = UINT64_MAX; + + delete globals::dimension; + globals::player = entt::null; + globals::dimension = nullptr; + + gui::message_box::reset(); + gui::message_box::set_title("disconnected.disconnected"); + gui::message_box::set_subtitle(packet.reason.c_str()); + gui::message_box::add_button("disconnected.back", [](void) { + globals::gui_screen = GUI_PLAY_MENU; + gui::window_title::update(); + }); + + globals::gui_screen = GUI_MESSAGE_BOX; +} + +static void on_set_voxel_packet(const protocol::SetVoxel& packet) +{ + auto cpos = coord::to_chunk(packet.vpos); + auto lpos = coord::to_local(packet.vpos); + auto index = coord::to_index(lpos); + + if(auto chunk = globals::dimension->find_chunk(cpos)) { + auto packet_voxel = world::voxel_registry::find(packet.voxel); + + if(chunk->get_voxel(index) != packet_voxel) { + chunk->set_voxel(packet_voxel, index); + + world::ChunkUpdateEvent event; + event.dimension = globals::dimension; + event.chunk = chunk; + event.cpos = cpos; + + // Send a generic ChunkUpdate event to shake + // up the mesher; directly calling world::set_voxel + // here would result in a networked feedback loop + // caused by event handler below tripping + globals::dispatcher.trigger(event); + } + } +} + +// NOTE: [session] is a good place for this since [receive] +// handles entity data sent by the server and [session] handles +// everything else network related that is not player movement +static void on_voxel_set(const world::VoxelSetEvent& event) +{ + if(session::peer) { + // Propagate changes to the server + // FIXME: should we also validate things here or wait for the server to do so + protocol::SetVoxel packet; + packet.vpos = coord::to_voxel(event.cpos, event.lpos); + packet.voxel = event.voxel ? event.voxel->get_id() : NULL_VOXEL_ID; + + protocol::send(session::peer, protocol::encode(packet)); + } +} + +void session::init(void) +{ + session::peer = nullptr; + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = UINT64_MAX; + + globals::dispatcher.sink<protocol::LoginResponse>().connect<&on_login_response_packet>(); + globals::dispatcher.sink<protocol::Disconnect>().connect<&on_disconnect_packet>(); + globals::dispatcher.sink<protocol::SetVoxel>().connect<&on_set_voxel_packet>(); + + globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>(); +} + +void session::shutdown(void) +{ + session::disconnect("protocol.client_shutdown"); + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; +} + +void session::invalidate(void) +{ + if(session::peer) { + enet_peer_reset(session::peer); + + gui::message_box::reset(); + gui::message_box::set_title("disconnected.disconnected"); + gui::message_box::set_subtitle("enet.peer_connection_timeout"); + gui::message_box::add_button("disconnected.back", [](void) { + globals::gui_screen = GUI_PLAY_MENU; + gui::window_title::update(); + }); + + globals::gui_screen = GUI_MESSAGE_BOX; + } + + gui::client_chat::clear(); + + session::peer = nullptr; + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = UINT64_MAX; + + delete globals::dimension; + globals::player = entt::null; + globals::dimension = nullptr; +} + +void session::connect(std::string_view host, std::uint16_t port, std::string_view password) +{ + ENetAddress address; + enet_address_set_host(&address, std::string(host).c_str()); + address.port = port; + + session::peer = enet_host_connect(globals::client_host, &address, 1, 0); + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = math::crc64(password.data(), password.size()); + + if(!session::peer) { + server_password_hash = UINT64_MAX; + + gui::message_box::reset(); + gui::message_box::set_title("disconnected.disconnected"); + gui::message_box::set_subtitle("enet.peer_connection_failed"); + gui::message_box::add_button("disconnected.back", [](void) { + globals::gui_screen = GUI_PLAY_MENU; + gui::window_title::update(); + }); + + globals::gui_screen = GUI_MESSAGE_BOX; + + return; + } + + gui::progress_bar::reset(); + gui::progress_bar::set_title("connecting.connecting"); + gui::progress_bar::set_button("connecting.cancel_button", [](void) { + enet_peer_disconnect(session::peer, 0); + + session::peer = nullptr; + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = UINT64_MAX; + + delete globals::dimension; + globals::player = entt::null; + globals::dimension = nullptr; + + globals::gui_screen = GUI_PLAY_MENU; + }); + + globals::gui_screen = GUI_PROGRESS_BAR; +} + +void session::disconnect(std::string_view reason) +{ + if(session::peer) { + protocol::Disconnect packet; + packet.reason = std::string(reason); + + protocol::send(session::peer, protocol::encode(packet)); + + enet_host_flush(globals::client_host); + enet_host_service(globals::client_host, nullptr, 50); + enet_peer_reset(session::peer); + + session::peer = nullptr; + session::client_index = UINT16_MAX; + session::client_identity = UINT64_MAX; + + globals::fixed_frametime_us = UINT64_MAX; + globals::fixed_frametime = 0.0f; + globals::fixed_accumulator = 0; + + server_password_hash = UINT64_MAX; + + delete globals::dimension; + globals::player = entt::null; + globals::dimension = nullptr; + + gui::client_chat::clear(); + } +} + +void session::send_login_request(void) +{ + protocol::LoginRequest packet; + packet.game_version_major = version::major; + packet.voxel_registry_checksum = world::voxel_registry::get_checksum(); + packet.item_registry_checksum = world::item_registry::get_checksum(); + packet.password_hash = server_password_hash; + packet.username = client_game::username.get(); + packet.game_version_minor = version::minor; + packet.game_version_patch = version::patch; + + protocol::send(session::peer, protocol::encode(packet)); + + server_password_hash = UINT64_MAX; + + gui::progress_bar::set_title("connecting.logging_in"); + globals::gui_screen = GUI_PROGRESS_BAR; +} + +bool session::is_ingame(void) +{ + if(globals::dimension) { + return globals::dimension->entities.valid(globals::player); + } + else { + return false; + } +} diff --git a/game/client/session.hh b/src/game/client/session.hh index 8f4353e..f61d62d 100644 --- a/game/client/session.hh +++ b/src/game/client/session.hh @@ -1,27 +1,27 @@ -#pragma once
-
-namespace session
-{
-extern ENetPeer* peer;
-extern std::uint16_t client_index;
-extern std::uint64_t client_identity;
-} // namespace session
-
-namespace session
-{
-void init(void);
-void shutdown(void);
-void invalidate(void);
-} // namespace session
-
-namespace session
-{
-void connect(std::string_view hostname, std::uint16_t port, std::string_view password);
-void disconnect(std::string_view reason);
-void send_login_request(void);
-} // namespace session
-
-namespace session
-{
-bool is_ingame(void);
-} // namespace session
+#pragma once + +namespace session +{ +extern ENetPeer* peer; +extern std::uint16_t client_index; +extern std::uint64_t client_identity; +} // namespace session + +namespace session +{ +void init(void); +void shutdown(void); +void invalidate(void); +} // namespace session + +namespace session +{ +void connect(std::string_view hostname, std::uint16_t port, std::string_view password); +void disconnect(std::string_view reason); +void send_login_request(void); +} // namespace session + +namespace session +{ +bool is_ingame(void); +} // namespace session diff --git a/game/client/sound/CMakeLists.txt b/src/game/client/sound/CMakeLists.txt index 4b577d3..4b577d3 100644 --- a/game/client/sound/CMakeLists.txt +++ b/src/game/client/sound/CMakeLists.txt diff --git a/game/client/sound/sound.cc b/src/game/client/sound/sound.cc index 0eb0463..7dfe562 100644 --- a/game/client/sound/sound.cc +++ b/src/game/client/sound/sound.cc @@ -1,211 +1,211 @@ -#include "client/pch.hh"
-
-#include "client/sound/sound.hh"
-
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-#include "shared/protocol.hh"
-
-#include "client/entity/camera.hh"
-#include "client/entity/sound_emitter.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/resource/sound_effect.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-config::Float sound::volume_master(100.0f, 0.0f, 100.0f);
-config::Float sound::volume_effects(100.0f, 0.0f, 100.0f);
-config::Float sound::volume_music(100.0f, 0.0f, 100.0f);
-config::Float sound::volume_ui(100.0f, 0.0f, 100.0f);
-
-static ALuint generic_source;
-static ALuint player_source;
-static ALuint ui_source;
-
-static resource_ptr<SoundEffect> sfx_generic;
-static resource_ptr<SoundEffect> sfx_player;
-static resource_ptr<SoundEffect> sfx_ui;
-
-void sound::init_config(void)
-{
- globals::client_config.add_value("sound.volume_master", sound::volume_master);
- globals::client_config.add_value("sound.volume_effects", sound::volume_effects);
- globals::client_config.add_value("sound.volume_music", sound::volume_music);
- globals::client_config.add_value("sound.volume_ui", sound::volume_ui);
-
- settings::add_slider(1, sound::volume_master, settings_location::SOUND, "sound.volume_master", false, "%.0f%%");
-
- settings::add_slider(0, sound::volume_effects, settings_location::SOUND_LEVELS, "sound.volume_effects", false, "%.0f%%");
- settings::add_slider(1, sound::volume_music, settings_location::SOUND_LEVELS, "sound.volume_music", false, "%.0f%%");
- settings::add_slider(2, sound::volume_ui, settings_location::SOUND_LEVELS, "sound.volume_ui", false, "%.0f%%");
-}
-
-void sound::init(void)
-{
- alGenSources(1, &generic_source);
- alSourcei(generic_source, AL_SOURCE_RELATIVE, AL_TRUE);
- alSource3f(generic_source, AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSource3f(generic_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
-
- alGenSources(1, &player_source);
- alSourcei(player_source, AL_SOURCE_RELATIVE, AL_TRUE);
- alSource3f(player_source, AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSource3f(player_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
-
- alGenSources(1, &ui_source);
- alSourcei(ui_source, AL_SOURCE_RELATIVE, AL_TRUE);
- alSource3f(ui_source, AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSource3f(ui_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
-
- sfx_generic = nullptr;
- sfx_player = nullptr;
- sfx_ui = nullptr;
-}
-
-void sound::init_late(void)
-{
-}
-
-void sound::shutdown(void)
-{
- sfx_ui = nullptr;
- sfx_player = nullptr;
- sfx_generic = nullptr;
-
- alDeleteBuffers(1, &ui_source);
- alDeleteSources(1, &generic_source);
- alDeleteSources(1, &player_source);
-}
-
-void sound::update(void)
-{
- auto effects_gain = glm::clamp(0.01f * sound::volume_effects.get_value(), 0.0f, 1.0f);
- alSourcef(generic_source, AL_GAIN, effects_gain);
- alSourcef(player_source, AL_GAIN, effects_gain);
-
- auto ui_gain = glm::clamp(0.01f * sound::volume_ui.get_value(), 0.0f, 1.0f);
- alSourcef(ui_source, AL_GAIN, ui_gain);
-}
-
-void sound::play_generic(std::string_view sound, bool looping, float pitch)
-{
- if(sound.size()) {
- sound::play_generic(resource::load<SoundEffect>(sound), looping, pitch);
- }
- else {
- sound::play_generic(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch);
- }
-}
-
-void sound::play_entity(entt::entity entity, std::string_view sound, bool looping, float pitch)
-{
- if(sound.size()) {
- sound::play_entity(entity, resource::load<SoundEffect>(sound), looping, pitch);
- }
- else {
- sound::play_entity(entity, static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch);
- }
-}
-
-void sound::play_player(std::string_view sound, bool looping, float pitch)
-{
- if(sound.size()) {
- sound::play_player(resource::load<SoundEffect>(sound), looping, pitch);
- }
- else {
- sound::play_player(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch);
- }
-}
-
-void sound::play_ui(std::string_view sound, bool looping, float pitch)
-{
- if(sound.size()) {
- sound::play_ui(resource::load<SoundEffect>(sound), looping, pitch);
- }
- else {
- sound::play_ui(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch);
- }
-}
-
-void sound::play_generic(resource_ptr<SoundEffect> sound, bool looping, float pitch)
-{
- alSourceRewind(generic_source);
-
- sfx_generic = sound;
-
- if(sfx_generic) {
- alSourcei(generic_source, AL_BUFFER, sfx_generic->buffer);
- alSourcei(generic_source, AL_LOOPING, looping);
- alSourcef(generic_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH));
- alSourcePlay(generic_source);
- }
-}
-
-void sound::play_entity(entt::entity entity, resource_ptr<SoundEffect> sound, bool looping, float pitch)
-{
- if(globals::dimension && globals::dimension->entities.valid(entity)) {
- if(auto emitter = globals::dimension->entities.try_get<entity::SoundEmitter>(entity)) {
- alSourceRewind(emitter->source);
-
- emitter->sound = sound;
-
- if(emitter->sound) {
- alSourcei(emitter->source, AL_BUFFER, emitter->sound->buffer);
- alSourcei(emitter->source, AL_LOOPING, looping);
- alSourcef(emitter->source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH));
- alSourcePlay(emitter->source);
- }
- }
- }
-}
-
-void sound::play_player(resource_ptr<SoundEffect> sound, bool looping, float pitch)
-{
- if(sound && session::is_ingame()) {
- protocol::EntitySound packet;
- packet.entity = globals::player;
- packet.sound = sound->name;
- packet.looping = looping;
- packet.pitch = pitch;
-
- protocol::send(session::peer, protocol::encode(packet));
- }
-
- alSourceRewind(player_source);
-
- sfx_player = sound;
-
- if(sfx_player) {
- alSourcei(player_source, AL_BUFFER, sfx_player->buffer);
- alSourcei(player_source, AL_LOOPING, looping);
- alSourcef(player_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH));
- alSourcePlay(player_source);
- }
-}
-
-void sound::play_ui(resource_ptr<SoundEffect> sound, bool looping, float pitch)
-{
- alSourceRewind(ui_source);
-
- sfx_ui = sound;
-
- if(sfx_ui) {
- alSourcei(ui_source, AL_BUFFER, sfx_ui->buffer);
- alSourcei(ui_source, AL_LOOPING, looping);
- alSourcef(ui_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH));
- alSourcePlay(ui_source);
- }
-}
+#include "client/pch.hh" + +#include "client/sound/sound.hh" + +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/resource.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" +#include "shared/protocol.hh" + +#include "client/entity/camera.hh" +#include "client/entity/sound_emitter.hh" + +#include "client/gui/settings.hh" + +#include "client/resource/sound_effect.hh" + +#include "client/const.hh" +#include "client/globals.hh" +#include "client/session.hh" + +config::Float sound::volume_master(100.0f, 0.0f, 100.0f); +config::Float sound::volume_effects(100.0f, 0.0f, 100.0f); +config::Float sound::volume_music(100.0f, 0.0f, 100.0f); +config::Float sound::volume_ui(100.0f, 0.0f, 100.0f); + +static ALuint generic_source; +static ALuint player_source; +static ALuint ui_source; + +static resource_ptr<SoundEffect> sfx_generic; +static resource_ptr<SoundEffect> sfx_player; +static resource_ptr<SoundEffect> sfx_ui; + +void sound::init_config(void) +{ + globals::client_config.add_value("sound.volume_master", sound::volume_master); + globals::client_config.add_value("sound.volume_effects", sound::volume_effects); + globals::client_config.add_value("sound.volume_music", sound::volume_music); + globals::client_config.add_value("sound.volume_ui", sound::volume_ui); + + settings::add_slider(1, sound::volume_master, settings_location::SOUND, "sound.volume_master", false, "%.0f%%"); + + settings::add_slider(0, sound::volume_effects, settings_location::SOUND_LEVELS, "sound.volume_effects", false, "%.0f%%"); + settings::add_slider(1, sound::volume_music, settings_location::SOUND_LEVELS, "sound.volume_music", false, "%.0f%%"); + settings::add_slider(2, sound::volume_ui, settings_location::SOUND_LEVELS, "sound.volume_ui", false, "%.0f%%"); +} + +void sound::init(void) +{ + alGenSources(1, &generic_source); + alSourcei(generic_source, AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(generic_source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(generic_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + + alGenSources(1, &player_source); + alSourcei(player_source, AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(player_source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(player_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + + alGenSources(1, &ui_source); + alSourcei(ui_source, AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ui_source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(ui_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + + sfx_generic = nullptr; + sfx_player = nullptr; + sfx_ui = nullptr; +} + +void sound::init_late(void) +{ +} + +void sound::shutdown(void) +{ + sfx_ui = nullptr; + sfx_player = nullptr; + sfx_generic = nullptr; + + alDeleteBuffers(1, &ui_source); + alDeleteSources(1, &generic_source); + alDeleteSources(1, &player_source); +} + +void sound::update(void) +{ + auto effects_gain = glm::clamp(0.01f * sound::volume_effects.get_value(), 0.0f, 1.0f); + alSourcef(generic_source, AL_GAIN, effects_gain); + alSourcef(player_source, AL_GAIN, effects_gain); + + auto ui_gain = glm::clamp(0.01f * sound::volume_ui.get_value(), 0.0f, 1.0f); + alSourcef(ui_source, AL_GAIN, ui_gain); +} + +void sound::play_generic(std::string_view sound, bool looping, float pitch) +{ + if(sound.size()) { + sound::play_generic(resource::load<SoundEffect>(sound), looping, pitch); + } + else { + sound::play_generic(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch); + } +} + +void sound::play_entity(entt::entity entity, std::string_view sound, bool looping, float pitch) +{ + if(sound.size()) { + sound::play_entity(entity, resource::load<SoundEffect>(sound), looping, pitch); + } + else { + sound::play_entity(entity, static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch); + } +} + +void sound::play_player(std::string_view sound, bool looping, float pitch) +{ + if(sound.size()) { + sound::play_player(resource::load<SoundEffect>(sound), looping, pitch); + } + else { + sound::play_player(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch); + } +} + +void sound::play_ui(std::string_view sound, bool looping, float pitch) +{ + if(sound.size()) { + sound::play_ui(resource::load<SoundEffect>(sound), looping, pitch); + } + else { + sound::play_ui(static_cast<resource_ptr<SoundEffect>>(nullptr), looping, pitch); + } +} + +void sound::play_generic(resource_ptr<SoundEffect> sound, bool looping, float pitch) +{ + alSourceRewind(generic_source); + + sfx_generic = sound; + + if(sfx_generic) { + alSourcei(generic_source, AL_BUFFER, sfx_generic->buffer); + alSourcei(generic_source, AL_LOOPING, looping); + alSourcef(generic_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH)); + alSourcePlay(generic_source); + } +} + +void sound::play_entity(entt::entity entity, resource_ptr<SoundEffect> sound, bool looping, float pitch) +{ + if(globals::dimension && globals::dimension->entities.valid(entity)) { + if(auto emitter = globals::dimension->entities.try_get<entity::SoundEmitter>(entity)) { + alSourceRewind(emitter->source); + + emitter->sound = sound; + + if(emitter->sound) { + alSourcei(emitter->source, AL_BUFFER, emitter->sound->buffer); + alSourcei(emitter->source, AL_LOOPING, looping); + alSourcef(emitter->source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH)); + alSourcePlay(emitter->source); + } + } + } +} + +void sound::play_player(resource_ptr<SoundEffect> sound, bool looping, float pitch) +{ + if(sound && session::is_ingame()) { + protocol::EntitySound packet; + packet.entity = globals::player; + packet.sound = sound->name; + packet.looping = looping; + packet.pitch = pitch; + + protocol::send(session::peer, protocol::encode(packet)); + } + + alSourceRewind(player_source); + + sfx_player = sound; + + if(sfx_player) { + alSourcei(player_source, AL_BUFFER, sfx_player->buffer); + alSourcei(player_source, AL_LOOPING, looping); + alSourcef(player_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH)); + alSourcePlay(player_source); + } +} + +void sound::play_ui(resource_ptr<SoundEffect> sound, bool looping, float pitch) +{ + alSourceRewind(ui_source); + + sfx_ui = sound; + + if(sfx_ui) { + alSourcei(ui_source, AL_BUFFER, sfx_ui->buffer); + alSourcei(ui_source, AL_LOOPING, looping); + alSourcef(ui_source, AL_PITCH, glm::clamp(pitch, MIN_PITCH, MAX_PITCH)); + alSourcePlay(ui_source); + } +} diff --git a/game/client/sound/sound.hh b/src/game/client/sound/sound.hh index c794845..d96d0c4 100644 --- a/game/client/sound/sound.hh +++ b/src/game/client/sound/sound.hh @@ -1,43 +1,43 @@ -#pragma once
-
-#include "core/resource/resource.hh"
-
-namespace config
-{
-class Float;
-} // namespace config
-
-struct SoundEffect;
-
-namespace sound
-{
-extern config::Float volume_master;
-extern config::Float volume_effects;
-extern config::Float volume_music;
-extern config::Float volume_ui;
-} // namespace sound
-
-namespace sound
-{
-void init_config(void);
-void init(void);
-void init_late(void);
-void shutdown(void);
-void update(void);
-} // namespace sound
-
-namespace sound
-{
-void play_generic(std::string_view sound, bool looping, float pitch);
-void play_entity(entt::entity entity, std::string_view sound, bool looping, float pitch);
-void play_player(std::string_view sound, bool looping, float pitch);
-void play_ui(std::string_view sound, bool looping, float pitch);
-} // namespace sound
-
-namespace sound
-{
-void play_generic(resource_ptr<SoundEffect> sound, bool looping, float pitch);
-void play_entity(entt::entity entity, resource_ptr<SoundEffect> sound, bool looping, float pitch);
-void play_player(resource_ptr<SoundEffect> sound, bool looping, float pitch);
-void play_ui(resource_ptr<SoundEffect> sound, bool looping, float pitch);
-} // namespace sound
+#pragma once + +#include "core/resource/resource.hh" + +namespace config +{ +class Float; +} // namespace config + +struct SoundEffect; + +namespace sound +{ +extern config::Float volume_master; +extern config::Float volume_effects; +extern config::Float volume_music; +extern config::Float volume_ui; +} // namespace sound + +namespace sound +{ +void init_config(void); +void init(void); +void init_late(void); +void shutdown(void); +void update(void); +} // namespace sound + +namespace sound +{ +void play_generic(std::string_view sound, bool looping, float pitch); +void play_entity(entt::entity entity, std::string_view sound, bool looping, float pitch); +void play_player(std::string_view sound, bool looping, float pitch); +void play_ui(std::string_view sound, bool looping, float pitch); +} // namespace sound + +namespace sound +{ +void play_generic(resource_ptr<SoundEffect> sound, bool looping, float pitch); +void play_entity(entt::entity entity, resource_ptr<SoundEffect> sound, bool looping, float pitch); +void play_player(resource_ptr<SoundEffect> sound, bool looping, float pitch); +void play_ui(resource_ptr<SoundEffect> sound, bool looping, float pitch); +} // namespace sound diff --git a/game/client/toggles.cc b/src/game/client/toggles.cc index 34d03c7..833e099 100644 --- a/game/client/toggles.cc +++ b/src/game/client/toggles.cc @@ -1,157 +1,157 @@ -#include "client/pch.hh"
-
-#include "client/toggles.hh"
-
-#include "core/io/config_map.hh"
-
-#include "client/gui/chat.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-
-struct ToggleInfo final {
- std::string_view description;
- int glfw_keycode;
- bool is_enabled;
-};
-
-bool toggles::is_sequence_await = false;
-
-static ToggleInfo toggle_infos[TOGGLE_COUNT];
-
-static void print_toggle_state(const ToggleInfo& info)
-{
- if(info.description.size()) {
- if(info.is_enabled) {
- gui::client_chat::print(std::format("[toggles] {} ON", info.description));
- }
- else {
- gui::client_chat::print(std::format("[toggles] {} OFF", info.description));
- }
- }
-}
-
-static void toggle_value(ToggleInfo& info, toggle_type type)
-{
- if(info.is_enabled) {
- info.is_enabled = false;
- globals::dispatcher.trigger(ToggleDisabledEvent { type });
- }
- else {
- info.is_enabled = true;
- globals::dispatcher.trigger(ToggleEnabledEvent { type });
- }
-
- print_toggle_state(info);
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(globals::gui_keybind_ptr) {
- // The UI keybind subsystem has the authority
- // over debug toggles and it hogs the input keys
- return;
- }
-
- if(event.key == DEBUG_KEY) {
- if(event.action == GLFW_PRESS) {
- toggles::is_sequence_await = true;
- ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- return;
- }
-
- if(event.action == GLFW_RELEASE) {
- toggles::is_sequence_await = false;
- ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- return;
- }
- }
-
- if((event.action == GLFW_PRESS) && toggles::is_sequence_await) {
- if(event.key == GLFW_KEY_L) {
- // This causes the language subsystem
- // to re-parse the JSON file essentially
- // causing the game to soft-reload language
- gui::language::set(gui::language::get_current());
- return;
- }
-
- for(toggle_type i = 0; i < TOGGLE_COUNT; ++i) {
- if(event.key == toggle_infos[i].glfw_keycode) {
- toggle_value(toggle_infos[i], i);
- return;
- }
- }
- }
-}
-
-void toggles::init(void)
-{
- toggle_infos[TOGGLE_WIREFRAME].description = "wireframe";
- toggle_infos[TOGGLE_WIREFRAME].glfw_keycode = GLFW_KEY_Z;
- toggle_infos[TOGGLE_WIREFRAME].is_enabled = false;
-
- toggle_infos[TOGGLE_FULLBRIGHT].description = "fullbright";
- toggle_infos[TOGGLE_FULLBRIGHT].glfw_keycode = GLFW_KEY_J;
- toggle_infos[TOGGLE_FULLBRIGHT].is_enabled = false;
-
- toggle_infos[TOGGLE_CHUNK_AABB].description = "chunk Borders";
- toggle_infos[TOGGLE_CHUNK_AABB].glfw_keycode = GLFW_KEY_G;
- toggle_infos[TOGGLE_CHUNK_AABB].is_enabled = false;
-
- toggle_infos[TOGGLE_METRICS_UI].description = std::string_view();
- toggle_infos[TOGGLE_METRICS_UI].glfw_keycode = GLFW_KEY_V;
- toggle_infos[TOGGLE_METRICS_UI].is_enabled = false;
-
- toggle_infos[TOGGLE_USE_GAMEPAD].description = "gamepad input";
- toggle_infos[TOGGLE_USE_GAMEPAD].glfw_keycode = GLFW_KEY_P;
- toggle_infos[TOGGLE_USE_GAMEPAD].is_enabled = false;
-
- toggle_infos[TOGGLE_PM_FLIGHT].description = "flight mode";
- toggle_infos[TOGGLE_PM_FLIGHT].glfw_keycode = GLFW_KEY_F;
- toggle_infos[TOGGLE_PM_FLIGHT].is_enabled = false;
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
-}
-
-void toggles::init_late(void)
-{
- for(toggle_type i = 0; i < TOGGLE_COUNT; ++i) {
- if(toggle_infos[i].is_enabled) {
- globals::dispatcher.trigger(ToggleEnabledEvent { i });
- }
- else {
- globals::dispatcher.trigger(ToggleDisabledEvent { i });
- }
- }
-}
-
-bool toggles::get(toggle_type type)
-{
- if(type < TOGGLE_COUNT) {
- return toggle_infos[type].is_enabled;
- }
- else {
- return false;
- }
-}
-
-void toggles::set(toggle_type type, bool value)
-{
- if(type < TOGGLE_COUNT) {
- if(value) {
- toggle_infos[type].is_enabled = true;
- globals::dispatcher.trigger(ToggleEnabledEvent { type });
- }
- else {
- toggle_infos[type].is_enabled = false;
- globals::dispatcher.trigger(ToggleDisabledEvent { type });
- }
-
- print_toggle_state(toggle_infos[type]);
- }
-}
+#include "client/pch.hh" + +#include "client/toggles.hh" + +#include "core/io/config_map.hh" + +#include "client/gui/chat.hh" +#include "client/gui/language.hh" + +#include "client/io/gamepad.hh" +#include "client/io/glfw.hh" + +#include "client/const.hh" +#include "client/globals.hh" + +struct ToggleInfo final { + std::string_view description; + int glfw_keycode; + bool is_enabled; +}; + +bool toggles::is_sequence_await = false; + +static ToggleInfo toggle_infos[TOGGLE_COUNT]; + +static void print_toggle_state(const ToggleInfo& info) +{ + if(info.description.size()) { + if(info.is_enabled) { + gui::client_chat::print(std::format("[toggles] {} ON", info.description)); + } + else { + gui::client_chat::print(std::format("[toggles] {} OFF", info.description)); + } + } +} + +static void toggle_value(ToggleInfo& info, toggle_type type) +{ + if(info.is_enabled) { + info.is_enabled = false; + globals::dispatcher.trigger(ToggleDisabledEvent { type }); + } + else { + info.is_enabled = true; + globals::dispatcher.trigger(ToggleEnabledEvent { type }); + } + + print_toggle_state(info); +} + +static void on_glfw_key(const io::GlfwKeyEvent& event) +{ + if(globals::gui_keybind_ptr) { + // The UI keybind subsystem has the authority + // over debug toggles and it hogs the input keys + return; + } + + if(event.key == DEBUG_KEY) { + if(event.action == GLFW_PRESS) { + toggles::is_sequence_await = true; + ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; + return; + } + + if(event.action == GLFW_RELEASE) { + toggles::is_sequence_await = false; + ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + return; + } + } + + if((event.action == GLFW_PRESS) && toggles::is_sequence_await) { + if(event.key == GLFW_KEY_L) { + // This causes the language subsystem + // to re-parse the JSON file essentially + // causing the game to soft-reload language + gui::language::set(gui::language::get_current()); + return; + } + + for(toggle_type i = 0; i < TOGGLE_COUNT; ++i) { + if(event.key == toggle_infos[i].glfw_keycode) { + toggle_value(toggle_infos[i], i); + return; + } + } + } +} + +void toggles::init(void) +{ + toggle_infos[TOGGLE_WIREFRAME].description = "wireframe"; + toggle_infos[TOGGLE_WIREFRAME].glfw_keycode = GLFW_KEY_Z; + toggle_infos[TOGGLE_WIREFRAME].is_enabled = false; + + toggle_infos[TOGGLE_FULLBRIGHT].description = "fullbright"; + toggle_infos[TOGGLE_FULLBRIGHT].glfw_keycode = GLFW_KEY_J; + toggle_infos[TOGGLE_FULLBRIGHT].is_enabled = false; + + toggle_infos[TOGGLE_CHUNK_AABB].description = "chunk Borders"; + toggle_infos[TOGGLE_CHUNK_AABB].glfw_keycode = GLFW_KEY_G; + toggle_infos[TOGGLE_CHUNK_AABB].is_enabled = false; + + toggle_infos[TOGGLE_METRICS_UI].description = std::string_view(); + toggle_infos[TOGGLE_METRICS_UI].glfw_keycode = GLFW_KEY_V; + toggle_infos[TOGGLE_METRICS_UI].is_enabled = false; + + toggle_infos[TOGGLE_USE_GAMEPAD].description = "gamepad input"; + toggle_infos[TOGGLE_USE_GAMEPAD].glfw_keycode = GLFW_KEY_P; + toggle_infos[TOGGLE_USE_GAMEPAD].is_enabled = false; + + toggle_infos[TOGGLE_PM_FLIGHT].description = "flight mode"; + toggle_infos[TOGGLE_PM_FLIGHT].glfw_keycode = GLFW_KEY_F; + toggle_infos[TOGGLE_PM_FLIGHT].is_enabled = false; + + globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>(); +} + +void toggles::init_late(void) +{ + for(toggle_type i = 0; i < TOGGLE_COUNT; ++i) { + if(toggle_infos[i].is_enabled) { + globals::dispatcher.trigger(ToggleEnabledEvent { i }); + } + else { + globals::dispatcher.trigger(ToggleDisabledEvent { i }); + } + } +} + +bool toggles::get(toggle_type type) +{ + if(type < TOGGLE_COUNT) { + return toggle_infos[type].is_enabled; + } + else { + return false; + } +} + +void toggles::set(toggle_type type, bool value) +{ + if(type < TOGGLE_COUNT) { + if(value) { + toggle_infos[type].is_enabled = true; + globals::dispatcher.trigger(ToggleEnabledEvent { type }); + } + else { + toggle_infos[type].is_enabled = false; + globals::dispatcher.trigger(ToggleDisabledEvent { type }); + } + + print_toggle_state(toggle_infos[type]); + } +} diff --git a/game/client/toggles.hh b/src/game/client/toggles.hh index 8ef780e..d051a92 100644 --- a/game/client/toggles.hh +++ b/src/game/client/toggles.hh @@ -1,35 +1,35 @@ -#pragma once
-
-using toggle_type = unsigned int;
-constexpr static toggle_type TOGGLE_WIREFRAME = 0x0000U; // Render things in wireframe mode
-constexpr static toggle_type TOGGLE_FULLBRIGHT = 0x0001U; // Render things without lighting
-constexpr static toggle_type TOGGLE_CHUNK_AABB = 0x0002U; // Render chunk bounding boxes
-constexpr static toggle_type TOGGLE_METRICS_UI = 0x0003U; // Render debug metrics overlay
-constexpr static toggle_type TOGGLE_USE_GAMEPAD = 0x0004U; // Use gamepad for player movement
-constexpr static toggle_type TOGGLE_PM_FLIGHT = 0x0005U; // Enable flight for player movement
-constexpr static std::size_t TOGGLE_COUNT = 0x0006U;
-
-struct ToggleEnabledEvent final {
- toggle_type type;
-};
-
-struct ToggleDisabledEvent final {
- toggle_type type;
-};
-
-namespace toggles
-{
-// The value is true whenever the debug
-// toggles manager awaits for a sequenced key
-// to be pressed. During this no input should
-// be processed by any other gameplay system
-extern bool is_sequence_await;
-} // namespace toggles
-
-namespace toggles
-{
-void init(void);
-void init_late(void);
-bool get(toggle_type type);
-void set(toggle_type type, bool value);
-} // namespace toggles
+#pragma once + +using toggle_type = unsigned int; +constexpr static toggle_type TOGGLE_WIREFRAME = 0x0000U; // Render things in wireframe mode +constexpr static toggle_type TOGGLE_FULLBRIGHT = 0x0001U; // Render things without lighting +constexpr static toggle_type TOGGLE_CHUNK_AABB = 0x0002U; // Render chunk bounding boxes +constexpr static toggle_type TOGGLE_METRICS_UI = 0x0003U; // Render debug metrics overlay +constexpr static toggle_type TOGGLE_USE_GAMEPAD = 0x0004U; // Use gamepad for player movement +constexpr static toggle_type TOGGLE_PM_FLIGHT = 0x0005U; // Enable flight for player movement +constexpr static std::size_t TOGGLE_COUNT = 0x0006U; + +struct ToggleEnabledEvent final { + toggle_type type; +}; + +struct ToggleDisabledEvent final { + toggle_type type; +}; + +namespace toggles +{ +// The value is true whenever the debug +// toggles manager awaits for a sequenced key +// to be pressed. During this no input should +// be processed by any other gameplay system +extern bool is_sequence_await; +} // namespace toggles + +namespace toggles +{ +void init(void); +void init_late(void); +bool get(toggle_type type); +void set(toggle_type type, bool value); +} // namespace toggles diff --git a/game/client/vclient.ico b/src/game/client/vclient.ico Binary files differindex 5f3ccd2..5f3ccd2 100644 --- a/game/client/vclient.ico +++ b/src/game/client/vclient.ico diff --git a/game/client/vclient.rc b/src/game/client/vclient.rc index 0268ca0..0268ca0 100644 --- a/game/client/vclient.rc +++ b/src/game/client/vclient.rc diff --git a/game/client/world/CMakeLists.txt b/src/game/client/world/CMakeLists.txt index fdf96bf..fdf96bf 100644 --- a/game/client/world/CMakeLists.txt +++ b/src/game/client/world/CMakeLists.txt diff --git a/game/client/world/chunk_mesher.cc b/src/game/client/world/chunk_mesher.cc index da90d2e..5e58760 100644 --- a/game/client/world/chunk_mesher.cc +++ b/src/game/client/world/chunk_mesher.cc @@ -1,450 +1,450 @@ -#include "client/pch.hh"
-
-#include "client/world/chunk_mesher.hh"
-
-#include "core/math/crc64.hh"
-
-#include "core/threading.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-#include "shared/world/voxel.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-
-#include "client/world/chunk_quad.hh"
-#include "client/world/voxel_atlas.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-using QuadBuilder = std::vector<world::ChunkQuad>;
-
-using CachedChunkCoord = unsigned short;
-constexpr static CachedChunkCoord CPOS_ITSELF = 0x0000;
-constexpr static CachedChunkCoord CPOS_NORTH = 0x0001;
-constexpr static CachedChunkCoord CPOS_SOUTH = 0x0002;
-constexpr static CachedChunkCoord CPOS_EAST = 0x0003;
-constexpr static CachedChunkCoord CPOS_WEST = 0x0004;
-constexpr static CachedChunkCoord CPOS_TOP = 0x0005;
-constexpr static CachedChunkCoord CPOS_BOTTOM = 0x0006;
-constexpr static const size_t NUM_CACHED_CPOS = 7;
-
-static const CachedChunkCoord get_cached_cpos(const chunk_pos& pivot, const chunk_pos& cpos)
-{
- static const CachedChunkCoord nx[3] = { CPOS_WEST, 0, CPOS_EAST };
- static const CachedChunkCoord ny[3] = { CPOS_BOTTOM, 0, CPOS_TOP };
- static const CachedChunkCoord nz[3] = { CPOS_NORTH, 0, CPOS_SOUTH };
-
- if(pivot != cpos) {
- chunk_pos delta = pivot - cpos;
- delta[0] = glm::clamp<std::int64_t>(delta[0], -1, 1);
- delta[1] = glm::clamp<std::int64_t>(delta[1], -1, 1);
- delta[2] = glm::clamp<std::int64_t>(delta[2], -1, 1);
-
- if(delta[0]) {
- return nx[delta[0] + 1];
- }
- else if(delta[1]) {
- return ny[delta[1] + 1];
- }
- else {
- return nz[delta[2] + 1];
- }
- }
-
- return CPOS_ITSELF;
-}
-
-class GL_MeshingTask final : public Task {
-public:
- explicit GL_MeshingTask(entt::entity entity, const chunk_pos& cpos);
- virtual ~GL_MeshingTask(void) = default;
- virtual void process(void) override;
- virtual void finalize(void) override;
-
-private:
- bool vis_test(const world::Voxel* voxel, const local_pos& lpos) const;
- void push_quad_a(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face);
- void push_quad_v(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face, std::size_t entropy);
- void make_cube(const world::Voxel* voxel, const local_pos& lpos, world::VoxelVisBits vis, std::size_t entropy);
- void cache_chunk(const chunk_pos& cpos);
-
-private:
- std::array<world::VoxelStorage, NUM_CACHED_CPOS> m_cache;
- std::vector<QuadBuilder> m_quads_b; // blending
- std::vector<QuadBuilder> m_quads_s; // solid
- entt::entity m_entity;
- chunk_pos m_cpos;
-};
-
-GL_MeshingTask::GL_MeshingTask(entt::entity entity, const chunk_pos& cpos)
-{
- m_entity = entity;
- m_cpos = cpos;
-
- cache_chunk(m_cpos);
- cache_chunk(m_cpos + DIR_NORTH<chunk_pos::value_type>);
- cache_chunk(m_cpos + DIR_SOUTH<chunk_pos::value_type>);
- cache_chunk(m_cpos + DIR_EAST<chunk_pos::value_type>);
- cache_chunk(m_cpos + DIR_WEST<chunk_pos::value_type>);
- cache_chunk(m_cpos + DIR_DOWN<chunk_pos::value_type>);
- cache_chunk(m_cpos + DIR_UP<chunk_pos::value_type>);
-}
-
-void GL_MeshingTask::process(void)
-{
- m_quads_b.resize(world::voxel_atlas::plane_count());
- m_quads_s.resize(world::voxel_atlas::plane_count());
-
- const auto& voxels = m_cache.at(CPOS_ITSELF);
-
- for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) {
- if(m_status == task_status::CANCELLED) {
- m_quads_b.clear();
- m_quads_s.clear();
- return;
- }
-
- const auto lpos = coord::to_local(i);
- const auto voxel = world::voxel_registry::find(voxels[i]);
-
- if(voxel == nullptr) {
- // Either a NULL_VOXEL_ID or something went
- // horribly wrong and we don't what this is
- continue;
- }
-
- unsigned int vis = 0U;
-
- if(vis_test(voxel, lpos + DIR_NORTH<local_pos::value_type>)) {
- vis |= world::VVIS_NORTH;
- }
-
- if(vis_test(voxel, lpos + DIR_SOUTH<local_pos::value_type>)) {
- vis |= world::VVIS_SOUTH;
- }
-
- if(vis_test(voxel, lpos + DIR_EAST<local_pos::value_type>)) {
- vis |= world::VVIS_EAST;
- }
-
- if(vis_test(voxel, lpos + DIR_WEST<local_pos::value_type>)) {
- vis |= world::VVIS_WEST;
- }
-
- if(vis_test(voxel, lpos + DIR_UP<local_pos::value_type>)) {
- vis |= world::VVIS_UP;
- }
-
- if(vis_test(voxel, lpos + DIR_DOWN<local_pos::value_type>)) {
- vis |= world::VVIS_DOWN;
- }
-
- const auto vpos = coord::to_voxel(m_cpos, lpos);
- const auto entropy_src = vpos[0] * vpos[1] * vpos[2];
- const auto entropy = math::crc64(&entropy_src, sizeof(entropy_src));
-
- // FIXME: handle different voxel types
- make_cube(voxel, lpos, world::VoxelVisBits(vis), entropy);
- }
-}
-
-void GL_MeshingTask::finalize(void)
-{
- if(!globals::dimension || !globals::dimension->chunks.valid(m_entity)) {
- // We either disconnected or something
- // else happened that invalidated the entity
- return;
- }
-
- auto& component = globals::dimension->chunks.emplace_or_replace<world::ChunkMesh>(m_entity);
-
- const std::size_t plane_count_nb = m_quads_s.size();
- const std::size_t plane_count_b = m_quads_b.size();
-
- bool has_no_submeshes_b = true;
- bool has_no_submeshes_nb = true;
-
- component.quad_nb.resize(plane_count_nb);
- component.quad_b.resize(plane_count_b);
-
- for(std::size_t plane = 0; plane < plane_count_nb; ++plane) {
- auto& builder = m_quads_s[plane];
- auto& buffer = component.quad_nb[plane];
-
- if(builder.empty()) {
- if(buffer.handle) {
- glDeleteBuffers(1, &buffer.handle);
- buffer.handle = 0;
- buffer.size = 0;
- }
- }
- else {
- if(!buffer.handle) {
- glGenBuffers(1, &buffer.handle);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, buffer.handle);
- glBufferData(GL_ARRAY_BUFFER, sizeof(world::ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW);
- buffer.size = builder.size();
- has_no_submeshes_nb = false;
- }
- }
-
- for(std::size_t plane = 0; plane < plane_count_b; ++plane) {
- auto& builder = m_quads_b[plane];
- auto& buffer = component.quad_b[plane];
-
- if(builder.empty()) {
- if(buffer.handle) {
- glDeleteBuffers(1, &buffer.handle);
- buffer.handle = 0;
- buffer.size = 0;
- }
- }
- else {
- if(!buffer.handle) {
- glGenBuffers(1, &buffer.handle);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, buffer.handle);
- glBufferData(GL_ARRAY_BUFFER, sizeof(world::ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW);
- buffer.size = builder.size();
- has_no_submeshes_b = false;
- }
- }
-
- if(has_no_submeshes_b && has_no_submeshes_nb) {
- globals::dimension->chunks.remove<world::ChunkMesh>(m_entity);
- }
-}
-
-bool GL_MeshingTask::vis_test(const world::Voxel* voxel, const local_pos& lpos) const
-{
- const auto pvpos = coord::to_voxel(m_cpos, lpos);
- const auto pcpos = coord::to_chunk(pvpos);
- const auto plpos = coord::to_local(pvpos);
- const auto index = coord::to_index(plpos);
-
- const auto cached_cpos = get_cached_cpos(m_cpos, pcpos);
- const auto& voxels = m_cache.at(cached_cpos);
- const auto neighbour = world::voxel_registry::find(voxels[index]);
-
- bool result;
-
- if(neighbour == nullptr) {
- result = true;
- }
- else if(neighbour == voxel) {
- result = false;
- }
- else if(neighbour->get_render_mode() != voxel->get_render_mode()) {
- result = true;
- }
- else {
- result = false;
- }
-
- return result;
-}
-
-void GL_MeshingTask::push_quad_a(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face)
-{
- auto cached_offset = voxel->get_cached_face_offset(face);
- auto cached_plane = voxel->get_cached_face_plane(face);
- auto& textures = voxel->get_face_textures(face);
-
- switch(voxel->get_render_mode()) {
- case world::VRENDER_OPAQUE:
- m_quads_s[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset, textures.size()));
- break;
-
- case world::VRENDER_BLEND:
- m_quads_b[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset, textures.size()));
- break;
- }
-}
-
-void GL_MeshingTask::push_quad_v(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face,
- std::size_t entropy)
-{
- auto cached_offset = voxel->get_cached_face_offset(face);
- auto cached_plane = voxel->get_cached_face_plane(face);
- auto& textures = voxel->get_face_textures(face);
- auto index = entropy % textures.size();
-
- switch(voxel->get_render_mode()) {
- case world::VRENDER_OPAQUE:
- m_quads_s[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset + index, 0));
- break;
-
- case world::VRENDER_BLEND:
- m_quads_b[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset + index, 0));
- break;
- }
-}
-
-void GL_MeshingTask::make_cube(const world::Voxel* voxel, const local_pos& lpos, world::VoxelVisBits vis, std::size_t entropy)
-{
- const glm::fvec3 fpos = glm::fvec3(lpos);
- const glm::fvec2 fsize = glm::fvec2(1.0f, 1.0f);
-
- if(voxel->is_animated()) {
- if(vis & world::VVIS_NORTH) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_NORTH);
- }
-
- if(vis & world::VVIS_SOUTH) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_SOUTH);
- }
-
- if(vis & world::VVIS_EAST) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_EAST);
- }
-
- if(vis & world::VVIS_WEST) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_WEST);
- }
-
- if(vis & world::VVIS_UP) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_TOP);
- }
-
- if(vis & world::VVIS_DOWN) {
- push_quad_a(voxel, fpos, fsize, world::VFACE_BOTTOM);
- }
- }
- else {
- if(vis & world::VVIS_NORTH) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_NORTH, entropy);
- }
-
- if(vis & world::VVIS_SOUTH) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_SOUTH, entropy);
- }
-
- if(vis & world::VVIS_EAST) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_EAST, entropy);
- }
-
- if(vis & world::VVIS_WEST) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_WEST, entropy);
- }
-
- if(vis & world::VVIS_UP) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_TOP, entropy);
- }
-
- if(vis & world::VVIS_DOWN) {
- push_quad_v(voxel, fpos, fsize, world::VFACE_BOTTOM, entropy);
- }
- }
-}
-
-void GL_MeshingTask::cache_chunk(const chunk_pos& cpos)
-{
- const auto index = get_cached_cpos(m_cpos, cpos);
-
- if(const auto chunk = globals::dimension->find_chunk(cpos)) {
- m_cache[index] = chunk->get_voxels();
- return;
- }
-}
-
-// Bogus internal flag component
-struct NeedsMeshingComponent final {};
-
-static void on_chunk_create(const world::ChunkCreateEvent& event)
-{
- const std::array<chunk_pos, 6> neighbours = {
- event.cpos + DIR_NORTH<chunk_pos::value_type>,
- event.cpos + DIR_SOUTH<chunk_pos::value_type>,
- event.cpos + DIR_EAST<chunk_pos::value_type>,
- event.cpos + DIR_WEST<chunk_pos::value_type>,
- event.cpos + DIR_UP<chunk_pos::value_type>,
- event.cpos + DIR_DOWN<chunk_pos::value_type>,
- };
-
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
-
- for(const chunk_pos& cpos : neighbours) {
- if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) {
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
- continue;
- }
- }
-}
-
-static void on_chunk_update(const world::ChunkUpdateEvent& event)
-{
- const std::array<chunk_pos, 6> neighbours = {
- event.cpos + DIR_NORTH<chunk_pos::value_type>,
- event.cpos + DIR_SOUTH<chunk_pos::value_type>,
- event.cpos + DIR_EAST<chunk_pos::value_type>,
- event.cpos + DIR_WEST<chunk_pos::value_type>,
- event.cpos + DIR_UP<chunk_pos::value_type>,
- event.cpos + DIR_DOWN<chunk_pos::value_type>,
- };
-
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
-
- for(const chunk_pos& cpos : neighbours) {
- if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) {
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
- continue;
- }
- }
-}
-
-static void on_voxel_set(const world::VoxelSetEvent& event)
-{
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
-
- std::vector<chunk_pos> neighbours;
-
- for(int dim = 0; dim < 3; dim += 1) {
- chunk_pos offset = chunk_pos(0, 0, 0);
- offset[dim] = 1;
-
- if(event.lpos[dim] == 0) {
- neighbours.push_back(event.cpos - offset);
- continue;
- }
-
- if(event.lpos[dim] == (CHUNK_SIZE - 1)) {
- neighbours.push_back(event.cpos + offset);
- continue;
- }
- }
-
- for(const chunk_pos& cpos : neighbours) {
- if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) {
- globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
- continue;
- }
- }
-}
-
-void world::chunk_mesher::init(void)
-{
- globals::dispatcher.sink<ChunkCreateEvent>().connect<&on_chunk_create>();
- globals::dispatcher.sink<ChunkUpdateEvent>().connect<&on_chunk_update>();
- globals::dispatcher.sink<VoxelSetEvent>().connect<&on_voxel_set>();
-}
-
-void world::chunk_mesher::shutdown(void)
-{
-}
-
-void world::chunk_mesher::update(void)
-{
- if(session::is_ingame()) {
- const auto group = globals::dimension->chunks.group<NeedsMeshingComponent>(entt::get<ChunkComponent>);
- for(const auto [entity, chunk] : group.each()) {
- globals::dimension->chunks.remove<NeedsMeshingComponent>(entity);
- threading::submit<GL_MeshingTask>(entity, chunk.cpos);
- }
- }
-}
+#include "client/pch.hh" + +#include "client/world/chunk_mesher.hh" + +#include "core/math/crc64.hh" + +#include "core/threading.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" +#include "shared/world/voxel.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" + +#include "client/world/chunk_quad.hh" +#include "client/world/voxel_atlas.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +using QuadBuilder = std::vector<world::ChunkQuad>; + +using CachedChunkCoord = unsigned short; +constexpr static CachedChunkCoord CPOS_ITSELF = 0x0000; +constexpr static CachedChunkCoord CPOS_NORTH = 0x0001; +constexpr static CachedChunkCoord CPOS_SOUTH = 0x0002; +constexpr static CachedChunkCoord CPOS_EAST = 0x0003; +constexpr static CachedChunkCoord CPOS_WEST = 0x0004; +constexpr static CachedChunkCoord CPOS_TOP = 0x0005; +constexpr static CachedChunkCoord CPOS_BOTTOM = 0x0006; +constexpr static const size_t NUM_CACHED_CPOS = 7; + +static const CachedChunkCoord get_cached_cpos(const chunk_pos& pivot, const chunk_pos& cpos) +{ + static const CachedChunkCoord nx[3] = { CPOS_WEST, 0, CPOS_EAST }; + static const CachedChunkCoord ny[3] = { CPOS_BOTTOM, 0, CPOS_TOP }; + static const CachedChunkCoord nz[3] = { CPOS_NORTH, 0, CPOS_SOUTH }; + + if(pivot != cpos) { + chunk_pos delta = pivot - cpos; + delta[0] = glm::clamp<chunk_pos::value_type>(delta[0], -1, 1); + delta[1] = glm::clamp<chunk_pos::value_type>(delta[1], -1, 1); + delta[2] = glm::clamp<chunk_pos::value_type>(delta[2], -1, 1); + + if(delta[0]) { + return nx[delta[0] + 1]; + } + else if(delta[1]) { + return ny[delta[1] + 1]; + } + else { + return nz[delta[2] + 1]; + } + } + + return CPOS_ITSELF; +} + +class GL_MeshingTask final : public Task { +public: + explicit GL_MeshingTask(entt::entity entity, const chunk_pos& cpos); + virtual ~GL_MeshingTask(void) = default; + virtual void process(void) override; + virtual void finalize(void) override; + +private: + bool vis_test(const world::Voxel* voxel, const local_pos& lpos) const; + void push_quad_a(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face); + void push_quad_v(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face, std::size_t entropy); + void make_cube(const world::Voxel* voxel, const local_pos& lpos, world::VoxelVisBits vis, std::size_t entropy); + void cache_chunk(const chunk_pos& cpos); + +private: + std::array<world::VoxelStorage, NUM_CACHED_CPOS> m_cache; + std::vector<QuadBuilder> m_quads_b; // blending + std::vector<QuadBuilder> m_quads_s; // solid + entt::entity m_entity; + chunk_pos m_cpos; +}; + +GL_MeshingTask::GL_MeshingTask(entt::entity entity, const chunk_pos& cpos) +{ + m_entity = entity; + m_cpos = cpos; + + cache_chunk(m_cpos); + cache_chunk(m_cpos + DIR_NORTH<chunk_pos::value_type>); + cache_chunk(m_cpos + DIR_SOUTH<chunk_pos::value_type>); + cache_chunk(m_cpos + DIR_EAST<chunk_pos::value_type>); + cache_chunk(m_cpos + DIR_WEST<chunk_pos::value_type>); + cache_chunk(m_cpos + DIR_DOWN<chunk_pos::value_type>); + cache_chunk(m_cpos + DIR_UP<chunk_pos::value_type>); +} + +void GL_MeshingTask::process(void) +{ + m_quads_b.resize(world::voxel_atlas::plane_count()); + m_quads_s.resize(world::voxel_atlas::plane_count()); + + const auto& voxels = m_cache.at(CPOS_ITSELF); + + for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { + if(m_status == task_status::CANCELLED) { + m_quads_b.clear(); + m_quads_s.clear(); + return; + } + + const auto lpos = coord::to_local(i); + const auto voxel = world::voxel_registry::find(voxels[i]); + + if(voxel == nullptr) { + // Either a NULL_VOXEL_ID or something went + // horribly wrong and we don't what this is + continue; + } + + unsigned int vis = 0U; + + if(vis_test(voxel, lpos + DIR_NORTH<local_pos::value_type>)) { + vis |= world::VVIS_NORTH; + } + + if(vis_test(voxel, lpos + DIR_SOUTH<local_pos::value_type>)) { + vis |= world::VVIS_SOUTH; + } + + if(vis_test(voxel, lpos + DIR_EAST<local_pos::value_type>)) { + vis |= world::VVIS_EAST; + } + + if(vis_test(voxel, lpos + DIR_WEST<local_pos::value_type>)) { + vis |= world::VVIS_WEST; + } + + if(vis_test(voxel, lpos + DIR_UP<local_pos::value_type>)) { + vis |= world::VVIS_UP; + } + + if(vis_test(voxel, lpos + DIR_DOWN<local_pos::value_type>)) { + vis |= world::VVIS_DOWN; + } + + const auto vpos = coord::to_voxel(m_cpos, lpos); + const auto entropy_src = vpos[0] * vpos[1] * vpos[2]; + const auto entropy = math::crc64(&entropy_src, sizeof(entropy_src)); + + // FIXME: handle different voxel types + make_cube(voxel, lpos, world::VoxelVisBits(vis), entropy); + } +} + +void GL_MeshingTask::finalize(void) +{ + if(!globals::dimension || !globals::dimension->chunks.valid(m_entity)) { + // We either disconnected or something + // else happened that invalidated the entity + return; + } + + auto& component = globals::dimension->chunks.emplace_or_replace<world::ChunkMesh>(m_entity); + + const std::size_t plane_count_nb = m_quads_s.size(); + const std::size_t plane_count_b = m_quads_b.size(); + + bool has_no_submeshes_b = true; + bool has_no_submeshes_nb = true; + + component.quad_nb.resize(plane_count_nb); + component.quad_b.resize(plane_count_b); + + for(std::size_t plane = 0; plane < plane_count_nb; ++plane) { + auto& builder = m_quads_s[plane]; + auto& buffer = component.quad_nb[plane]; + + if(builder.empty()) { + if(buffer.handle) { + glDeleteBuffers(1, &buffer.handle); + buffer.handle = 0; + buffer.size = 0; + } + } + else { + if(!buffer.handle) { + glGenBuffers(1, &buffer.handle); + } + + glBindBuffer(GL_ARRAY_BUFFER, buffer.handle); + glBufferData(GL_ARRAY_BUFFER, sizeof(world::ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW); + buffer.size = builder.size(); + has_no_submeshes_nb = false; + } + } + + for(std::size_t plane = 0; plane < plane_count_b; ++plane) { + auto& builder = m_quads_b[plane]; + auto& buffer = component.quad_b[plane]; + + if(builder.empty()) { + if(buffer.handle) { + glDeleteBuffers(1, &buffer.handle); + buffer.handle = 0; + buffer.size = 0; + } + } + else { + if(!buffer.handle) { + glGenBuffers(1, &buffer.handle); + } + + glBindBuffer(GL_ARRAY_BUFFER, buffer.handle); + glBufferData(GL_ARRAY_BUFFER, sizeof(world::ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW); + buffer.size = builder.size(); + has_no_submeshes_b = false; + } + } + + if(has_no_submeshes_b && has_no_submeshes_nb) { + globals::dimension->chunks.remove<world::ChunkMesh>(m_entity); + } +} + +bool GL_MeshingTask::vis_test(const world::Voxel* voxel, const local_pos& lpos) const +{ + const auto pvpos = coord::to_voxel(m_cpos, lpos); + const auto pcpos = coord::to_chunk(pvpos); + const auto plpos = coord::to_local(pvpos); + const auto index = coord::to_index(plpos); + + const auto cached_cpos = get_cached_cpos(m_cpos, pcpos); + const auto& voxels = m_cache.at(cached_cpos); + const auto neighbour = world::voxel_registry::find(voxels[index]); + + bool result; + + if(neighbour == nullptr) { + result = true; + } + else if(neighbour == voxel) { + result = false; + } + else if(neighbour->get_render_mode() != voxel->get_render_mode()) { + result = true; + } + else { + result = false; + } + + return result; +} + +void GL_MeshingTask::push_quad_a(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face) +{ + auto cached_offset = voxel->get_cached_face_offset(face); + auto cached_plane = voxel->get_cached_face_plane(face); + auto& textures = voxel->get_face_textures(face); + + switch(voxel->get_render_mode()) { + case world::VRENDER_OPAQUE: + m_quads_s[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset, textures.size())); + break; + + case world::VRENDER_BLEND: + m_quads_b[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset, textures.size())); + break; + } +} + +void GL_MeshingTask::push_quad_v(const world::Voxel* voxel, const glm::fvec3& pos, const glm::fvec2& size, world::VoxelFace face, + std::size_t entropy) +{ + auto cached_offset = voxel->get_cached_face_offset(face); + auto cached_plane = voxel->get_cached_face_plane(face); + auto& textures = voxel->get_face_textures(face); + auto index = entropy % textures.size(); + + switch(voxel->get_render_mode()) { + case world::VRENDER_OPAQUE: + m_quads_s[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset + index, 0)); + break; + + case world::VRENDER_BLEND: + m_quads_b[cached_plane].push_back(make_chunk_quad(pos, size, face, cached_offset + index, 0)); + break; + } +} + +void GL_MeshingTask::make_cube(const world::Voxel* voxel, const local_pos& lpos, world::VoxelVisBits vis, std::size_t entropy) +{ + const glm::fvec3 fpos = glm::fvec3(lpos); + const glm::fvec2 fsize = glm::fvec2(1.0f, 1.0f); + + if(voxel->is_animated()) { + if(vis & world::VVIS_NORTH) { + push_quad_a(voxel, fpos, fsize, world::VFACE_NORTH); + } + + if(vis & world::VVIS_SOUTH) { + push_quad_a(voxel, fpos, fsize, world::VFACE_SOUTH); + } + + if(vis & world::VVIS_EAST) { + push_quad_a(voxel, fpos, fsize, world::VFACE_EAST); + } + + if(vis & world::VVIS_WEST) { + push_quad_a(voxel, fpos, fsize, world::VFACE_WEST); + } + + if(vis & world::VVIS_UP) { + push_quad_a(voxel, fpos, fsize, world::VFACE_TOP); + } + + if(vis & world::VVIS_DOWN) { + push_quad_a(voxel, fpos, fsize, world::VFACE_BOTTOM); + } + } + else { + if(vis & world::VVIS_NORTH) { + push_quad_v(voxel, fpos, fsize, world::VFACE_NORTH, entropy); + } + + if(vis & world::VVIS_SOUTH) { + push_quad_v(voxel, fpos, fsize, world::VFACE_SOUTH, entropy); + } + + if(vis & world::VVIS_EAST) { + push_quad_v(voxel, fpos, fsize, world::VFACE_EAST, entropy); + } + + if(vis & world::VVIS_WEST) { + push_quad_v(voxel, fpos, fsize, world::VFACE_WEST, entropy); + } + + if(vis & world::VVIS_UP) { + push_quad_v(voxel, fpos, fsize, world::VFACE_TOP, entropy); + } + + if(vis & world::VVIS_DOWN) { + push_quad_v(voxel, fpos, fsize, world::VFACE_BOTTOM, entropy); + } + } +} + +void GL_MeshingTask::cache_chunk(const chunk_pos& cpos) +{ + const auto index = get_cached_cpos(m_cpos, cpos); + + if(const auto chunk = globals::dimension->find_chunk(cpos)) { + m_cache[index] = chunk->get_voxels(); + return; + } +} + +// Bogus internal flag component +struct NeedsMeshingComponent final {}; + +static void on_chunk_create(const world::ChunkCreateEvent& event) +{ + const std::array<chunk_pos, 6> neighbours = { + event.cpos + DIR_NORTH<chunk_pos::value_type>, + event.cpos + DIR_SOUTH<chunk_pos::value_type>, + event.cpos + DIR_EAST<chunk_pos::value_type>, + event.cpos + DIR_WEST<chunk_pos::value_type>, + event.cpos + DIR_UP<chunk_pos::value_type>, + event.cpos + DIR_DOWN<chunk_pos::value_type>, + }; + + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity()); + + for(const chunk_pos& cpos : neighbours) { + if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) { + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity()); + continue; + } + } +} + +static void on_chunk_update(const world::ChunkUpdateEvent& event) +{ + const std::array<chunk_pos, 6> neighbours = { + event.cpos + DIR_NORTH<chunk_pos::value_type>, + event.cpos + DIR_SOUTH<chunk_pos::value_type>, + event.cpos + DIR_EAST<chunk_pos::value_type>, + event.cpos + DIR_WEST<chunk_pos::value_type>, + event.cpos + DIR_UP<chunk_pos::value_type>, + event.cpos + DIR_DOWN<chunk_pos::value_type>, + }; + + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity()); + + for(const chunk_pos& cpos : neighbours) { + if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) { + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity()); + continue; + } + } +} + +static void on_voxel_set(const world::VoxelSetEvent& event) +{ + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity()); + + std::vector<chunk_pos> neighbours; + + for(int dim = 0; dim < 3; dim += 1) { + chunk_pos offset = chunk_pos(0, 0, 0); + offset[dim] = 1; + + if(event.lpos[dim] == 0) { + neighbours.push_back(event.cpos - offset); + continue; + } + + if(event.lpos[dim] == (CHUNK_SIZE - 1)) { + neighbours.push_back(event.cpos + offset); + continue; + } + } + + for(const chunk_pos& cpos : neighbours) { + if(const world::Chunk* chunk = globals::dimension->find_chunk(cpos)) { + globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity()); + continue; + } + } +} + +void world::chunk_mesher::init(void) +{ + globals::dispatcher.sink<ChunkCreateEvent>().connect<&on_chunk_create>(); + globals::dispatcher.sink<ChunkUpdateEvent>().connect<&on_chunk_update>(); + globals::dispatcher.sink<VoxelSetEvent>().connect<&on_voxel_set>(); +} + +void world::chunk_mesher::shutdown(void) +{ +} + +void world::chunk_mesher::update(void) +{ + if(session::is_ingame()) { + const auto group = globals::dimension->chunks.group<NeedsMeshingComponent>(entt::get<ChunkComponent>); + for(const auto [entity, chunk] : group.each()) { + globals::dimension->chunks.remove<NeedsMeshingComponent>(entity); + threading::submit<GL_MeshingTask>(entity, chunk.cpos); + } + } +} diff --git a/game/client/world/chunk_mesher.hh b/src/game/client/world/chunk_mesher.hh index 1ef5035..cb0c7c5 100644 --- a/game/client/world/chunk_mesher.hh +++ b/src/game/client/world/chunk_mesher.hh @@ -1,18 +1,18 @@ -#pragma once
-
-#include "client/world/chunk_vbo.hh"
-
-namespace world
-{
-struct ChunkMesh final {
- std::vector<ChunkVBO> quad_nb;
- std::vector<ChunkVBO> quad_b;
-};
-} // namespace world
-
-namespace world::chunk_mesher
-{
-void init(void);
-void shutdown(void);
-void update(void);
-} // namespace world::chunk_mesher
+#pragma once + +#include "client/world/chunk_vbo.hh" + +namespace world +{ +struct ChunkMesh final { + std::vector<ChunkVBO> quad_nb; + std::vector<ChunkVBO> quad_b; +}; +} // namespace world + +namespace world::chunk_mesher +{ +void init(void); +void shutdown(void); +void update(void); +} // namespace world::chunk_mesher diff --git a/game/client/world/chunk_quad.hh b/src/game/client/world/chunk_quad.hh index d68977e..01ed5f2 100644 --- a/game/client/world/chunk_quad.hh +++ b/src/game/client/world/chunk_quad.hh @@ -1,41 +1,41 @@ -#pragma once
-
-#include "core/math/constexpr.hh"
-
-#include "shared/world/voxel_registry.hh"
-
-namespace world
-{
-// [0] XXXXXXXXYYYYYYYYZZZZZZZZWWWWHHHH
-// [1] FFFFTTTTTTTTTTTAAAAA------------
-using ChunkQuad = std::array<std::uint32_t, 2>;
-} // namespace world
-
-namespace world
-{
-constexpr inline static ChunkQuad make_chunk_quad(const glm::fvec3& position, const glm::fvec2& size, VoxelFace face, std::size_t texture,
- std::size_t frames)
-{
- ChunkQuad result = {};
- result[0] = 0x00000000;
- result[1] = 0x00000000;
-
- // [0] XXXXXXXXYYYYYYYYZZZZZZZZ--------
- result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.x * 16.0f)) << 24U;
- result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.y * 16.0f)) << 16U;
- result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.z * 16.0f)) << 8U;
-
- // [0] ------------------------WWWWHHHH
- result[0] |= (0x0000000FU & static_cast<std::uint32_t>(size.x * 16.0f - 1.0f)) << 4U;
- result[0] |= (0x0000000FU & static_cast<std::uint32_t>(size.y * 16.0f - 1.0f));
-
- // [1] FFFF----------------------------
- result[1] |= (0x0000000FU & static_cast<std::uint32_t>(face)) << 28U;
-
- // [1] ----TTTTTTTTTTTAAAAA------------
- result[1] |= (0x000007FFU & static_cast<std::uint32_t>(texture)) << 17U;
- result[1] |= (0x0000001FU & static_cast<std::uint32_t>(frames)) << 12U;
-
- return result;
-}
-} // namespace world
+#pragma once + +#include "core/math/constexpr.hh" + +#include "shared/world/voxel_registry.hh" + +namespace world +{ +// [0] XXXXXXXXYYYYYYYYZZZZZZZZWWWWHHHH +// [1] FFFFTTTTTTTTTTTAAAAA------------ +using ChunkQuad = std::array<std::uint32_t, 2>; +} // namespace world + +namespace world +{ +constexpr inline static ChunkQuad make_chunk_quad(const glm::fvec3& position, const glm::fvec2& size, VoxelFace face, std::size_t texture, + std::size_t frames) +{ + ChunkQuad result = {}; + result[0] = 0x00000000; + result[1] = 0x00000000; + + // [0] XXXXXXXXYYYYYYYYZZZZZZZZ-------- + result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.x * 16.0f)) << 24U; + result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.y * 16.0f)) << 16U; + result[0] |= (0x000000FFU & static_cast<std::uint32_t>(position.z * 16.0f)) << 8U; + + // [0] ------------------------WWWWHHHH + result[0] |= (0x0000000FU & static_cast<std::uint32_t>(size.x * 16.0f - 1.0f)) << 4U; + result[0] |= (0x0000000FU & static_cast<std::uint32_t>(size.y * 16.0f - 1.0f)); + + // [1] FFFF---------------------------- + result[1] |= (0x0000000FU & static_cast<std::uint32_t>(face)) << 28U; + + // [1] ----TTTTTTTTTTTAAAAA------------ + result[1] |= (0x000007FFU & static_cast<std::uint32_t>(texture)) << 17U; + result[1] |= (0x0000001FU & static_cast<std::uint32_t>(frames)) << 12U; + + return result; +} +} // namespace world diff --git a/game/client/world/chunk_renderer.cc b/src/game/client/world/chunk_renderer.cc index 1b195d7..573d1b7 100644 --- a/game/client/world/chunk_renderer.cc +++ b/src/game/client/world/chunk_renderer.cc @@ -1,204 +1,205 @@ -#include "client/pch.hh"
-
-#include "client/world/chunk_renderer.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/world/chunk_mesher.hh"
-#include "client/world/chunk_quad.hh"
-#include "client/world/outline.hh"
-#include "client/world/skybox.hh"
-#include "client/world/voxel_anims.hh"
-#include "client/world/voxel_atlas.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/program.hh"
-#include "client/toggles.hh"
-
-// ONLY TOUCH THESE IF THE RESPECTIVE SHADER
-// VARIANT MACRO DECLARATIONS LAYOUT CHANGED AS WELL
-constexpr static unsigned int WORLD_CURVATURE = 0U;
-constexpr static unsigned int WORLD_FOG = 1U;
-
-static config::Boolean depth_sort_chunks(true);
-
-static GL_Program quad_program;
-static std::size_t u_quad_vproj_matrix;
-static std::size_t u_quad_world_position;
-static std::size_t u_quad_timings;
-static std::size_t u_quad_fog_color;
-static std::size_t u_quad_view_distance;
-static std::size_t u_quad_textures;
-static GLuint quad_vaobj;
-static GLuint quad_vbo;
-
-void world::chunk_renderer::init(void)
-{
- globals::client_config.add_value("chunk_renderer.depth_sort_chunks", depth_sort_chunks);
-
- settings::add_checkbox(5, depth_sort_chunks, settings_location::VIDEO, "chunk_renderer.depth_sort_chunks", false);
-
- if(!quad_program.setup("shaders/chunk_quad.vert", "shaders/chunk_quad.frag")) {
- spdlog::critical("chunk_renderer: quad_program: setup failed");
- std::terminate();
- }
-
- u_quad_vproj_matrix = quad_program.add_uniform("u_ViewProjMatrix");
- u_quad_world_position = quad_program.add_uniform("u_WorldPosition");
- u_quad_timings = quad_program.add_uniform("u_Timings");
- u_quad_fog_color = quad_program.add_uniform("u_FogColor");
- u_quad_view_distance = quad_program.add_uniform("u_ViewDistance");
- u_quad_textures = quad_program.add_uniform("u_Textures");
-
- const glm::fvec3 vertices[4] = {
- glm::fvec3(1.0f, 0.0f, 1.0f),
- glm::fvec3(1.0f, 0.0f, 0.0f),
- glm::fvec3(0.0f, 0.0f, 1.0f),
- glm::fvec3(0.0f, 0.0f, 0.0f),
- };
-
- glGenVertexArrays(1, &quad_vaobj);
- glBindVertexArray(quad_vaobj);
-
- glGenBuffers(1, &quad_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- glEnableVertexAttribArray(0);
- glVertexAttribDivisor(0, 0);
- glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr);
-}
-
-void world::chunk_renderer::shutdown(void)
-{
- glDeleteBuffers(1, &quad_vbo);
- glDeleteVertexArrays(1, &quad_vaobj);
- quad_program.destroy();
-}
-
-void world::chunk_renderer::render(void)
-{
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glLineWidth(1.0f);
-
- if(toggles::get(TOGGLE_WIREFRAME)) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- }
- else {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-
- quad_program.set_variant_vert(WORLD_CURVATURE, client_game::world_curvature.get_value());
- quad_program.set_variant_vert(WORLD_FOG, client_game::fog_mode.get_value());
- quad_program.set_variant_frag(WORLD_FOG, client_game::fog_mode.get_value());
-
- if(!quad_program.update()) {
- spdlog::critical("chunk_renderer: quad_program: update failed");
- quad_program.destroy();
- std::terminate();
- }
-
- GLuint timings[3];
- timings[0] = globals::window_frametime;
- timings[1] = globals::window_frametime_avg;
- timings[2] = world::voxel_anims::frame;
-
- const auto group = globals::dimension->chunks.group<ChunkComponent>(entt::get<world::ChunkMesh>);
-
- if(depth_sort_chunks.get_value()) {
- // FIXME: speed! sorting every frame doesn't look
- // like a good idea. Can we store the group elsewhere and
- // still have all the up-to-date chunk things inside?
- group.sort([](entt::entity ea, entt::entity eb) {
- const auto dir_a = globals::dimension->chunks.get<ChunkComponent>(ea).cpos - entity::camera::position_chunk;
- const auto dir_b = globals::dimension->chunks.get<ChunkComponent>(eb).cpos - entity::camera::position_chunk;
-
- const auto da = dir_a[0] * dir_a[0] + dir_a[1] * dir_a[1] + dir_a[2] * dir_a[2];
- const auto db = dir_b[0] * dir_b[0] + dir_b[1] * dir_b[1] + dir_b[2] * dir_b[2];
-
- return da > db;
- });
- }
-
- for(std::size_t plane_id = 0; plane_id < world::voxel_atlas::plane_count(); ++plane_id) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D_ARRAY, world::voxel_atlas::plane_texture(plane_id));
-
- glBindVertexArray(quad_vaobj);
-
- glUseProgram(quad_program.handle);
- glUniformMatrix4fv(quad_program.uniforms[u_quad_vproj_matrix].location, 1, false, glm::value_ptr(entity::camera::matrix));
- glUniform3uiv(quad_program.uniforms[u_quad_timings].location, 1, timings);
- glUniform4fv(quad_program.uniforms[u_quad_fog_color].location, 1, glm::value_ptr(world::skybox::fog_color));
- glUniform1f(quad_program.uniforms[u_quad_view_distance].location, entity::camera::view_distance.get_value() * CHUNK_SIZE);
- glUniform1i(quad_program.uniforms[u_quad_textures].location, 0); // GL_TEXTURE0
-
- glDisable(GL_BLEND);
-
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- glFrontFace(GL_CCW);
-
- for(const auto [entity, chunk, mesh] : group.each()) {
- if(plane_id < mesh.quad_nb.size() && mesh.quad_nb[plane_id].handle && mesh.quad_nb[plane_id].size) {
- const auto wpos = coord::to_fvec3(chunk.cpos - entity::camera::position_chunk);
- glUniform3fv(quad_program.uniforms[u_quad_world_position].location, 1, glm::value_ptr(wpos));
-
- glBindBuffer(GL_ARRAY_BUFFER, mesh.quad_nb[plane_id].handle);
-
- glEnableVertexAttribArray(1);
- glVertexAttribDivisor(1, 1);
- glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, sizeof(ChunkQuad), nullptr);
-
- glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, mesh.quad_nb[plane_id].size);
-
- globals::num_drawcalls += 1;
- globals::num_triangles += 2 * mesh.quad_nb[plane_id].size;
- }
- }
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- for(const auto [entity, chunk, mesh] : group.each()) {
- if(plane_id < mesh.quad_b.size() && mesh.quad_b[plane_id].handle && mesh.quad_b[plane_id].size) {
- const auto wpos = coord::to_fvec3(chunk.cpos - entity::camera::position_chunk);
- glUniform3fv(quad_program.uniforms[u_quad_world_position].location, 1, glm::value_ptr(wpos));
-
- glBindBuffer(GL_ARRAY_BUFFER, mesh.quad_b[plane_id].handle);
-
- glEnableVertexAttribArray(1);
- glVertexAttribDivisor(1, 1);
- glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, sizeof(ChunkQuad), nullptr);
-
- glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, mesh.quad_b[plane_id].size);
-
- globals::num_drawcalls += 1;
- globals::num_triangles += 2 * mesh.quad_b[plane_id].size;
- }
- }
- }
-
- if(toggles::get(TOGGLE_CHUNK_AABB)) {
- world::outline::prepare();
-
- for(const auto [entity, chunk, mesh] : group.each()) {
- const auto size = glm::fvec3(CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);
- world::outline::cube(chunk.cpos, glm::fvec3(0.0f, 0.0f, 0.0f), size, 1.0f, glm::fvec4(1.0f, 1.0f, 0.0f, 1.0f));
- }
- }
-}
+#include "client/pch.hh" + +#include "client/world/chunk_renderer.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +#include "client/entity/camera.hh" + +#include "client/gui/settings.hh" + +#include "client/world/chunk_mesher.hh" +#include "client/world/chunk_quad.hh" +#include "client/world/outline.hh" +#include "client/world/skybox.hh" +#include "client/world/voxel_anims.hh" +#include "client/world/voxel_atlas.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/program.hh" +#include "client/toggles.hh" + +// ONLY TOUCH THESE IF THE RESPECTIVE SHADER +// VARIANT MACRO DECLARATIONS LAYOUT CHANGED AS WELL +constexpr static unsigned int WORLD_CURVATURE = 0U; +constexpr static unsigned int WORLD_FOG = 1U; + +static config::Boolean depth_sort_chunks(true); + +static GL_Program quad_program; +static std::size_t u_quad_vproj_matrix; +static std::size_t u_quad_world_position; +static std::size_t u_quad_timings; +static std::size_t u_quad_fog_color; +static std::size_t u_quad_view_distance; +static std::size_t u_quad_textures; +static GLuint quad_vaobj; +static GLuint quad_vbo; + +void world::chunk_renderer::init(void) +{ + globals::client_config.add_value("chunk_renderer.depth_sort_chunks", depth_sort_chunks); + + settings::add_checkbox(5, depth_sort_chunks, settings_location::VIDEO, "chunk_renderer.depth_sort_chunks", false); + + if(!quad_program.setup("shaders/chunk_quad.vert", "shaders/chunk_quad.frag")) { + spdlog::critical("chunk_renderer: quad_program: setup failed"); + std::terminate(); + } + + u_quad_vproj_matrix = quad_program.add_uniform("u_ViewProjMatrix"); + u_quad_world_position = quad_program.add_uniform("u_WorldPosition"); + u_quad_timings = quad_program.add_uniform("u_Timings"); + u_quad_fog_color = quad_program.add_uniform("u_FogColor"); + u_quad_view_distance = quad_program.add_uniform("u_ViewDistance"); + u_quad_textures = quad_program.add_uniform("u_Textures"); + + const glm::fvec3 vertices[4] = { + glm::fvec3(1.0f, 0.0f, 1.0f), + glm::fvec3(1.0f, 0.0f, 0.0f), + glm::fvec3(0.0f, 0.0f, 1.0f), + glm::fvec3(0.0f, 0.0f, 0.0f), + }; + + glGenVertexArrays(1, &quad_vaobj); + glBindVertexArray(quad_vaobj); + + glGenBuffers(1, &quad_vbo); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribDivisor(0, 0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr); +} + +void world::chunk_renderer::shutdown(void) +{ + glDeleteBuffers(1, &quad_vbo); + glDeleteVertexArrays(1, &quad_vaobj); + quad_program.destroy(); +} + +void world::chunk_renderer::render(void) +{ + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glLineWidth(1.0f); + + if(toggles::get(TOGGLE_WIREFRAME)) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + quad_program.set_variant_vert(WORLD_CURVATURE, client_game::world_curvature.get_value()); + quad_program.set_variant_vert(WORLD_FOG, client_game::fog_mode.get_value()); + quad_program.set_variant_frag(WORLD_FOG, client_game::fog_mode.get_value()); + + if(!quad_program.update()) { + spdlog::critical("chunk_renderer: quad_program: update failed"); + quad_program.destroy(); + std::terminate(); + } + + GLuint timings[3]; + timings[0] = static_cast<GLuint>(globals::window_frametime); + timings[1] = static_cast<GLuint>(globals::window_frametime_avg); + timings[2] = static_cast<GLuint>(world::voxel_anims::frame); + + const auto group = globals::dimension->chunks.group<ChunkComponent>(entt::get<world::ChunkMesh>); + + if(depth_sort_chunks.get_value()) { + // FIXME: speed! sorting every frame doesn't look + // like a good idea. Can we store the group elsewhere and + // still have all the up-to-date chunk things inside? + group.sort([](entt::entity ea, entt::entity eb) { + const auto dir_a = globals::dimension->chunks.get<ChunkComponent>(ea).cpos - entity::camera::position_chunk; + const auto dir_b = globals::dimension->chunks.get<ChunkComponent>(eb).cpos - entity::camera::position_chunk; + + const auto da = dir_a[0] * dir_a[0] + dir_a[1] * dir_a[1] + dir_a[2] * dir_a[2]; + const auto db = dir_b[0] * dir_b[0] + dir_b[1] * dir_b[1] + dir_b[2] * dir_b[2]; + + return da > db; + }); + } + + for(std::size_t plane_id = 0; plane_id < world::voxel_atlas::plane_count(); ++plane_id) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D_ARRAY, world::voxel_atlas::plane_texture(plane_id)); + + glBindVertexArray(quad_vaobj); + + glUseProgram(quad_program.handle); + glUniformMatrix4fv(quad_program.uniforms[u_quad_vproj_matrix].location, 1, false, glm::value_ptr(entity::camera::matrix)); + glUniform3uiv(quad_program.uniforms[u_quad_timings].location, 1, timings); + glUniform4fv(quad_program.uniforms[u_quad_fog_color].location, 1, glm::value_ptr(world::skybox::fog_color)); + glUniform1f(quad_program.uniforms[u_quad_view_distance].location, + static_cast<GLfloat>(entity::camera::view_distance.get_value() * CHUNK_SIZE)); + glUniform1i(quad_program.uniforms[u_quad_textures].location, 0); // GL_TEXTURE0 + + glDisable(GL_BLEND); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + + for(const auto [entity, chunk, mesh] : group.each()) { + if(plane_id < mesh.quad_nb.size() && mesh.quad_nb[plane_id].handle && mesh.quad_nb[plane_id].size) { + const auto wpos = coord::to_fvec3(chunk.cpos - entity::camera::position_chunk); + glUniform3fv(quad_program.uniforms[u_quad_world_position].location, 1, glm::value_ptr(wpos)); + + glBindBuffer(GL_ARRAY_BUFFER, mesh.quad_nb[plane_id].handle); + + glEnableVertexAttribArray(1); + glVertexAttribDivisor(1, 1); + glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, sizeof(ChunkQuad), nullptr); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, static_cast<GLsizei>(mesh.quad_nb[plane_id].size)); + + globals::num_drawcalls += 1; + globals::num_triangles += 2 * mesh.quad_nb[plane_id].size; + } + } + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + for(const auto [entity, chunk, mesh] : group.each()) { + if(plane_id < mesh.quad_b.size() && mesh.quad_b[plane_id].handle && mesh.quad_b[plane_id].size) { + const auto wpos = coord::to_fvec3(chunk.cpos - entity::camera::position_chunk); + glUniform3fv(quad_program.uniforms[u_quad_world_position].location, 1, glm::value_ptr(wpos)); + + glBindBuffer(GL_ARRAY_BUFFER, mesh.quad_b[plane_id].handle); + + glEnableVertexAttribArray(1); + glVertexAttribDivisor(1, 1); + glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, sizeof(ChunkQuad), nullptr); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, static_cast<GLsizei>(mesh.quad_b[plane_id].size)); + + globals::num_drawcalls += 1; + globals::num_triangles += 2 * mesh.quad_b[plane_id].size; + } + } + } + + if(toggles::get(TOGGLE_CHUNK_AABB)) { + world::outline::prepare(); + + for(const auto [entity, chunk, mesh] : group.each()) { + const auto size = glm::fvec3(CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE); + world::outline::cube(chunk.cpos, glm::fvec3(0.0f, 0.0f, 0.0f), size, 1.0f, glm::fvec4(1.0f, 1.0f, 0.0f, 1.0f)); + } + } +} diff --git a/game/client/world/chunk_renderer.hh b/src/game/client/world/chunk_renderer.hh index 88b381f..2b73225 100644 --- a/game/client/world/chunk_renderer.hh +++ b/src/game/client/world/chunk_renderer.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace world::chunk_renderer
-{
-void init(void);
-void shutdown(void);
-void render(void);
-} // namespace world::chunk_renderer
+#pragma once + +namespace world::chunk_renderer +{ +void init(void); +void shutdown(void); +void render(void); +} // namespace world::chunk_renderer diff --git a/game/client/world/chunk_vbo.hh b/src/game/client/world/chunk_vbo.hh index 9fedf0d..175b34f 100644 --- a/game/client/world/chunk_vbo.hh +++ b/src/game/client/world/chunk_vbo.hh @@ -1,22 +1,22 @@ -#pragma once
-
-namespace world
-{
-class ChunkVBO final {
-public:
- std::size_t size;
- GLuint handle;
-
-public:
- inline ~ChunkVBO(void)
- {
- // The ChunkVBO structure is meant to be a part
- // of the ChunkMesh component within the EnTT registry;
- // When the registry is cleaned or a chunk is removed, components
- // are expected to be safely disposed of so we need a destructor;
- if(handle) {
- glDeleteBuffers(1, &handle);
- }
- }
-};
-} // namespace world
+#pragma once + +namespace world +{ +class ChunkVBO final { +public: + std::size_t size; + GLuint handle; + +public: + inline ~ChunkVBO(void) + { + // The ChunkVBO structure is meant to be a part + // of the ChunkMesh component within the EnTT registry; + // When the registry is cleaned or a chunk is removed, components + // are expected to be safely disposed of so we need a destructor; + if(handle) { + glDeleteBuffers(1, &handle); + } + } +}; +} // namespace world diff --git a/game/client/world/chunk_visibility.cc b/src/game/client/world/chunk_visibility.cc index e8828ee..871c04b 100644 --- a/game/client/world/chunk_visibility.cc +++ b/src/game/client/world/chunk_visibility.cc @@ -1,90 +1,90 @@ -#include "client/pch.hh"
-
-#include "client/world/chunk_visibility.hh"
-
-#include "core/config/number.hh"
-
-#include "core/math/vectors.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/chunk_aabb.hh"
-#include "shared/world/dimension.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-// Sending a somewhat large amount of network packets
-// can easily overwhelm both client, server and the network
-// channel created between the two. To prevent this from happening
-// we throttle the client's ever increasing itch for new chunks
-constexpr static unsigned int MAX_CHUNKS_REQUESTS_PER_FRAME = 16U;
-
-static world::ChunkAABB current_view_box;
-static world::ChunkAABB previous_view_box;
-static std::vector<chunk_pos> requests;
-
-static void update_requests(void)
-{
- requests.clear();
-
- for(auto cx = current_view_box.min.x; cx != current_view_box.max.x; cx += 1)
- for(auto cy = current_view_box.min.y; cy != current_view_box.max.y; cy += 1)
- for(auto cz = current_view_box.min.z; cz != current_view_box.max.z; cz += 1) {
- auto cpos = chunk_pos(cx, cy, cz);
-
- if(!globals::dimension->find_chunk(cpos)) {
- requests.push_back(cpos);
- }
- }
-
- std::sort(requests.begin(), requests.end(), [](const chunk_pos& cpos_a, const chunk_pos& cpos_b) {
- auto da = math::distance2(cpos_a, entity::camera::position_chunk);
- auto db = math::distance2(cpos_b, entity::camera::position_chunk);
- return da > db;
- });
-}
-
-void world::chunk_visibility::update_late(void)
-{
- current_view_box.min = entity::camera::position_chunk - static_cast<chunk_pos::value_type>(entity::camera::view_distance.get_value());
- current_view_box.max = entity::camera::position_chunk + static_cast<chunk_pos::value_type>(entity::camera::view_distance.get_value());
-
- if(!session::is_ingame()) {
- // This makes sure the previous view box
- // is always different from the current one
- previous_view_box.min = chunk_pos(INT32_MIN, INT32_MIN, INT32_MIN);
- previous_view_box.max = chunk_pos(INT32_MAX, INT32_MAX, INT32_MAX);
- return;
- }
-
- if((current_view_box.min != previous_view_box.min) || (current_view_box.max != previous_view_box.max)) {
- update_requests();
- }
-
- for(unsigned int i = 0U; i < MAX_CHUNKS_REQUESTS_PER_FRAME; ++i) {
- if(requests.empty()) {
- // Done sending requests
- break;
- }
-
- protocol::RequestChunk packet;
- packet.cpos = requests.back();
- protocol::send(session::peer, protocol::encode(packet));
-
- requests.pop_back();
- }
-
- auto view = globals::dimension->chunks.view<ChunkComponent>();
-
- for(const auto [entity, chunk] : view.each()) {
- if(!current_view_box.contains(chunk.cpos)) {
- globals::dimension->remove_chunk(entity);
- }
- }
-
- previous_view_box = current_view_box;
-}
+#include "client/pch.hh" + +#include "client/world/chunk_visibility.hh" + +#include "core/config/number.hh" + +#include "core/math/vectors.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/chunk_aabb.hh" +#include "shared/world/dimension.hh" + +#include "shared/protocol.hh" + +#include "client/entity/camera.hh" + +#include "client/globals.hh" +#include "client/session.hh" + +// Sending a somewhat large amount of network packets +// can easily overwhelm both client, server and the network +// channel created between the two. To prevent this from happening +// we throttle the client's ever increasing itch for new chunks +constexpr static unsigned int MAX_CHUNKS_REQUESTS_PER_FRAME = 16U; + +static world::ChunkAABB current_view_box; +static world::ChunkAABB previous_view_box; +static std::vector<chunk_pos> requests; + +static void update_requests(void) +{ + requests.clear(); + + for(auto cx = current_view_box.min.x; cx != current_view_box.max.x; cx += 1) + for(auto cy = current_view_box.min.y; cy != current_view_box.max.y; cy += 1) + for(auto cz = current_view_box.min.z; cz != current_view_box.max.z; cz += 1) { + auto cpos = chunk_pos(cx, cy, cz); + + if(!globals::dimension->find_chunk(cpos)) { + requests.push_back(cpos); + } + } + + std::sort(requests.begin(), requests.end(), [](const chunk_pos& cpos_a, const chunk_pos& cpos_b) { + auto da = math::distance2(cpos_a, entity::camera::position_chunk); + auto db = math::distance2(cpos_b, entity::camera::position_chunk); + return da > db; + }); +} + +void world::chunk_visibility::update_late(void) +{ + current_view_box.min = entity::camera::position_chunk - static_cast<chunk_pos::value_type>(entity::camera::view_distance.get_value()); + current_view_box.max = entity::camera::position_chunk + static_cast<chunk_pos::value_type>(entity::camera::view_distance.get_value()); + + if(!session::is_ingame()) { + // This makes sure the previous view box + // is always different from the current one + previous_view_box.min = chunk_pos(INT32_MIN, INT32_MIN, INT32_MIN); + previous_view_box.max = chunk_pos(INT32_MAX, INT32_MAX, INT32_MAX); + return; + } + + if((current_view_box.min != previous_view_box.min) || (current_view_box.max != previous_view_box.max)) { + update_requests(); + } + + for(unsigned int i = 0U; i < MAX_CHUNKS_REQUESTS_PER_FRAME; ++i) { + if(requests.empty()) { + // Done sending requests + break; + } + + protocol::RequestChunk packet; + packet.cpos = requests.back(); + protocol::send(session::peer, protocol::encode(packet)); + + requests.pop_back(); + } + + auto view = globals::dimension->chunks.view<ChunkComponent>(); + + for(const auto [entity, chunk] : view.each()) { + if(!current_view_box.contains(chunk.cpos)) { + globals::dimension->remove_chunk(entity); + } + } + + previous_view_box = current_view_box; +} diff --git a/game/client/world/chunk_visibility.hh b/src/game/client/world/chunk_visibility.hh index e9b2d89..8d1f3cd 100644 --- a/game/client/world/chunk_visibility.hh +++ b/src/game/client/world/chunk_visibility.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace world::chunk_visibility
-{
-void update_late(void);
-} // namespace world::chunk_visibility
+#pragma once + +namespace world::chunk_visibility +{ +void update_late(void); +} // namespace world::chunk_visibility diff --git a/game/client/world/outline.cc b/src/game/client/world/outline.cc index 62f9624..763debf 100644 --- a/game/client/world/outline.cc +++ b/src/game/client/world/outline.cc @@ -1,150 +1,150 @@ -#include "client/pch.hh"
-
-#include "client/world/outline.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/const.hh"
-#include "client/game.hh"
-#include "client/program.hh"
-
-// ONLY TOUCH THESE IF THE RESPECTIVE SHADER
-// VARIANT MACRO DECLARATIONS LAYOUT CHANGED AS WELL
-constexpr static unsigned int WORLD_CURVATURE = 0U;
-
-static GL_Program program;
-static std::size_t u_vpmatrix;
-static std::size_t u_worldpos;
-static std::size_t u_viewdist;
-static std::size_t u_modulate;
-static std::size_t u_scale;
-
-static GLuint vaobj;
-static GLuint cube_vbo;
-static GLuint line_vbo;
-
-void world::outline::init(void)
-{
- if(!program.setup("shaders/outline.vert", "shaders/outline.frag")) {
- spdlog::critical("outline: program setup failed");
- std::terminate();
- }
-
- u_vpmatrix = program.add_uniform("u_ViewProjMatrix");
- u_worldpos = program.add_uniform("u_WorldPosition");
- u_viewdist = program.add_uniform("u_ViewDistance");
- u_modulate = program.add_uniform("u_Modulate");
- u_scale = program.add_uniform("u_Scale");
-
- const glm::fvec3 cube_vertices[24] = {
- glm::fvec3(0.0f, 0.0f, 0.0f),
- glm::fvec3(0.0f, 1.0f, 0.0f),
- glm::fvec3(0.0f, 1.0f, 0.0f),
- glm::fvec3(1.0f, 1.0f, 0.0f),
- glm::fvec3(1.0f, 1.0f, 0.0f),
- glm::fvec3(1.0f, 0.0f, 0.0f),
- glm::fvec3(1.0f, 0.0f, 0.0f),
- glm::fvec3(0.0f, 0.0f, 0.0f),
-
- glm::fvec3(0.0f, 0.0f, 1.0f),
- glm::fvec3(0.0f, 1.0f, 1.0f),
- glm::fvec3(0.0f, 1.0f, 1.0f),
- glm::fvec3(1.0f, 1.0f, 1.0f),
- glm::fvec3(1.0f, 1.0f, 1.0f),
- glm::fvec3(1.0f, 0.0f, 1.0f),
- glm::fvec3(1.0f, 0.0f, 1.0f),
- glm::fvec3(0.0f, 0.0f, 1.0f),
-
- glm::fvec3(0.0f, 0.0f, 0.0f),
- glm::fvec3(0.0f, 0.0f, 1.0f),
- glm::fvec3(0.0f, 1.0f, 0.0f),
- glm::fvec3(0.0f, 1.0f, 1.0f),
- glm::fvec3(1.0f, 0.0f, 0.0f),
- glm::fvec3(1.0f, 0.0f, 1.0f),
- glm::fvec3(1.0f, 1.0f, 0.0f),
- glm::fvec3(1.0f, 1.0f, 1.0f),
- };
-
- glGenBuffers(1, &cube_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
-
- const glm::fvec3 line_vertices[2] = {
- glm::fvec3(0.0f, 0.0f, 0.0f),
- glm::fvec3(1.0f, 1.0f, 1.0f),
- };
-
- glGenBuffers(1, &line_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, line_vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(line_vertices), line_vertices, GL_STATIC_DRAW);
-
- glGenVertexArrays(1, &vaobj);
-
- glBindVertexArray(vaobj);
- glEnableVertexAttribArray(0);
- glVertexAttribDivisor(0, 0);
-}
-
-void world::outline::shutdown(void)
-{
- glDeleteVertexArrays(1, &vaobj);
- glDeleteBuffers(1, &line_vbo);
- glDeleteBuffers(1, &cube_vbo);
- program.destroy();
-}
-
-void world::outline::prepare(void)
-{
- program.set_variant_vert(WORLD_CURVATURE, client_game::world_curvature.get_value());
-
- if(!program.update()) {
- spdlog::critical("outline_renderer: program update failed");
- std::terminate();
- }
-
- glDisable(GL_CULL_FACE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
- glUseProgram(program.handle);
- glUniformMatrix4fv(program.uniforms[u_vpmatrix].location, 1, false, glm::value_ptr(entity::camera::matrix));
- glUniform1f(program.uniforms[u_viewdist].location, CHUNK_SIZE * entity::camera::view_distance.get_value());
-
- glBindVertexArray(vaobj);
- glEnableVertexAttribArray(0);
- glVertexAttribDivisor(0, 0);
-}
-
-void world::outline::cube(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color)
-{
- auto patch_cpos = cpos - entity::camera::position_chunk;
-
- glLineWidth(thickness);
-
- glUniform3fv(program.uniforms[u_worldpos].location, 1, glm::value_ptr(coord::to_fvec3(patch_cpos, fpos)));
- glUniform4fv(program.uniforms[u_modulate].location, 1, glm::value_ptr(color));
- glUniform3fv(program.uniforms[u_scale].location, 1, glm::value_ptr(size));
-
- glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
- glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr);
- glDrawArrays(GL_LINES, 0, 24);
-}
-
-void world::outline::line(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color)
-{
- auto patch_cpos = cpos - entity::camera::position_chunk;
-
- glLineWidth(thickness);
-
- glUniform3fv(program.uniforms[u_worldpos].location, 1, glm::value_ptr(coord::to_fvec3(patch_cpos, fpos)));
- glUniform4fv(program.uniforms[u_modulate].location, 1, glm::value_ptr(color));
- glUniform3fv(program.uniforms[u_scale].location, 1, glm::value_ptr(size));
-
- glBindBuffer(GL_ARRAY_BUFFER, line_vbo);
- glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr);
- glDrawArrays(GL_LINES, 0, 2);
-}
+#include "client/pch.hh" + +#include "client/world/outline.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" + +#include "shared/coord.hh" + +#include "client/entity/camera.hh" + +#include "client/const.hh" +#include "client/game.hh" +#include "client/program.hh" + +// ONLY TOUCH THESE IF THE RESPECTIVE SHADER +// VARIANT MACRO DECLARATIONS LAYOUT CHANGED AS WELL +constexpr static unsigned int WORLD_CURVATURE = 0U; + +static GL_Program program; +static std::size_t u_vpmatrix; +static std::size_t u_worldpos; +static std::size_t u_viewdist; +static std::size_t u_modulate; +static std::size_t u_scale; + +static GLuint vaobj; +static GLuint cube_vbo; +static GLuint line_vbo; + +void world::outline::init(void) +{ + if(!program.setup("shaders/outline.vert", "shaders/outline.frag")) { + spdlog::critical("outline: program setup failed"); + std::terminate(); + } + + u_vpmatrix = program.add_uniform("u_ViewProjMatrix"); + u_worldpos = program.add_uniform("u_WorldPosition"); + u_viewdist = program.add_uniform("u_ViewDistance"); + u_modulate = program.add_uniform("u_Modulate"); + u_scale = program.add_uniform("u_Scale"); + + const glm::fvec3 cube_vertices[24] = { + glm::fvec3(0.0f, 0.0f, 0.0f), + glm::fvec3(0.0f, 1.0f, 0.0f), + glm::fvec3(0.0f, 1.0f, 0.0f), + glm::fvec3(1.0f, 1.0f, 0.0f), + glm::fvec3(1.0f, 1.0f, 0.0f), + glm::fvec3(1.0f, 0.0f, 0.0f), + glm::fvec3(1.0f, 0.0f, 0.0f), + glm::fvec3(0.0f, 0.0f, 0.0f), + + glm::fvec3(0.0f, 0.0f, 1.0f), + glm::fvec3(0.0f, 1.0f, 1.0f), + glm::fvec3(0.0f, 1.0f, 1.0f), + glm::fvec3(1.0f, 1.0f, 1.0f), + glm::fvec3(1.0f, 1.0f, 1.0f), + glm::fvec3(1.0f, 0.0f, 1.0f), + glm::fvec3(1.0f, 0.0f, 1.0f), + glm::fvec3(0.0f, 0.0f, 1.0f), + + glm::fvec3(0.0f, 0.0f, 0.0f), + glm::fvec3(0.0f, 0.0f, 1.0f), + glm::fvec3(0.0f, 1.0f, 0.0f), + glm::fvec3(0.0f, 1.0f, 1.0f), + glm::fvec3(1.0f, 0.0f, 0.0f), + glm::fvec3(1.0f, 0.0f, 1.0f), + glm::fvec3(1.0f, 1.0f, 0.0f), + glm::fvec3(1.0f, 1.0f, 1.0f), + }; + + glGenBuffers(1, &cube_vbo); + glBindBuffer(GL_ARRAY_BUFFER, cube_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); + + const glm::fvec3 line_vertices[2] = { + glm::fvec3(0.0f, 0.0f, 0.0f), + glm::fvec3(1.0f, 1.0f, 1.0f), + }; + + glGenBuffers(1, &line_vbo); + glBindBuffer(GL_ARRAY_BUFFER, line_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(line_vertices), line_vertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vaobj); + + glBindVertexArray(vaobj); + glEnableVertexAttribArray(0); + glVertexAttribDivisor(0, 0); +} + +void world::outline::shutdown(void) +{ + glDeleteVertexArrays(1, &vaobj); + glDeleteBuffers(1, &line_vbo); + glDeleteBuffers(1, &cube_vbo); + program.destroy(); +} + +void world::outline::prepare(void) +{ + program.set_variant_vert(WORLD_CURVATURE, client_game::world_curvature.get_value()); + + if(!program.update()) { + spdlog::critical("outline_renderer: program update failed"); + std::terminate(); + } + + glDisable(GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glUseProgram(program.handle); + glUniformMatrix4fv(program.uniforms[u_vpmatrix].location, 1, false, glm::value_ptr(entity::camera::matrix)); + glUniform1f(program.uniforms[u_viewdist].location, static_cast<GLfloat>(CHUNK_SIZE * entity::camera::view_distance.get_value())); + + glBindVertexArray(vaobj); + glEnableVertexAttribArray(0); + glVertexAttribDivisor(0, 0); +} + +void world::outline::cube(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color) +{ + auto patch_cpos = cpos - entity::camera::position_chunk; + + glLineWidth(thickness); + + glUniform3fv(program.uniforms[u_worldpos].location, 1, glm::value_ptr(coord::to_fvec3(patch_cpos, fpos))); + glUniform4fv(program.uniforms[u_modulate].location, 1, glm::value_ptr(color)); + glUniform3fv(program.uniforms[u_scale].location, 1, glm::value_ptr(size)); + + glBindBuffer(GL_ARRAY_BUFFER, cube_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr); + glDrawArrays(GL_LINES, 0, 24); +} + +void world::outline::line(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color) +{ + auto patch_cpos = cpos - entity::camera::position_chunk; + + glLineWidth(thickness); + + glUniform3fv(program.uniforms[u_worldpos].location, 1, glm::value_ptr(coord::to_fvec3(patch_cpos, fpos))); + glUniform4fv(program.uniforms[u_modulate].location, 1, glm::value_ptr(color)); + glUniform3fv(program.uniforms[u_scale].location, 1, glm::value_ptr(size)); + + glBindBuffer(GL_ARRAY_BUFFER, line_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(glm::fvec3), nullptr); + glDrawArrays(GL_LINES, 0, 2); +} diff --git a/game/client/world/outline.hh b/src/game/client/world/outline.hh index bd69ecc..2456a32 100644 --- a/game/client/world/outline.hh +++ b/src/game/client/world/outline.hh @@ -1,16 +1,16 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world::outline
-{
-void init(void);
-void shutdown(void);
-void prepare(void);
-} // namespace world::outline
-
-namespace world::outline
-{
-void cube(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color);
-void line(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color);
-} // namespace world::outline
+#pragma once + +#include "shared/types.hh" + +namespace world::outline +{ +void init(void); +void shutdown(void); +void prepare(void); +} // namespace world::outline + +namespace world::outline +{ +void cube(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color); +void line(const chunk_pos& cpos, const glm::fvec3& fpos, const glm::fvec3& size, float thickness, const glm::fvec4& color); +} // namespace world::outline diff --git a/game/client/world/player_target.cc b/src/game/client/world/player_target.cc index 3ede47e..5969381 100644 --- a/game/client/world/player_target.cc +++ b/src/game/client/world/player_target.cc @@ -1,64 +1,64 @@ -#include "client/pch.hh"
-
-#include "client/world/player_target.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/ray_dda.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-#include "client/world/outline.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static float MAX_REACH = 16.0f;
-
-voxel_pos world::player_target::coord;
-voxel_pos world::player_target::normal;
-const world::Voxel* world::player_target::voxel;
-
-void world::player_target::init(void)
-{
- world::player_target::coord = voxel_pos();
- world::player_target::normal = voxel_pos();
- world::player_target::voxel = nullptr;
-}
-
-void world::player_target::update(void)
-{
- if(session::is_ingame()) {
- RayDDA ray(globals::dimension, entity::camera::position_chunk, entity::camera::position_local, entity::camera::direction);
-
- do {
- world::player_target::voxel = ray.step();
-
- if(world::player_target::voxel) {
- world::player_target::coord = ray.vpos;
- world::player_target::normal = ray.vnormal;
- break;
- }
-
- world::player_target::coord = voxel_pos();
- world::player_target::normal = voxel_pos();
- } while(ray.distance < MAX_REACH);
- }
- else {
- world::player_target::voxel = nullptr;
- world::player_target::coord = voxel_pos();
- world::player_target::normal = voxel_pos();
- }
-}
-
-void world::player_target::render(void)
-{
- if(world::player_target::voxel && !client_game::hide_hud) {
- auto cpos = coord::to_chunk(world::player_target::coord);
- auto fpos = coord::to_local(world::player_target::coord);
-
- world::outline::prepare();
- world::outline::cube(cpos, glm::fvec3(fpos), glm::fvec3(1.0f), 2.0f, glm::fvec4(0.0f, 0.0f, 0.0f, 1.0f));
- }
-}
+#include "client/pch.hh" + +#include "client/world/player_target.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/ray_dda.hh" + +#include "shared/coord.hh" + +#include "client/entity/camera.hh" +#include "client/world/outline.hh" + +#include "client/game.hh" +#include "client/globals.hh" +#include "client/session.hh" + +constexpr static float MAX_REACH = 16.0f; + +voxel_pos world::player_target::coord; +voxel_pos world::player_target::normal; +const world::Voxel* world::player_target::voxel; + +void world::player_target::init(void) +{ + world::player_target::coord = voxel_pos(); + world::player_target::normal = voxel_pos(); + world::player_target::voxel = nullptr; +} + +void world::player_target::update(void) +{ + if(session::is_ingame()) { + RayDDA ray(globals::dimension, entity::camera::position_chunk, entity::camera::position_local, entity::camera::direction); + + do { + world::player_target::voxel = ray.step(); + + if(world::player_target::voxel) { + world::player_target::coord = ray.vpos; + world::player_target::normal = ray.vnormal; + break; + } + + world::player_target::coord = voxel_pos(); + world::player_target::normal = voxel_pos(); + } while(ray.distance < MAX_REACH); + } + else { + world::player_target::voxel = nullptr; + world::player_target::coord = voxel_pos(); + world::player_target::normal = voxel_pos(); + } +} + +void world::player_target::render(void) +{ + if(world::player_target::voxel && !client_game::hide_hud) { + auto cpos = coord::to_chunk(world::player_target::coord); + auto fpos = coord::to_local(world::player_target::coord); + + world::outline::prepare(); + world::outline::cube(cpos, glm::fvec3(fpos), glm::fvec3(1.0f), 2.0f, glm::fvec4(0.0f, 0.0f, 0.0f, 1.0f)); + } +} diff --git a/game/client/world/player_target.hh b/src/game/client/world/player_target.hh index 34532c3..175be02 100644 --- a/game/client/world/player_target.hh +++ b/src/game/client/world/player_target.hh @@ -1,17 +1,17 @@ -#pragma once
-
-#include "shared/world/voxel_registry.hh"
-
-namespace world::player_target
-{
-extern voxel_pos coord;
-extern voxel_pos normal;
-extern const Voxel* voxel;
-} // namespace world::player_target
-
-namespace world::player_target
-{
-void init(void);
-void update(void);
-void render(void);
-} // namespace world::player_target
+#pragma once + +#include "shared/world/voxel_registry.hh" + +namespace world::player_target +{ +extern voxel_pos coord; +extern voxel_pos normal; +extern const Voxel* voxel; +} // namespace world::player_target + +namespace world::player_target +{ +void init(void); +void update(void); +void render(void); +} // namespace world::player_target diff --git a/game/client/world/skybox.cc b/src/game/client/world/skybox.cc index cfff141..5e52fa4 100644 --- a/game/client/world/skybox.cc +++ b/src/game/client/world/skybox.cc @@ -1,11 +1,11 @@ -#include "client/pch.hh"
-
-#include "client/world/skybox.hh"
-
-glm::fvec3 world::skybox::fog_color;
-
-void world::skybox::init(void)
-{
- // https://convertingcolors.com/hex-color-B1F3FF.html
- world::skybox::fog_color = glm::fvec3(0.690f, 0.950f, 1.000f);
-}
+#include "client/pch.hh" + +#include "client/world/skybox.hh" + +glm::fvec3 world::skybox::fog_color; + +void world::skybox::init(void) +{ + // https://convertingcolors.com/hex-color-B1F3FF.html + world::skybox::fog_color = glm::fvec3(0.690f, 0.950f, 1.000f); +} diff --git a/game/client/world/skybox.hh b/src/game/client/world/skybox.hh index 39a514b..40113cd 100644 --- a/game/client/world/skybox.hh +++ b/src/game/client/world/skybox.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace world::skybox
-{
-extern glm::fvec3 fog_color;
-} // namespace world::skybox
-
-namespace world::skybox
-{
-void init(void);
-} // namespace world::skybox
+#pragma once + +namespace world::skybox +{ +extern glm::fvec3 fog_color; +} // namespace world::skybox + +namespace world::skybox +{ +void init(void); +} // namespace world::skybox diff --git a/game/client/world/voxel_anims.cc b/src/game/client/world/voxel_anims.cc index 185d463..3d7cfd4 100644 --- a/game/client/world/voxel_anims.cc +++ b/src/game/client/world/voxel_anims.cc @@ -1,33 +1,33 @@ -#include "client/pch.hh"
-
-#include "client/world/voxel_anims.hh"
-
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/globals.hh"
-
-static config::Unsigned base_framerate(16U, 1U, 16U);
-
-std::uint64_t world::voxel_anims::nextframe = 0U;
-std::uint32_t world::voxel_anims::frame = 0U;
-
-void world::voxel_anims::init(void)
-{
- globals::client_config.add_value("voxel_anims.base_framerate", base_framerate);
-
- world::voxel_anims::nextframe = 0U;
- world::voxel_anims::frame = 0U;
-}
-
-void world::voxel_anims::update(void)
-{
- if(globals::curtime >= world::voxel_anims::nextframe) {
- world::voxel_anims::nextframe = globals::curtime
- + static_cast<std::uint64_t>(1000000.0 / static_cast<float>(base_framerate.get_value()));
- world::voxel_anims::frame += 1U;
- }
-}
+#include "client/pch.hh" + +#include "client/world/voxel_anims.hh" + +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" + +#include "client/globals.hh" + +static config::Unsigned base_framerate(16U, 1U, 16U); + +std::uint64_t world::voxel_anims::nextframe = 0U; +std::uint32_t world::voxel_anims::frame = 0U; + +void world::voxel_anims::init(void) +{ + globals::client_config.add_value("voxel_anims.base_framerate", base_framerate); + + world::voxel_anims::nextframe = 0U; + world::voxel_anims::frame = 0U; +} + +void world::voxel_anims::update(void) +{ + if(globals::curtime >= world::voxel_anims::nextframe) { + world::voxel_anims::nextframe = globals::curtime + + static_cast<std::uint64_t>(1000000.0 / static_cast<float>(base_framerate.get_value())); + world::voxel_anims::frame += 1U; + } +} diff --git a/game/client/world/voxel_anims.hh b/src/game/client/world/voxel_anims.hh index e4fe73e..0d8a0d0 100644 --- a/game/client/world/voxel_anims.hh +++ b/src/game/client/world/voxel_anims.hh @@ -1,13 +1,13 @@ -#pragma once
-
-namespace world::voxel_anims
-{
-extern std::uint64_t nextframe;
-extern std::uint32_t frame;
-} // namespace world::voxel_anims
-
-namespace world::voxel_anims
-{
-void init(void);
-void update(void);
-} // namespace world::voxel_anims
+#pragma once + +namespace world::voxel_anims +{ +extern std::uint64_t nextframe; +extern std::uint32_t frame; +} // namespace world::voxel_anims + +namespace world::voxel_anims +{ +void init(void); +void update(void); +} // namespace world::voxel_anims diff --git a/game/client/world/voxel_atlas.cc b/src/game/client/world/voxel_atlas.cc index 67832d3..4307dad 100644 --- a/game/client/world/voxel_atlas.cc +++ b/src/game/client/world/voxel_atlas.cc @@ -1,185 +1,186 @@ -#include "client/pch.hh"
-
-#include "client/world/voxel_atlas.hh"
-
-#include "core/math/constexpr.hh"
-#include "core/math/crc64.hh"
-
-#include "core/resource/image.hh"
-#include "core/resource/resource.hh"
-
-struct AtlasPlane final {
- std::unordered_map<std::size_t, std::size_t> lookup;
- std::vector<world::AtlasStrip> strips;
- std::size_t layer_count_max;
- std::size_t layer_count;
- std::size_t plane_id;
- GLuint gl_texture;
-};
-
-static int atlas_width;
-static int atlas_height;
-static std::size_t atlas_count;
-static std::vector<AtlasPlane> planes;
-
-// Certain animated and varied voxels just double their
-// textures (see the "default" texture part in VoxelInfoBuilder::build)
-// so there could either be six UNIQUE atlas strips or only one
-// https://crypto.stackexchange.com/questions/55162/best-way-to-hash-two-values-into-one
-static std::size_t vector_hash(const std::vector<std::string>& strings)
-{
- std::size_t source = 0;
- for(const std::string& str : strings)
- source += math::crc64(str);
- return math::crc64(&source, sizeof(source));
-}
-
-static void plane_setup(AtlasPlane& plane)
-{
- glGenTextures(1, &plane.gl_texture);
- glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture);
- glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, atlas_width, atlas_height, plane.layer_count_max, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
-}
-
-static world::AtlasStrip* plane_lookup(AtlasPlane& plane, std::size_t hash_value)
-{
- const auto it = plane.lookup.find(hash_value);
-
- if(it != plane.lookup.cend()) {
- return &plane.strips[it->second];
- }
-
- return nullptr;
-}
-
-static world::AtlasStrip* plane_new_strip(AtlasPlane& plane, const std::vector<std::string>& paths, std::size_t hash_value)
-{
- world::AtlasStrip strip = {};
- strip.offset = plane.layer_count;
- strip.plane = plane.plane_id;
-
- glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture);
-
- for(std::size_t i = 0; i < paths.size(); ++i) {
- if(auto image = resource::load<Image>(paths[i].c_str(), IMAGE_LOAD_FLIP)) {
- if((image->size.x != atlas_width) || (image->size.y != atlas_height)) {
- spdlog::warn("atlas: {}: size mismatch", paths[i]);
- continue;
- }
-
- const std::size_t offset = strip.offset + i;
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, offset, image->size.x, image->size.y, 1, GL_RGBA, GL_UNSIGNED_BYTE,
- image->pixels);
- }
- }
-
- plane.layer_count += paths.size();
-
- const std::size_t index = plane.strips.size();
- plane.lookup.emplace(hash_value, index);
- plane.strips.push_back(std::move(strip));
- return &plane.strips[index];
-}
-
-void world::voxel_atlas::create(int width, int height, std::size_t count)
-{
- GLint max_plane_layers;
-
- atlas_width = 1 << math::log2(width);
- atlas_height = 1 << math::log2(height);
-
- // Clipping this at OpenGL 4.5 limit of 2048 is important due to
- // how voxel quad meshes are packed in memory: each texture index is
- // confined in 11 bits so having bigger atlas planes makes no sense;
- glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_plane_layers);
- max_plane_layers = glm::clamp(max_plane_layers, 256, 2048);
-
- for(long i = count; i > 0L; i -= max_plane_layers) {
- AtlasPlane plane = {};
- plane.plane_id = planes.size();
- plane.layer_count_max = glm::min<std::size_t>(max_plane_layers, i);
- plane.layer_count = 0;
-
- const std::size_t save_id = plane.plane_id;
- planes.push_back(std::move(plane));
- plane_setup(planes[save_id]);
- }
-
- spdlog::debug("voxel_atlas: count={}", count);
- spdlog::debug("voxel_atlas: atlas_size=[{}x{}]", atlas_width, atlas_height);
- spdlog::debug("voxel_atlas: max_plane_layers={}", max_plane_layers);
-}
-
-void world::voxel_atlas::destroy(void)
-{
- for(const AtlasPlane& plane : planes)
- glDeleteTextures(1, &plane.gl_texture);
- atlas_width = 0;
- atlas_height = 0;
- planes.clear();
-}
-
-std::size_t world::voxel_atlas::plane_count(void)
-{
- return planes.size();
-}
-
-GLuint world::voxel_atlas::plane_texture(std::size_t plane_id)
-{
- if(plane_id < planes.size()) {
- return planes[plane_id].gl_texture;
- }
- else {
- return 0;
- }
-}
-
-void world::voxel_atlas::generate_mipmaps(void)
-{
- for(const AtlasPlane& plane : planes) {
- glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture);
- glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
- }
-}
-
-world::AtlasStrip* world::voxel_atlas::find_or_load(const std::vector<std::string>& paths)
-{
- const std::size_t hash_value = vector_hash(paths);
-
- for(AtlasPlane& plane : planes) {
- if(AtlasStrip* strip = plane_lookup(plane, hash_value)) {
- return strip;
- }
-
- continue;
- }
-
- for(AtlasPlane& plane : planes) {
- if((plane.layer_count + paths.size()) <= plane.layer_count_max) {
- return plane_new_strip(plane, paths, hash_value);
- }
-
- continue;
- }
-
- return nullptr;
-}
-
-world::AtlasStrip* world::voxel_atlas::find(const std::vector<std::string>& paths)
-{
- const std::size_t hash_value = vector_hash(paths);
-
- for(AtlasPlane& plane : planes) {
- if(AtlasStrip* strip = plane_lookup(plane, hash_value)) {
- return strip;
- }
-
- continue;
- }
-
- return nullptr;
-}
+#include "client/pch.hh" + +#include "client/world/voxel_atlas.hh" + +#include "core/math/constexpr.hh" +#include "core/math/crc64.hh" + +#include "core/resource/image.hh" +#include "core/resource/resource.hh" + +struct AtlasPlane final { + std::unordered_map<std::size_t, std::size_t> lookup; + std::vector<world::AtlasStrip> strips; + std::size_t layer_count_max; + std::size_t layer_count; + std::size_t plane_id; + GLuint gl_texture; +}; + +static int atlas_width; +static int atlas_height; +static std::size_t atlas_count; +static std::vector<AtlasPlane> planes; + +// Certain animated and varied voxels just double their +// textures (see the "default" texture part in VoxelInfoBuilder::build) +// so there could either be six UNIQUE atlas strips or only one +// https://crypto.stackexchange.com/questions/55162/best-way-to-hash-two-values-into-one +static std::size_t vector_hash(const std::vector<std::string>& strings) +{ + std::size_t source = 0; + for(const std::string& str : strings) + source += math::crc64(str); + return math::crc64(&source, sizeof(source)); +} + +static void plane_setup(AtlasPlane& plane) +{ + glGenTextures(1, &plane.gl_texture); + glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, atlas_width, atlas_height, static_cast<GLsizei>(plane.layer_count_max), 0, GL_RED, + GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); +} + +static world::AtlasStrip* plane_lookup(AtlasPlane& plane, std::size_t hash_value) +{ + const auto it = plane.lookup.find(hash_value); + + if(it != plane.lookup.cend()) { + return &plane.strips[it->second]; + } + + return nullptr; +} + +static world::AtlasStrip* plane_new_strip(AtlasPlane& plane, const std::vector<std::string>& paths, std::size_t hash_value) +{ + world::AtlasStrip strip = {}; + strip.offset = plane.layer_count; + strip.plane = plane.plane_id; + + glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture); + + for(std::size_t i = 0; i < paths.size(); ++i) { + if(auto image = resource::load<Image>(paths[i].c_str(), IMAGE_LOAD_FLIP)) { + if((image->size.x != atlas_width) || (image->size.y != atlas_height)) { + spdlog::warn("atlas: {}: size mismatch", paths[i]); + continue; + } + + const std::size_t offset = strip.offset + i; + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, static_cast<GLint>(offset), image->size.x, image->size.y, 1, GL_RGBA, + GL_UNSIGNED_BYTE, image->pixels); + } + } + + plane.layer_count += paths.size(); + + const std::size_t index = plane.strips.size(); + plane.lookup.emplace(hash_value, index); + plane.strips.push_back(std::move(strip)); + return &plane.strips[index]; +} + +void world::voxel_atlas::create(int width, int height, std::size_t count) +{ + GLint max_plane_layers; + + atlas_width = 1 << math::log2(width); + atlas_height = 1 << math::log2(height); + + // Clipping this at OpenGL 4.5 limit of 2048 is important due to + // how voxel quad meshes are packed in memory: each texture index is + // confined in 11 bits so having bigger atlas planes makes no sense; + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_plane_layers); + max_plane_layers = glm::clamp(max_plane_layers, 256, 2048); + + for(long i = static_cast<long>(count); i > 0L; i -= max_plane_layers) { + AtlasPlane plane = {}; + plane.plane_id = planes.size(); + plane.layer_count_max = glm::min<std::size_t>(max_plane_layers, i); + plane.layer_count = 0; + + const std::size_t save_id = plane.plane_id; + planes.push_back(std::move(plane)); + plane_setup(planes[save_id]); + } + + spdlog::debug("voxel_atlas: count={}", count); + spdlog::debug("voxel_atlas: atlas_size=[{}x{}]", atlas_width, atlas_height); + spdlog::debug("voxel_atlas: max_plane_layers={}", max_plane_layers); +} + +void world::voxel_atlas::destroy(void) +{ + for(const AtlasPlane& plane : planes) + glDeleteTextures(1, &plane.gl_texture); + atlas_width = 0; + atlas_height = 0; + planes.clear(); +} + +std::size_t world::voxel_atlas::plane_count(void) +{ + return planes.size(); +} + +GLuint world::voxel_atlas::plane_texture(std::size_t plane_id) +{ + if(plane_id < planes.size()) { + return planes[plane_id].gl_texture; + } + else { + return 0; + } +} + +void world::voxel_atlas::generate_mipmaps(void) +{ + for(const AtlasPlane& plane : planes) { + glBindTexture(GL_TEXTURE_2D_ARRAY, plane.gl_texture); + glGenerateMipmap(GL_TEXTURE_2D_ARRAY); + } +} + +world::AtlasStrip* world::voxel_atlas::find_or_load(const std::vector<std::string>& paths) +{ + const std::size_t hash_value = vector_hash(paths); + + for(AtlasPlane& plane : planes) { + if(AtlasStrip* strip = plane_lookup(plane, hash_value)) { + return strip; + } + + continue; + } + + for(AtlasPlane& plane : planes) { + if((plane.layer_count + paths.size()) <= plane.layer_count_max) { + return plane_new_strip(plane, paths, hash_value); + } + + continue; + } + + return nullptr; +} + +world::AtlasStrip* world::voxel_atlas::find(const std::vector<std::string>& paths) +{ + const std::size_t hash_value = vector_hash(paths); + + for(AtlasPlane& plane : planes) { + if(AtlasStrip* strip = plane_lookup(plane, hash_value)) { + return strip; + } + + continue; + } + + return nullptr; +} diff --git a/game/client/world/voxel_atlas.hh b/src/game/client/world/voxel_atlas.hh index 4ae6381..70e8a1e 100644 --- a/game/client/world/voxel_atlas.hh +++ b/src/game/client/world/voxel_atlas.hh @@ -1,28 +1,28 @@ -#pragma once
-
-namespace world
-{
-struct AtlasStrip final {
- std::size_t offset;
- std::size_t plane;
-};
-} // namespace world
-
-namespace world::voxel_atlas
-{
-void create(int width, int height, std::size_t count);
-void destroy(void);
-} // namespace world::voxel_atlas
-
-namespace world::voxel_atlas
-{
-std::size_t plane_count(void);
-GLuint plane_texture(std::size_t plane_id);
-void generate_mipmaps(void);
-} // namespace world::voxel_atlas
-
-namespace world::voxel_atlas
-{
-AtlasStrip* find_or_load(const std::vector<std::string>& paths);
-AtlasStrip* find(const std::vector<std::string>& paths);
-} // namespace world::voxel_atlas
+#pragma once + +namespace world +{ +struct AtlasStrip final { + std::size_t offset; + std::size_t plane; +}; +} // namespace world + +namespace world::voxel_atlas +{ +void create(int width, int height, std::size_t count); +void destroy(void); +} // namespace world::voxel_atlas + +namespace world::voxel_atlas +{ +std::size_t plane_count(void); +GLuint plane_texture(std::size_t plane_id); +void generate_mipmaps(void); +} // namespace world::voxel_atlas + +namespace world::voxel_atlas +{ +AtlasStrip* find_or_load(const std::vector<std::string>& paths); +AtlasStrip* find(const std::vector<std::string>& paths); +} // namespace world::voxel_atlas diff --git a/game/client/world/voxel_sounds.cc b/src/game/client/world/voxel_sounds.cc index fe91f01..42552f5 100644 --- a/game/client/world/voxel_sounds.cc +++ b/src/game/client/world/voxel_sounds.cc @@ -1,83 +1,83 @@ -#include "client/pch.hh"
-
-#include "client/world/voxel_sounds.hh"
-
-#include "client/resource/sound_effect.hh"
-
-static std::vector<resource_ptr<SoundEffect>> footsteps_sounds[world::VMAT_COUNT];
-static std::mt19937_64 randomizer;
-
-static void add_footsteps_effect(world::VoxelMaterial material, std::string_view name)
-{
- if(auto effect = resource::load<SoundEffect>(name)) {
- footsteps_sounds[material].push_back(effect);
- }
-}
-
-static resource_ptr<SoundEffect> get_footsteps_effect(world::VoxelMaterial material)
-{
- auto surface_index = static_cast<std::size_t>(material);
-
- if(surface_index >= world::VMAT_COUNT) {
- // Surface index out of range
- return nullptr;
- }
-
- const auto& sounds = footsteps_sounds[surface_index];
-
- if(sounds.empty()) {
- // No sounds for this surface
- return nullptr;
- }
-
- auto dist = std::uniform_int_distribution<std::size_t>(0, sounds.size() - 1);
- return sounds.at(dist(randomizer));
-}
-
-void world::voxel_sounds::init(void)
-{
- add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default1.wav");
- add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default2.wav");
- add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default3.wav");
- add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default4.wav");
-
- add_footsteps_effect(VMAT_DIRT, "sounds/surface/dirt1.wav");
-
- add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass1.wav");
- add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass2.wav");
- add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass3.wav");
-
- add_footsteps_effect(VMAT_GRAVEL, "sounds/surface/gravel1.wav");
-
- add_footsteps_effect(VMAT_SAND, "sounds/surface/sand1.wav");
- add_footsteps_effect(VMAT_SAND, "sounds/surface/sand2.wav");
-
- add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood1.wav");
- add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood2.wav");
- add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood3.wav");
-}
-
-void world::voxel_sounds::shutdown(void)
-{
- for(std::size_t i = 0; i < world::VMAT_COUNT; ++i) {
- footsteps_sounds[i].clear();
- }
-}
-
-resource_ptr<SoundEffect> world::voxel_sounds::get_footsteps(world::VoxelMaterial material)
-{
- if(auto effect = get_footsteps_effect(material)) {
- return effect;
- }
-
- if(auto effect = get_footsteps_effect(VMAT_DEFAULT)) {
- return effect;
- }
-
- return nullptr;
-}
-
-resource_ptr<SoundEffect> world::voxel_sounds::get_placebreak(world::VoxelMaterial material)
-{
- return nullptr;
-}
+#include "client/pch.hh" + +#include "client/world/voxel_sounds.hh" + +#include "client/resource/sound_effect.hh" + +static std::vector<resource_ptr<SoundEffect>> footsteps_sounds[world::VMAT_COUNT]; +static std::mt19937_64 randomizer; + +static void add_footsteps_effect(world::VoxelMaterial material, std::string_view name) +{ + if(auto effect = resource::load<SoundEffect>(name)) { + footsteps_sounds[material].push_back(effect); + } +} + +static resource_ptr<SoundEffect> get_footsteps_effect(world::VoxelMaterial material) +{ + auto surface_index = static_cast<std::size_t>(material); + + if(surface_index >= world::VMAT_COUNT) { + // Surface index out of range + return nullptr; + } + + const auto& sounds = footsteps_sounds[surface_index]; + + if(sounds.empty()) { + // No sounds for this surface + return nullptr; + } + + auto dist = std::uniform_int_distribution<std::size_t>(0, sounds.size() - 1); + return sounds.at(dist(randomizer)); +} + +void world::voxel_sounds::init(void) +{ + add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default1.wav"); + add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default2.wav"); + add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default3.wav"); + add_footsteps_effect(VMAT_DEFAULT, "sounds/surface/default4.wav"); + + add_footsteps_effect(VMAT_DIRT, "sounds/surface/dirt1.wav"); + + add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass1.wav"); + add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass2.wav"); + add_footsteps_effect(VMAT_GRASS, "sounds/surface/grass3.wav"); + + add_footsteps_effect(VMAT_GRAVEL, "sounds/surface/gravel1.wav"); + + add_footsteps_effect(VMAT_SAND, "sounds/surface/sand1.wav"); + add_footsteps_effect(VMAT_SAND, "sounds/surface/sand2.wav"); + + add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood1.wav"); + add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood2.wav"); + add_footsteps_effect(VMAT_WOOD, "sounds/surface/wood3.wav"); +} + +void world::voxel_sounds::shutdown(void) +{ + for(std::size_t i = 0; i < world::VMAT_COUNT; ++i) { + footsteps_sounds[i].clear(); + } +} + +resource_ptr<SoundEffect> world::voxel_sounds::get_footsteps(world::VoxelMaterial material) +{ + if(auto effect = get_footsteps_effect(material)) { + return effect; + } + + if(auto effect = get_footsteps_effect(VMAT_DEFAULT)) { + return effect; + } + + return nullptr; +} + +resource_ptr<SoundEffect> world::voxel_sounds::get_placebreak(world::VoxelMaterial material) +{ + return nullptr; +} diff --git a/game/client/world/voxel_sounds.hh b/src/game/client/world/voxel_sounds.hh index d0f3e07..dc02cbd 100644 --- a/game/client/world/voxel_sounds.hh +++ b/src/game/client/world/voxel_sounds.hh @@ -1,19 +1,19 @@ -#pragma once
-
-#include "core/resource/resource.hh"
-
-#include "shared/world/voxel.hh"
-
-struct SoundEffect;
-
-namespace world::voxel_sounds
-{
-void init(void);
-void shutdown(void);
-} // namespace world::voxel_sounds
-
-namespace world::voxel_sounds
-{
-resource_ptr<SoundEffect> get_footsteps(VoxelMaterial material);
-resource_ptr<SoundEffect> get_placebreak(VoxelMaterial material);
-} // namespace world::voxel_sounds
+#pragma once + +#include "core/resource/resource.hh" + +#include "shared/world/voxel.hh" + +struct SoundEffect; + +namespace world::voxel_sounds +{ +void init(void); +void shutdown(void); +} // namespace world::voxel_sounds + +namespace world::voxel_sounds +{ +resource_ptr<SoundEffect> get_footsteps(VoxelMaterial material); +resource_ptr<SoundEffect> get_placebreak(VoxelMaterial material); +} // namespace world::voxel_sounds diff --git a/game/server/CMakeLists.txt b/src/game/server/CMakeLists.txt index a4b5fd9..4672a89 100644 --- a/game/server/CMakeLists.txt +++ b/src/game/server/CMakeLists.txt @@ -16,8 +16,8 @@ add_executable(vserver "${CMAKE_CURRENT_LIST_DIR}/whitelist.cc" "${CMAKE_CURRENT_LIST_DIR}/whitelist.hh") target_compile_features(vserver PUBLIC cxx_std_20) -target_include_directories(vserver PRIVATE "${PROJECT_SOURCE_DIR}") -target_include_directories(vserver PRIVATE "${PROJECT_SOURCE_DIR}/game") +target_include_directories(vserver PRIVATE "${PROJECT_SOURCE_DIR}/src") +target_include_directories(vserver PRIVATE "${PROJECT_SOURCE_DIR}/src/game") target_precompile_headers(vserver PRIVATE "${CMAKE_CURRENT_LIST_DIR}/pch.hh") target_link_libraries(vserver PUBLIC shared) diff --git a/game/server/chat.cc b/src/game/server/chat.cc index fadfaa2..a0ceba8 100644 --- a/game/server/chat.cc +++ b/src/game/server/chat.cc @@ -1,55 +1,55 @@ -#include "server/pch.hh"
-
-#include "server/chat.hh"
-
-#include "server/globals.hh"
-#include "server/sessions.hh"
-#include "shared/protocol.hh"
-
-static void on_chat_message_packet(const protocol::ChatMessage& packet)
-{
- if(packet.type == protocol::ChatMessage::TEXT_MESSAGE) {
- if(auto session = sessions::find(packet.peer)) {
- server_chat::broadcast(packet.message.c_str(), session->client_username.c_str());
- }
- else {
- server_chat::broadcast(packet.message.c_str(), packet.sender.c_str());
- }
- }
-}
-
-void server_chat::init(void)
-{
- globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>();
-}
-
-void server_chat::broadcast(std::string_view message)
-{
- server_chat::broadcast(message, "server");
-}
-
-void server_chat::broadcast(std::string_view message, std::string_view sender)
-{
- protocol::ChatMessage packet;
- packet.type = protocol::ChatMessage::TEXT_MESSAGE;
- packet.message = message;
- packet.sender = sender;
-
- protocol::broadcast(globals::server_host, protocol::encode(packet));
-
- spdlog::info("<{}> {}", sender, message);
-}
-
-void server_chat::send(Session* session, std::string_view message)
-{
- server_chat::send(session, message, "server");
-}
-
-void server_chat::send(Session* session, std::string_view message, std::string_view sender)
-{
- protocol::ChatMessage packet;
- packet.type = protocol::ChatMessage::TEXT_MESSAGE;
- packet.message = message;
- packet.sender = sender;
- protocol::broadcast(globals::server_host, protocol::encode(packet));
-}
+#include "server/pch.hh" + +#include "server/chat.hh" + +#include "server/globals.hh" +#include "server/sessions.hh" +#include "shared/protocol.hh" + +static void on_chat_message_packet(const protocol::ChatMessage& packet) +{ + if(packet.type == protocol::ChatMessage::TEXT_MESSAGE) { + if(auto session = sessions::find(packet.peer)) { + server_chat::broadcast(packet.message.c_str(), session->client_username.c_str()); + } + else { + server_chat::broadcast(packet.message.c_str(), packet.sender.c_str()); + } + } +} + +void server_chat::init(void) +{ + globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>(); +} + +void server_chat::broadcast(std::string_view message) +{ + server_chat::broadcast(message, "server"); +} + +void server_chat::broadcast(std::string_view message, std::string_view sender) +{ + protocol::ChatMessage packet; + packet.type = protocol::ChatMessage::TEXT_MESSAGE; + packet.message = message; + packet.sender = sender; + + protocol::broadcast(globals::server_host, protocol::encode(packet)); + + spdlog::info("<{}> {}", sender, message); +} + +void server_chat::send(Session* session, std::string_view message) +{ + server_chat::send(session, message, "server"); +} + +void server_chat::send(Session* session, std::string_view message, std::string_view sender) +{ + protocol::ChatMessage packet; + packet.type = protocol::ChatMessage::TEXT_MESSAGE; + packet.message = message; + packet.sender = sender; + protocol::broadcast(globals::server_host, protocol::encode(packet)); +} diff --git a/game/server/chat.hh b/src/game/server/chat.hh index 76ddbbb..1b3e11b 100644 --- a/game/server/chat.hh +++ b/src/game/server/chat.hh @@ -1,12 +1,12 @@ -#pragma once
-
-struct Session;
-
-namespace server_chat
-{
-void init(void);
-void broadcast(std::string_view message);
-void broadcast(std::string_view message, std::string_view sender);
-void send(Session* session, std::string_view message);
-void send(Session* session, std::string_view message, std::string_view sender);
-} // namespace server_chat
+#pragma once + +struct Session; + +namespace server_chat +{ +void init(void); +void broadcast(std::string_view message); +void broadcast(std::string_view message, std::string_view sender); +void send(Session* session, std::string_view message); +void send(Session* session, std::string_view message, std::string_view sender); +} // namespace server_chat diff --git a/game/server/game.cc b/src/game/server/game.cc index f9802ae..3a13690 100644 --- a/game/server/game.cc +++ b/src/game/server/game.cc @@ -1,163 +1,163 @@ -#include "server/pch.hh"
-
-#include "server/game.hh"
-
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/cmdline.hh"
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-#include "core/math/crc64.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "shared/entity/collision.hh"
-#include "shared/entity/gravity.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/stasis.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/game_items.hh"
-#include "shared/game_voxels.hh"
-#include "shared/protocol.hh"
-#include "shared/splash.hh"
-
-#include "server/world/random_tick.hh"
-#include "server/world/universe.hh"
-#include "server/world/unloader.hh"
-#include "server/world/worldgen.hh"
-
-#include "server/chat.hh"
-#include "server/globals.hh"
-#include "server/receive.hh"
-#include "server/sessions.hh"
-#include "server/status.hh"
-#include "server/whitelist.hh"
-
-config::Unsigned server_game::view_distance(4U, 4U, 32U);
-
-std::uint64_t server_game::password_hash = UINT64_MAX;
-
-static config::Number<enet_uint16> listen_port(protocol::PORT, 1024U, UINT16_MAX);
-static config::Unsigned status_peers(2U, 1U, 16U);
-static config::String password_string("");
-
-void server_game::init(void)
-{
- globals::server_config.add_value("game.listen_port", listen_port);
- globals::server_config.add_value("game.status_peers", status_peers);
- globals::server_config.add_value("game.password", password_string);
- globals::server_config.add_value("game.view_distance", server_game::view_distance);
-
- sessions::init();
-
- whitelist::init();
-
- splash::init_server();
-
- status::init();
-
- server_chat::init();
- server_recieve::init();
-
- world::worldgen::init();
-
- world::unloader::init();
- world::universe::init();
-
- world::random_tick::init();
-}
-
-void server_game::init_late(void)
-{
- server_game::password_hash = math::crc64(password_string.get_value());
-
- sessions::init_late();
-
- whitelist::init_late();
-
- ENetAddress address;
- address.host = ENET_HOST_ANY;
- address.port = listen_port.get_value();
-
- globals::server_host = enet_host_create(&address, sessions::max_players.get_value() + status_peers.get_value(), 1, 0, 0);
-
- if(!globals::server_host) {
- spdlog::critical("game: unable to setup an ENet host");
- std::terminate();
- }
-
- spdlog::info("game: host: {} player + {} status peers", sessions::max_players.get_value(), status_peers.get_value());
- spdlog::info("game: host: listening on UDP port {}", address.port);
-
- game_voxels::populate();
- game_items::populate();
-
- world::unloader::init_late();
- world::universe::init_late();
-
- sessions::init_post_universe();
-}
-
-void server_game::shutdown(void)
-{
- protocol::Disconnect packet;
- packet.reason = "protocol.server_shutdown";
- protocol::broadcast(globals::server_host, protocol::encode(packet));
-
- whitelist::shutdown();
-
- sessions::shutdown();
-
- enet_host_flush(globals::server_host);
- enet_host_service(globals::server_host, nullptr, 500);
- enet_host_destroy(globals::server_host);
-
- world::universe::shutdown();
-}
-
-void server_game::fixed_update(void)
-{
- // FIXME: threading
- for(auto dimension : globals::dimensions) {
- entity::Collision::fixed_update(dimension.second);
- entity::Velocity::fixed_update(dimension.second);
- entity::Transform::fixed_update(dimension.second);
- entity::Gravity::fixed_update(dimension.second);
- entity::Stasis::fixed_update(dimension.second);
-
- for(auto [entity, component] : dimension.second->chunks.view<world::ChunkComponent>().each()) {
- world::random_tick::tick(component.cpos, component.chunk);
- }
- }
-}
-
-void server_game::fixed_update_late(void)
-{
- ENetEvent enet_event;
-
- while(0 < enet_host_service(globals::server_host, &enet_event, 0)) {
- if(enet_event.type == ENET_EVENT_TYPE_DISCONNECT) {
- sessions::destroy(sessions::find(enet_event.peer));
- sessions::refresh_scoreboard();
- continue;
- }
-
- if(enet_event.type == ENET_EVENT_TYPE_RECEIVE) {
- protocol::decode(globals::dispatcher, enet_event.packet, enet_event.peer);
- enet_packet_destroy(enet_event.packet);
- continue;
- }
- }
-
- // FIXME: threading
- for(auto dimension : globals::dimensions) {
- world::unloader::fixed_update_late(dimension.second);
- }
-}
+#include "server/pch.hh" + +#include "server/game.hh" + +#include "core/config/number.hh" +#include "core/config/string.hh" + +#include "core/io/cmdline.hh" +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" +#include "core/math/crc64.hh" + +#include "core/utils/epoch.hh" + +#include "shared/entity/collision.hh" +#include "shared/entity/gravity.hh" +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/stasis.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/game_items.hh" +#include "shared/game_voxels.hh" +#include "shared/protocol.hh" +#include "shared/splash.hh" + +#include "server/world/random_tick.hh" +#include "server/world/universe.hh" +#include "server/world/unloader.hh" +#include "server/world/worldgen.hh" + +#include "server/chat.hh" +#include "server/globals.hh" +#include "server/receive.hh" +#include "server/sessions.hh" +#include "server/status.hh" +#include "server/whitelist.hh" + +config::Unsigned server_game::view_distance(4U, 4U, 32U); + +std::uint64_t server_game::password_hash = UINT64_MAX; + +static config::Number<enet_uint16> listen_port(protocol::PORT, 1024U, UINT16_MAX); +static config::Unsigned status_peers(2U, 1U, 16U); +static config::String password_string(""); + +void server_game::init(void) +{ + globals::server_config.add_value("game.listen_port", listen_port); + globals::server_config.add_value("game.status_peers", status_peers); + globals::server_config.add_value("game.password", password_string); + globals::server_config.add_value("game.view_distance", server_game::view_distance); + + sessions::init(); + + whitelist::init(); + + splash::init_server(); + + status::init(); + + server_chat::init(); + server_recieve::init(); + + world::worldgen::init(); + + world::unloader::init(); + world::universe::init(); + + world::random_tick::init(); +} + +void server_game::init_late(void) +{ + server_game::password_hash = math::crc64(password_string.get_value()); + + sessions::init_late(); + + whitelist::init_late(); + + ENetAddress address; + address.host = ENET_HOST_ANY; + address.port = listen_port.get_value(); + + globals::server_host = enet_host_create(&address, sessions::max_players.get_value() + status_peers.get_value(), 1, 0, 0); + + if(!globals::server_host) { + spdlog::critical("game: unable to setup an ENet host"); + std::terminate(); + } + + spdlog::info("game: host: {} player + {} status peers", sessions::max_players.get_value(), status_peers.get_value()); + spdlog::info("game: host: listening on UDP port {}", address.port); + + game_voxels::populate(); + game_items::populate(); + + world::unloader::init_late(); + world::universe::init_late(); + + sessions::init_post_universe(); +} + +void server_game::shutdown(void) +{ + protocol::Disconnect packet; + packet.reason = "protocol.server_shutdown"; + protocol::broadcast(globals::server_host, protocol::encode(packet)); + + whitelist::shutdown(); + + sessions::shutdown(); + + enet_host_flush(globals::server_host); + enet_host_service(globals::server_host, nullptr, 500); + enet_host_destroy(globals::server_host); + + world::universe::shutdown(); +} + +void server_game::fixed_update(void) +{ + // FIXME: threading + for(auto dimension : globals::dimensions) { + entity::Collision::fixed_update(dimension.second); + entity::Velocity::fixed_update(dimension.second); + entity::Transform::fixed_update(dimension.second); + entity::Gravity::fixed_update(dimension.second); + entity::Stasis::fixed_update(dimension.second); + + for(auto [entity, component] : dimension.second->chunks.view<world::ChunkComponent>().each()) { + world::random_tick::tick(component.cpos, component.chunk); + } + } +} + +void server_game::fixed_update_late(void) +{ + ENetEvent enet_event; + + while(0 < enet_host_service(globals::server_host, &enet_event, 0)) { + if(enet_event.type == ENET_EVENT_TYPE_DISCONNECT) { + sessions::destroy(sessions::find(enet_event.peer)); + sessions::refresh_scoreboard(); + continue; + } + + if(enet_event.type == ENET_EVENT_TYPE_RECEIVE) { + protocol::decode(globals::dispatcher, enet_event.packet, enet_event.peer); + enet_packet_destroy(enet_event.packet); + continue; + } + } + + // FIXME: threading + for(auto dimension : globals::dimensions) { + world::unloader::fixed_update_late(dimension.second); + } +} diff --git a/game/server/game.hh b/src/game/server/game.hh index 99ba3d6..1dbe4b8 100644 --- a/game/server/game.hh +++ b/src/game/server/game.hh @@ -1,25 +1,25 @@ -#pragma once
-
-namespace config
-{
-class Unsigned;
-} // namespace config
-
-namespace server_game
-{
-extern config::Unsigned view_distance;
-} // namespace server_game
-
-namespace server_game
-{
-extern std::uint64_t password_hash;
-} // namespace server_game
-
-namespace server_game
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void fixed_update(void);
-void fixed_update_late(void);
-} // namespace server_game
+#pragma once + +namespace config +{ +class Unsigned; +} // namespace config + +namespace server_game +{ +extern config::Unsigned view_distance; +} // namespace server_game + +namespace server_game +{ +extern std::uint64_t password_hash; +} // namespace server_game + +namespace server_game +{ +void init(void); +void init_late(void); +void shutdown(void); +void fixed_update(void); +void fixed_update_late(void); +} // namespace server_game diff --git a/game/server/globals.cc b/src/game/server/globals.cc index 9e1875d..7d79e4d 100644 --- a/game/server/globals.cc +++ b/src/game/server/globals.cc @@ -1,18 +1,18 @@ -#include "server/pch.hh"
-
-#include "server/globals.hh"
-
-#include "core/io/config_map.hh"
-
-#include "shared/protocol.hh"
-
-io::ConfigMap globals::server_config;
-
-ENetHost* globals::server_host;
-
-bool globals::is_running;
-unsigned int globals::tickrate;
-std::uint64_t globals::tickrate_dt;
-
-world::Dimension* globals::spawn_dimension;
-std::unordered_map<std::string, world::Dimension*> globals::dimensions;
+#include "server/pch.hh" + +#include "server/globals.hh" + +#include "core/io/config_map.hh" + +#include "shared/protocol.hh" + +io::ConfigMap globals::server_config; + +ENetHost* globals::server_host; + +bool globals::is_running; +unsigned int globals::tickrate; +std::uint64_t globals::tickrate_dt; + +world::Dimension* globals::spawn_dimension; +std::unordered_map<std::string, world::Dimension*> globals::dimensions; diff --git a/game/server/globals.hh b/src/game/server/globals.hh index e9aa174..b684d3b 100644 --- a/game/server/globals.hh +++ b/src/game/server/globals.hh @@ -1,27 +1,27 @@ -#pragma once
-
-#include "shared/globals.hh"
-
-namespace io
-{
-class ConfigMap;
-} // namespace io
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace globals
-{
-extern io::ConfigMap server_config;
-
-extern ENetHost* server_host;
-
-extern bool is_running;
-extern unsigned int tickrate;
-extern std::uint64_t tickrate_dt;
-
-extern world::Dimension* spawn_dimension;
-extern std::unordered_map<std::string, world::Dimension*> dimensions;
-} // namespace globals
+#pragma once + +#include "shared/globals.hh" + +namespace io +{ +class ConfigMap; +} // namespace io + +namespace world +{ +class Dimension; +} // namespace world + +namespace globals +{ +extern io::ConfigMap server_config; + +extern ENetHost* server_host; + +extern bool is_running; +extern unsigned int tickrate; +extern std::uint64_t tickrate_dt; + +extern world::Dimension* spawn_dimension; +extern std::unordered_map<std::string, world::Dimension*> dimensions; +} // namespace globals diff --git a/game/server/main.cc b/src/game/server/main.cc index 3316407..cf265a4 100644 --- a/game/server/main.cc +++ b/src/game/server/main.cc @@ -1,108 +1,108 @@ -#include "server/pch.hh"
-
-#include "core/config/number.hh"
-
-#include "core/io/cmdline.hh"
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/image.hh"
-#include "core/resource/resource.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "core/threading.hh"
-#include "core/version.hh"
-
-#include "shared/game.hh"
-#include "shared/protocol.hh"
-
-#include "server/game.hh"
-#include "server/globals.hh"
-
-static config::Unsigned server_tickrate(protocol::TICKRATE, 10U, 300U);
-
-static void on_termination_signal(int)
-{
- spdlog::warn("server: received termination signal");
- globals::is_running = false;
-}
-
-int main(int argc, char** argv)
-{
- io::cmdline::create(argc, argv);
-
- shared_game::init(argc, argv);
-
- spdlog::info("Voxelius Server {}", version::semver);
-
- globals::fixed_frametime = 0.0f;
- globals::fixed_frametime_avg = 0.0f;
- globals::fixed_frametime_us = 0;
- globals::fixed_framecount = 0;
-
- globals::curtime = utils::unix_microseconds();
-
- globals::is_running = true;
-
- std::signal(SIGINT, &on_termination_signal);
- std::signal(SIGTERM, &on_termination_signal);
-
- Image::register_resource();
-
- server_game::init();
-
- threading::init();
-
- globals::server_config.add_value("server.tickrate", server_tickrate);
- globals::server_config.load_file("server.conf");
- globals::server_config.load_cmdline();
-
- globals::tickrate = server_tickrate.get_value();
- globals::tickrate_dt = static_cast<std::uint64_t>(1000000.0f / static_cast<float>(globals::tickrate));
-
- server_game::init_late();
-
- std::uint64_t last_curtime = globals::curtime;
-
- while(globals::is_running) {
- globals::curtime = utils::unix_microseconds();
-
- globals::fixed_frametime_us = globals::curtime - last_curtime;
- globals::fixed_frametime = static_cast<float>(globals::fixed_frametime_us) / 1000000.0f;
- globals::fixed_frametime_avg += globals::fixed_frametime;
- globals::fixed_frametime_avg *= 0.5f;
-
- last_curtime = globals::curtime;
-
- server_game::fixed_update();
- server_game::fixed_update_late();
-
- globals::dispatcher.update();
-
- globals::fixed_framecount += 1;
-
- std::this_thread::sleep_for(std::chrono::microseconds(globals::tickrate_dt));
-
- resource::soft_cleanup();
-
- threading::update();
- }
-
- server_game::shutdown();
-
- resource::hard_cleanup();
-
- threading::shutdown();
-
- spdlog::info("server: shutdown after {} frames", globals::fixed_framecount);
- spdlog::info("server: average framerate: {:.03f} TPS", 1.0f / globals::fixed_frametime_avg);
- spdlog::info("server: average frametime: {:.03f} MSPT", 1000.0f * globals::fixed_frametime_avg);
-
- globals::server_config.save_file("server.conf");
-
- shared_game::shutdown();
-
- return EXIT_SUCCESS;
-}
+#include "server/pch.hh" + +#include "core/config/number.hh" + +#include "core/io/cmdline.hh" +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" + +#include "core/resource/image.hh" +#include "core/resource/resource.hh" + +#include "core/utils/epoch.hh" + +#include "core/threading.hh" +#include "core/version.hh" + +#include "shared/game.hh" +#include "shared/protocol.hh" + +#include "server/game.hh" +#include "server/globals.hh" + +static config::Unsigned server_tickrate(protocol::TICKRATE, 10U, 300U); + +static void on_termination_signal(int) +{ + spdlog::warn("server: received termination signal"); + globals::is_running = false; +} + +int main(int argc, char** argv) +{ + io::cmdline::create(argc, argv); + + shared_game::init(argc, argv, "voxelius-server.log"); + + spdlog::info("Voxelius Server {}", version::full); + + globals::fixed_frametime = 0.0f; + globals::fixed_frametime_avg = 0.0f; + globals::fixed_frametime_us = 0; + globals::fixed_framecount = 0; + + globals::curtime = utils::unix_microseconds(); + + globals::is_running = true; + + std::signal(SIGINT, &on_termination_signal); + std::signal(SIGTERM, &on_termination_signal); + + Image::register_resource(); + + server_game::init(); + + threading::init(); + + globals::server_config.add_value("server.tickrate", server_tickrate); + globals::server_config.load_file("server.conf"); + globals::server_config.load_cmdline(); + + globals::tickrate = server_tickrate.get_value(); + globals::tickrate_dt = static_cast<std::uint64_t>(1000000.0f / static_cast<float>(globals::tickrate)); + + server_game::init_late(); + + std::uint64_t last_curtime = globals::curtime; + + while(globals::is_running) { + globals::curtime = utils::unix_microseconds(); + + globals::fixed_frametime_us = globals::curtime - last_curtime; + globals::fixed_frametime = static_cast<float>(globals::fixed_frametime_us) / 1000000.0f; + globals::fixed_frametime_avg += globals::fixed_frametime; + globals::fixed_frametime_avg *= 0.5f; + + last_curtime = globals::curtime; + + server_game::fixed_update(); + server_game::fixed_update_late(); + + globals::dispatcher.update(); + + globals::fixed_framecount += 1; + + std::this_thread::sleep_for(std::chrono::microseconds(globals::tickrate_dt)); + + resource::soft_cleanup(); + + threading::update(); + } + + server_game::shutdown(); + + resource::hard_cleanup(); + + threading::shutdown(); + + spdlog::info("server: shutdown after {} frames", globals::fixed_framecount); + spdlog::info("server: average framerate: {:.03f} TPS", 1.0f / globals::fixed_frametime_avg); + spdlog::info("server: average frametime: {:.03f} MSPT", 1000.0f * globals::fixed_frametime_avg); + + globals::server_config.save_file("server.conf"); + + shared_game::shutdown(); + + return EXIT_SUCCESS; +} diff --git a/game/server/pch.hh b/src/game/server/pch.hh index e90ebbd..6f42c17 100644 --- a/game/server/pch.hh +++ b/src/game/server/pch.hh @@ -1,3 +1,3 @@ -#pragma once
-
-#include <shared/pch.hh>
+#pragma once + +#include <shared/pch.hh> diff --git a/game/server/receive.cc b/src/game/server/receive.cc index 612674e..b804450 100644 --- a/game/server/receive.cc +++ b/src/game/server/receive.cc @@ -1,175 +1,175 @@ -#include "server/pch.hh"
-
-#include "server/receive.hh"
-
-#include "core/config/number.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/chunk_aabb.hh"
-#include "shared/world/dimension.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/protocol.hh"
-
-#include "server/world/inhabited.hh"
-#include "server/world/universe.hh"
-#include "server/world/worldgen.hh"
-
-#include "server/game.hh"
-#include "server/globals.hh"
-#include "server/sessions.hh"
-
-static void on_entity_transform_packet(const protocol::EntityTransform& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(session->dimension && session->dimension->entities.valid(session->player_entity)) {
- auto& component = session->dimension->entities.emplace_or_replace<entity::Transform>(session->player_entity);
- component.angles = packet.angles;
- component.chunk = packet.chunk;
- component.local = packet.local;
-
- protocol::EntityTransform response;
- response.entity = session->player_entity;
- response.angles = component.angles;
- response.chunk = component.chunk;
- response.local = component.local;
-
- // Propagate changes to the rest of the world
- // except the peer that has sent the packet in the first place
- sessions::broadcast(session->dimension, protocol::encode(response), session->peer);
- }
- }
-}
-
-static void on_entity_velocity_packet(const protocol::EntityVelocity& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(session->dimension && session->dimension->entities.valid(session->player_entity)) {
- auto& component = session->dimension->entities.emplace_or_replace<entity::Velocity>(session->player_entity);
- component.value = packet.value;
-
- protocol::EntityVelocity response;
- response.entity = session->player_entity;
- response.value = component.value;
-
- // Propagate changes to the rest of the world
- // except the peer that has sent the packet in the first place
- sessions::broadcast(session->dimension, protocol::encode(response), session->peer);
- }
- }
-}
-
-static void on_entity_head_packet(const protocol::EntityHead& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(session->dimension && session->dimension->entities.valid(session->player_entity)) {
- auto& component = session->dimension->entities.emplace_or_replace<entity::Head>(session->player_entity);
- component.angles = packet.angles;
-
- protocol::EntityHead response;
- response.entity = session->player_entity;
- response.angles = component.angles;
-
- // Propagate changes to the rest of the world
- // except the peer that has sent the packet in the first place
- sessions::broadcast(session->dimension, protocol::encode(response), session->peer);
- }
- }
-}
-
-static void on_set_voxel_packet(const protocol::SetVoxel& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(session->dimension && !session->dimension->set_voxel(world::voxel_registry::find(packet.voxel), packet.vpos)) {
- auto cpos = coord::to_chunk(packet.vpos);
- auto lpos = coord::to_local(packet.vpos);
- auto index = coord::to_index(lpos);
-
- if(world::worldgen::is_generating(session->dimension, cpos)) {
- // The chunk is currently being generated;
- // ignore all requests from players to build there
- return;
- }
-
- auto chunk = session->dimension->find_chunk(cpos);
-
- if(chunk == nullptr) {
- // The chunk is not loaded, so we must
- // ignore any requests from players to build there
- return;
- }
-
- chunk->set_voxel(world::voxel_registry::find(packet.voxel), index);
-
- session->dimension->chunks.emplace_or_replace<world::Inhabited>(chunk->get_entity());
-
- protocol::SetVoxel response;
- response.vpos = packet.vpos;
- response.voxel = packet.voxel;
- sessions::broadcast(session->dimension, protocol::encode(response), session->peer);
-
- return;
- }
- }
-}
-
-static void on_request_chunk_packet(const protocol::RequestChunk& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(!session->dimension || !session->dimension->entities.valid(session->player_entity)) {
- // De-spawned sessions cannot request
- // chunks from the server; that's cheating!!!
- return;
- }
-
- if(auto transform = session->dimension->entities.try_get<entity::Transform>(session->player_entity)) {
- world::ChunkAABB view_box;
- view_box.min = transform->chunk - static_cast<chunk_pos::value_type>(server_game::view_distance.get_value());
- view_box.max = transform->chunk + static_cast<chunk_pos::value_type>(server_game::view_distance.get_value());
-
- if(view_box.contains(packet.cpos)) {
- if(auto chunk = world::universe::load_chunk(session->dimension, packet.cpos)) {
- protocol::ChunkVoxels response;
- response.chunk = packet.cpos;
- response.voxels = chunk->get_voxels();
- protocol::send(packet.peer, protocol::encode(response));
- }
- else {
- world::worldgen::request_chunk(session, packet.cpos);
- }
- }
- }
- }
-}
-
-static void on_entity_sound_packet(const protocol::EntitySound& packet)
-{
- if(auto session = sessions::find(packet.peer)) {
- if(!session->dimension || !session->dimension->entities.valid(session->player_entity)) {
- // De-spawned sessions cannot play sounds
- return;
- }
-
- protocol::EntitySound response;
- response.entity = session->player_entity;
- response.sound = packet.sound;
- response.looping = packet.looping;
- response.pitch = packet.pitch;
-
- sessions::broadcast(session->dimension, protocol::encode(response), packet.peer);
- }
-}
-
-void server_recieve::init(void)
-{
- globals::dispatcher.sink<protocol::EntityTransform>().connect<&on_entity_transform_packet>();
- globals::dispatcher.sink<protocol::EntityVelocity>().connect<&on_entity_velocity_packet>();
- globals::dispatcher.sink<protocol::EntityHead>().connect<&on_entity_head_packet>();
- globals::dispatcher.sink<protocol::SetVoxel>().connect<&on_set_voxel_packet>();
- globals::dispatcher.sink<protocol::RequestChunk>().connect<&on_request_chunk_packet>();
- globals::dispatcher.sink<protocol::EntitySound>().connect<&on_entity_sound_packet>();
-}
+#include "server/pch.hh" + +#include "server/receive.hh" + +#include "core/config/number.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/chunk_aabb.hh" +#include "shared/world/dimension.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/protocol.hh" + +#include "server/world/inhabited.hh" +#include "server/world/universe.hh" +#include "server/world/worldgen.hh" + +#include "server/game.hh" +#include "server/globals.hh" +#include "server/sessions.hh" + +static void on_entity_transform_packet(const protocol::EntityTransform& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(session->dimension && session->dimension->entities.valid(session->player_entity)) { + auto& component = session->dimension->entities.emplace_or_replace<entity::Transform>(session->player_entity); + component.angles = packet.angles; + component.chunk = packet.chunk; + component.local = packet.local; + + protocol::EntityTransform response; + response.entity = session->player_entity; + response.angles = component.angles; + response.chunk = component.chunk; + response.local = component.local; + + // Propagate changes to the rest of the world + // except the peer that has sent the packet in the first place + sessions::broadcast(session->dimension, protocol::encode(response), session->peer); + } + } +} + +static void on_entity_velocity_packet(const protocol::EntityVelocity& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(session->dimension && session->dimension->entities.valid(session->player_entity)) { + auto& component = session->dimension->entities.emplace_or_replace<entity::Velocity>(session->player_entity); + component.value = packet.value; + + protocol::EntityVelocity response; + response.entity = session->player_entity; + response.value = component.value; + + // Propagate changes to the rest of the world + // except the peer that has sent the packet in the first place + sessions::broadcast(session->dimension, protocol::encode(response), session->peer); + } + } +} + +static void on_entity_head_packet(const protocol::EntityHead& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(session->dimension && session->dimension->entities.valid(session->player_entity)) { + auto& component = session->dimension->entities.emplace_or_replace<entity::Head>(session->player_entity); + component.angles = packet.angles; + + protocol::EntityHead response; + response.entity = session->player_entity; + response.angles = component.angles; + + // Propagate changes to the rest of the world + // except the peer that has sent the packet in the first place + sessions::broadcast(session->dimension, protocol::encode(response), session->peer); + } + } +} + +static void on_set_voxel_packet(const protocol::SetVoxel& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(session->dimension && !session->dimension->set_voxel(world::voxel_registry::find(packet.voxel), packet.vpos)) { + auto cpos = coord::to_chunk(packet.vpos); + auto lpos = coord::to_local(packet.vpos); + auto index = coord::to_index(lpos); + + if(world::worldgen::is_generating(session->dimension, cpos)) { + // The chunk is currently being generated; + // ignore all requests from players to build there + return; + } + + auto chunk = session->dimension->find_chunk(cpos); + + if(chunk == nullptr) { + // The chunk is not loaded, so we must + // ignore any requests from players to build there + return; + } + + chunk->set_voxel(world::voxel_registry::find(packet.voxel), index); + + session->dimension->chunks.emplace_or_replace<world::Inhabited>(chunk->get_entity()); + + protocol::SetVoxel response; + response.vpos = packet.vpos; + response.voxel = packet.voxel; + sessions::broadcast(session->dimension, protocol::encode(response), session->peer); + + return; + } + } +} + +static void on_request_chunk_packet(const protocol::RequestChunk& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(!session->dimension || !session->dimension->entities.valid(session->player_entity)) { + // De-spawned sessions cannot request + // chunks from the server; that's cheating!!! + return; + } + + if(auto transform = session->dimension->entities.try_get<entity::Transform>(session->player_entity)) { + world::ChunkAABB view_box; + view_box.min = transform->chunk - static_cast<chunk_pos::value_type>(server_game::view_distance.get_value()); + view_box.max = transform->chunk + static_cast<chunk_pos::value_type>(server_game::view_distance.get_value()); + + if(view_box.contains(packet.cpos)) { + if(auto chunk = world::universe::load_chunk(session->dimension, packet.cpos)) { + protocol::ChunkVoxels response; + response.chunk = packet.cpos; + response.voxels = chunk->get_voxels(); + protocol::send(packet.peer, protocol::encode(response)); + } + else { + world::worldgen::request_chunk(session, packet.cpos); + } + } + } + } +} + +static void on_entity_sound_packet(const protocol::EntitySound& packet) +{ + if(auto session = sessions::find(packet.peer)) { + if(!session->dimension || !session->dimension->entities.valid(session->player_entity)) { + // De-spawned sessions cannot play sounds + return; + } + + protocol::EntitySound response; + response.entity = session->player_entity; + response.sound = packet.sound; + response.looping = packet.looping; + response.pitch = packet.pitch; + + sessions::broadcast(session->dimension, protocol::encode(response), packet.peer); + } +} + +void server_recieve::init(void) +{ + globals::dispatcher.sink<protocol::EntityTransform>().connect<&on_entity_transform_packet>(); + globals::dispatcher.sink<protocol::EntityVelocity>().connect<&on_entity_velocity_packet>(); + globals::dispatcher.sink<protocol::EntityHead>().connect<&on_entity_head_packet>(); + globals::dispatcher.sink<protocol::SetVoxel>().connect<&on_set_voxel_packet>(); + globals::dispatcher.sink<protocol::RequestChunk>().connect<&on_request_chunk_packet>(); + globals::dispatcher.sink<protocol::EntitySound>().connect<&on_entity_sound_packet>(); +} diff --git a/game/server/receive.hh b/src/game/server/receive.hh index a8d531e..4150226 100644 --- a/game/server/receive.hh +++ b/src/game/server/receive.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace server_recieve
-{
-void init(void);
-} // namespace server_recieve
+#pragma once + +namespace server_recieve +{ +void init(void); +} // namespace server_recieve diff --git a/game/server/sessions.cc b/src/game/server/sessions.cc index b8dbbea..3a63ae8 100644 --- a/game/server/sessions.cc +++ b/src/game/server/sessions.cc @@ -1,452 +1,452 @@ -#include "server/pch.hh"
-
-#include "server/sessions.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-#include "core/math/crc64.hh"
-
-#include "core/utils/string.hh"
-
-#include "core/version.hh"
-
-#include "shared/entity/factory.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-#include "shared/world/item_registry.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/protocol.hh"
-
-#include "server/game.hh"
-#include "server/globals.hh"
-#include "server/whitelist.hh"
-
-class DimensionListener final {
-public:
- explicit DimensionListener(world::Dimension* dimension);
- void on_destroy_entity(const entt::registry& registry, entt::entity entity);
-
-private:
- world::Dimension* dimension;
-};
-
-config::Unsigned sessions::max_players(8U, 1U, 128U);
-unsigned int sessions::num_players = 0U;
-
-static config::Boolean strict_version_matching(true);
-
-static emhash8::HashMap<std::string, Session*> username_map;
-static emhash8::HashMap<std::uint64_t, Session*> identity_map;
-static std::vector<DimensionListener> dimension_listeners;
-static std::vector<Session> sessions_vector;
-
-static void on_login_request_packet(const protocol::LoginRequest& packet)
-{
- if(packet.game_version_major > version::major) {
- protocol::Disconnect response;
- response.reason = "protocol.outdated_server";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(packet.game_version_minor < version::minor) {
- protocol::Disconnect response;
- response.reason = "protocol.outdated_client";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(strict_version_matching.get_value()) {
- if(packet.game_version_minor > version::minor || packet.game_version_patch > version::patch) {
- protocol::Disconnect response;
- response.reason = "protocol.outdated_server";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(packet.game_version_minor < version::minor || packet.game_version_patch < version::patch) {
- protocol::Disconnect response;
- response.reason = "protocol.outdated_client";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
- }
-
- // FIXME: calculate voxel registry checksum ahead of time
- // instead of figuring it out every time a new player connects
- if(packet.voxel_registry_checksum != world::voxel_registry::get_checksum()) {
- protocol::Disconnect response;
- response.reason = "protocol.voxel_registry_checksum";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(packet.item_registry_checksum != world::item_registry::get_checksum()) {
- protocol::Disconnect response;
- response.reason = "protocol.item_registry_checksum";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- // Don't assign new usernames and just kick the player if
- // an another client using the same username is already connected
- // and playing; since we have a whitelist, adding "(1)" isn't feasible anymore
- if(username_map.contains(packet.username)) {
- protocol::Disconnect response;
- response.reason = "protocol.username_taken";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(whitelist::enabled.get_value()) {
- if(!whitelist::contains(packet.username.c_str())) {
- protocol::Disconnect response;
- response.reason = "protocol.not_whitelisted";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(!whitelist::matches(packet.username.c_str(), packet.password_hash)) {
- protocol::Disconnect response;
- response.reason = "protocol.password_incorrect";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
- }
- else if(packet.password_hash != server_game::password_hash) {
- protocol::Disconnect response;
- response.reason = "protocol.password_incorrect";
- protocol::send(packet.peer, protocol::encode(response));
- return;
- }
-
- if(Session* session = sessions::create(packet.peer, packet.username.c_str())) {
- protocol::LoginResponse response;
- response.client_index = session->client_index;
- response.client_identity = session->client_identity;
- response.server_tickrate = globals::tickrate;
- protocol::send(packet.peer, protocol::encode(response));
-
- protocol::DimensionInfo dim_info;
- dim_info.name = globals::spawn_dimension->get_name();
- dim_info.gravity = globals::spawn_dimension->get_gravity();
- protocol::send(packet.peer, protocol::encode(dim_info));
-
- spdlog::info("sessions: {} [{}] logged in with client_index={} in {}", session->client_username, session->client_identity,
- session->client_index, globals::spawn_dimension->get_name());
-
- // FIXME: only send entities that are present within the current
- // player's view bounding box; this also would mean we're not sending
- // anything here and just straight up spawing the player and await them
- // to receive all the chunks and entites they feel like requesting
- for(auto entity : globals::spawn_dimension->entities.view<entt::entity>()) {
- if(const auto head = globals::spawn_dimension->entities.try_get<entity::Head>(entity)) {
- protocol::EntityHead head_packet;
- head_packet.entity = entity;
- head_packet.angles = head->angles;
- protocol::send(session->peer, protocol::encode(head_packet));
- }
-
- if(const auto transform = globals::spawn_dimension->entities.try_get<entity::Transform>(entity)) {
- protocol::EntityTransform transform_packet;
- transform_packet.entity = entity;
- transform_packet.angles = transform->angles;
- transform_packet.chunk = transform->chunk;
- transform_packet.local = transform->local;
- protocol::send(session->peer, protocol::encode(transform_packet));
- }
-
- if(const auto velocity = globals::spawn_dimension->entities.try_get<entity::Velocity>(entity)) {
- protocol::EntityVelocity velocity_packet;
- velocity_packet.entity = entity;
- velocity_packet.value = velocity->value;
- protocol::send(session->peer, protocol::encode(velocity_packet));
- }
-
- if(globals::spawn_dimension->entities.all_of<entity::Player>(entity)) {
- protocol::EntityPlayer player_packet;
- player_packet.entity = entity;
- protocol::send(session->peer, protocol::encode(player_packet));
- }
- }
-
- session->dimension = globals::spawn_dimension;
- session->player_entity = globals::spawn_dimension->entities.create();
- entity::shared::create_player(globals::spawn_dimension, session->player_entity);
-
- const auto& head = globals::spawn_dimension->entities.get<entity::Head>(session->player_entity);
- const auto& transform = globals::spawn_dimension->entities.get<entity::Transform>(session->player_entity);
- const auto& velocity = globals::spawn_dimension->entities.get<entity::Velocity>(session->player_entity);
-
- protocol::EntityHead head_packet;
- head_packet.entity = session->player_entity;
- head_packet.angles = head.angles;
-
- protocol::EntityTransform transform_packet;
- transform_packet.entity = session->player_entity;
- transform_packet.angles = transform.angles;
- transform_packet.chunk = transform.chunk;
- transform_packet.local = transform.local;
-
- protocol::EntityVelocity velocity_packet;
- velocity_packet.entity = session->player_entity;
- velocity_packet.value = velocity.value;
-
- protocol::EntityPlayer player_packet;
- player_packet.entity = session->player_entity;
-
- protocol::broadcast(globals::server_host, protocol::encode(head_packet));
- protocol::broadcast(globals::server_host, protocol::encode(transform_packet));
- protocol::broadcast(globals::server_host, protocol::encode(velocity_packet));
- protocol::broadcast(globals::server_host, protocol::encode(player_packet));
-
- protocol::SpawnPlayer spawn_packet;
- spawn_packet.entity = session->player_entity;
-
- // SpawnPlayer serves a different purpose compared to EntityPlayer
- // The latter is used to construct entities (as in "attach a component")
- // whilst the SpawnPlayer packet is used to notify client-side that the
- // entity identifier in the packet is to be treated as the local player entity
- protocol::send(session->peer, protocol::encode(spawn_packet));
-
- protocol::ChatMessage message;
- message.type = protocol::ChatMessage::PLAYER_JOIN;
- message.sender = session->client_username;
- message.message = std::string();
-
- protocol::broadcast(globals::server_host, protocol::encode(message));
-
- sessions::refresh_scoreboard();
-
- return;
- }
-
- protocol::Disconnect response;
- response.reason = "protocol.server_full";
- protocol::send(packet.peer, protocol::encode(response));
-}
-
-static void on_disconnect_packet(const protocol::Disconnect& packet)
-{
- if(Session* session = sessions::find(packet.peer)) {
- protocol::ChatMessage message;
- message.type = protocol::ChatMessage::PLAYER_LEAVE;
- message.sender = session->client_username;
- message.message = packet.reason;
-
- protocol::broadcast(globals::server_host, protocol::encode(message), session->peer);
-
- spdlog::info("{} disconnected ({})", session->client_username, packet.reason);
-
- sessions::destroy(session);
- sessions::refresh_scoreboard();
- }
-}
-
-// NOTE: [sessions] is a good place for this since [receive]
-// handles entity data sent by players and [sessions] handles
-// everything else network related that is not player movement
-static void on_voxel_set(const world::VoxelSetEvent& event)
-{
- protocol::SetVoxel packet;
- packet.vpos = coord::to_voxel(event.cpos, event.lpos);
- packet.voxel = event.voxel ? event.voxel->get_id() : NULL_VOXEL_ID;
- packet.flags = 0U; // UNDONE
- protocol::broadcast(globals::server_host, protocol::encode(packet));
-}
-
-DimensionListener::DimensionListener(world::Dimension* dimension)
-{
- this->dimension = dimension;
-}
-
-void DimensionListener::on_destroy_entity(const entt::registry& registry, entt::entity entity)
-{
- protocol::RemoveEntity packet;
- packet.entity = entity;
- sessions::broadcast(dimension, protocol::encode(packet));
-}
-
-void sessions::init(void)
-{
- globals::server_config.add_value("sessions.strict_version_matching", strict_version_matching);
- globals::server_config.add_value("sessions.max_players", sessions::max_players);
-
- globals::dispatcher.sink<protocol::LoginRequest>().connect<&on_login_request_packet>();
- globals::dispatcher.sink<protocol::Disconnect>().connect<&on_disconnect_packet>();
-
- globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>();
-}
-
-void sessions::init_late(void)
-{
- sessions::num_players = 0U;
-
- username_map.clear();
- identity_map.clear();
- sessions_vector.resize(sessions::max_players.get_value(), Session());
-
- for(unsigned int i = 0U; i < sessions::max_players.get_value(); ++i) {
- sessions_vector[i].client_index = UINT16_MAX;
- sessions_vector[i].client_identity = UINT64_MAX;
- sessions_vector[i].client_username = std::string();
- sessions_vector[i].player_entity = entt::null;
- sessions_vector[i].peer = nullptr;
- }
-}
-
-void sessions::init_post_universe(void)
-{
- for(auto& dimension : globals::dimensions) {
- dimension_listeners.push_back(DimensionListener(dimension.second));
- dimension.second->entities.on_destroy<entt::entity>().connect<&DimensionListener::on_destroy_entity>(dimension_listeners.back());
- }
-}
-
-void sessions::shutdown(void)
-{
- username_map.clear();
- identity_map.clear();
- sessions_vector.clear();
- dimension_listeners.clear();
-}
-
-Session* sessions::create(ENetPeer* peer, std::string_view client_username)
-{
- for(unsigned int i = 0U; i < sessions::max_players.get_value(); ++i) {
- if(!sessions_vector[i].peer) {
- std::uint64_t client_identity = math::crc64(client_username.data(), client_username.size());
-
- sessions_vector[i].client_index = i;
- sessions_vector[i].client_identity = client_identity;
- sessions_vector[i].client_username = client_username;
- sessions_vector[i].player_entity = entt::null;
- sessions_vector[i].peer = peer;
-
- username_map[std::string(client_username)] = &sessions_vector[i];
- identity_map[client_identity] = &sessions_vector[i];
-
- peer->data = &sessions_vector[i];
-
- sessions::num_players += 1U;
-
- return &sessions_vector[i];
- }
- }
-
- return nullptr;
-}
-
-Session* sessions::find(std::string_view client_username)
-{
- const auto it = username_map.find(std::string(client_username));
- if(it != username_map.cend()) {
- return it->second;
- }
- else {
- return nullptr;
- }
-}
-
-Session* sessions::find(std::uint16_t client_index)
-{
- if(client_index < sessions_vector.size()) {
- if(!sessions_vector[client_index].peer) {
- return nullptr;
- }
- else {
- return &sessions_vector[client_index];
- }
- }
-
- return nullptr;
-}
-
-Session* sessions::find(std::uint64_t client_identity)
-{
- const auto it = identity_map.find(client_identity);
-
- if(it != identity_map.cend()) {
- return it->second;
- }
- else {
- return nullptr;
- }
-}
-
-Session* sessions::find(ENetPeer* peer)
-{
- if(peer != nullptr) {
- return reinterpret_cast<Session*>(peer->data);
- }
- else {
- return nullptr;
- }
-}
-
-void sessions::destroy(Session* session)
-{
- if(session) {
- if(session->peer) {
- // Make sure we don't leave a mark
- session->peer->data = nullptr;
- }
-
- if(session->dimension) {
- session->dimension->entities.destroy(session->player_entity);
- }
-
- username_map.erase(session->client_username);
- identity_map.erase(session->client_identity);
-
- session->client_index = UINT16_MAX;
- session->client_identity = UINT64_MAX;
- session->client_username = std::string();
- session->player_entity = entt::null;
- session->peer = nullptr;
-
- sessions::num_players -= 1U;
- }
-}
-
-void sessions::broadcast(const world::Dimension* dimension, ENetPacket* packet)
-{
- for(const auto& session : sessions_vector) {
- if(session.peer && (session.dimension == dimension)) {
- enet_peer_send(session.peer, protocol::CHANNEL, packet);
- }
- }
-}
-
-void sessions::broadcast(const world::Dimension* dimension, ENetPacket* packet, ENetPeer* except)
-{
- for(const auto& session : sessions_vector) {
- if(session.peer && (session.peer != except)) {
- enet_peer_send(session.peer, protocol::CHANNEL, packet);
- }
- }
-}
-
-void sessions::refresh_scoreboard(void)
-{
- protocol::ScoreboardUpdate packet;
-
- for(std::size_t i = 0; i < sessions::max_players.get_value(); ++i) {
- if(sessions_vector[i].peer) {
- packet.names.push_back(sessions_vector[i].client_username);
- }
- }
-
- protocol::broadcast(globals::server_host, protocol::encode(packet));
-}
+#include "server/pch.hh" + +#include "server/sessions.hh" + +#include "core/config/boolean.hh" +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "core/math/constexpr.hh" +#include "core/math/crc64.hh" + +#include "core/utils/string.hh" + +#include "core/version.hh" + +#include "shared/entity/factory.hh" +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" +#include "shared/world/item_registry.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/protocol.hh" + +#include "server/game.hh" +#include "server/globals.hh" +#include "server/whitelist.hh" + +class DimensionListener final { +public: + explicit DimensionListener(world::Dimension* dimension); + void on_destroy_entity(const entt::registry& registry, entt::entity entity); + +private: + world::Dimension* dimension; +}; + +config::Unsigned sessions::max_players(8U, 1U, 128U); +unsigned int sessions::num_players = 0U; + +static config::Boolean strict_version_matching(true); + +static emhash8::HashMap<std::string, Session*> username_map; +static emhash8::HashMap<std::uint64_t, Session*> identity_map; +static std::vector<DimensionListener> dimension_listeners; +static std::vector<Session> sessions_vector; + +static void on_login_request_packet(const protocol::LoginRequest& packet) +{ + if(packet.game_version_major > version::major) { + protocol::Disconnect response; + response.reason = "protocol.outdated_server"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(packet.game_version_minor < version::minor) { + protocol::Disconnect response; + response.reason = "protocol.outdated_client"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(strict_version_matching.get_value()) { + if(packet.game_version_minor > version::minor || packet.game_version_patch > version::patch) { + protocol::Disconnect response; + response.reason = "protocol.outdated_server"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(packet.game_version_minor < version::minor || packet.game_version_patch < version::patch) { + protocol::Disconnect response; + response.reason = "protocol.outdated_client"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + } + + // FIXME: calculate voxel registry checksum ahead of time + // instead of figuring it out every time a new player connects + if(packet.voxel_registry_checksum != world::voxel_registry::get_checksum()) { + protocol::Disconnect response; + response.reason = "protocol.voxel_registry_checksum"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(packet.item_registry_checksum != world::item_registry::get_checksum()) { + protocol::Disconnect response; + response.reason = "protocol.item_registry_checksum"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + // Don't assign new usernames and just kick the player if + // an another client using the same username is already connected + // and playing; since we have a whitelist, adding "(1)" isn't feasible anymore + if(username_map.contains(packet.username)) { + protocol::Disconnect response; + response.reason = "protocol.username_taken"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(whitelist::enabled.get_value()) { + if(!whitelist::contains(packet.username.c_str())) { + protocol::Disconnect response; + response.reason = "protocol.not_whitelisted"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(!whitelist::matches(packet.username.c_str(), packet.password_hash)) { + protocol::Disconnect response; + response.reason = "protocol.password_incorrect"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + } + else if(packet.password_hash != server_game::password_hash) { + protocol::Disconnect response; + response.reason = "protocol.password_incorrect"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(Session* session = sessions::create(packet.peer, packet.username.c_str())) { + protocol::LoginResponse response; + response.client_index = session->client_index; + response.client_identity = session->client_identity; + response.server_tickrate = globals::tickrate; + protocol::send(packet.peer, protocol::encode(response)); + + protocol::DimensionInfo dim_info; + dim_info.name = globals::spawn_dimension->get_name(); + dim_info.gravity = globals::spawn_dimension->get_gravity(); + protocol::send(packet.peer, protocol::encode(dim_info)); + + spdlog::info("sessions: {} [{}] logged in with client_index={} in {}", session->client_username, session->client_identity, + session->client_index, globals::spawn_dimension->get_name()); + + // FIXME: only send entities that are present within the current + // player's view bounding box; this also would mean we're not sending + // anything here and just straight up spawing the player and await them + // to receive all the chunks and entites they feel like requesting + for(auto entity : globals::spawn_dimension->entities.view<entt::entity>()) { + if(const auto head = globals::spawn_dimension->entities.try_get<entity::Head>(entity)) { + protocol::EntityHead head_packet; + head_packet.entity = entity; + head_packet.angles = head->angles; + protocol::send(session->peer, protocol::encode(head_packet)); + } + + if(const auto transform = globals::spawn_dimension->entities.try_get<entity::Transform>(entity)) { + protocol::EntityTransform transform_packet; + transform_packet.entity = entity; + transform_packet.angles = transform->angles; + transform_packet.chunk = transform->chunk; + transform_packet.local = transform->local; + protocol::send(session->peer, protocol::encode(transform_packet)); + } + + if(const auto velocity = globals::spawn_dimension->entities.try_get<entity::Velocity>(entity)) { + protocol::EntityVelocity velocity_packet; + velocity_packet.entity = entity; + velocity_packet.value = velocity->value; + protocol::send(session->peer, protocol::encode(velocity_packet)); + } + + if(globals::spawn_dimension->entities.all_of<entity::Player>(entity)) { + protocol::EntityPlayer player_packet; + player_packet.entity = entity; + protocol::send(session->peer, protocol::encode(player_packet)); + } + } + + session->dimension = globals::spawn_dimension; + session->player_entity = globals::spawn_dimension->entities.create(); + entity::shared::create_player(globals::spawn_dimension, session->player_entity); + + const auto& head = globals::spawn_dimension->entities.get<entity::Head>(session->player_entity); + const auto& transform = globals::spawn_dimension->entities.get<entity::Transform>(session->player_entity); + const auto& velocity = globals::spawn_dimension->entities.get<entity::Velocity>(session->player_entity); + + protocol::EntityHead head_packet; + head_packet.entity = session->player_entity; + head_packet.angles = head.angles; + + protocol::EntityTransform transform_packet; + transform_packet.entity = session->player_entity; + transform_packet.angles = transform.angles; + transform_packet.chunk = transform.chunk; + transform_packet.local = transform.local; + + protocol::EntityVelocity velocity_packet; + velocity_packet.entity = session->player_entity; + velocity_packet.value = velocity.value; + + protocol::EntityPlayer player_packet; + player_packet.entity = session->player_entity; + + protocol::broadcast(globals::server_host, protocol::encode(head_packet)); + protocol::broadcast(globals::server_host, protocol::encode(transform_packet)); + protocol::broadcast(globals::server_host, protocol::encode(velocity_packet)); + protocol::broadcast(globals::server_host, protocol::encode(player_packet)); + + protocol::SpawnPlayer spawn_packet; + spawn_packet.entity = session->player_entity; + + // SpawnPlayer serves a different purpose compared to EntityPlayer + // The latter is used to construct entities (as in "attach a component") + // whilst the SpawnPlayer packet is used to notify client-side that the + // entity identifier in the packet is to be treated as the local player entity + protocol::send(session->peer, protocol::encode(spawn_packet)); + + protocol::ChatMessage message; + message.type = protocol::ChatMessage::PLAYER_JOIN; + message.sender = session->client_username; + message.message = std::string(); + + protocol::broadcast(globals::server_host, protocol::encode(message)); + + sessions::refresh_scoreboard(); + + return; + } + + protocol::Disconnect response; + response.reason = "protocol.server_full"; + protocol::send(packet.peer, protocol::encode(response)); +} + +static void on_disconnect_packet(const protocol::Disconnect& packet) +{ + if(Session* session = sessions::find(packet.peer)) { + protocol::ChatMessage message; + message.type = protocol::ChatMessage::PLAYER_LEAVE; + message.sender = session->client_username; + message.message = packet.reason; + + protocol::broadcast(globals::server_host, protocol::encode(message), session->peer); + + spdlog::info("{} disconnected ({})", session->client_username, packet.reason); + + sessions::destroy(session); + sessions::refresh_scoreboard(); + } +} + +// NOTE: [sessions] is a good place for this since [receive] +// handles entity data sent by players and [sessions] handles +// everything else network related that is not player movement +static void on_voxel_set(const world::VoxelSetEvent& event) +{ + protocol::SetVoxel packet; + packet.vpos = coord::to_voxel(event.cpos, event.lpos); + packet.voxel = event.voxel ? event.voxel->get_id() : NULL_VOXEL_ID; + packet.flags = 0U; // UNDONE + protocol::broadcast(globals::server_host, protocol::encode(packet)); +} + +DimensionListener::DimensionListener(world::Dimension* dimension) +{ + this->dimension = dimension; +} + +void DimensionListener::on_destroy_entity(const entt::registry& registry, entt::entity entity) +{ + protocol::RemoveEntity packet; + packet.entity = entity; + sessions::broadcast(dimension, protocol::encode(packet)); +} + +void sessions::init(void) +{ + globals::server_config.add_value("sessions.strict_version_matching", strict_version_matching); + globals::server_config.add_value("sessions.max_players", sessions::max_players); + + globals::dispatcher.sink<protocol::LoginRequest>().connect<&on_login_request_packet>(); + globals::dispatcher.sink<protocol::Disconnect>().connect<&on_disconnect_packet>(); + + globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>(); +} + +void sessions::init_late(void) +{ + sessions::num_players = 0U; + + username_map.clear(); + identity_map.clear(); + sessions_vector.resize(sessions::max_players.get_value(), Session()); + + for(unsigned int i = 0U; i < sessions::max_players.get_value(); ++i) { + sessions_vector[i].client_index = UINT16_MAX; + sessions_vector[i].client_identity = UINT64_MAX; + sessions_vector[i].client_username = std::string(); + sessions_vector[i].player_entity = entt::null; + sessions_vector[i].peer = nullptr; + } +} + +void sessions::init_post_universe(void) +{ + for(auto& dimension : globals::dimensions) { + dimension_listeners.push_back(DimensionListener(dimension.second)); + dimension.second->entities.on_destroy<entt::entity>().connect<&DimensionListener::on_destroy_entity>(dimension_listeners.back()); + } +} + +void sessions::shutdown(void) +{ + username_map.clear(); + identity_map.clear(); + sessions_vector.clear(); + dimension_listeners.clear(); +} + +Session* sessions::create(ENetPeer* peer, std::string_view client_username) +{ + for(unsigned int i = 0U; i < sessions::max_players.get_value(); ++i) { + if(!sessions_vector[i].peer) { + std::uint64_t client_identity = math::crc64(client_username.data(), client_username.size()); + + sessions_vector[i].client_index = i; + sessions_vector[i].client_identity = client_identity; + sessions_vector[i].client_username = client_username; + sessions_vector[i].player_entity = entt::null; + sessions_vector[i].peer = peer; + + username_map[std::string(client_username)] = &sessions_vector[i]; + identity_map[client_identity] = &sessions_vector[i]; + + peer->data = &sessions_vector[i]; + + sessions::num_players += 1U; + + return &sessions_vector[i]; + } + } + + return nullptr; +} + +Session* sessions::find(std::string_view client_username) +{ + const auto it = username_map.find(std::string(client_username)); + if(it != username_map.cend()) { + return it->second; + } + else { + return nullptr; + } +} + +Session* sessions::find(std::uint16_t client_index) +{ + if(client_index < sessions_vector.size()) { + if(!sessions_vector[client_index].peer) { + return nullptr; + } + else { + return &sessions_vector[client_index]; + } + } + + return nullptr; +} + +Session* sessions::find(std::uint64_t client_identity) +{ + const auto it = identity_map.find(client_identity); + + if(it != identity_map.cend()) { + return it->second; + } + else { + return nullptr; + } +} + +Session* sessions::find(ENetPeer* peer) +{ + if(peer != nullptr) { + return reinterpret_cast<Session*>(peer->data); + } + else { + return nullptr; + } +} + +void sessions::destroy(Session* session) +{ + if(session) { + if(session->peer) { + // Make sure we don't leave a mark + session->peer->data = nullptr; + } + + if(session->dimension) { + session->dimension->entities.destroy(session->player_entity); + } + + username_map.erase(session->client_username); + identity_map.erase(session->client_identity); + + session->client_index = UINT16_MAX; + session->client_identity = UINT64_MAX; + session->client_username = std::string(); + session->player_entity = entt::null; + session->peer = nullptr; + + sessions::num_players -= 1U; + } +} + +void sessions::broadcast(const world::Dimension* dimension, ENetPacket* packet) +{ + for(const auto& session : sessions_vector) { + if(session.peer && (session.dimension == dimension)) { + enet_peer_send(session.peer, protocol::CHANNEL, packet); + } + } +} + +void sessions::broadcast(const world::Dimension* dimension, ENetPacket* packet, ENetPeer* except) +{ + for(const auto& session : sessions_vector) { + if(session.peer && (session.peer != except)) { + enet_peer_send(session.peer, protocol::CHANNEL, packet); + } + } +} + +void sessions::refresh_scoreboard(void) +{ + protocol::ScoreboardUpdate packet; + + for(std::size_t i = 0; i < sessions::max_players.get_value(); ++i) { + if(sessions_vector[i].peer) { + packet.names.push_back(sessions_vector[i].client_username); + } + } + + protocol::broadcast(globals::server_host, protocol::encode(packet)); +} diff --git a/game/server/sessions.hh b/src/game/server/sessions.hh index 14d50e1..656b76d 100644 --- a/game/server/sessions.hh +++ b/src/game/server/sessions.hh @@ -1,55 +1,55 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace config
-{
-class Unsigned;
-} // namespace config
-
-struct Session final {
- std::uint16_t client_index;
- std::uint64_t client_identity;
- std::string client_username;
- entt::entity player_entity;
- world::Dimension* dimension;
- ENetPeer* peer;
-};
-
-namespace sessions
-{
-extern config::Unsigned max_players;
-extern unsigned int num_players;
-} // namespace sessions
-
-namespace sessions
-{
-void init(void);
-void init_late(void);
-void init_post_universe(void);
-void shutdown(void);
-} // namespace sessions
-
-namespace sessions
-{
-Session* create(ENetPeer* peer, std::string_view client_username);
-Session* find(std::string_view client_username);
-Session* find(std::uint16_t client_index);
-Session* find(std::uint64_t client_identity);
-Session* find(ENetPeer* peer);
-void destroy(Session* session);
-} // namespace sessions
-
-namespace sessions
-{
-void broadcast(const world::Dimension* dimension, ENetPacket* packet);
-void broadcast(const world::Dimension* dimension, ENetPacket* packet, ENetPeer* except);
-} // namespace sessions
-
-namespace sessions
-{
-void refresh_scoreboard(void);
-} // namespace sessions
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace config +{ +class Unsigned; +} // namespace config + +struct Session final { + std::uint16_t client_index; + std::uint64_t client_identity; + std::string client_username; + entt::entity player_entity; + world::Dimension* dimension; + ENetPeer* peer; +}; + +namespace sessions +{ +extern config::Unsigned max_players; +extern unsigned int num_players; +} // namespace sessions + +namespace sessions +{ +void init(void); +void init_late(void); +void init_post_universe(void); +void shutdown(void); +} // namespace sessions + +namespace sessions +{ +Session* create(ENetPeer* peer, std::string_view client_username); +Session* find(std::string_view client_username); +Session* find(std::uint16_t client_index); +Session* find(std::uint64_t client_identity); +Session* find(ENetPeer* peer); +void destroy(Session* session); +} // namespace sessions + +namespace sessions +{ +void broadcast(const world::Dimension* dimension, ENetPacket* packet); +void broadcast(const world::Dimension* dimension, ENetPacket* packet, ENetPeer* except); +} // namespace sessions + +namespace sessions +{ +void refresh_scoreboard(void); +} // namespace sessions diff --git a/game/server/status.cc b/src/game/server/status.cc index 0edd0a0..9414a76 100644 --- a/game/server/status.cc +++ b/src/game/server/status.cc @@ -1,30 +1,30 @@ -#include "server/pch.hh"
-
-#include "server/status.hh"
-
-#include "core/config/number.hh"
-
-#include "core/version.hh"
-
-#include "shared/protocol.hh"
-#include "shared/splash.hh"
-
-#include "server/globals.hh"
-#include "server/sessions.hh"
-
-static void on_status_request_packet(const protocol::StatusRequest& packet)
-{
- protocol::StatusResponse response;
- response.game_version_major = version::major;
- response.max_players = sessions::max_players.get_value();
- response.num_players = sessions::num_players;
- response.motd = splash::get();
- response.game_version_minor = version::minor;
- response.game_version_patch = version::patch;
- protocol::send(packet.peer, protocol::encode(response));
-}
-
-void status::init(void)
-{
- globals::dispatcher.sink<protocol::StatusRequest>().connect<&on_status_request_packet>();
-}
+#include "server/pch.hh" + +#include "server/status.hh" + +#include "core/config/number.hh" + +#include "core/version.hh" + +#include "shared/protocol.hh" +#include "shared/splash.hh" + +#include "server/globals.hh" +#include "server/sessions.hh" + +static void on_status_request_packet(const protocol::StatusRequest& packet) +{ + protocol::StatusResponse response; + response.game_version_major = version::major; + response.max_players = sessions::max_players.get_value(); + response.num_players = sessions::num_players; + response.motd = splash::get(); + response.game_version_minor = version::minor; + response.game_version_patch = version::patch; + protocol::send(packet.peer, protocol::encode(response)); +} + +void status::init(void) +{ + globals::dispatcher.sink<protocol::StatusRequest>().connect<&on_status_request_packet>(); +} diff --git a/game/server/status.hh b/src/game/server/status.hh index d298827..35370a0 100644 --- a/game/server/status.hh +++ b/src/game/server/status.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace status
-{
-void init(void);
-} // namespace status
+#pragma once + +namespace status +{ +void init(void); +} // namespace status diff --git a/src/game/server/vserver.ico b/src/game/server/vserver.ico Binary files differnew file mode 100644 index 0000000..02ff006 --- /dev/null +++ b/src/game/server/vserver.ico diff --git a/game/server/vserver.rc b/src/game/server/vserver.rc index b6828bf..b6828bf 100644 --- a/game/server/vserver.rc +++ b/src/game/server/vserver.rc diff --git a/game/server/whitelist.cc b/src/game/server/whitelist.cc index f2599b9..3f1c413 100644 --- a/game/server/whitelist.cc +++ b/src/game/server/whitelist.cc @@ -1,102 +1,102 @@ -#include "server/pch.hh"
-
-#include "server/whitelist.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-#include "core/io/physfs.hh"
-
-#include "core/math/crc64.hh"
-
-#include "core/utils/string.hh"
-
-#include "server/game.hh"
-#include "server/globals.hh"
-
-constexpr static std::string_view DEFAULT_FILENAME = "whitelist.txt";
-constexpr static char SEPARATOR_CHAR = ':';
-
-config::Boolean whitelist::enabled(false);
-config::String whitelist::filename(DEFAULT_FILENAME);
-
-static emhash8::HashMap<std::string, std::uint64_t> whitelist_map;
-
-void whitelist::init(void)
-{
- globals::server_config.add_value("whitelist.enabled", whitelist::enabled);
- globals::server_config.add_value("whitelist.filename", whitelist::filename);
-}
-
-void whitelist::init_late(void)
-{
- whitelist_map.clear();
-
- if(!whitelist::enabled.get_value()) {
- // Not enabled, shouldn't
- // even bother with parsing
- // the whitelist file
- return;
- }
-
- if(utils::is_whitespace(whitelist::filename.get_value())) {
- spdlog::warn("whitelist: enabled but filename is empty, using default ({})", DEFAULT_FILENAME);
- whitelist::filename.set(DEFAULT_FILENAME);
- }
-
- PHYSFS_File* file = PHYSFS_openRead(whitelist::filename.c_str());
-
- if(file == nullptr) {
- spdlog::warn("whitelist: {}: {}", whitelist::filename.get(), io::physfs_error());
- whitelist::enabled.set_value(false);
- return;
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- std::istringstream stream(source);
- std::string line;
-
- while(std::getline(stream, line)) {
- const auto location = line.find_last_of(SEPARATOR_CHAR);
-
- if(location == std::string::npos) {
- // Entries that don't define a password field default
- // to the global server password; this allows easier adding
- // of guest accounts which can later be edited to use a better password
- whitelist_map[line] = server_game::password_hash;
- }
- else {
- const auto username = line.substr(0, location);
- const auto password = line.substr(location + 1);
- whitelist_map[username] = math::crc64(password);
- }
- }
-
- PHYSFS_close(file);
-}
-
-void whitelist::shutdown(void)
-{
- // UNDONE: implement saving
-}
-
-bool whitelist::contains(std::string_view username)
-{
- return whitelist_map.contains(std::string(username));
-}
-
-bool whitelist::matches(std::string_view username, std::uint64_t password_hash)
-{
- const auto it = whitelist_map.find(std::string(username));
-
- if(it == whitelist_map.cend()) {
- // Not whitelisted, no match
- return false;
- }
-
- return it->second == password_hash;
-}
+#include "server/pch.hh" + +#include "server/whitelist.hh" + +#include "core/config/boolean.hh" +#include "core/config/string.hh" + +#include "core/io/config_map.hh" +#include "core/io/physfs.hh" + +#include "core/math/crc64.hh" + +#include "core/utils/string.hh" + +#include "server/game.hh" +#include "server/globals.hh" + +constexpr static std::string_view DEFAULT_FILENAME = "whitelist.txt"; +constexpr static char SEPARATOR_CHAR = ':'; + +config::Boolean whitelist::enabled(false); +config::String whitelist::filename(DEFAULT_FILENAME); + +static emhash8::HashMap<std::string, std::uint64_t> whitelist_map; + +void whitelist::init(void) +{ + globals::server_config.add_value("whitelist.enabled", whitelist::enabled); + globals::server_config.add_value("whitelist.filename", whitelist::filename); +} + +void whitelist::init_late(void) +{ + whitelist_map.clear(); + + if(!whitelist::enabled.get_value()) { + // Not enabled, shouldn't + // even bother with parsing + // the whitelist file + return; + } + + if(utils::is_whitespace(whitelist::filename.get_value())) { + spdlog::warn("whitelist: enabled but filename is empty, using default ({})", DEFAULT_FILENAME); + whitelist::filename.set(DEFAULT_FILENAME); + } + + PHYSFS_File* file = PHYSFS_openRead(whitelist::filename.c_str()); + + if(file == nullptr) { + spdlog::warn("whitelist: {}: {}", whitelist::filename.get(), io::physfs_error()); + whitelist::enabled.set_value(false); + return; + } + + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + std::istringstream stream(source); + std::string line; + + while(std::getline(stream, line)) { + const auto location = line.find_last_of(SEPARATOR_CHAR); + + if(location == std::string::npos) { + // Entries that don't define a password field default + // to the global server password; this allows easier adding + // of guest accounts which can later be edited to use a better password + whitelist_map[line] = server_game::password_hash; + } + else { + const auto username = line.substr(0, location); + const auto password = line.substr(location + 1); + whitelist_map[username] = math::crc64(password); + } + } + + PHYSFS_close(file); +} + +void whitelist::shutdown(void) +{ + // UNDONE: implement saving +} + +bool whitelist::contains(std::string_view username) +{ + return whitelist_map.contains(std::string(username)); +} + +bool whitelist::matches(std::string_view username, std::uint64_t password_hash) +{ + const auto it = whitelist_map.find(std::string(username)); + + if(it == whitelist_map.cend()) { + // Not whitelisted, no match + return false; + } + + return it->second == password_hash; +} diff --git a/game/server/whitelist.hh b/src/game/server/whitelist.hh index 990b15a..4695d16 100644 --- a/game/server/whitelist.hh +++ b/src/game/server/whitelist.hh @@ -1,26 +1,26 @@ -#pragma once
-
-namespace config
-{
-class Boolean;
-class String;
-} // namespace config
-
-namespace whitelist
-{
-extern config::Boolean enabled;
-extern config::String filename;
-} // namespace whitelist
-
-namespace whitelist
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-} // namespace whitelist
-
-namespace whitelist
-{
-bool contains(std::string_view username);
-bool matches(std::string_view username, std::uint64_t password_hash);
-} // namespace whitelist
+#pragma once + +namespace config +{ +class Boolean; +class String; +} // namespace config + +namespace whitelist +{ +extern config::Boolean enabled; +extern config::String filename; +} // namespace whitelist + +namespace whitelist +{ +void init(void); +void init_late(void); +void shutdown(void); +} // namespace whitelist + +namespace whitelist +{ +bool contains(std::string_view username); +bool matches(std::string_view username, std::uint64_t password_hash); +} // namespace whitelist diff --git a/game/server/world/CMakeLists.txt b/src/game/server/world/CMakeLists.txt index 58a2216..58a2216 100644 --- a/game/server/world/CMakeLists.txt +++ b/src/game/server/world/CMakeLists.txt diff --git a/game/server/world/inhabited.hh b/src/game/server/world/inhabited.hh index 5eba9ef..57008e9 100644 --- a/game/server/world/inhabited.hh +++ b/src/game/server/world/inhabited.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace world
-{
-struct Inhabited final {};
-} // namespace world
+#pragma once + +namespace world +{ +struct Inhabited final {}; +} // namespace world diff --git a/game/server/world/overworld.cc b/src/game/server/world/overworld.cc index b72a816..1a558c1 100644 --- a/game/server/world/overworld.cc +++ b/src/game/server/world/overworld.cc @@ -1,385 +1,396 @@ -#include "server/pch.hh"
-
-#include "server/world/overworld.hh"
-
-#include "core/math/vectors.hh"
-
-#include "shared/world/voxel.hh"
-#include "shared/world/voxel_storage.hh"
-
-#include "shared/coord.hh"
-#include "shared/game_voxels.hh"
-
-// FIXME: load these from a file
-static void compute_tree_feature(unsigned int height, world::Feature& feature, const world::Voxel* log_voxel,
- const world::Voxel* leaves_voxel)
-{
- // Ensure the tree height is too small
- height = glm::max<unsigned int>(height, 4U);
-
- // Put down a single piece of dirt
- feature.push_back({ voxel_pos(0, -1, 0), game_voxels::dirt, true });
-
- // Generate tree stem
- for(unsigned int i = 0; i < height; ++i) {
- feature.push_back({ voxel_pos(0, i, 0), log_voxel, true });
- }
-
- auto leaves_start = height - 3U;
- auto leaves_thick_end = height - 2U;
- auto leaves_thin_end = height - 1U;
-
- // Generate the thin 3x3 layer of leaves that
- // starts from leaves_start and ends at leaves_thin_end
- for(unsigned int i = leaves_start; i <= leaves_thin_end; ++i) {
- feature.push_back({ local_pos(-1, i, -1), leaves_voxel, false });
- feature.push_back({ local_pos(-1, i, +0), leaves_voxel, false });
- feature.push_back({ local_pos(-1, i, +1), leaves_voxel, false });
- feature.push_back({ local_pos(+0, i, -1), leaves_voxel, false });
- feature.push_back({ local_pos(+0, i, +1), leaves_voxel, false });
- feature.push_back({ local_pos(+1, i, -1), leaves_voxel, false });
- feature.push_back({ local_pos(+1, i, +0), leaves_voxel, false });
- feature.push_back({ local_pos(+1, i, +1), leaves_voxel, false });
- }
-
- // Generate the tree cap; a 3x3 patch of leaves
- // that is slapped right on top of the thin 3x3 layer
- feature.push_back({ local_pos(-1, height, +0), leaves_voxel, false });
- feature.push_back({ local_pos(+0, height, -1), leaves_voxel, false });
- feature.push_back({ local_pos(+0, height, +0), leaves_voxel, false });
- feature.push_back({ local_pos(+0, height, +1), leaves_voxel, false });
- feature.push_back({ local_pos(+1, height, +0), leaves_voxel, false });
-
- // Generate the thin 5x5 layer of leaves that
- // starts from leaves_start and ends at leaves_thin_end
- for(unsigned int i = leaves_start; i <= leaves_thick_end; ++i) {
- feature.push_back({ local_pos(-1, i, -2), leaves_voxel, false });
- feature.push_back({ local_pos(-1, i, +2), leaves_voxel, false });
- feature.push_back({ local_pos(-2, i, -1), leaves_voxel, false });
- feature.push_back({ local_pos(-2, i, -2), leaves_voxel, false });
- feature.push_back({ local_pos(-2, i, +0), leaves_voxel, false });
- feature.push_back({ local_pos(-2, i, +1), leaves_voxel, false });
- feature.push_back({ local_pos(-2, i, +2), leaves_voxel, false });
- feature.push_back({ local_pos(+0, i, -2), leaves_voxel, false });
- feature.push_back({ local_pos(+0, i, +2), leaves_voxel, false });
- feature.push_back({ local_pos(+1, i, -2), leaves_voxel, false });
- feature.push_back({ local_pos(+1, i, +2), leaves_voxel, false });
- feature.push_back({ local_pos(+2, i, -1), leaves_voxel, false });
- feature.push_back({ local_pos(+2, i, -2), leaves_voxel, false });
- feature.push_back({ local_pos(+2, i, +0), leaves_voxel, false });
- feature.push_back({ local_pos(+2, i, +1), leaves_voxel, false });
- feature.push_back({ local_pos(+2, i, +2), leaves_voxel, false });
- }
-}
-
-world::Overworld::Overworld(std::string_view name) : Dimension(name, -30.0f)
-{
- m_bottommost_chunk.set_limits(-64, -4);
- m_terrain_variation.set_limits(16, 256);
-
- compute_tree_feature(4U, m_feat_tree[0], game_voxels::oak_log, game_voxels::oak_leaves);
- compute_tree_feature(5U, m_feat_tree[1], game_voxels::oak_log, game_voxels::oak_leaves);
- compute_tree_feature(6U, m_feat_tree[2], game_voxels::oak_log, game_voxels::oak_leaves);
- compute_tree_feature(8U, m_feat_tree[3], game_voxels::oak_log, game_voxels::oak_leaves);
-}
-
-void world::Overworld::init(io::ConfigMap& config)
-{
- m_terrain_variation.set_value(64);
- m_bottommost_chunk.set_value(-4);
-
- config.add_value("overworld.terrain_variation", m_terrain_variation);
- config.add_value("overworld.bottommost_chunk", m_bottommost_chunk);
-}
-
-void world::Overworld::init_late(std::uint64_t global_seed)
-{
- std::mt19937 twister(global_seed);
-
- m_fnl_variation = fnlCreateState();
- m_fnl_variation.seed = static_cast<int>(twister());
- m_fnl_variation.noise_type = FNL_NOISE_PERLIN;
- m_fnl_variation.frequency = 0.001f;
-
- m_fnl_terrain = fnlCreateState();
- m_fnl_terrain.seed = static_cast<int>(twister());
- m_fnl_terrain.noise_type = FNL_NOISE_OPENSIMPLEX2S;
- m_fnl_terrain.fractal_type = FNL_FRACTAL_FBM;
- m_fnl_terrain.frequency = 0.005f;
- m_fnl_terrain.octaves = 4;
-
- m_fnl_caves_a = fnlCreateState();
- m_fnl_caves_a.seed = static_cast<int>(twister());
- m_fnl_caves_a.noise_type = FNL_NOISE_PERLIN;
- m_fnl_caves_a.fractal_type = FNL_FRACTAL_RIDGED;
- m_fnl_caves_a.frequency = 0.0125f;
- m_fnl_caves_a.octaves = 1;
-
- m_fnl_caves_b = fnlCreateState();
- m_fnl_caves_b.seed = static_cast<int>(twister());
- m_fnl_caves_b.noise_type = FNL_NOISE_OPENSIMPLEX2S;
- m_fnl_caves_b.fractal_type = FNL_FRACTAL_RIDGED;
- m_fnl_caves_b.frequency = 0.0125f;
- m_fnl_caves_b.octaves = 1;
-
- m_fnl_nvdi = fnlCreateState();
- m_fnl_nvdi.seed = static_cast<int>(twister());
- m_fnl_nvdi.noise_type = FNL_NOISE_OPENSIMPLEX2S;
- m_fnl_nvdi.frequency = 1.0f;
-
- m_metamap.clear();
-}
-
-bool world::Overworld::generate(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- if(cpos.y <= m_bottommost_chunk.get_value()) {
- // If the player asks the generator
- // to generate a lot of stuff below
- // the surface, it will happily chew
- // through all the server threads
- return false;
- }
-
- voxels.fill(NULL_VOXEL_ID);
-
- m_mutex.lock();
- generate_terrain(cpos, voxels);
- m_mutex.unlock();
-
- m_mutex.lock();
- generate_surface(cpos, voxels);
- m_mutex.unlock();
-
- m_mutex.lock();
- generate_caves(cpos, voxels);
- m_mutex.unlock();
-
- m_mutex.lock();
- generate_features(cpos, voxels);
- m_mutex.unlock();
-
- return true;
-}
-
-bool world::Overworld::is_inside_cave(const voxel_pos& vpos)
-{
- auto noise_a = fnlGetNoise3D(&m_fnl_caves_a, vpos.x, vpos.y * 2.0f, vpos.z);
- auto noise_b = fnlGetNoise3D(&m_fnl_caves_b, vpos.x, vpos.y * 2.0f, vpos.z);
- return (noise_a > 0.95f) && (noise_b > 0.85f);
-}
-
-bool world::Overworld::is_inside_terrain(const voxel_pos& vpos)
-{
- auto variation_noise = fnlGetNoise3D(&m_fnl_terrain, vpos.x, vpos.y, vpos.z);
- auto variation = m_terrain_variation.get_value() * (1.0f - (variation_noise * variation_noise));
- auto noise = variation * fnlGetNoise3D(&m_fnl_terrain, vpos.x, vpos.y, vpos.z) - vpos.y;
- return noise > 0.0f;
-}
-
-const world::Overworld_Metadata& world::Overworld::get_or_create_metadata(const chunk_pos_xz& cpos)
-{
- auto it = m_metamap.find(cpos);
-
- if(it != m_metamap.cend()) {
- // Metadata is present
- return it->second;
- }
-
- auto& metadata = m_metamap.insert_or_assign(cpos, Overworld_Metadata()).first->second;
- metadata.entropy.fill(std::numeric_limits<std::uint64_t>::max());
- metadata.heightmap.fill(std::numeric_limits<voxel_pos::value_type>::min());
-
- auto twister = std::mt19937_64(std::hash<chunk_pos_xz>()(cpos));
- auto variation = m_terrain_variation.get_value();
-
- // Generator might need some randomness
- // that depends on 2D coordinates, so we
- // generate this entropy ahead of time
- for(int i = 0; i < CHUNK_AREA; ++i) {
- metadata.entropy[i] = twister();
- }
-
- // Generate speculative heightmap;
- // Cave generation might have issues with placing
- // surface features such as trees but I genuinely don't give a shit
- for(int lx = 0; lx < CHUNK_SIZE; lx += 1) {
- for(int lz = 0; lz < CHUNK_SIZE; lz += 1) {
- auto hdx = static_cast<std::size_t>(lx + lz * CHUNK_SIZE);
- auto vpos = coord::to_voxel(chunk_pos(cpos.x, 0, cpos.y), local_pos(lx, 0, lz));
-
- for(vpos.y = variation; vpos.y >= -variation; vpos.y -= 1) {
- if(is_inside_terrain(vpos)) {
- metadata.heightmap[hdx] = vpos.y;
- break;
- }
- }
- }
- }
-
- auto nvdi_value = 0.5f + 0.5f * fnlGetNoise2D(&m_fnl_nvdi, cpos.x, cpos.y);
- auto tree_density = (nvdi_value >= 0.33f) ? static_cast<unsigned int>(glm::floor(nvdi_value * 4.0f)) : 0U;
-
- for(unsigned int i = 0U; i < tree_density; ++i) {
- auto lpos = local_pos((twister() % CHUNK_SIZE), (twister() % OW_NUM_TREES), (twister() % CHUNK_SIZE));
- auto is_unique = true;
-
- for(const auto& check_lpos : metadata.trees) {
- if(math::distance2(check_lpos, lpos) <= 9) {
- is_unique = false;
- break;
- }
- }
-
- if(is_unique) {
- metadata.trees.push_back(lpos);
- }
- }
-
- return metadata;
-}
-
-void world::Overworld::generate_terrain(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z));
- auto variation = m_terrain_variation.get_value();
-
- for(unsigned long i = 0; i < CHUNK_VOLUME; ++i) {
- auto lpos = coord::to_local(i);
- auto vpos = coord::to_voxel(cpos, lpos);
-
- if(vpos.y > variation) {
- voxels[i] = NULL_VOXEL_ID;
- continue;
- }
-
- if(vpos.y < -variation) {
- voxels[i] = game_voxels::stone->get_id();
- continue;
- }
-
- if(is_inside_terrain(vpos)) {
- voxels[i] = game_voxels::stone->get_id();
- continue;
- }
- }
-}
-
-void world::Overworld::generate_surface(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z));
- auto variation = m_terrain_variation.get_value();
-
- for(unsigned long i = 0; i < CHUNK_VOLUME; ++i) {
- auto lpos = coord::to_local(i);
- auto vpos = coord::to_voxel(cpos, lpos);
- auto hdx = static_cast<std::size_t>(lpos.x + lpos.z * CHUNK_SIZE);
-
- if((vpos.y > variation) || (vpos.y < -variation)) {
- // Speculative optimization
- continue;
- }
-
- if(voxels[i] == NULL_VOXEL_ID) {
- // Surface voxel checks only apply for solid voxels;
- // it's kind of obvious you can't replace air with grass
- continue;
- }
-
- unsigned int depth = 0U;
-
- for(unsigned int dy = 0U; dy < 5U; dy += 1U) {
- auto d_lpos = local_pos(lpos.x, lpos.y + dy + 1, lpos.z);
- auto d_vpos = coord::to_voxel(cpos, d_lpos);
- auto d_index = coord::to_index(d_lpos);
-
- if(d_lpos.y >= CHUNK_SIZE) {
- if(!is_inside_terrain(d_vpos)) {
- break;
- }
-
- depth += 1U;
- }
- else {
- if(voxels[d_index] == NULL_VOXEL_ID) {
- break;
- }
-
- depth += 1U;
- }
- }
-
- if(depth < 5U) {
- if(depth == 0U) {
- voxels[i] = game_voxels::grass->get_id();
- }
- else {
- voxels[i] = game_voxels::dirt->get_id();
- }
- }
- }
-}
-
-void world::Overworld::generate_caves(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z));
- auto variation = m_terrain_variation.get_value();
-
- for(unsigned long i = 0U; i < CHUNK_VOLUME; ++i) {
- auto lpos = coord::to_local(i);
- auto vpos = coord::to_voxel(cpos, lpos);
-
- if(vpos.y > variation) {
- // Speculative optimization - there's no solid
- // terrain above variation to carve caves out from
- continue;
- }
-
- if(is_inside_cave(vpos)) {
- voxels[i] = NULL_VOXEL_ID;
- continue;
- }
- }
-}
-
-void world::Overworld::generate_features(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- const chunk_pos_xz tree_chunks[] = {
- chunk_pos_xz(cpos.x - 0, cpos.z - 1),
- chunk_pos_xz(cpos.x - 1, cpos.z - 1),
- chunk_pos_xz(cpos.x - 1, cpos.z + 0),
- chunk_pos_xz(cpos.x - 1, cpos.z + 1),
- chunk_pos_xz(cpos.x + 0, cpos.z + 0),
- chunk_pos_xz(cpos.x + 0, cpos.z + 1),
- chunk_pos_xz(cpos.x + 1, cpos.z - 1),
- chunk_pos_xz(cpos.x + 1, cpos.z + 0),
- chunk_pos_xz(cpos.x + 1, cpos.z + 1),
- };
-
- for(unsigned int i = 0U; i < math::array_size(tree_chunks); ++i) {
- const auto& cpos_xz = tree_chunks[i];
- const auto& metadata = get_or_create_metadata(cpos_xz);
-
- for(const auto& tree_info : metadata.trees) {
- auto hdx = static_cast<std::size_t>(tree_info.x + tree_info.z * CHUNK_SIZE);
- auto height = metadata.heightmap[hdx];
-
- if(height == std::numeric_limits<voxel_pos::value_type>::min()) {
- // What happened? Cave happened
- continue;
- }
-
- auto cpos_xyz = chunk_pos(cpos_xz.x, 0, cpos_xz.y);
- auto lpos_xyz = local_pos(tree_info.x, 0, tree_info.z);
-
- auto vpos = coord::to_voxel(cpos_xyz, lpos_xyz);
- vpos.y = height;
-
- if(is_inside_cave(vpos)) {
- // Cave is in the way
- continue;
- }
-
- m_feat_tree[tree_info.y].place(vpos + DIR_UP<voxel_pos::value_type>, cpos, voxels);
- }
- }
-}
+#include "server/pch.hh" + +#include "server/world/overworld.hh" + +#include "core/math/vectors.hh" + +#include "shared/world/voxel.hh" +#include "shared/world/voxel_storage.hh" + +#include "shared/coord.hh" +#include "shared/game_voxels.hh" + +// FIXME: load these from a file +static void compute_tree_feature(unsigned int height, world::Feature& feature, const world::Voxel* log_voxel, + const world::Voxel* leaves_voxel) +{ + // Ensure the tree height is too small + height = glm::max<unsigned int>(height, 4U); + + // Put down a single piece of dirt + feature.push_back({ voxel_pos(0, -1, 0), game_voxels::dirt, true }); + + // Generate tree stem + for(unsigned int i = 0; i < height; ++i) { + feature.push_back({ voxel_pos(0, i, 0), log_voxel, true }); + } + + auto leaves_start = height - 3U; + auto leaves_thick_end = height - 2U; + auto leaves_thin_end = height - 1U; + + // Generate the thin 3x3 layer of leaves that + // starts from leaves_start and ends at leaves_thin_end + for(unsigned int i = leaves_start; i <= leaves_thin_end; ++i) { + feature.push_back({ local_pos(-1, i, -1), leaves_voxel, false }); + feature.push_back({ local_pos(-1, i, +0), leaves_voxel, false }); + feature.push_back({ local_pos(-1, i, +1), leaves_voxel, false }); + feature.push_back({ local_pos(+0, i, -1), leaves_voxel, false }); + feature.push_back({ local_pos(+0, i, +1), leaves_voxel, false }); + feature.push_back({ local_pos(+1, i, -1), leaves_voxel, false }); + feature.push_back({ local_pos(+1, i, +0), leaves_voxel, false }); + feature.push_back({ local_pos(+1, i, +1), leaves_voxel, false }); + } + + // Generate the tree cap; a 3x3 patch of leaves + // that is slapped right on top of the thin 3x3 layer + feature.push_back({ local_pos(-1, height, +0), leaves_voxel, false }); + feature.push_back({ local_pos(+0, height, -1), leaves_voxel, false }); + feature.push_back({ local_pos(+0, height, +0), leaves_voxel, false }); + feature.push_back({ local_pos(+0, height, +1), leaves_voxel, false }); + feature.push_back({ local_pos(+1, height, +0), leaves_voxel, false }); + + // Generate the thin 5x5 layer of leaves that + // starts from leaves_start and ends at leaves_thin_end + for(unsigned int i = leaves_start; i <= leaves_thick_end; ++i) { + feature.push_back({ local_pos(-1, i, -2), leaves_voxel, false }); + feature.push_back({ local_pos(-1, i, +2), leaves_voxel, false }); + feature.push_back({ local_pos(-2, i, -1), leaves_voxel, false }); + feature.push_back({ local_pos(-2, i, -2), leaves_voxel, false }); + feature.push_back({ local_pos(-2, i, +0), leaves_voxel, false }); + feature.push_back({ local_pos(-2, i, +1), leaves_voxel, false }); + feature.push_back({ local_pos(-2, i, +2), leaves_voxel, false }); + feature.push_back({ local_pos(+0, i, -2), leaves_voxel, false }); + feature.push_back({ local_pos(+0, i, +2), leaves_voxel, false }); + feature.push_back({ local_pos(+1, i, -2), leaves_voxel, false }); + feature.push_back({ local_pos(+1, i, +2), leaves_voxel, false }); + feature.push_back({ local_pos(+2, i, -1), leaves_voxel, false }); + feature.push_back({ local_pos(+2, i, -2), leaves_voxel, false }); + feature.push_back({ local_pos(+2, i, +0), leaves_voxel, false }); + feature.push_back({ local_pos(+2, i, +1), leaves_voxel, false }); + feature.push_back({ local_pos(+2, i, +2), leaves_voxel, false }); + } +} + +world::Overworld::Overworld(std::string_view name) : Dimension(name, -30.0f) +{ + m_bottommost_chunk.set_limits(-64, -4); + m_terrain_variation.set_limits(16, 256); + + compute_tree_feature(4U, m_feat_tree[0], game_voxels::oak_log, game_voxels::oak_leaves); + compute_tree_feature(5U, m_feat_tree[1], game_voxels::oak_log, game_voxels::oak_leaves); + compute_tree_feature(6U, m_feat_tree[2], game_voxels::oak_log, game_voxels::oak_leaves); + compute_tree_feature(8U, m_feat_tree[3], game_voxels::oak_log, game_voxels::oak_leaves); +} + +void world::Overworld::init(io::ConfigMap& config) +{ + m_terrain_variation.set_value(64); + m_bottommost_chunk.set_value(-4); + + config.add_value("overworld.terrain_variation", m_terrain_variation); + config.add_value("overworld.bottommost_chunk", m_bottommost_chunk); +} + +void world::Overworld::init_late(std::uint64_t global_seed) +{ + std::mt19937_64 twister(global_seed); + + m_fnl_variation = fnlCreateState(); + m_fnl_variation.seed = static_cast<int>(twister()); + m_fnl_variation.noise_type = FNL_NOISE_PERLIN; + m_fnl_variation.frequency = 0.001f; + + m_fnl_terrain = fnlCreateState(); + m_fnl_terrain.seed = static_cast<int>(twister()); + m_fnl_terrain.noise_type = FNL_NOISE_OPENSIMPLEX2S; + m_fnl_terrain.fractal_type = FNL_FRACTAL_FBM; + m_fnl_terrain.frequency = 0.005f; + m_fnl_terrain.octaves = 4; + + m_fnl_caves_a = fnlCreateState(); + m_fnl_caves_a.seed = static_cast<int>(twister()); + m_fnl_caves_a.noise_type = FNL_NOISE_PERLIN; + m_fnl_caves_a.fractal_type = FNL_FRACTAL_RIDGED; + m_fnl_caves_a.frequency = 0.0125f; + m_fnl_caves_a.octaves = 1; + + m_fnl_caves_b = fnlCreateState(); + m_fnl_caves_b.seed = static_cast<int>(twister()); + m_fnl_caves_b.noise_type = FNL_NOISE_OPENSIMPLEX2S; + m_fnl_caves_b.fractal_type = FNL_FRACTAL_RIDGED; + m_fnl_caves_b.frequency = 0.0125f; + m_fnl_caves_b.octaves = 1; + + m_fnl_nvdi = fnlCreateState(); + m_fnl_nvdi.seed = static_cast<int>(twister()); + m_fnl_nvdi.noise_type = FNL_NOISE_OPENSIMPLEX2S; + m_fnl_nvdi.frequency = 1.0f; + + m_metamap.clear(); +} + +bool world::Overworld::generate(const chunk_pos& cpos, VoxelStorage& voxels) +{ + if(cpos.y <= m_bottommost_chunk.get_value()) { + // If the player asks the generator + // to generate a lot of stuff below + // the surface, it will happily chew + // through all the server threads + return false; + } + + voxels.fill(NULL_VOXEL_ID); + + m_mutex.lock(); + generate_terrain(cpos, voxels); + m_mutex.unlock(); + + m_mutex.lock(); + generate_surface(cpos, voxels); + m_mutex.unlock(); + + m_mutex.lock(); + generate_caves(cpos, voxels); + m_mutex.unlock(); + + m_mutex.lock(); + generate_features(cpos, voxels); + m_mutex.unlock(); + + return true; +} + +bool world::Overworld::is_inside_cave(const voxel_pos& vpos) +{ + auto vpos_x = static_cast<float>(vpos.x); + auto vpos_y = static_cast<float>(vpos.y) * 2.0f; + auto vpos_z = static_cast<float>(vpos.z); + + auto noise_a = fnlGetNoise3D(&m_fnl_caves_a, vpos_x, vpos_y, vpos_z); + auto noise_b = fnlGetNoise3D(&m_fnl_caves_b, vpos_x, vpos_y, vpos_z); + return (noise_a > 0.95f) && (noise_b > 0.85f); +} + +bool world::Overworld::is_inside_terrain(const voxel_pos& vpos) +{ + auto vpos_x = static_cast<float>(vpos.x); + auto vpos_y = static_cast<float>(vpos.y); + auto vpos_z = static_cast<float>(vpos.z); + + auto variation_noise = fnlGetNoise3D(&m_fnl_terrain, vpos_x, vpos_y, vpos_z); + auto variation = m_terrain_variation.get_value() * (1.0f - (variation_noise * variation_noise)); + auto noise = variation * fnlGetNoise3D(&m_fnl_terrain, vpos_x, vpos_y, vpos_z) - vpos.y; + return noise > 0.0f; +} + +const world::Overworld_Metadata& world::Overworld::get_or_create_metadata(const chunk_pos_xz& cpos) +{ + auto it = m_metamap.find(cpos); + + if(it != m_metamap.cend()) { + // Metadata is present + return it->second; + } + + auto& metadata = m_metamap.insert_or_assign(cpos, Overworld_Metadata()).first->second; + metadata.entropy.fill(std::numeric_limits<std::uint64_t>::max()); + metadata.heightmap.fill(std::numeric_limits<voxel_pos::value_type>::min()); + + auto twister = std::mt19937_64(std::hash<chunk_pos_xz>()(cpos)); + auto variation = m_terrain_variation.get_value(); + + // Generator might need some randomness + // that depends on 2D coordinates, so we + // generate this entropy ahead of time + for(int i = 0; i < CHUNK_AREA; ++i) { + metadata.entropy[i] = twister(); + } + + // Generate speculative heightmap; + // Cave generation might have issues with placing + // surface features such as trees but I genuinely don't give a shit + for(int lx = 0; lx < CHUNK_SIZE; lx += 1) { + for(int lz = 0; lz < CHUNK_SIZE; lz += 1) { + auto hdx = static_cast<std::size_t>(lx + lz * CHUNK_SIZE); + auto vpos = coord::to_voxel(chunk_pos(cpos.x, 0, cpos.y), local_pos(lx, 0, lz)); + + for(vpos.y = variation; vpos.y >= -variation; vpos.y -= 1) { + if(is_inside_terrain(vpos)) { + metadata.heightmap[hdx] = vpos.y; + break; + } + } + } + } + + auto cpos_x = static_cast<float>(cpos.x); + auto cpos_y = static_cast<float>(cpos.y); + + auto nvdi_value = 0.5f + 0.5f * fnlGetNoise2D(&m_fnl_nvdi, cpos_x, cpos_y); + auto tree_density = (nvdi_value >= 0.33f) ? static_cast<unsigned int>(glm::floor(nvdi_value * 4.0f)) : 0U; + + for(unsigned int i = 0U; i < tree_density; ++i) { + auto lpos = local_pos((twister() % CHUNK_SIZE), (twister() % OW_NUM_TREES), (twister() % CHUNK_SIZE)); + auto is_unique = true; + + for(const auto& check_lpos : metadata.trees) { + if(math::distance2(check_lpos, lpos) <= 9) { + is_unique = false; + break; + } + } + + if(is_unique) { + metadata.trees.push_back(lpos); + } + } + + return metadata; +} + +void world::Overworld::generate_terrain(const chunk_pos& cpos, VoxelStorage& voxels) +{ + auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z)); + auto variation = m_terrain_variation.get_value(); + + for(unsigned long i = 0; i < CHUNK_VOLUME; ++i) { + auto lpos = coord::to_local(i); + auto vpos = coord::to_voxel(cpos, lpos); + + if(vpos.y > variation) { + voxels[i] = NULL_VOXEL_ID; + continue; + } + + if(vpos.y < -variation) { + voxels[i] = game_voxels::stone->get_id(); + continue; + } + + if(is_inside_terrain(vpos)) { + voxels[i] = game_voxels::stone->get_id(); + continue; + } + } +} + +void world::Overworld::generate_surface(const chunk_pos& cpos, VoxelStorage& voxels) +{ + auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z)); + auto variation = m_terrain_variation.get_value(); + + for(unsigned long i = 0; i < CHUNK_VOLUME; ++i) { + auto lpos = coord::to_local(i); + auto vpos = coord::to_voxel(cpos, lpos); + auto hdx = static_cast<std::size_t>(lpos.x + lpos.z * CHUNK_SIZE); + + if((vpos.y > variation) || (vpos.y < -variation)) { + // Speculative optimization + continue; + } + + if(voxels[i] == NULL_VOXEL_ID) { + // Surface voxel checks only apply for solid voxels; + // it's kind of obvious you can't replace air with grass + continue; + } + + unsigned int depth = 0U; + + for(unsigned int dy = 0U; dy < 5U; dy += 1U) { + auto d_lpos = local_pos(lpos.x, lpos.y + dy + 1, lpos.z); + auto d_vpos = coord::to_voxel(cpos, d_lpos); + auto d_index = coord::to_index(d_lpos); + + if(d_lpos.y >= CHUNK_SIZE) { + if(!is_inside_terrain(d_vpos)) { + break; + } + + depth += 1U; + } + else { + if(voxels[d_index] == NULL_VOXEL_ID) { + break; + } + + depth += 1U; + } + } + + if(depth < 5U) { + if(depth == 0U) { + voxels[i] = game_voxels::grass->get_id(); + } + else { + voxels[i] = game_voxels::dirt->get_id(); + } + } + } +} + +void world::Overworld::generate_caves(const chunk_pos& cpos, VoxelStorage& voxels) +{ + auto& metadata = get_or_create_metadata(chunk_pos_xz(cpos.x, cpos.z)); + auto variation = m_terrain_variation.get_value(); + + for(unsigned long i = 0U; i < CHUNK_VOLUME; ++i) { + auto lpos = coord::to_local(i); + auto vpos = coord::to_voxel(cpos, lpos); + + if(vpos.y > variation) { + // Speculative optimization - there's no solid + // terrain above variation to carve caves out from + continue; + } + + if(is_inside_cave(vpos)) { + voxels[i] = NULL_VOXEL_ID; + continue; + } + } +} + +void world::Overworld::generate_features(const chunk_pos& cpos, VoxelStorage& voxels) +{ + const chunk_pos_xz tree_chunks[] = { + chunk_pos_xz(cpos.x - 0, cpos.z - 1), + chunk_pos_xz(cpos.x - 1, cpos.z - 1), + chunk_pos_xz(cpos.x - 1, cpos.z + 0), + chunk_pos_xz(cpos.x - 1, cpos.z + 1), + chunk_pos_xz(cpos.x + 0, cpos.z + 0), + chunk_pos_xz(cpos.x + 0, cpos.z + 1), + chunk_pos_xz(cpos.x + 1, cpos.z - 1), + chunk_pos_xz(cpos.x + 1, cpos.z + 0), + chunk_pos_xz(cpos.x + 1, cpos.z + 1), + }; + + for(unsigned int i = 0U; i < math::array_size(tree_chunks); ++i) { + const auto& cpos_xz = tree_chunks[i]; + const auto& metadata = get_or_create_metadata(cpos_xz); + + for(const auto& tree_info : metadata.trees) { + auto hdx = static_cast<std::size_t>(tree_info.x + tree_info.z * CHUNK_SIZE); + auto height = metadata.heightmap[hdx]; + + if(height == std::numeric_limits<voxel_pos::value_type>::min()) { + // What happened? Cave happened + continue; + } + + auto cpos_xyz = chunk_pos(cpos_xz.x, 0, cpos_xz.y); + auto lpos_xyz = local_pos(tree_info.x, 0, tree_info.z); + + auto vpos = coord::to_voxel(cpos_xyz, lpos_xyz); + vpos.y = height; + + if(is_inside_cave(vpos)) { + // Cave is in the way + continue; + } + + m_feat_tree[tree_info.y].place(vpos + DIR_UP<voxel_pos::value_type>, cpos, voxels); + } + } +} diff --git a/game/server/world/overworld.hh b/src/game/server/world/overworld.hh index a8112cf..f3fc8cf 100644 --- a/game/server/world/overworld.hh +++ b/src/game/server/world/overworld.hh @@ -1,68 +1,68 @@ -#pragma once
-
-#include "core/config/number.hh"
-
-#include "core/io/config_map.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/feature.hh"
-
-#include "shared/const.hh"
-
-constexpr static unsigned int OW_NUM_TREES = 4U;
-
-namespace world
-{
-struct Overworld_Metadata final {
- world::dimension_entropy_map entropy;
- world::dimension_height_map heightmap;
- std::vector<local_pos> trees;
-};
-} // namespace world
-
-namespace world
-{
-class Overworld final : public Dimension {
-public:
- explicit Overworld(std::string_view name);
- virtual ~Overworld(void) = default;
-
-public:
- virtual void init(io::ConfigMap& config) override;
- virtual void init_late(std::uint64_t global_seed) override;
- virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels) override;
-
-private:
- bool is_inside_cave(const voxel_pos& vpos);
- bool is_inside_terrain(const voxel_pos& vpos);
-
-private:
- const Overworld_Metadata& get_or_create_metadata(const chunk_pos_xz& cpos);
-
-private:
- void generate_terrain(const chunk_pos& cpos, VoxelStorage& voxels);
- void generate_surface(const chunk_pos& cpos, VoxelStorage& voxels);
- void generate_caves(const chunk_pos& cpos, VoxelStorage& voxels);
- void generate_features(const chunk_pos& cpos, VoxelStorage& voxels);
-
-private:
- config::Int m_terrain_variation;
- config::Int m_bottommost_chunk;
-
-private:
- emhash8::HashMap<chunk_pos_xz, Overworld_Metadata> m_metamap;
-
-private:
- fnl_state m_fnl_variation;
- fnl_state m_fnl_terrain;
- fnl_state m_fnl_caves_a;
- fnl_state m_fnl_caves_b;
- fnl_state m_fnl_nvdi;
-
-private:
- Feature m_feat_tree[OW_NUM_TREES];
-
-private:
- std::mutex m_mutex;
-};
-} // namespace world
+#pragma once + +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/feature.hh" + +#include "shared/const.hh" + +constexpr static unsigned int OW_NUM_TREES = 4U; + +namespace world +{ +struct Overworld_Metadata final { + world::dimension_entropy_map entropy; + world::dimension_height_map heightmap; + std::vector<local_pos> trees; +}; +} // namespace world + +namespace world +{ +class Overworld final : public Dimension { +public: + explicit Overworld(std::string_view name); + virtual ~Overworld(void) = default; + +public: + virtual void init(io::ConfigMap& config) override; + virtual void init_late(std::uint64_t global_seed) override; + virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels) override; + +private: + bool is_inside_cave(const voxel_pos& vpos); + bool is_inside_terrain(const voxel_pos& vpos); + +private: + const Overworld_Metadata& get_or_create_metadata(const chunk_pos_xz& cpos); + +private: + void generate_terrain(const chunk_pos& cpos, VoxelStorage& voxels); + void generate_surface(const chunk_pos& cpos, VoxelStorage& voxels); + void generate_caves(const chunk_pos& cpos, VoxelStorage& voxels); + void generate_features(const chunk_pos& cpos, VoxelStorage& voxels); + +private: + config::Int m_terrain_variation; + config::Int m_bottommost_chunk; + +private: + emhash8::HashMap<chunk_pos_xz, Overworld_Metadata> m_metamap; + +private: + fnl_state m_fnl_variation; + fnl_state m_fnl_terrain; + fnl_state m_fnl_caves_a; + fnl_state m_fnl_caves_b; + fnl_state m_fnl_nvdi; + +private: + Feature m_feat_tree[OW_NUM_TREES]; + +private: + std::mutex m_mutex; +}; +} // namespace world diff --git a/game/server/world/random_tick.cc b/src/game/server/world/random_tick.cc index c5fa47c..c5fa47c 100644 --- a/game/server/world/random_tick.cc +++ b/src/game/server/world/random_tick.cc diff --git a/game/server/world/random_tick.hh b/src/game/server/world/random_tick.hh index 4ef1691..4ef1691 100644 --- a/game/server/world/random_tick.hh +++ b/src/game/server/world/random_tick.hh diff --git a/game/server/world/universe.cc b/src/game/server/world/universe.cc index b27a8de..6d52951 100644 --- a/game/server/world/universe.cc +++ b/src/game/server/world/universe.cc @@ -1,222 +1,222 @@ -#include "server/pch.hh"
-
-#include "server/world/universe.hh"
-
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/buffer.hh"
-#include "core/io/config_map.hh"
-#include "core/io/physfs.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-
-#include "server/world/inhabited.hh"
-#include "server/world/overworld.hh"
-
-#include "server/globals.hh"
-
-struct DimensionMetadata final {
- std::string config_path;
- std::string zvox_dir;
- io::ConfigMap config;
-};
-
-static config::String universe_name("save");
-
-static io::ConfigMap universe_config;
-static config::Unsigned64 universe_config_seed;
-static config::String universe_spawn_dimension("world");
-
-static std::string universe_config_path;
-static std::unordered_map<world::Dimension*, DimensionMetadata*> metadata_map;
-
-static std::string make_chunk_filename(const DimensionMetadata* metadata, const chunk_pos& cpos)
-{
- const auto unsigned_x = static_cast<std::uint32_t>(cpos.x);
- const auto unsigned_y = static_cast<std::uint32_t>(cpos.y);
- const auto unsigned_z = static_cast<std::uint32_t>(cpos.z);
- return std::format("{}/{:08X}-{:08X}-{:08X}.zvox", metadata->zvox_dir, unsigned_x, unsigned_y, unsigned_z);
-}
-
-static void add_new_dimension(world::Dimension* dimension)
-{
- if(globals::dimensions.count(std::string(dimension->get_name()))) {
- spdlog::critical("universe: dimension named {} already exists", dimension->get_name());
- std::terminate();
- }
-
- auto dimension_dir = std::format("{}/{}", universe_name.get(), dimension->get_name());
-
- if(!PHYSFS_mkdir(dimension_dir.c_str())) {
- spdlog::critical("universe: {}: {}", dimension_dir, io::physfs_error());
- std::terminate();
- }
-
- auto metadata = new DimensionMetadata;
- metadata->config_path = std::format("{}/dimension.conf", dimension_dir);
- metadata->zvox_dir = std::format("{}/chunk", dimension_dir);
-
- if(!PHYSFS_mkdir(metadata->zvox_dir.c_str())) {
- spdlog::critical("universe: {}: {}", metadata->zvox_dir, io::physfs_error());
- std::terminate();
- }
-
- globals::dimensions.insert_or_assign(std::string(dimension->get_name()), dimension);
-
- auto& mapped_metadata = metadata_map.insert_or_assign(dimension, metadata).first->second;
-
- dimension->init(mapped_metadata->config);
-
- mapped_metadata->config.load_file(mapped_metadata->config_path.c_str());
-
- dimension->init_late(universe_config_seed.get_value());
-}
-
-static void internal_save_chunk(const DimensionMetadata* metadata, const world::Dimension* dimension, const chunk_pos& cpos,
- const world::Chunk* chunk)
-{
- auto path = make_chunk_filename(metadata, cpos);
-
- io::WriteBuffer buffer;
- chunk->get_voxels().serialize(buffer);
-
- if(auto file = buffer.to_file(path.c_str())) {
- PHYSFS_close(file);
- return;
- }
-}
-
-void world::universe::init(void)
-{
- // If the world is newly created, the seed will
- // be chosed based on the current system's view on UNIX time
- universe_config_seed.set_value(utils::unix_microseconds());
-
- // We're going to read files from directory named with
- // the value of this config value. Since config is also
- // read from command line, the [--universe <name>] parameter still works
- globals::server_config.add_value("universe", universe_name);
-
- universe_config.add_value("global_seed", universe_config_seed);
- universe_config.add_value("spawn_dimension", universe_spawn_dimension);
-}
-
-void world::universe::init_late(void)
-{
- const auto universe_dir = std::string(universe_name.get());
-
- if(!PHYSFS_mkdir(universe_dir.c_str())) {
- spdlog::critical("universe: {}: {}", universe_dir, io::physfs_error());
- std::terminate();
- }
-
- universe_config_path = std::format("{}/universe.conf", universe_dir);
- universe_config.load_file(universe_config_path.c_str());
-
- add_new_dimension(new Overworld("world"));
-
- // UNDONE: lua scripts to setup dimensions
- if(globals::dimensions.empty()) {
- spdlog::critical("universe: no dimensions");
- std::terminate();
- }
-
- auto spawn_dimension = globals::dimensions.find(universe_spawn_dimension.get_value());
-
- if(spawn_dimension == globals::dimensions.cend()) {
- spdlog::critical("universe: {} is not a valid dimension name", universe_spawn_dimension.get());
- std::terminate();
- }
-
- globals::spawn_dimension = spawn_dimension->second;
-}
-
-void world::universe::shutdown(void)
-{
- for(const auto metadata : metadata_map) {
- metadata.second->config.save_file(metadata.second->config_path.c_str());
- delete metadata.second;
- }
-
- metadata_map.clear();
-
- for(const auto dimension : globals::dimensions) {
- world::universe::save_all_chunks(dimension.second);
- delete dimension.second;
- }
-
- globals::dimensions.clear();
- globals::spawn_dimension = nullptr;
-
- universe_config.save_file(universe_config_path.c_str());
-}
-
-world::Chunk* world::universe::load_chunk(Dimension* dimension, const chunk_pos& cpos)
-{
- if(auto chunk = dimension->find_chunk(cpos)) {
- // Just return the existing chunk which is
- // most probable to be up to date compared to
- // whatever the hell is currently stored on disk
- return chunk;
- }
-
- auto metadata = metadata_map.find(dimension);
-
- if(metadata == metadata_map.cend()) {
- // The dimension is for sure a weird one
- return nullptr;
- }
-
- if(auto file = PHYSFS_openRead(make_chunk_filename(metadata->second, cpos).c_str())) {
- VoxelStorage voxels;
- io::ReadBuffer buffer(file);
- voxels.deserialize(buffer);
-
- PHYSFS_close(file);
-
- auto chunk = dimension->create_chunk(cpos);
- chunk->set_voxels(voxels);
-
- // Make sure we're going to save it later
- dimension->chunks.emplace_or_replace<Inhabited>(chunk->get_entity());
-
- return chunk;
- }
-
- return nullptr;
-}
-
-void world::universe::save_chunk(Dimension* dimension, const chunk_pos& cpos)
-{
- auto metadata = metadata_map.find(dimension);
-
- if(metadata == metadata_map.cend()) {
- // Cannot save a chunk in a dimension
- // that doesn't have a metadata struct
- return;
- }
-
- if(auto chunk = dimension->find_chunk(cpos)) {
- internal_save_chunk(metadata->second, dimension, cpos, chunk);
- }
-}
-
-void world::universe::save_all_chunks(Dimension* dimension)
-{
- auto group = dimension->chunks.group(entt::get<ChunkComponent, Inhabited>);
- auto metadata = metadata_map.find(dimension);
-
- if(metadata == metadata_map.cend()) {
- // Cannot save a chunk in a dimension
- // that doesn't have a metadata struct
- return;
- }
-
- for(auto [entity, chunk] : group.each()) {
- internal_save_chunk(metadata->second, dimension, chunk.cpos, chunk.chunk);
- }
-}
+#include "server/pch.hh" + +#include "server/world/universe.hh" + +#include "core/config/number.hh" +#include "core/config/string.hh" + +#include "core/io/buffer.hh" +#include "core/io/config_map.hh" +#include "core/io/physfs.hh" + +#include "core/utils/epoch.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" + +#include "server/world/inhabited.hh" +#include "server/world/overworld.hh" + +#include "server/globals.hh" + +struct DimensionMetadata final { + std::string config_path; + std::string zvox_dir; + io::ConfigMap config; +}; + +static config::String universe_name("save"); + +static io::ConfigMap universe_config; +static config::Unsigned64 universe_config_seed; +static config::String universe_spawn_dimension("world"); + +static std::string universe_config_path; +static std::unordered_map<world::Dimension*, DimensionMetadata*> metadata_map; + +static std::string make_chunk_filename(const DimensionMetadata* metadata, const chunk_pos& cpos) +{ + const auto unsigned_x = static_cast<std::uint32_t>(cpos.x); + const auto unsigned_y = static_cast<std::uint32_t>(cpos.y); + const auto unsigned_z = static_cast<std::uint32_t>(cpos.z); + return std::format("{}/{:08X}-{:08X}-{:08X}.zvox", metadata->zvox_dir, unsigned_x, unsigned_y, unsigned_z); +} + +static void add_new_dimension(world::Dimension* dimension) +{ + if(globals::dimensions.count(std::string(dimension->get_name()))) { + spdlog::critical("universe: dimension named {} already exists", dimension->get_name()); + std::terminate(); + } + + auto dimension_dir = std::format("{}/{}", universe_name.get(), dimension->get_name()); + + if(!PHYSFS_mkdir(dimension_dir.c_str())) { + spdlog::critical("universe: {}: {}", dimension_dir, io::physfs_error()); + std::terminate(); + } + + auto metadata = new DimensionMetadata; + metadata->config_path = std::format("{}/dimension.conf", dimension_dir); + metadata->zvox_dir = std::format("{}/chunk", dimension_dir); + + if(!PHYSFS_mkdir(metadata->zvox_dir.c_str())) { + spdlog::critical("universe: {}: {}", metadata->zvox_dir, io::physfs_error()); + std::terminate(); + } + + globals::dimensions.insert_or_assign(std::string(dimension->get_name()), dimension); + + auto& mapped_metadata = metadata_map.insert_or_assign(dimension, metadata).first->second; + + dimension->init(mapped_metadata->config); + + mapped_metadata->config.load_file(mapped_metadata->config_path.c_str()); + + dimension->init_late(universe_config_seed.get_value()); +} + +static void internal_save_chunk(const DimensionMetadata* metadata, const world::Dimension* dimension, const chunk_pos& cpos, + const world::Chunk* chunk) +{ + auto path = make_chunk_filename(metadata, cpos); + + io::WriteBuffer buffer; + chunk->get_voxels().serialize(buffer); + + if(auto file = buffer.to_file(path.c_str())) { + PHYSFS_close(file); + return; + } +} + +void world::universe::init(void) +{ + // If the world is newly created, the seed will + // be chosed based on the current system's view on UNIX time + universe_config_seed.set_value(utils::unix_microseconds()); + + // We're going to read files from directory named with + // the value of this config value. Since config is also + // read from command line, the [--universe <name>] parameter still works + globals::server_config.add_value("universe", universe_name); + + universe_config.add_value("global_seed", universe_config_seed); + universe_config.add_value("spawn_dimension", universe_spawn_dimension); +} + +void world::universe::init_late(void) +{ + const auto universe_dir = std::string(universe_name.get()); + + if(!PHYSFS_mkdir(universe_dir.c_str())) { + spdlog::critical("universe: {}: {}", universe_dir, io::physfs_error()); + std::terminate(); + } + + universe_config_path = std::format("{}/universe.conf", universe_dir); + universe_config.load_file(universe_config_path.c_str()); + + add_new_dimension(new Overworld("world")); + + // UNDONE: lua scripts to setup dimensions + if(globals::dimensions.empty()) { + spdlog::critical("universe: no dimensions"); + std::terminate(); + } + + auto spawn_dimension = globals::dimensions.find(universe_spawn_dimension.get_value()); + + if(spawn_dimension == globals::dimensions.cend()) { + spdlog::critical("universe: {} is not a valid dimension name", universe_spawn_dimension.get()); + std::terminate(); + } + + globals::spawn_dimension = spawn_dimension->second; +} + +void world::universe::shutdown(void) +{ + for(const auto metadata : metadata_map) { + metadata.second->config.save_file(metadata.second->config_path.c_str()); + delete metadata.second; + } + + metadata_map.clear(); + + for(const auto dimension : globals::dimensions) { + world::universe::save_all_chunks(dimension.second); + delete dimension.second; + } + + globals::dimensions.clear(); + globals::spawn_dimension = nullptr; + + universe_config.save_file(universe_config_path.c_str()); +} + +world::Chunk* world::universe::load_chunk(Dimension* dimension, const chunk_pos& cpos) +{ + if(auto chunk = dimension->find_chunk(cpos)) { + // Just return the existing chunk which is + // most probable to be up to date compared to + // whatever the hell is currently stored on disk + return chunk; + } + + auto metadata = metadata_map.find(dimension); + + if(metadata == metadata_map.cend()) { + // The dimension is for sure a weird one + return nullptr; + } + + if(auto file = PHYSFS_openRead(make_chunk_filename(metadata->second, cpos).c_str())) { + VoxelStorage voxels; + io::ReadBuffer buffer(file); + voxels.deserialize(buffer); + + PHYSFS_close(file); + + auto chunk = dimension->create_chunk(cpos); + chunk->set_voxels(voxels); + + // Make sure we're going to save it later + dimension->chunks.emplace_or_replace<Inhabited>(chunk->get_entity()); + + return chunk; + } + + return nullptr; +} + +void world::universe::save_chunk(Dimension* dimension, const chunk_pos& cpos) +{ + auto metadata = metadata_map.find(dimension); + + if(metadata == metadata_map.cend()) { + // Cannot save a chunk in a dimension + // that doesn't have a metadata struct + return; + } + + if(auto chunk = dimension->find_chunk(cpos)) { + internal_save_chunk(metadata->second, dimension, cpos, chunk); + } +} + +void world::universe::save_all_chunks(Dimension* dimension) +{ + auto group = dimension->chunks.group(entt::get<ChunkComponent, Inhabited>); + auto metadata = metadata_map.find(dimension); + + if(metadata == metadata_map.cend()) { + // Cannot save a chunk in a dimension + // that doesn't have a metadata struct + return; + } + + for(auto [entity, chunk] : group.each()) { + internal_save_chunk(metadata->second, dimension, chunk.cpos, chunk.chunk); + } +} diff --git a/game/server/world/universe.hh b/src/game/server/world/universe.hh index 966ac70..e542eca 100644 --- a/game/server/world/universe.hh +++ b/src/game/server/world/universe.hh @@ -1,25 +1,25 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world
-{
-class Chunk;
-class Dimension;
-} // namespace world
-
-class Session;
-
-namespace world::universe
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-} // namespace world::universe
-
-namespace world::universe
-{
-Chunk* load_chunk(Dimension* dimension, const chunk_pos& cpos);
-void save_chunk(Dimension* dimension, const chunk_pos& cpos);
-void save_all_chunks(Dimension* dimension);
-} // namespace world::universe
+#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Chunk; +class Dimension; +} // namespace world + +struct Session; + +namespace world::universe +{ +void init(void); +void init_late(void); +void shutdown(void); +} // namespace world::universe + +namespace world::universe +{ +Chunk* load_chunk(Dimension* dimension, const chunk_pos& cpos); +void save_chunk(Dimension* dimension, const chunk_pos& cpos); +void save_all_chunks(Dimension* dimension); +} // namespace world::universe diff --git a/game/server/world/unloader.cc b/src/game/server/world/unloader.cc index 371a96f..4a3f4e1 100644 --- a/game/server/world/unloader.cc +++ b/src/game/server/world/unloader.cc @@ -1,78 +1,78 @@ -#include "server/pch.hh"
-
-#include "server/world/unloader.hh"
-
-#include "core/config/number.hh"
-
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/chunk_aabb.hh"
-#include "shared/world/dimension.hh"
-
-#include "server/world/inhabited.hh"
-#include "server/world/universe.hh"
-
-#include "server/game.hh"
-#include "server/globals.hh"
-
-static void on_chunk_update(const world::ChunkUpdateEvent& event)
-{
- event.dimension->chunks.emplace_or_replace<world::Inhabited>(event.chunk->get_entity());
-}
-
-static void on_voxel_set(const world::VoxelSetEvent& event)
-{
- event.dimension->chunks.emplace_or_replace<world::Inhabited>(event.chunk->get_entity());
-}
-
-void world::unloader::init(void)
-{
- globals::dispatcher.sink<world::ChunkUpdateEvent>().connect<&on_chunk_update>();
- globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>();
-}
-
-void world::unloader::init_late(void)
-{
-}
-
-void world::unloader::fixed_update_late(Dimension* dimension)
-{
- auto group = dimension->entities.group(entt::get<entity::Player, entity::Transform>);
- auto boxes = std::vector<ChunkAABB>();
-
- for(const auto [entity, transform] : group.each()) {
- ChunkAABB aabb;
- aabb.min = transform.chunk - static_cast<chunk_pos::value_type>(server_game::view_distance.get_value());
- aabb.max = transform.chunk + static_cast<chunk_pos::value_type>(server_game::view_distance.get_value());
- boxes.push_back(aabb);
- }
-
- auto view = dimension->chunks.view<ChunkComponent>();
- auto chunk_in_view = false;
-
- for(const auto [entity, chunk] : view.each()) {
- chunk_in_view = false;
-
- for(const auto& aabb : boxes) {
- if(aabb.contains(chunk.cpos)) {
- chunk_in_view = true;
- break;
- }
- }
-
- if(chunk_in_view) {
- // The chunk is within view box of at least
- // a single player; we shouldn't unload it now
- continue;
- }
-
- if(dimension->chunks.any_of<Inhabited>(entity)) {
- // Only store inhabited chunks on disk
- world::universe::save_chunk(dimension, chunk.cpos);
- }
-
- dimension->remove_chunk(entity);
- }
-}
+#include "server/pch.hh" + +#include "server/world/unloader.hh" + +#include "core/config/number.hh" + +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/chunk_aabb.hh" +#include "shared/world/dimension.hh" + +#include "server/world/inhabited.hh" +#include "server/world/universe.hh" + +#include "server/game.hh" +#include "server/globals.hh" + +static void on_chunk_update(const world::ChunkUpdateEvent& event) +{ + event.dimension->chunks.emplace_or_replace<world::Inhabited>(event.chunk->get_entity()); +} + +static void on_voxel_set(const world::VoxelSetEvent& event) +{ + event.dimension->chunks.emplace_or_replace<world::Inhabited>(event.chunk->get_entity()); +} + +void world::unloader::init(void) +{ + globals::dispatcher.sink<world::ChunkUpdateEvent>().connect<&on_chunk_update>(); + globals::dispatcher.sink<world::VoxelSetEvent>().connect<&on_voxel_set>(); +} + +void world::unloader::init_late(void) +{ +} + +void world::unloader::fixed_update_late(Dimension* dimension) +{ + auto group = dimension->entities.group(entt::get<entity::Player, entity::Transform>); + auto boxes = std::vector<ChunkAABB>(); + + for(const auto [entity, transform] : group.each()) { + ChunkAABB aabb; + aabb.min = transform.chunk - static_cast<chunk_pos::value_type>(server_game::view_distance.get_value()); + aabb.max = transform.chunk + static_cast<chunk_pos::value_type>(server_game::view_distance.get_value()); + boxes.push_back(aabb); + } + + auto view = dimension->chunks.view<ChunkComponent>(); + auto chunk_in_view = false; + + for(const auto [entity, chunk] : view.each()) { + chunk_in_view = false; + + for(const auto& aabb : boxes) { + if(aabb.contains(chunk.cpos)) { + chunk_in_view = true; + break; + } + } + + if(chunk_in_view) { + // The chunk is within view box of at least + // a single player; we shouldn't unload it now + continue; + } + + if(dimension->chunks.any_of<Inhabited>(entity)) { + // Only store inhabited chunks on disk + world::universe::save_chunk(dimension, chunk.cpos); + } + + dimension->remove_chunk(entity); + } +} diff --git a/game/server/world/unloader.hh b/src/game/server/world/unloader.hh index a5b1da1..9682de6 100644 --- a/game/server/world/unloader.hh +++ b/src/game/server/world/unloader.hh @@ -1,13 +1,13 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace world::unloader
-{
-void init(void);
-void init_late(void);
-void fixed_update_late(Dimension* dimension);
-} // namespace world::unloader
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace world::unloader +{ +void init(void); +void init_late(void); +void fixed_update_late(Dimension* dimension); +} // namespace world::unloader diff --git a/game/server/world/worldgen.cc b/src/game/server/world/worldgen.cc index 3d8154c..8b02b52 100644 --- a/game/server/world/worldgen.cc +++ b/src/game/server/world/worldgen.cc @@ -1,151 +1,151 @@ -#include "server/pch.hh"
-
-#include "server/world/worldgen.hh"
-
-#include "core/io/cmdline.hh"
-
-#include "core/threading.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-
-#include "shared/protocol.hh"
-
-#include "server/world/inhabited.hh"
-
-#include "server/globals.hh"
-#include "server/sessions.hh"
-
-static bool aggressive_caching;
-
-static emhash8::HashMap<world::Dimension*, emhash8::HashMap<chunk_pos, std::unordered_set<Session*>>> active_tasks;
-
-class WorldgenTask final : public Task {
-public:
- explicit WorldgenTask(world::Dimension* dimension, const chunk_pos& cpos);
- virtual ~WorldgenTask(void) = default;
- virtual void process(void) override;
- virtual void finalize(void) override;
-
-private:
- world::Dimension* m_dimension;
- world::VoxelStorage m_voxels;
- chunk_pos m_cpos;
-};
-
-WorldgenTask::WorldgenTask(world::Dimension* dimension, const chunk_pos& cpos)
-{
- m_dimension = dimension;
- m_voxels.fill(rand()); // trolling
- m_cpos = cpos;
-}
-
-void WorldgenTask::process(void)
-{
- if(!m_dimension->generate(m_cpos, m_voxels)) {
- set_status(task_status::CANCELLED);
- }
-}
-
-void WorldgenTask::finalize(void)
-{
- auto dim_tasks = active_tasks.find(m_dimension);
-
- if(dim_tasks == active_tasks.cend()) {
- // Normally this should never happen but
- // one can never be sure about anything
- // when that anything is threaded out
- return;
- }
-
- auto it = dim_tasks->second.find(m_cpos);
-
- if(it == dim_tasks->second.cend()) {
- // Normally this should never happen but
- // one can never be sure about anything
- // when that anything is threaded out
- return;
- }
-
- auto chunk = m_dimension->create_chunk(m_cpos);
- chunk->set_voxels(m_voxels);
-
- if(aggressive_caching) {
- // Marking the chunk with InhabitedComponent makes
- // it so that it is saved regardles of whether it was
- // modified by players or not. This isn't particularly
- // good for server-side disk usage but it might improve performance
- m_dimension->chunks.emplace<world::Inhabited>(chunk->get_entity());
- }
-
- protocol::ChunkVoxels response;
- response.voxels = m_voxels;
- response.chunk = m_cpos;
-
- auto packet = protocol::encode(response);
-
- for(auto session : it->second) {
- if(session->peer) {
- // Respond with the voxels to every session
- // that has requested this specific chunk for this dimension
- enet_peer_send(session->peer, protocol::CHANNEL, packet);
- }
- }
-
- dim_tasks->second.erase(it);
-
- if(dim_tasks->second.empty()) {
- // There are no more requests
- // to generate a chunk for that
- // dimension, at least for now
- active_tasks.erase(dim_tasks);
- }
-}
-
-void world::worldgen::init(void)
-{
- aggressive_caching = io::cmdline::contains("aggressive-caching");
-}
-
-bool world::worldgen::is_generating(Dimension* dimension, const chunk_pos& cpos)
-{
- auto dim_tasks = active_tasks.find(dimension);
-
- if(dim_tasks == active_tasks.cend()) {
- // No tasks for this dimension
- return false;
- }
-
- auto it = dim_tasks->second.find(cpos);
-
- if(it == dim_tasks->second.cend()) {
- // Not generating this chunk
- return false;
- }
-
- return true;
-}
-
-void world::worldgen::request_chunk(Session* session, const chunk_pos& cpos)
-{
- if(session->dimension) {
- auto dim_tasks = active_tasks.find(session->dimension);
-
- if(dim_tasks == active_tasks.cend()) {
- dim_tasks = active_tasks.emplace(session->dimension, emhash8::HashMap<chunk_pos, std::unordered_set<Session*>>()).first;
- }
-
- auto it = dim_tasks->second.find(cpos);
-
- if(it == dim_tasks->second.cend()) {
- auto& sessions = dim_tasks->second.insert_or_assign(cpos, std::unordered_set<Session*>()).first->second;
- sessions.insert(session);
-
- threading::submit<WorldgenTask>(session->dimension, cpos);
-
- return;
- }
-
- it->second.insert(session);
- }
-}
+#include "server/pch.hh" + +#include "server/world/worldgen.hh" + +#include "core/io/cmdline.hh" + +#include "core/threading.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" + +#include "shared/protocol.hh" + +#include "server/world/inhabited.hh" + +#include "server/globals.hh" +#include "server/sessions.hh" + +static bool aggressive_caching; + +static emhash8::HashMap<world::Dimension*, emhash8::HashMap<chunk_pos, std::unordered_set<Session*>>> active_tasks; + +class WorldgenTask final : public Task { +public: + explicit WorldgenTask(world::Dimension* dimension, const chunk_pos& cpos); + virtual ~WorldgenTask(void) = default; + virtual void process(void) override; + virtual void finalize(void) override; + +private: + world::Dimension* m_dimension; + world::VoxelStorage m_voxels; + chunk_pos m_cpos; +}; + +WorldgenTask::WorldgenTask(world::Dimension* dimension, const chunk_pos& cpos) +{ + m_dimension = dimension; + m_voxels.fill(rand()); // trolling + m_cpos = cpos; +} + +void WorldgenTask::process(void) +{ + if(!m_dimension->generate(m_cpos, m_voxels)) { + set_status(task_status::CANCELLED); + } +} + +void WorldgenTask::finalize(void) +{ + auto dim_tasks = active_tasks.find(m_dimension); + + if(dim_tasks == active_tasks.cend()) { + // Normally this should never happen but + // one can never be sure about anything + // when that anything is threaded out + return; + } + + auto it = dim_tasks->second.find(m_cpos); + + if(it == dim_tasks->second.cend()) { + // Normally this should never happen but + // one can never be sure about anything + // when that anything is threaded out + return; + } + + auto chunk = m_dimension->create_chunk(m_cpos); + chunk->set_voxels(m_voxels); + + if(aggressive_caching) { + // Marking the chunk with InhabitedComponent makes + // it so that it is saved regardles of whether it was + // modified by players or not. This isn't particularly + // good for server-side disk usage but it might improve performance + m_dimension->chunks.emplace<world::Inhabited>(chunk->get_entity()); + } + + protocol::ChunkVoxels response; + response.voxels = m_voxels; + response.chunk = m_cpos; + + auto packet = protocol::encode(response); + + for(auto session : it->second) { + if(session->peer) { + // Respond with the voxels to every session + // that has requested this specific chunk for this dimension + enet_peer_send(session->peer, protocol::CHANNEL, packet); + } + } + + dim_tasks->second.erase(it); + + if(dim_tasks->second.empty()) { + // There are no more requests + // to generate a chunk for that + // dimension, at least for now + active_tasks.erase(dim_tasks); + } +} + +void world::worldgen::init(void) +{ + aggressive_caching = io::cmdline::contains("aggressive-caching"); +} + +bool world::worldgen::is_generating(Dimension* dimension, const chunk_pos& cpos) +{ + auto dim_tasks = active_tasks.find(dimension); + + if(dim_tasks == active_tasks.cend()) { + // No tasks for this dimension + return false; + } + + auto it = dim_tasks->second.find(cpos); + + if(it == dim_tasks->second.cend()) { + // Not generating this chunk + return false; + } + + return true; +} + +void world::worldgen::request_chunk(Session* session, const chunk_pos& cpos) +{ + if(session->dimension) { + auto dim_tasks = active_tasks.find(session->dimension); + + if(dim_tasks == active_tasks.cend()) { + dim_tasks = active_tasks.emplace(session->dimension, emhash8::HashMap<chunk_pos, std::unordered_set<Session*>>()).first; + } + + auto it = dim_tasks->second.find(cpos); + + if(it == dim_tasks->second.cend()) { + auto& sessions = dim_tasks->second.insert_or_assign(cpos, std::unordered_set<Session*>()).first->second; + sessions.insert(session); + + threading::submit<WorldgenTask>(session->dimension, cpos); + + return; + } + + it->second.insert(session); + } +} diff --git a/game/server/world/worldgen.hh b/src/game/server/world/worldgen.hh index eeb3e19..30d7070 100644 --- a/game/server/world/worldgen.hh +++ b/src/game/server/world/worldgen.hh @@ -1,21 +1,21 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-class Session;
-
-namespace world::worldgen
-{
-void init(void);
-} // namespace world::worldgen
-
-namespace world::worldgen
-{
-bool is_generating(Dimension* dimension, const chunk_pos& cpos);
-void request_chunk(Session* session, const chunk_pos& cpos);
-} // namespace world::worldgen
+#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Dimension; +} // namespace world + +struct Session; + +namespace world::worldgen +{ +void init(void); +} // namespace world::worldgen + +namespace world::worldgen +{ +bool is_generating(Dimension* dimension, const chunk_pos& cpos); +void request_chunk(Session* session, const chunk_pos& cpos); +} // namespace world::worldgen diff --git a/game/shared/CMakeLists.txt b/src/game/shared/CMakeLists.txt index d4cb6d8..73da95f 100644 --- a/game/shared/CMakeLists.txt +++ b/src/game/shared/CMakeLists.txt @@ -16,8 +16,8 @@ add_library(shared STATIC "${CMAKE_CURRENT_LIST_DIR}/splash.hh" "${CMAKE_CURRENT_LIST_DIR}/types.hh") target_compile_features(shared PUBLIC cxx_std_20) -target_include_directories(shared PRIVATE "${PROJECT_SOURCE_DIR}") -target_include_directories(shared PRIVATE "${PROJECT_SOURCE_DIR}/game") +target_include_directories(shared PRIVATE "${PROJECT_SOURCE_DIR}/src") +target_include_directories(shared PRIVATE "${PROJECT_SOURCE_DIR}/src/game") target_precompile_headers(shared PRIVATE "${CMAKE_CURRENT_LIST_DIR}/pch.hh") target_link_libraries(shared PUBLIC core enet entt FNL miniz parson) diff --git a/game/shared/const.hh b/src/game/shared/const.hh index 6851ff7..187962a 100644 --- a/game/shared/const.hh +++ b/src/game/shared/const.hh @@ -1,43 +1,43 @@ -#pragma once
-
-#include "core/math/constexpr.hh"
-
-constexpr static unsigned int CHUNK_SIZE = 16;
-constexpr static unsigned int CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE;
-constexpr static unsigned int CHUNK_VOLUME = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
-constexpr static unsigned int CHUNK_BITSHIFT = math::log2(CHUNK_SIZE);
-
-template<typename T>
-constexpr static glm::vec<3, T> DIR_NORTH = glm::vec<3, T>(0, 0, +1);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_SOUTH = glm::vec<3, T>(0, 0, -1);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_EAST = glm::vec<3, T>(-1, 0, 0);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_WEST = glm::vec<3, T>(+1, 0, 0);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_DOWN = glm::vec<3, T>(0, -1, 0);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_UP = glm::vec<3, T>(0, +1, 0);
-
-template<typename T>
-constexpr static glm::vec<3, T> DIR_FORWARD = glm::vec<3, T>(0, 0, +1);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_BACK = glm::vec<3, T>(0, 0, -1);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_LEFT = glm::vec<3, T>(-1, 0, 0);
-template<typename T>
-constexpr static glm::vec<3, T> DIR_RIGHT = glm::vec<3, T>(+1, 0, 0);
-
-template<typename T>
-constexpr static glm::vec<3, T> UNIT_X = glm::vec<3, T>(1, 0, 0);
-template<typename T>
-constexpr static glm::vec<3, T> UNIT_Y = glm::vec<3, T>(0, 1, 0);
-template<typename T>
-constexpr static glm::vec<3, T> UNIT_Z = glm::vec<3, T>(0, 0, 1);
-
-template<typename T>
-constexpr static glm::vec<2, T> ZERO_VEC2 = glm::vec<2, T>(0, 0);
-
-template<typename T>
-constexpr static glm::vec<3, T> ZERO_VEC3 = glm::vec<3, T>(0, 0, 0);
+#pragma once + +#include "core/math/constexpr.hh" + +constexpr static unsigned int CHUNK_SIZE = 16; +constexpr static unsigned int CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE; +constexpr static unsigned int CHUNK_VOLUME = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE; +constexpr static unsigned int CHUNK_BITSHIFT = math::log2(CHUNK_SIZE); + +template<typename T> +constexpr static glm::vec<3, T> DIR_NORTH = glm::vec<3, T>(0, 0, +1); +template<typename T> +constexpr static glm::vec<3, T> DIR_SOUTH = glm::vec<3, T>(0, 0, -1); +template<typename T> +constexpr static glm::vec<3, T> DIR_EAST = glm::vec<3, T>(-1, 0, 0); +template<typename T> +constexpr static glm::vec<3, T> DIR_WEST = glm::vec<3, T>(+1, 0, 0); +template<typename T> +constexpr static glm::vec<3, T> DIR_DOWN = glm::vec<3, T>(0, -1, 0); +template<typename T> +constexpr static glm::vec<3, T> DIR_UP = glm::vec<3, T>(0, +1, 0); + +template<typename T> +constexpr static glm::vec<3, T> DIR_FORWARD = glm::vec<3, T>(0, 0, +1); +template<typename T> +constexpr static glm::vec<3, T> DIR_BACK = glm::vec<3, T>(0, 0, -1); +template<typename T> +constexpr static glm::vec<3, T> DIR_LEFT = glm::vec<3, T>(-1, 0, 0); +template<typename T> +constexpr static glm::vec<3, T> DIR_RIGHT = glm::vec<3, T>(+1, 0, 0); + +template<typename T> +constexpr static glm::vec<3, T> UNIT_X = glm::vec<3, T>(1, 0, 0); +template<typename T> +constexpr static glm::vec<3, T> UNIT_Y = glm::vec<3, T>(0, 1, 0); +template<typename T> +constexpr static glm::vec<3, T> UNIT_Z = glm::vec<3, T>(0, 0, 1); + +template<typename T> +constexpr static glm::vec<2, T> ZERO_VEC2 = glm::vec<2, T>(0, 0); + +template<typename T> +constexpr static glm::vec<3, T> ZERO_VEC3 = glm::vec<3, T>(0, 0, 0); diff --git a/game/shared/coord.hh b/src/game/shared/coord.hh index 9f9afc7..9d9be18 100644 --- a/game/shared/coord.hh +++ b/src/game/shared/coord.hh @@ -1,145 +1,145 @@ -#pragma once
-
-#include "shared/const.hh"
-#include "shared/types.hh"
-
-namespace coord
-{
-constexpr chunk_pos to_chunk(const voxel_pos& vpos);
-} // namespace coord
-
-namespace coord
-{
-constexpr local_pos to_local(const voxel_pos& vpos);
-constexpr local_pos to_local(const glm::fvec3& fvec);
-constexpr local_pos to_local(std::size_t index);
-} // namespace coord
-
-namespace coord
-{
-constexpr voxel_pos to_voxel(const chunk_pos& cpos, const local_pos& lpos);
-constexpr voxel_pos to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec);
-} // namespace coord
-
-namespace coord
-{
-constexpr std::size_t to_index(const local_pos& lpos);
-} // namespace coord
-
-namespace coord
-{
-constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec);
-constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos);
-constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos, const glm::fvec3& fvec);
-} // namespace coord
-
-namespace coord
-{
-constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos);
-constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos);
-} // namespace coord
-
-inline constexpr chunk_pos coord::to_chunk(const voxel_pos& vpos)
-{
- return chunk_pos {
- static_cast<chunk_pos::value_type>(vpos.x >> CHUNK_BITSHIFT),
- static_cast<chunk_pos::value_type>(vpos.y >> CHUNK_BITSHIFT),
- static_cast<chunk_pos::value_type>(vpos.z >> CHUNK_BITSHIFT),
- };
-}
-
-inline constexpr local_pos coord::to_local(const voxel_pos& vpos)
-{
- return local_pos {
- static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.x, CHUNK_SIZE)),
- static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.y, CHUNK_SIZE)),
- static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.z, CHUNK_SIZE)),
- };
-}
-
-inline constexpr local_pos coord::to_local(const glm::fvec3& fvec)
-{
- return local_pos {
- static_cast<local_pos::value_type>(fvec.x),
- static_cast<local_pos::value_type>(fvec.y),
- static_cast<local_pos::value_type>(fvec.z),
- };
-}
-
-inline constexpr local_pos coord::to_local(std::size_t index)
-{
- return local_pos {
- static_cast<local_pos::value_type>((index % CHUNK_SIZE)),
- static_cast<local_pos::value_type>((index / CHUNK_SIZE) / CHUNK_SIZE),
- static_cast<local_pos::value_type>((index / CHUNK_SIZE) % CHUNK_SIZE),
- };
-}
-
-inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const local_pos& lpos)
-{
- return voxel_pos {
- lpos.x + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT),
- lpos.y + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT),
- lpos.z + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT),
- };
-}
-
-inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec)
-{
- return voxel_pos {
- static_cast<voxel_pos::value_type>(fvec.x) + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT),
- static_cast<voxel_pos::value_type>(fvec.y) + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT),
- static_cast<voxel_pos::value_type>(fvec.z) + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT),
- };
-}
-
-inline constexpr std::size_t coord::to_index(const local_pos& lpos)
-{
- return static_cast<std::size_t>((lpos.y * CHUNK_SIZE + lpos.z) * CHUNK_SIZE + lpos.x);
-}
-
-inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec)
-{
- return glm::fvec3 {
- static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + fvec.x,
- static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + fvec.y,
- static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + fvec.z,
- };
-}
-
-inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos)
-{
- return glm::fvec3 {
- static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) - pivot_fvec.x,
- static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) - pivot_fvec.y,
- static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) - pivot_fvec.z,
- };
-}
-
-inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos,
- const glm::fvec3& fvec)
-{
- return glm::fvec3 {
- static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + (fvec.x - pivot_fvec.x),
- static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + (fvec.y - pivot_fvec.y),
- static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + (fvec.z - pivot_fvec.z),
- };
-}
-
-inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos)
-{
- return glm::fvec3 {
- static_cast<float>(cpos.x << CHUNK_BITSHIFT),
- static_cast<float>(cpos.y << CHUNK_BITSHIFT),
- static_cast<float>(cpos.z << CHUNK_BITSHIFT),
- };
-}
-
-inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos)
-{
- return glm::fvec3 {
- fpos.x + static_cast<float>(cpos.x << CHUNK_BITSHIFT),
- fpos.y + static_cast<float>(cpos.y << CHUNK_BITSHIFT),
- fpos.z + static_cast<float>(cpos.z << CHUNK_BITSHIFT),
- };
-}
+#pragma once + +#include "shared/const.hh" +#include "shared/types.hh" + +namespace coord +{ +constexpr chunk_pos to_chunk(const voxel_pos& vpos); +} // namespace coord + +namespace coord +{ +constexpr local_pos to_local(const voxel_pos& vpos); +constexpr local_pos to_local(const glm::fvec3& fvec); +constexpr local_pos to_local(std::size_t index); +} // namespace coord + +namespace coord +{ +constexpr voxel_pos to_voxel(const chunk_pos& cpos, const local_pos& lpos); +constexpr voxel_pos to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec); +} // namespace coord + +namespace coord +{ +constexpr std::size_t to_index(const local_pos& lpos); +} // namespace coord + +namespace coord +{ +constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec); +constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos); +constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos, const glm::fvec3& fvec); +} // namespace coord + +namespace coord +{ +constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos); +constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos); +} // namespace coord + +inline constexpr chunk_pos coord::to_chunk(const voxel_pos& vpos) +{ + return chunk_pos { + static_cast<chunk_pos::value_type>(vpos.x >> CHUNK_BITSHIFT), + static_cast<chunk_pos::value_type>(vpos.y >> CHUNK_BITSHIFT), + static_cast<chunk_pos::value_type>(vpos.z >> CHUNK_BITSHIFT), + }; +} + +inline constexpr local_pos coord::to_local(const voxel_pos& vpos) +{ + return local_pos { + static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.x, CHUNK_SIZE)), + static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.y, CHUNK_SIZE)), + static_cast<local_pos::value_type>(math::mod_signed<voxel_pos::value_type>(vpos.z, CHUNK_SIZE)), + }; +} + +inline constexpr local_pos coord::to_local(const glm::fvec3& fvec) +{ + return local_pos { + static_cast<local_pos::value_type>(fvec.x), + static_cast<local_pos::value_type>(fvec.y), + static_cast<local_pos::value_type>(fvec.z), + }; +} + +inline constexpr local_pos coord::to_local(std::size_t index) +{ + return local_pos { + static_cast<local_pos::value_type>((index % CHUNK_SIZE)), + static_cast<local_pos::value_type>((index / CHUNK_SIZE) / CHUNK_SIZE), + static_cast<local_pos::value_type>((index / CHUNK_SIZE) % CHUNK_SIZE), + }; +} + +inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const local_pos& lpos) +{ + return voxel_pos { + lpos.x + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT), + lpos.y + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT), + lpos.z + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT), + }; +} + +inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec) +{ + return voxel_pos { + static_cast<voxel_pos::value_type>(fvec.x) + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT), + static_cast<voxel_pos::value_type>(fvec.y) + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT), + static_cast<voxel_pos::value_type>(fvec.z) + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT), + }; +} + +inline constexpr std::size_t coord::to_index(const local_pos& lpos) +{ + return static_cast<std::size_t>((lpos.y * CHUNK_SIZE + lpos.z) * CHUNK_SIZE + lpos.x); +} + +inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec) +{ + return glm::fvec3 { + static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + fvec.x, + static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + fvec.y, + static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + fvec.z, + }; +} + +inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos) +{ + return glm::fvec3 { + static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) - pivot_fvec.x, + static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) - pivot_fvec.y, + static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) - pivot_fvec.z, + }; +} + +inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos, + const glm::fvec3& fvec) +{ + return glm::fvec3 { + static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + (fvec.x - pivot_fvec.x), + static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + (fvec.y - pivot_fvec.y), + static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + (fvec.z - pivot_fvec.z), + }; +} + +inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos) +{ + return glm::fvec3 { + static_cast<float>(cpos.x << CHUNK_BITSHIFT), + static_cast<float>(cpos.y << CHUNK_BITSHIFT), + static_cast<float>(cpos.z << CHUNK_BITSHIFT), + }; +} + +inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos) +{ + return glm::fvec3 { + fpos.x + static_cast<float>(cpos.x << CHUNK_BITSHIFT), + fpos.y + static_cast<float>(cpos.y << CHUNK_BITSHIFT), + fpos.z + static_cast<float>(cpos.z << CHUNK_BITSHIFT), + }; +} diff --git a/game/shared/entity/CMakeLists.txt b/src/game/shared/entity/CMakeLists.txt index 36e45b6..36e45b6 100644 --- a/game/shared/entity/CMakeLists.txt +++ b/src/game/shared/entity/CMakeLists.txt diff --git a/game/shared/entity/collision.cc b/src/game/shared/entity/collision.cc index d2bc0a9..bc9209b 100644 --- a/game/shared/entity/collision.cc +++ b/src/game/shared/entity/collision.cc @@ -1,173 +1,173 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/collision.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "shared/entity/gravity.hh"
-#include "shared/entity/grounded.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/globals.hh"
-
-static int vgrid_collide(const world::Dimension* dimension, int d, entity::Collision& collision, entity::Transform& transform,
- entity::Velocity& velocity, world::VoxelMaterial& touch_surface)
-{
- const auto move = globals::fixed_frametime * velocity.value[d];
- const auto move_sign = math::sign<int>(move);
-
- const auto& ref_aabb = collision.aabb;
- const auto current_aabb = ref_aabb.push(transform.local);
-
- auto next_aabb = math::AABBf(current_aabb);
- next_aabb.min[d] += move;
- next_aabb.max[d] += move;
-
- local_pos lpos_min;
- lpos_min.x = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.x));
- lpos_min.y = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.y));
- lpos_min.z = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.z));
-
- local_pos lpos_max;
- lpos_max.x = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.x));
- lpos_max.y = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.y));
- lpos_max.z = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.z));
-
- // Other axes
- const int u = (d + 1) % 3;
- const int v = (d + 2) % 3;
-
- local_pos::value_type ddir;
- local_pos::value_type dmin;
- local_pos::value_type dmax;
-
- if(move < 0.0f) {
- ddir = local_pos::value_type(+1);
- dmin = lpos_min[d];
- dmax = lpos_max[d];
- }
- else {
- ddir = local_pos::value_type(-1);
- dmin = lpos_max[d];
- dmax = lpos_min[d];
- }
-
- world::VoxelTouch latch_touch = world::VTOUCH_NONE;
- glm::fvec3 latch_values = glm::fvec3(0.0f, 0.0f, 0.0f);
- world::VoxelMaterial latch_surface = world::VMAT_UNKNOWN;
- math::AABBf latch_vbox;
-
- for(auto i = dmin; i != dmax; i += ddir) {
- for(auto j = lpos_min[u]; j < lpos_max[u]; ++j)
- for(auto k = lpos_min[v]; k < lpos_max[v]; ++k) {
- local_pos lpos;
- lpos[d] = i;
- lpos[u] = j;
- lpos[v] = k;
-
- auto vpos = coord::to_voxel(transform.chunk, lpos);
- auto voxel = dimension->get_voxel(vpos);
-
- if(voxel == nullptr) {
- // Don't collide with something
- // that we assume to be nothing
- continue;
- }
-
- math::AABBf vbox(voxel->get_collision().push(lpos));
-
- if(!next_aabb.intersect(vbox)) {
- // No intersection between the voxel
- // and the entity's collision hull
- continue;
- }
-
- if(voxel->is_touch_type<world::VTOUCH_SOLID>()) {
- // Solid touch type makes a collision
- // response whenever it is encountered
- velocity.value[d] = 0.0f;
- touch_surface = voxel->get_surface_material();
- return move_sign;
- }
-
- // In case of other touch types, they
- // are latched and the last ever touch
- // type is then responded to
- if(voxel->get_touch_type() != world::VTOUCH_NONE) {
- latch_touch = voxel->get_touch_type();
- latch_values = voxel->get_touch_values();
- latch_surface = voxel->get_surface_material();
- latch_vbox = vbox;
- continue;
- }
- }
- }
-
- if(latch_touch != world::VTOUCH_NONE) {
- if(latch_touch == world::VTOUCH_BOUNCE) {
- const auto move_distance = glm::abs(current_aabb.min[d] - next_aabb.min[d]);
- const auto threshold = 2.0f * globals::fixed_frametime;
-
- if(move_distance > threshold) {
- velocity.value[d] *= -latch_values[d];
- }
- else {
- velocity.value[d] = 0.0f;
- }
-
- touch_surface = latch_surface;
-
- return move_sign;
- }
-
- if(latch_touch == world::VTOUCH_SINK) {
- velocity.value[d] *= latch_values[d];
- touch_surface = latch_surface;
- return move_sign;
- }
- }
-
- return 0;
-}
-
-void entity::Collision::fixed_update(world::Dimension* dimension)
-{
- // FIXME: this isn't particularly accurate considering
- // some voxels might be passable and some other voxels
- // might apply some slowing factor; what I might do in the
- // future is to add a specific value to the voxel registry
- // entries that would specify the amount of force we apply
- // to prevent player movement inside a specific voxel, plus
- // we shouldn't treat all voxels as full cubes if we want
- // to support slabs, stairs and non-full liquid voxels in the future
-
- auto group = dimension->entities.group<entity::Collision>(entt::get<entity::Transform, entity::Velocity>);
-
- for(auto [entity, collision, transform, velocity] : group.each()) {
- auto surface = world::VMAT_UNKNOWN;
- auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface);
-
- if(dimension->entities.any_of<entity::Gravity>(entity)) {
- if(vertical_move == math::sign<int>(dimension->get_gravity())) {
- dimension->entities.emplace_or_replace<entity::Grounded>(entity, entity::Grounded { surface });
- }
- else {
- dimension->entities.remove<entity::Grounded>(entity);
- }
- }
- else {
- // The entity cannot be grounded because the component
- // setup of said entity should not let it comprehend the
- // concept of resting on the ground (it flies around)
- dimension->entities.remove<entity::Grounded>(entity);
- }
-
- vgrid_collide(dimension, 0, collision, transform, velocity, surface);
- vgrid_collide(dimension, 2, collision, transform, velocity, surface);
- }
-}
+#include "shared/pch.hh" + +#include "shared/entity/collision.hh" + +#include "core/math/constexpr.hh" + +#include "shared/entity/gravity.hh" +#include "shared/entity/grounded.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/globals.hh" + +static int vgrid_collide(const world::Dimension* dimension, int d, entity::Collision& collision, entity::Transform& transform, + entity::Velocity& velocity, world::VoxelMaterial& touch_surface) +{ + const auto move = globals::fixed_frametime * velocity.value[d]; + const auto move_sign = math::sign<int>(move); + + const auto& ref_aabb = collision.aabb; + const auto current_aabb = ref_aabb.push(transform.local); + + auto next_aabb = math::AABBf(current_aabb); + next_aabb.min[d] += move; + next_aabb.max[d] += move; + + local_pos lpos_min; + lpos_min.x = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.x)); + lpos_min.y = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.y)); + lpos_min.z = static_cast<local_pos::value_type>(glm::floor(next_aabb.min.z)); + + local_pos lpos_max; + lpos_max.x = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.x)); + lpos_max.y = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.y)); + lpos_max.z = static_cast<local_pos::value_type>(glm::ceil(next_aabb.max.z)); + + // Other axes + const int u = (d + 1) % 3; + const int v = (d + 2) % 3; + + local_pos::value_type ddir; + local_pos::value_type dmin; + local_pos::value_type dmax; + + if(move < 0.0f) { + ddir = local_pos::value_type(+1); + dmin = lpos_min[d]; + dmax = lpos_max[d]; + } + else { + ddir = local_pos::value_type(-1); + dmin = lpos_max[d]; + dmax = lpos_min[d]; + } + + world::VoxelTouch latch_touch = world::VTOUCH_NONE; + glm::fvec3 latch_values = glm::fvec3(0.0f, 0.0f, 0.0f); + world::VoxelMaterial latch_surface = world::VMAT_UNKNOWN; + math::AABBf latch_vbox; + + for(auto i = dmin; i != dmax; i += ddir) { + for(auto j = lpos_min[u]; j < lpos_max[u]; ++j) + for(auto k = lpos_min[v]; k < lpos_max[v]; ++k) { + local_pos lpos; + lpos[d] = i; + lpos[u] = j; + lpos[v] = k; + + auto vpos = coord::to_voxel(transform.chunk, lpos); + auto voxel = dimension->get_voxel(vpos); + + if(voxel == nullptr) { + // Don't collide with something + // that we assume to be nothing + continue; + } + + math::AABBf vbox(voxel->get_collision().push(lpos)); + + if(!next_aabb.intersect(vbox)) { + // No intersection between the voxel + // and the entity's collision hull + continue; + } + + if(voxel->is_touch_type<world::VTOUCH_SOLID>()) { + // Solid touch type makes a collision + // response whenever it is encountered + velocity.value[d] = 0.0f; + touch_surface = voxel->get_surface_material(); + return move_sign; + } + + // In case of other touch types, they + // are latched and the last ever touch + // type is then responded to + if(voxel->get_touch_type() != world::VTOUCH_NONE) { + latch_touch = voxel->get_touch_type(); + latch_values = voxel->get_touch_values(); + latch_surface = voxel->get_surface_material(); + latch_vbox = vbox; + continue; + } + } + } + + if(latch_touch != world::VTOUCH_NONE) { + if(latch_touch == world::VTOUCH_BOUNCE) { + const auto move_distance = glm::abs(current_aabb.min[d] - next_aabb.min[d]); + const auto threshold = 2.0f * globals::fixed_frametime; + + if(move_distance > threshold) { + velocity.value[d] *= -latch_values[d]; + } + else { + velocity.value[d] = 0.0f; + } + + touch_surface = latch_surface; + + return move_sign; + } + + if(latch_touch == world::VTOUCH_SINK) { + velocity.value[d] *= latch_values[d]; + touch_surface = latch_surface; + return move_sign; + } + } + + return 0; +} + +void entity::Collision::fixed_update(world::Dimension* dimension) +{ + // FIXME: this isn't particularly accurate considering + // some voxels might be passable and some other voxels + // might apply some slowing factor; what I might do in the + // future is to add a specific value to the voxel registry + // entries that would specify the amount of force we apply + // to prevent player movement inside a specific voxel, plus + // we shouldn't treat all voxels as full cubes if we want + // to support slabs, stairs and non-full liquid voxels in the future + + auto group = dimension->entities.group<entity::Collision>(entt::get<entity::Transform, entity::Velocity>); + + for(auto [entity, collision, transform, velocity] : group.each()) { + auto surface = world::VMAT_UNKNOWN; + auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface); + + if(dimension->entities.any_of<entity::Gravity>(entity)) { + if(vertical_move == math::sign<int>(dimension->get_gravity())) { + dimension->entities.emplace_or_replace<entity::Grounded>(entity, entity::Grounded { surface }); + } + else { + dimension->entities.remove<entity::Grounded>(entity); + } + } + else { + // The entity cannot be grounded because the component + // setup of said entity should not let it comprehend the + // concept of resting on the ground (it flies around) + dimension->entities.remove<entity::Grounded>(entity); + } + + vgrid_collide(dimension, 0, collision, transform, velocity, surface); + vgrid_collide(dimension, 2, collision, transform, velocity, surface); + } +} diff --git a/game/shared/entity/collision.hh b/src/game/shared/entity/collision.hh index 95a9b86..b37f409 100644 --- a/game/shared/entity/collision.hh +++ b/src/game/shared/entity/collision.hh @@ -1,21 +1,21 @@ -#pragma once
-
-#include "core/math/aabb.hh"
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity
-{
-struct Collision final {
- math::AABBf aabb;
-
-public:
- // NOTE: entity::Collision::fixed_update must be called
- // before entity::Transform::fixed_update and entity::Velocity::fixed_update
- // because both transform and velocity may be updated internally
- static void fixed_update(world::Dimension* dimension);
-};
-} // namespace entity
+#pragma once + +#include "core/math/aabb.hh" + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity +{ +struct Collision final { + math::AABBf aabb; + +public: + // NOTE: entity::Collision::fixed_update must be called + // before entity::Transform::fixed_update and entity::Velocity::fixed_update + // because both transform and velocity may be updated internally + static void fixed_update(world::Dimension* dimension); +}; +} // namespace entity diff --git a/game/shared/entity/factory.cc b/src/game/shared/entity/factory.cc index ba95b73..619a418 100644 --- a/game/shared/entity/factory.cc +++ b/src/game/shared/entity/factory.cc @@ -1,37 +1,37 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/factory.hh"
-
-#include "shared/entity/collision.hh"
-#include "shared/entity/gravity.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/globals.hh"
-
-void entity::shared::create_player(world::Dimension* dimension, entt::entity entity)
-{
- spdlog::debug("factory[{}]: assigning player components to {}", dimension->get_name(), static_cast<std::uint64_t>(entity));
-
- auto& collision = dimension->entities.emplace_or_replace<entity::Collision>(entity);
- collision.aabb.min = glm::fvec3(-0.4f, -1.6f, -0.4f);
- collision.aabb.max = glm::fvec3(+0.4f, +0.2f, +0.4f);
-
- auto& head = dimension->entities.emplace_or_replace<entity::Head>(entity);
- head.angles = glm::fvec3(0.0f, 0.0f, 0.0f);
- head.offset = glm::fvec3(0.0f, 0.0f, 0.0f);
-
- dimension->entities.emplace_or_replace<entity::Player>(entity);
-
- auto& transform = dimension->entities.emplace_or_replace<entity::Transform>(entity);
- transform.chunk = chunk_pos(0, 2, 0);
- transform.local = glm::fvec3(0.0f, 0.0f, 0.0f);
- transform.angles = glm::fvec3(0.0f, 0.0f, 0.0f);
-
- auto& velocity = dimension->entities.emplace_or_replace<entity::Velocity>(entity);
- velocity.value = glm::fvec3(0.0f, 0.0f, 0.0f);
-}
+#include "shared/pch.hh" + +#include "shared/entity/factory.hh" + +#include "shared/entity/collision.hh" +#include "shared/entity/gravity.hh" +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/globals.hh" + +void entity::shared::create_player(world::Dimension* dimension, entt::entity entity) +{ + spdlog::debug("factory[{}]: assigning player components to {}", dimension->get_name(), static_cast<std::uint64_t>(entity)); + + auto& collision = dimension->entities.emplace_or_replace<entity::Collision>(entity); + collision.aabb.min = glm::fvec3(-0.4f, -1.6f, -0.4f); + collision.aabb.max = glm::fvec3(+0.4f, +0.2f, +0.4f); + + auto& head = dimension->entities.emplace_or_replace<entity::Head>(entity); + head.angles = glm::fvec3(0.0f, 0.0f, 0.0f); + head.offset = glm::fvec3(0.0f, 0.0f, 0.0f); + + dimension->entities.emplace_or_replace<entity::Player>(entity); + + auto& transform = dimension->entities.emplace_or_replace<entity::Transform>(entity); + transform.chunk = chunk_pos(0, 2, 0); + transform.local = glm::fvec3(0.0f, 0.0f, 0.0f); + transform.angles = glm::fvec3(0.0f, 0.0f, 0.0f); + + auto& velocity = dimension->entities.emplace_or_replace<entity::Velocity>(entity); + velocity.value = glm::fvec3(0.0f, 0.0f, 0.0f); +} diff --git a/game/shared/entity/factory.hh b/src/game/shared/entity/factory.hh index be33045..e709060 100644 --- a/game/shared/entity/factory.hh +++ b/src/game/shared/entity/factory.hh @@ -1,11 +1,11 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity::shared
-{
-void create_player(world::Dimension* dimension, entt::entity entity);
-} // namespace entity::shared
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity::shared +{ +void create_player(world::Dimension* dimension, entt::entity entity); +} // namespace entity::shared diff --git a/game/shared/entity/gravity.cc b/src/game/shared/entity/gravity.cc index 09bc379..f1708aa 100644 --- a/game/shared/entity/gravity.cc +++ b/src/game/shared/entity/gravity.cc @@ -1,20 +1,20 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/gravity.hh"
-
-#include "shared/entity/stasis.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/globals.hh"
-
-void entity::Gravity::fixed_update(world::Dimension* dimension)
-{
- auto fixed_acceleration = globals::fixed_frametime * dimension->get_gravity();
- auto group = dimension->entities.group<entity::Gravity>(entt::get<entity::Velocity>, entt::exclude<entity::Stasis>);
-
- for(auto [entity, velocity] : group.each()) {
- velocity.value.y += fixed_acceleration;
- }
-}
+#include "shared/pch.hh" + +#include "shared/entity/gravity.hh" + +#include "shared/entity/stasis.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/dimension.hh" + +#include "shared/globals.hh" + +void entity::Gravity::fixed_update(world::Dimension* dimension) +{ + auto fixed_acceleration = globals::fixed_frametime * dimension->get_gravity(); + auto group = dimension->entities.group<entity::Gravity>(entt::get<entity::Velocity>, entt::exclude<entity::Stasis>); + + for(auto [entity, velocity] : group.each()) { + velocity.value.y += fixed_acceleration; + } +} diff --git a/game/shared/entity/gravity.hh b/src/game/shared/entity/gravity.hh index 2cbcbbc..21f4582 100644 --- a/game/shared/entity/gravity.hh +++ b/src/game/shared/entity/gravity.hh @@ -1,14 +1,14 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity
-{
-struct Gravity final {
-public:
- static void fixed_update(world::Dimension* dimension);
-};
-} // namespace entity
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity +{ +struct Gravity final { +public: + static void fixed_update(world::Dimension* dimension); +}; +} // namespace entity diff --git a/game/shared/entity/grounded.hh b/src/game/shared/entity/grounded.hh index 34a0f9e..6c33d1d 100644 --- a/game/shared/entity/grounded.hh +++ b/src/game/shared/entity/grounded.hh @@ -1,12 +1,12 @@ -#pragma once
-
-#include "shared/world/voxel.hh"
-
-namespace entity
-{
-// Assigned to entities which are grounded
-// according to the collision and gravity system
-struct Grounded final {
- world::VoxelMaterial surface;
-};
-} // namespace entity
+#pragma once + +#include "shared/world/voxel.hh" + +namespace entity +{ +// Assigned to entities which are grounded +// according to the collision and gravity system +struct Grounded final { + world::VoxelMaterial surface; +}; +} // namespace entity diff --git a/game/shared/entity/head.hh b/src/game/shared/entity/head.hh index 15ce7e5..3f5d6d1 100644 --- a/game/shared/entity/head.hh +++ b/src/game/shared/entity/head.hh @@ -1,16 +1,16 @@ -#pragma once
-
-namespace entity
-{
-struct Head {
- glm::fvec3 angles;
- glm::fvec3 offset;
-};
-} // namespace entity
-
-namespace entity::client
-{
-// Client-side only - interpolated and previous head
-struct HeadIntr final : public Head {};
-struct HeadPrev final : public Head {};
-} // namespace entity::client
+#pragma once + +namespace entity +{ +struct Head { + glm::fvec3 angles; + glm::fvec3 offset; +}; +} // namespace entity + +namespace entity::client +{ +// Client-side only - interpolated and previous head +struct HeadIntr final : public Head {}; +struct HeadPrev final : public Head {}; +} // namespace entity::client diff --git a/game/shared/entity/player.hh b/src/game/shared/entity/player.hh index abffd85..4bd0217 100644 --- a/game/shared/entity/player.hh +++ b/src/game/shared/entity/player.hh @@ -1,6 +1,6 @@ -#pragma once
-
-namespace entity
-{
-struct Player final {};
-} // namespace entity
+#pragma once + +namespace entity +{ +struct Player final {}; +} // namespace entity diff --git a/game/shared/entity/stasis.cc b/src/game/shared/entity/stasis.cc index eab8744..3b86294 100644 --- a/game/shared/entity/stasis.cc +++ b/src/game/shared/entity/stasis.cc @@ -1,21 +1,21 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/stasis.hh"
-
-#include "shared/entity/transform.hh"
-
-#include "shared/world/dimension.hh"
-
-void entity::Stasis::fixed_update(world::Dimension* dimension)
-{
- auto view = dimension->entities.view<entity::Transform>();
-
- for(auto [entity, transform] : view.each()) {
- if(dimension->find_chunk(transform.chunk)) {
- dimension->entities.remove<entity::Stasis>(entity);
- }
- else {
- dimension->entities.emplace_or_replace<entity::Stasis>(entity);
- }
- }
-}
+#include "shared/pch.hh" + +#include "shared/entity/stasis.hh" + +#include "shared/entity/transform.hh" + +#include "shared/world/dimension.hh" + +void entity::Stasis::fixed_update(world::Dimension* dimension) +{ + auto view = dimension->entities.view<entity::Transform>(); + + for(auto [entity, transform] : view.each()) { + if(dimension->find_chunk(transform.chunk)) { + dimension->entities.remove<entity::Stasis>(entity); + } + else { + dimension->entities.emplace_or_replace<entity::Stasis>(entity); + } + } +} diff --git a/game/shared/entity/stasis.hh b/src/game/shared/entity/stasis.hh index cb364ce..e6cb9e4 100644 --- a/game/shared/entity/stasis.hh +++ b/src/game/shared/entity/stasis.hh @@ -1,16 +1,16 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity
-{
-// Attached to entities with transform values
-// out of bounds in a specific dimension
-struct Stasis final {
-public:
- static void fixed_update(world::Dimension* dimension);
-};
-} // namespace entity
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity +{ +// Attached to entities with transform values +// out of bounds in a specific dimension +struct Stasis final { +public: + static void fixed_update(world::Dimension* dimension); +}; +} // namespace entity diff --git a/game/shared/entity/transform.cc b/src/game/shared/entity/transform.cc index 0339b9e..379ddd5 100644 --- a/game/shared/entity/transform.cc +++ b/src/game/shared/entity/transform.cc @@ -1,33 +1,33 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/transform.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/const.hh"
-
-constexpr inline static void update_component(unsigned int dim, entity::Transform& component)
-{
- if(component.local[dim] >= CHUNK_SIZE) {
- component.local[dim] -= CHUNK_SIZE;
- component.chunk[dim] += 1;
- return;
- }
-
- if(component.local[dim] < 0.0f) {
- component.local[dim] += CHUNK_SIZE;
- component.chunk[dim] -= 1;
- return;
- }
-}
-
-void entity::Transform::fixed_update(world::Dimension* dimension)
-{
- auto view = dimension->entities.view<entity::Transform>();
-
- for(auto [entity, transform] : view.each()) {
- update_component(0U, transform);
- update_component(1U, transform);
- update_component(2U, transform);
- }
-}
+#include "shared/pch.hh" + +#include "shared/entity/transform.hh" + +#include "shared/world/dimension.hh" + +#include "shared/const.hh" + +constexpr inline static void update_component(unsigned int dim, entity::Transform& component) +{ + if(component.local[dim] >= CHUNK_SIZE) { + component.local[dim] -= CHUNK_SIZE; + component.chunk[dim] += 1; + return; + } + + if(component.local[dim] < 0.0f) { + component.local[dim] += CHUNK_SIZE; + component.chunk[dim] -= 1; + return; + } +} + +void entity::Transform::fixed_update(world::Dimension* dimension) +{ + auto view = dimension->entities.view<entity::Transform>(); + + for(auto [entity, transform] : view.each()) { + update_component(0U, transform); + update_component(1U, transform); + update_component(2U, transform); + } +} diff --git a/game/shared/entity/transform.hh b/src/game/shared/entity/transform.hh index f7db095..2b357f8 100644 --- a/game/shared/entity/transform.hh +++ b/src/game/shared/entity/transform.hh @@ -1,30 +1,30 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity
-{
-struct Transform {
- chunk_pos chunk;
- glm::fvec3 local;
- glm::fvec3 angles;
-
-public:
- // Updates entity::Transform values so that
- // the local translation field is always within
- // local coodrinates; [floating-point precision]
- static void fixed_update(world::Dimension* dimension);
-};
-} // namespace entity
-
-namespace entity::client
-{
-// Client-side only - interpolated and previous transform
-struct TransformIntr final : public Transform {};
-struct TransformPrev final : public Transform {};
-} // namespace entity::client
+#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity +{ +struct Transform { + chunk_pos chunk; + glm::fvec3 local; + glm::fvec3 angles; + +public: + // Updates entity::Transform values so that + // the local translation field is always within + // local coodrinates; [floating-point precision] + static void fixed_update(world::Dimension* dimension); +}; +} // namespace entity + +namespace entity::client +{ +// Client-side only - interpolated and previous transform +struct TransformIntr final : public Transform {}; +struct TransformPrev final : public Transform {}; +} // namespace entity::client diff --git a/game/shared/entity/velocity.cc b/src/game/shared/entity/velocity.cc index 85ad53b..86df445 100644 --- a/game/shared/entity/velocity.cc +++ b/src/game/shared/entity/velocity.cc @@ -1,19 +1,19 @@ -#include "shared/pch.hh"
-
-#include "shared/entity/velocity.hh"
-
-#include "shared/entity/stasis.hh"
-#include "shared/entity/transform.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/globals.hh"
-
-void entity::Velocity::fixed_update(world::Dimension* dimension)
-{
- auto group = dimension->entities.group<entity::Velocity>(entt::get<entity::Transform>, entt::exclude<entity::Stasis>);
-
- for(auto [entity, velocity, transform] : group.each()) {
- transform.local += velocity.value * globals::fixed_frametime;
- }
-}
+#include "shared/pch.hh" + +#include "shared/entity/velocity.hh" + +#include "shared/entity/stasis.hh" +#include "shared/entity/transform.hh" + +#include "shared/world/dimension.hh" + +#include "shared/globals.hh" + +void entity::Velocity::fixed_update(world::Dimension* dimension) +{ + auto group = dimension->entities.group<entity::Velocity>(entt::get<entity::Transform>, entt::exclude<entity::Stasis>); + + for(auto [entity, velocity, transform] : group.each()) { + transform.local += velocity.value * globals::fixed_frametime; + } +} diff --git a/game/shared/entity/velocity.hh b/src/game/shared/entity/velocity.hh index e57e555..c8a1c91 100644 --- a/game/shared/entity/velocity.hh +++ b/src/game/shared/entity/velocity.hh @@ -1,19 +1,19 @@ -#pragma once
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace entity
-{
-struct Velocity final {
- glm::fvec3 value;
-
-public:
- // Updates entities entity::Transform values
- // according to velocities multiplied by fixed_frametime.
- // NOTE: This system was previously called inertial
- static void fixed_update(world::Dimension* dimension);
-};
-} // namespace entity
+#pragma once + +namespace world +{ +class Dimension; +} // namespace world + +namespace entity +{ +struct Velocity final { + glm::fvec3 value; + +public: + // Updates entities entity::Transform values + // according to velocities multiplied by fixed_frametime. + // NOTE: This system was previously called inertial + static void fixed_update(world::Dimension* dimension); +}; +} // namespace entity diff --git a/game/shared/game.cc b/src/game/shared/game.cc index 91bc3bc..a3a724d 100644 --- a/game/shared/game.cc +++ b/src/game/shared/game.cc @@ -1,124 +1,127 @@ -#include "shared/pch.hh"
-
-#include "shared/game.hh"
-
-#include "core/io/cmdline.hh"
-#include "core/io/physfs.hh"
-
-static std::filesystem::path get_gamepath(void)
-{
- if(auto gamepath = io::cmdline::get_cstr("gamepath")) {
- // Allow users and third-party launchers to override
- // content location. Perhaps this would work to allow
- // for a Minecraft-like versioning approach?
- return std::filesystem::path(gamepath);
- }
-
- return std::filesystem::current_path() / "data";
-}
-
-static std::filesystem::path get_userpath(void)
-{
- if(auto userpath = io::cmdline::get_cstr("userpath")) {
- // Allow users and third-party launchers to override
- // user data location. Perhaps this would work to allow
- // for a Minecraft-like versioning approach?
- return std::filesystem::path(userpath);
- }
-
- if(auto win_appdata = std::getenv("APPDATA")) {
- // On pre-seven Windows systems it's just AppData
- // On post-seven Windows systems it's AppData/Roaming
- return std::filesystem::path(win_appdata) / "voxelius";
- }
-
- if(auto xdg_home = std::getenv("XDG_DATA_HOME")) {
- // Systems with an active X11/Wayland session
- // theoretically should have this defined, and
- // it can be different from ${HOME} (I think).
- return std::filesystem::path(xdg_home) / ".voxelius";
- }
-
- if(auto unix_home = std::getenv("HOME")) {
- // Any spherical UNIX/UNIX-like system in vacuum
- // has this defined for every single user process.
- return std::filesystem::path(unix_home) / ".voxelius";
- }
-
- // Give up and save stuff into CWD
- return std::filesystem::current_path();
-}
-
-void shared_game::init(int argc, char** argv)
-{
- auto logger = spdlog::default_logger();
- auto& logger_sinks = logger->sinks();
-
- logger_sinks.clear();
- logger_sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
- logger_sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("voxelius.log", false));
-
-#if defined(NDEBUG)
- constexpr auto default_loglevel = spdlog::level::info;
-#else
- constexpr auto default_loglevel = spdlog::level::trace;
-#endif
-
- if(io::cmdline::contains("quiet")) {
- logger->set_level(spdlog::level::warn);
- }
- else if(io::cmdline::contains("verbose")) {
- logger->set_level(spdlog::level::trace);
- }
- else {
- logger->set_level(default_loglevel);
- }
-
- logger->set_pattern("%H:%M:%S.%e %^[%L]%$ %v");
- logger->flush();
-
- if(!PHYSFS_init(argv[0])) {
- spdlog::critical("physfs: init failed: {}", io::physfs_error());
- std::terminate();
- }
-
- auto gamepath = get_gamepath();
- auto userpath = get_userpath();
-
- spdlog::info("shared_game: set gamepath to {}", gamepath.string());
- spdlog::info("shared_game: set userpath to {}", userpath.string());
-
- std::error_code ignore_error = {};
- std::filesystem::create_directories(gamepath, ignore_error);
- std::filesystem::create_directories(userpath, ignore_error);
-
- if(!PHYSFS_mount(gamepath.string().c_str(), nullptr, false)) {
- spdlog::critical("physfs: mount {} failed: {}", gamepath.string(), io::physfs_error());
- std::terminate();
- }
-
- if(!PHYSFS_mount(userpath.string().c_str(), nullptr, false)) {
- spdlog::critical("physfs: mount {} failed: {}", userpath.string(), io::physfs_error());
- std::terminate();
- }
-
- if(!PHYSFS_setWriteDir(userpath.string().c_str())) {
- spdlog::critical("physfs: setwritedir {} failed: {}", userpath.string(), io::physfs_error());
- std::terminate();
- }
-
- if(enet_initialize()) {
- spdlog::critical("enet: init failed");
- std::terminate();
- }
-}
-
-void shared_game::shutdown(void)
-{
- enet_deinitialize();
-
- if(!PHYSFS_deinit()) {
- spdlog::critical("physfs: deinit failed: {}", io::physfs_error());
- std::terminate();
- }
-}
+#include "shared/pch.hh" + +#include "shared/game.hh" + +#include "core/io/cmdline.hh" +#include "core/io/physfs.hh" + +static std::filesystem::path get_gamepath(void) +{ + if(auto gamepath = io::cmdline::get_cstr("gamepath")) { + // Allow users and third-party launchers to override + // content location. Perhaps this would work to allow + // for a Minecraft-like versioning approach? + return std::filesystem::path(gamepath); + } + + return std::filesystem::current_path() / "assets"; +} + +static std::filesystem::path get_userpath(void) +{ + if(auto userpath = io::cmdline::get_cstr("userpath")) { + // Allow users and third-party launchers to override + // user data location. Perhaps this would work to allow + // for a Minecraft-like versioning approach? + return std::filesystem::path(userpath); + } + + if(auto win_appdata = std::getenv("APPDATA")) { + // On pre-seven Windows systems it's just AppData + // On post-seven Windows systems it's AppData/Roaming + return std::filesystem::path(win_appdata) / "voxelius"; + } + + if(auto xdg_home = std::getenv("XDG_DATA_HOME")) { + // Systems with an active X11/Wayland session + // theoretically should have this defined, and + // it can be different from ${HOME} (I think). + return std::filesystem::path(xdg_home) / ".voxelius"; + } + + if(auto unix_home = std::getenv("HOME")) { + // Any spherical UNIX/UNIX-like system in vacuum + // has this defined for every single user process. + return std::filesystem::path(unix_home) / ".voxelius"; + } + + // Give up and save stuff into CWD + return std::filesystem::current_path(); +} + +void shared_game::init(int argc, char** argv, std::string_view logfile) +{ + auto logger = spdlog::default_logger(); + auto& logger_sinks = logger->sinks(); + + logger_sinks.clear(); + logger_sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>()); + + if(logfile.size()) { + logger_sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(std::string(logfile), false)); + } + +#if defined(NDEBUG) + constexpr auto default_loglevel = spdlog::level::info; +#else + constexpr auto default_loglevel = spdlog::level::trace; +#endif + + if(io::cmdline::contains("quiet")) { + logger->set_level(spdlog::level::warn); + } + else if(io::cmdline::contains("verbose")) { + logger->set_level(spdlog::level::trace); + } + else { + logger->set_level(default_loglevel); + } + + logger->set_pattern("%H:%M:%S.%e %^[%L]%$ %v"); + logger->flush(); + + if(!PHYSFS_init(argv[0])) { + spdlog::critical("physfs: init failed: {}", io::physfs_error()); + std::terminate(); + } + + auto gamepath = get_gamepath(); + auto userpath = get_userpath(); + + spdlog::info("shared_game: set gamepath to {}", gamepath.string()); + spdlog::info("shared_game: set userpath to {}", userpath.string()); + + std::error_code ignore_error = {}; + std::filesystem::create_directories(gamepath, ignore_error); + std::filesystem::create_directories(userpath, ignore_error); + + if(!PHYSFS_mount(gamepath.string().c_str(), nullptr, false)) { + spdlog::critical("physfs: mount {} failed: {}", gamepath.string(), io::physfs_error()); + std::terminate(); + } + + if(!PHYSFS_mount(userpath.string().c_str(), nullptr, false)) { + spdlog::critical("physfs: mount {} failed: {}", userpath.string(), io::physfs_error()); + std::terminate(); + } + + if(!PHYSFS_setWriteDir(userpath.string().c_str())) { + spdlog::critical("physfs: setwritedir {} failed: {}", userpath.string(), io::physfs_error()); + std::terminate(); + } + + if(enet_initialize()) { + spdlog::critical("enet: init failed"); + std::terminate(); + } +} + +void shared_game::shutdown(void) +{ + enet_deinitialize(); + + if(!PHYSFS_deinit()) { + spdlog::critical("physfs: deinit failed: {}", io::physfs_error()); + std::terminate(); + } +} diff --git a/game/shared/game.hh b/src/game/shared/game.hh index 0dfbadb..6e89a3c 100644 --- a/game/shared/game.hh +++ b/src/game/shared/game.hh @@ -1,7 +1,7 @@ -#pragma once
-
-namespace shared_game
-{
-void init(int argc, char** argv);
-void shutdown(void);
-} // namespace shared_game
+#pragma once + +namespace shared_game +{ +void init(int argc, char** argv, std::string_view logfile = {}); +void shutdown(void); +} // namespace shared_game diff --git a/game/shared/game_items.cc b/src/game/shared/game_items.cc index cad73da..e239063 100644 --- a/game/shared/game_items.cc +++ b/src/game/shared/game_items.cc @@ -1,65 +1,65 @@ -#include "shared/pch.hh"
-
-#include "shared/game_items.hh"
-
-#include "shared/world/item_registry.hh"
-
-#include "shared/game_voxels.hh"
-
-const world::Item* game_items::stone = nullptr;
-const world::Item* game_items::cobblestone = nullptr;
-const world::Item* game_items::dirt = nullptr;
-const world::Item* game_items::grass = nullptr;
-const world::Item* game_items::oak_leaves = nullptr;
-const world::Item* game_items::oak_planks = nullptr;
-const world::Item* game_items::oak_log = nullptr;
-const world::Item* game_items::glass = nullptr;
-const world::Item* game_items::slime = nullptr;
-
-void game_items::populate(void)
-{
- auto stone_builder = world::ItemBuilder("stone");
- stone_builder.set_texture("textures/item/stone.png");
- stone_builder.set_place_voxel(game_voxels::stone);
- stone = world::item_registry::register_item(stone_builder);
-
- auto cobblestone_builder = world::ItemBuilder("cobblestone");
- cobblestone_builder.set_texture("textures/item/cobblestone.png");
- cobblestone_builder.set_place_voxel(game_voxels::cobblestone);
- cobblestone = world::item_registry::register_item(cobblestone_builder);
-
- auto dirt_builder = world::ItemBuilder("dirt");
- dirt_builder.set_texture("textures/item/dirt.png");
- dirt_builder.set_place_voxel(game_voxels::dirt);
- dirt = world::item_registry::register_item(dirt_builder);
-
- auto grass_builder = world::ItemBuilder("grass");
- grass_builder.set_texture("textures/item/grass.png");
- grass_builder.set_place_voxel(game_voxels::grass);
- grass = world::item_registry::register_item(grass_builder);
-
- auto oak_leaves_builder = world::ItemBuilder("oak_leaves");
- oak_leaves_builder.set_texture("textures/item/oak_leaves.png");
- oak_leaves_builder.set_place_voxel(game_voxels::oak_leaves);
- oak_leaves = world::item_registry::register_item(oak_leaves_builder);
-
- auto oak_planks_builder = world::ItemBuilder("oak_planks");
- oak_planks_builder.set_texture("textures/item/oak_planks.png");
- oak_planks_builder.set_place_voxel(game_voxels::oak_planks);
- oak_planks = world::item_registry::register_item(oak_planks_builder);
-
- auto oak_log_builder = world::ItemBuilder("oak_log");
- oak_log_builder.set_texture("textures/item/oak_log.png");
- oak_log_builder.set_place_voxel(game_voxels::oak_log);
- oak_log = world::item_registry::register_item(oak_log_builder);
-
- auto glass_builder = world::ItemBuilder("glass");
- glass_builder.set_texture("textures/item/glass.png");
- glass_builder.set_place_voxel(game_voxels::glass);
- glass = world::item_registry::register_item(glass_builder);
-
- auto slime_builder = world::ItemBuilder("slime");
- slime_builder.set_texture("textures/item/slime.png");
- slime_builder.set_place_voxel(game_voxels::slime);
- slime = world::item_registry::register_item(slime_builder);
-}
+#include "shared/pch.hh" + +#include "shared/game_items.hh" + +#include "shared/world/item_registry.hh" + +#include "shared/game_voxels.hh" + +const world::Item* game_items::stone = nullptr; +const world::Item* game_items::cobblestone = nullptr; +const world::Item* game_items::dirt = nullptr; +const world::Item* game_items::grass = nullptr; +const world::Item* game_items::oak_leaves = nullptr; +const world::Item* game_items::oak_planks = nullptr; +const world::Item* game_items::oak_log = nullptr; +const world::Item* game_items::glass = nullptr; +const world::Item* game_items::slime = nullptr; + +void game_items::populate(void) +{ + auto stone_builder = world::ItemBuilder("stone"); + stone_builder.set_texture("textures/item/stone.png"); + stone_builder.set_place_voxel(game_voxels::stone); + stone = world::item_registry::register_item(stone_builder); + + auto cobblestone_builder = world::ItemBuilder("cobblestone"); + cobblestone_builder.set_texture("textures/item/cobblestone.png"); + cobblestone_builder.set_place_voxel(game_voxels::cobblestone); + cobblestone = world::item_registry::register_item(cobblestone_builder); + + auto dirt_builder = world::ItemBuilder("dirt"); + dirt_builder.set_texture("textures/item/dirt.png"); + dirt_builder.set_place_voxel(game_voxels::dirt); + dirt = world::item_registry::register_item(dirt_builder); + + auto grass_builder = world::ItemBuilder("grass"); + grass_builder.set_texture("textures/item/grass.png"); + grass_builder.set_place_voxel(game_voxels::grass); + grass = world::item_registry::register_item(grass_builder); + + auto oak_leaves_builder = world::ItemBuilder("oak_leaves"); + oak_leaves_builder.set_texture("textures/item/oak_leaves.png"); + oak_leaves_builder.set_place_voxel(game_voxels::oak_leaves); + oak_leaves = world::item_registry::register_item(oak_leaves_builder); + + auto oak_planks_builder = world::ItemBuilder("oak_planks"); + oak_planks_builder.set_texture("textures/item/oak_planks.png"); + oak_planks_builder.set_place_voxel(game_voxels::oak_planks); + oak_planks = world::item_registry::register_item(oak_planks_builder); + + auto oak_log_builder = world::ItemBuilder("oak_log"); + oak_log_builder.set_texture("textures/item/oak_log.png"); + oak_log_builder.set_place_voxel(game_voxels::oak_log); + oak_log = world::item_registry::register_item(oak_log_builder); + + auto glass_builder = world::ItemBuilder("glass"); + glass_builder.set_texture("textures/item/glass.png"); + glass_builder.set_place_voxel(game_voxels::glass); + glass = world::item_registry::register_item(glass_builder); + + auto slime_builder = world::ItemBuilder("slime"); + slime_builder.set_texture("textures/item/slime.png"); + slime_builder.set_place_voxel(game_voxels::slime); + slime = world::item_registry::register_item(slime_builder); +} diff --git a/game/shared/game_items.hh b/src/game/shared/game_items.hh index 6f8eac9..c9b3638 100644 --- a/game/shared/game_items.hh +++ b/src/game/shared/game_items.hh @@ -1,24 +1,24 @@ -#pragma once
-
-namespace world
-{
-class Item;
-} // namespace world
-
-namespace game_items
-{
-extern const world::Item* stone;
-extern const world::Item* cobblestone;
-extern const world::Item* dirt;
-extern const world::Item* grass;
-extern const world::Item* oak_leaves;
-extern const world::Item* oak_planks;
-extern const world::Item* oak_log;
-extern const world::Item* glass;
-extern const world::Item* slime;
-} // namespace game_items
-
-namespace game_items
-{
-void populate(void);
-} // namespace game_items
+#pragma once + +namespace world +{ +class Item; +} // namespace world + +namespace game_items +{ +extern const world::Item* stone; +extern const world::Item* cobblestone; +extern const world::Item* dirt; +extern const world::Item* grass; +extern const world::Item* oak_leaves; +extern const world::Item* oak_planks; +extern const world::Item* oak_log; +extern const world::Item* glass; +extern const world::Item* slime; +} // namespace game_items + +namespace game_items +{ +void populate(void); +} // namespace game_items diff --git a/game/shared/game_voxels.cc b/src/game/shared/game_voxels.cc index 51cf873..c4c4ec3 100644 --- a/game/shared/game_voxels.cc +++ b/src/game/shared/game_voxels.cc @@ -1,152 +1,152 @@ -#include "shared/pch.hh"
-
-#include "shared/game_voxels.hh"
-
-#include "shared/world/dimension.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/const.hh"
-
-const world::Voxel* game_voxels::cobblestone = nullptr;
-const world::Voxel* game_voxels::dirt = nullptr;
-const world::Voxel* game_voxels::grass = nullptr;
-const world::Voxel* game_voxels::stone = nullptr;
-const world::Voxel* game_voxels::vtest = nullptr;
-const world::Voxel* game_voxels::vtest_ck = nullptr;
-const world::Voxel* game_voxels::oak_leaves = nullptr;
-const world::Voxel* game_voxels::oak_planks = nullptr;
-const world::Voxel* game_voxels::oak_log = nullptr;
-const world::Voxel* game_voxels::glass = nullptr;
-const world::Voxel* game_voxels::slime = nullptr;
-
-static void dirt_tick(world::Dimension* dimension, const voxel_pos& vpos)
-{
- auto grass_found = false;
- auto air_above = false;
-
- for(voxel_pos::value_type dx = -1; dx <= 1 && !grass_found; ++dx) {
- for(voxel_pos::value_type dy = -1; dy <= 1 && !grass_found; ++dy) {
- for(voxel_pos::value_type dz = -1; dz <= 1 && !grass_found; ++dz) {
- if(dx == 0 && dy == 0 && dz == 0) {
- // Skip self
- continue;
- }
-
- auto neighbour_vpos = vpos + voxel_pos(dx, dy, dz);
- auto neighbour_voxel = dimension->get_voxel(neighbour_vpos);
-
- // Voxel pointers returned by get_voxel() are the exact same
- // returned by the voxel registry, so we can compare pointers directly
- // and not bother with voxel_id property comparisons
- if(neighbour_voxel == game_voxels::grass) {
- grass_found = true;
- break;
- }
- }
- }
- }
-
- auto above_vpos = vpos + voxel_pos(0, 1, 0);
- auto above_voxel = dimension->get_voxel(above_vpos);
-
- if(above_voxel == nullptr || above_voxel->is_surface_material<world::VMAT_GLASS>()) {
- air_above = true;
- }
-
- if(grass_found && air_above) {
- dimension->set_voxel(game_voxels::grass, vpos);
- }
-}
-
-static void grass_tick(world::Dimension* dimension, const voxel_pos& vpos)
-{
- auto above_vpos = vpos + voxel_pos(0, 1, 0);
- auto above_voxel = dimension->get_voxel(above_vpos);
-
- if(above_voxel && !above_voxel->is_surface_material<world::VMAT_GLASS>()) {
- // Decay into dirt if something is blocking airflow
- dimension->set_voxel(game_voxels::dirt, vpos);
- }
-}
-
-void game_voxels::populate(void)
-{
- auto stone_builder = world::VoxelBuilder("stone");
- stone_builder.add_default_texture("textures/voxel/stone_01.png");
- stone_builder.add_default_texture("textures/voxel/stone_02.png");
- stone_builder.add_default_texture("textures/voxel/stone_03.png");
- stone_builder.add_default_texture("textures/voxel/stone_04.png");
- stone = world::voxel_registry::register_voxel(stone_builder);
-
- auto cobblestone_builder = world::VoxelBuilder("cobblestone");
- cobblestone_builder.add_default_texture("textures/voxel/cobblestone_01.png");
- cobblestone_builder.add_default_texture("textures/voxel/cobblestone_02.png");
- cobblestone = world::voxel_registry::register_voxel(cobblestone_builder);
-
- auto dirt_builder = world::VoxelBuilder("dirt");
- dirt_builder.add_default_texture("textures/voxel/dirt_01.png");
- dirt_builder.add_default_texture("textures/voxel/dirt_02.png");
- dirt_builder.add_default_texture("textures/voxel/dirt_03.png");
- dirt_builder.add_default_texture("textures/voxel/dirt_04.png");
- dirt_builder.set_surface_material(world::VMAT_DIRT);
- dirt_builder.set_on_tick(&dirt_tick);
- dirt = world::voxel_registry::register_voxel(dirt_builder);
-
- auto grass_builder = world::VoxelBuilder("grass");
- grass_builder.add_default_texture("textures/voxel/grass_side_01.png");
- grass_builder.add_default_texture("textures/voxel/grass_side_02.png");
- grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_01.png");
- grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_02.png");
- grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_03.png");
- grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_04.png");
- grass_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/grass_01.png");
- grass_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/grass_02.png");
- grass_builder.set_surface_material(world::VMAT_GRASS);
- grass_builder.set_on_tick(&grass_tick);
- grass = world::voxel_registry::register_voxel(grass_builder);
-
- auto vtest_builder = world::VoxelBuilder("vtest");
- vtest_builder.add_default_texture("textures/voxel/vtest_F1.png");
- vtest_builder.add_default_texture("textures/voxel/vtest_F2.png");
- vtest_builder.add_default_texture("textures/voxel/vtest_F3.png");
- vtest_builder.add_default_texture("textures/voxel/vtest_F4.png");
- vtest_builder.set_animated(true);
- vtest = world::voxel_registry::register_voxel(vtest_builder);
-
- auto vtest_ck_builder = world::VoxelBuilder("vtest_ck");
- vtest_ck_builder.add_default_texture("textures/voxel/chromakey.png");
- vtest_ck = world::voxel_registry::register_voxel(vtest_ck_builder);
-
- auto oak_leaves_builder = world::VoxelBuilder("oak_leaves");
- oak_leaves_builder.add_default_texture("textures/voxel/oak_leaves.png");
- oak_leaves_builder.set_surface_material(world::VMAT_GRASS);
- oak_leaves = world::voxel_registry::register_voxel(oak_leaves_builder);
-
- auto oak_planks_builder = world::VoxelBuilder("oak_planks");
- oak_planks_builder.add_default_texture("textures/voxel/oak_planks_01.png");
- oak_planks_builder.add_default_texture("textures/voxel/oak_planks_02.png");
- oak_planks_builder.set_surface_material(world::VMAT_WOOD);
- oak_planks = world::voxel_registry::register_voxel(oak_planks_builder);
-
- auto oak_log_builder = world::VoxelBuilder("oak_log");
- oak_log_builder.add_default_texture("textures/voxel/oak_wood_01.png");
- oak_log_builder.add_default_texture("textures/voxel/oak_wood_02.png");
- oak_log_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/oak_wood_top.png");
- oak_log_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/oak_wood_top.png");
- oak_log_builder.set_surface_material(world::VMAT_WOOD);
- oak_log = world::voxel_registry::register_voxel(oak_log_builder);
-
- auto glass_builder = world::VoxelBuilder("glass");
- glass_builder.add_default_texture("textures/voxel/glass_01.png");
- glass_builder.set_render_mode(world::VRENDER_BLEND);
- glass_builder.set_surface_material(world::VMAT_GLASS);
- glass = world::voxel_registry::register_voxel(glass_builder);
-
- auto slime_builder = world::VoxelBuilder("slime");
- slime_builder.add_default_texture("textures/voxel/slime_01.png");
- slime_builder.set_render_mode(world::VRENDER_BLEND);
- slime_builder.set_surface_material(world::VMAT_SLOSH);
- slime_builder.set_touch_type(world::VTOUCH_BOUNCE);
- slime_builder.set_touch_values({ 0.00f, 0.60f, 0.00f });
- slime = world::voxel_registry::register_voxel(slime_builder);
-}
+#include "shared/pch.hh" + +#include "shared/game_voxels.hh" + +#include "shared/world/dimension.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/const.hh" + +const world::Voxel* game_voxels::cobblestone = nullptr; +const world::Voxel* game_voxels::dirt = nullptr; +const world::Voxel* game_voxels::grass = nullptr; +const world::Voxel* game_voxels::stone = nullptr; +const world::Voxel* game_voxels::vtest = nullptr; +const world::Voxel* game_voxels::vtest_ck = nullptr; +const world::Voxel* game_voxels::oak_leaves = nullptr; +const world::Voxel* game_voxels::oak_planks = nullptr; +const world::Voxel* game_voxels::oak_log = nullptr; +const world::Voxel* game_voxels::glass = nullptr; +const world::Voxel* game_voxels::slime = nullptr; + +static void dirt_tick(world::Dimension* dimension, const voxel_pos& vpos) +{ + auto grass_found = false; + auto air_above = false; + + for(voxel_pos::value_type dx = -1; dx <= 1 && !grass_found; ++dx) { + for(voxel_pos::value_type dy = -1; dy <= 1 && !grass_found; ++dy) { + for(voxel_pos::value_type dz = -1; dz <= 1 && !grass_found; ++dz) { + if(dx == 0 && dy == 0 && dz == 0) { + // Skip self + continue; + } + + auto neighbour_vpos = vpos + voxel_pos(dx, dy, dz); + auto neighbour_voxel = dimension->get_voxel(neighbour_vpos); + + // Voxel pointers returned by get_voxel() are the exact same + // returned by the voxel registry, so we can compare pointers directly + // and not bother with voxel_id property comparisons + if(neighbour_voxel == game_voxels::grass) { + grass_found = true; + break; + } + } + } + } + + auto above_vpos = vpos + voxel_pos(0, 1, 0); + auto above_voxel = dimension->get_voxel(above_vpos); + + if(above_voxel == nullptr || above_voxel->is_surface_material<world::VMAT_GLASS>()) { + air_above = true; + } + + if(grass_found && air_above) { + dimension->set_voxel(game_voxels::grass, vpos); + } +} + +static void grass_tick(world::Dimension* dimension, const voxel_pos& vpos) +{ + auto above_vpos = vpos + voxel_pos(0, 1, 0); + auto above_voxel = dimension->get_voxel(above_vpos); + + if(above_voxel && !above_voxel->is_surface_material<world::VMAT_GLASS>()) { + // Decay into dirt if something is blocking airflow + dimension->set_voxel(game_voxels::dirt, vpos); + } +} + +void game_voxels::populate(void) +{ + auto stone_builder = world::VoxelBuilder("stone"); + stone_builder.add_default_texture("textures/voxel/stone_01.png"); + stone_builder.add_default_texture("textures/voxel/stone_02.png"); + stone_builder.add_default_texture("textures/voxel/stone_03.png"); + stone_builder.add_default_texture("textures/voxel/stone_04.png"); + stone = world::voxel_registry::register_voxel(stone_builder); + + auto cobblestone_builder = world::VoxelBuilder("cobblestone"); + cobblestone_builder.add_default_texture("textures/voxel/cobblestone_01.png"); + cobblestone_builder.add_default_texture("textures/voxel/cobblestone_02.png"); + cobblestone = world::voxel_registry::register_voxel(cobblestone_builder); + + auto dirt_builder = world::VoxelBuilder("dirt"); + dirt_builder.add_default_texture("textures/voxel/dirt_01.png"); + dirt_builder.add_default_texture("textures/voxel/dirt_02.png"); + dirt_builder.add_default_texture("textures/voxel/dirt_03.png"); + dirt_builder.add_default_texture("textures/voxel/dirt_04.png"); + dirt_builder.set_surface_material(world::VMAT_DIRT); + dirt_builder.set_on_tick(&dirt_tick); + dirt = world::voxel_registry::register_voxel(dirt_builder); + + auto grass_builder = world::VoxelBuilder("grass"); + grass_builder.add_default_texture("textures/voxel/grass_side_01.png"); + grass_builder.add_default_texture("textures/voxel/grass_side_02.png"); + grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_01.png"); + grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_02.png"); + grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_03.png"); + grass_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/dirt_04.png"); + grass_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/grass_01.png"); + grass_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/grass_02.png"); + grass_builder.set_surface_material(world::VMAT_GRASS); + grass_builder.set_on_tick(&grass_tick); + grass = world::voxel_registry::register_voxel(grass_builder); + + auto vtest_builder = world::VoxelBuilder("vtest"); + vtest_builder.add_default_texture("textures/voxel/vtest_F1.png"); + vtest_builder.add_default_texture("textures/voxel/vtest_F2.png"); + vtest_builder.add_default_texture("textures/voxel/vtest_F3.png"); + vtest_builder.add_default_texture("textures/voxel/vtest_F4.png"); + vtest_builder.set_animated(true); + vtest = world::voxel_registry::register_voxel(vtest_builder); + + auto vtest_ck_builder = world::VoxelBuilder("vtest_ck"); + vtest_ck_builder.add_default_texture("textures/voxel/chromakey.png"); + vtest_ck = world::voxel_registry::register_voxel(vtest_ck_builder); + + auto oak_leaves_builder = world::VoxelBuilder("oak_leaves"); + oak_leaves_builder.add_default_texture("textures/voxel/oak_leaves.png"); + oak_leaves_builder.set_surface_material(world::VMAT_GRASS); + oak_leaves = world::voxel_registry::register_voxel(oak_leaves_builder); + + auto oak_planks_builder = world::VoxelBuilder("oak_planks"); + oak_planks_builder.add_default_texture("textures/voxel/oak_planks_01.png"); + oak_planks_builder.add_default_texture("textures/voxel/oak_planks_02.png"); + oak_planks_builder.set_surface_material(world::VMAT_WOOD); + oak_planks = world::voxel_registry::register_voxel(oak_planks_builder); + + auto oak_log_builder = world::VoxelBuilder("oak_log"); + oak_log_builder.add_default_texture("textures/voxel/oak_wood_01.png"); + oak_log_builder.add_default_texture("textures/voxel/oak_wood_02.png"); + oak_log_builder.add_face_texture(world::VFACE_BOTTOM, "textures/voxel/oak_wood_top.png"); + oak_log_builder.add_face_texture(world::VFACE_TOP, "textures/voxel/oak_wood_top.png"); + oak_log_builder.set_surface_material(world::VMAT_WOOD); + oak_log = world::voxel_registry::register_voxel(oak_log_builder); + + auto glass_builder = world::VoxelBuilder("glass"); + glass_builder.add_default_texture("textures/voxel/glass_01.png"); + glass_builder.set_render_mode(world::VRENDER_BLEND); + glass_builder.set_surface_material(world::VMAT_GLASS); + glass = world::voxel_registry::register_voxel(glass_builder); + + auto slime_builder = world::VoxelBuilder("slime"); + slime_builder.add_default_texture("textures/voxel/slime_01.png"); + slime_builder.set_render_mode(world::VRENDER_BLEND); + slime_builder.set_surface_material(world::VMAT_SLOSH); + slime_builder.set_touch_type(world::VTOUCH_BOUNCE); + slime_builder.set_touch_values({ 0.00f, 0.60f, 0.00f }); + slime = world::voxel_registry::register_voxel(slime_builder); +} diff --git a/game/shared/game_voxels.hh b/src/game/shared/game_voxels.hh index 2211619..a8d155f 100644 --- a/game/shared/game_voxels.hh +++ b/src/game/shared/game_voxels.hh @@ -1,26 +1,26 @@ -#pragma once
-
-namespace world
-{
-class Voxel;
-} // namespace world
-
-namespace game_voxels
-{
-extern const world::Voxel* cobblestone;
-extern const world::Voxel* dirt;
-extern const world::Voxel* grass;
-extern const world::Voxel* stone;
-extern const world::Voxel* vtest;
-extern const world::Voxel* vtest_ck;
-extern const world::Voxel* oak_leaves;
-extern const world::Voxel* oak_planks;
-extern const world::Voxel* oak_log;
-extern const world::Voxel* glass;
-extern const world::Voxel* slime;
-} // namespace game_voxels
-
-namespace game_voxels
-{
-void populate(void);
-} // namespace game_voxels
+#pragma once + +namespace world +{ +class Voxel; +} // namespace world + +namespace game_voxels +{ +extern const world::Voxel* cobblestone; +extern const world::Voxel* dirt; +extern const world::Voxel* grass; +extern const world::Voxel* stone; +extern const world::Voxel* vtest; +extern const world::Voxel* vtest_ck; +extern const world::Voxel* oak_leaves; +extern const world::Voxel* oak_planks; +extern const world::Voxel* oak_log; +extern const world::Voxel* glass; +extern const world::Voxel* slime; +} // namespace game_voxels + +namespace game_voxels +{ +void populate(void); +} // namespace game_voxels diff --git a/game/shared/globals.cc b/src/game/shared/globals.cc index 1651402..8552214 100644 --- a/game/shared/globals.cc +++ b/src/game/shared/globals.cc @@ -1,12 +1,12 @@ -#include "shared/pch.hh"
-
-#include "shared/globals.hh"
-
-entt::dispatcher globals::dispatcher;
-
-float globals::fixed_frametime;
-float globals::fixed_frametime_avg;
-std::uint64_t globals::fixed_frametime_us;
-std::size_t globals::fixed_framecount;
-
-std::uint64_t globals::curtime;
+#include "shared/pch.hh" + +#include "shared/globals.hh" + +entt::dispatcher globals::dispatcher; + +float globals::fixed_frametime; +float globals::fixed_frametime_avg; +std::uint64_t globals::fixed_frametime_us; +std::size_t globals::fixed_framecount; + +std::uint64_t globals::curtime; diff --git a/game/shared/globals.hh b/src/game/shared/globals.hh index 4a5afd1..39a12a7 100644 --- a/game/shared/globals.hh +++ b/src/game/shared/globals.hh @@ -1,19 +1,19 @@ -#pragma once
-
-namespace globals
-{
-extern entt::dispatcher dispatcher;
-} // namespace globals
-
-namespace globals
-{
-extern float fixed_frametime;
-extern float fixed_frametime_avg;
-extern std::uint64_t fixed_frametime_us;
-extern std::size_t fixed_framecount;
-} // namespace globals
-
-namespace globals
-{
-extern std::uint64_t curtime;
-} // namespace globals
+#pragma once + +namespace globals +{ +extern entt::dispatcher dispatcher; +} // namespace globals + +namespace globals +{ +extern float fixed_frametime; +extern float fixed_frametime_avg; +extern std::uint64_t fixed_frametime_us; +extern std::size_t fixed_framecount; +} // namespace globals + +namespace globals +{ +extern std::uint64_t curtime; +} // namespace globals diff --git a/game/shared/pch.hh b/src/game/shared/pch.hh index 438f82a..e978e0f 100644 --- a/game/shared/pch.hh +++ b/src/game/shared/pch.hh @@ -1,19 +1,19 @@ -#pragma once
-
-#include <core/pch.hh> // inherit dependent includes from core.lib
-
-#include <csignal>
-
-#include <enet/enet.h>
-
-#include <entt/entity/registry.hpp>
-#include <entt/signal/dispatcher.hpp>
-
-#include <fastnoiselite.h>
-
-#include <miniz.h>
-
-#include <parson.h>
-
-#include <spdlog/sinks/basic_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
+#pragma once + +#include <core/pch.hh> // inherit dependent includes from core.lib + +#include <csignal> + +#include <enet/enet.h> + +#include <entt/entity/registry.hpp> +#include <entt/signal/dispatcher.hpp> + +#include <fastnoiselite.h> + +#include <miniz.h> + +#include <parson.h> + +#include <spdlog/sinks/basic_file_sink.h> +#include <spdlog/sinks/stdout_color_sinks.h> diff --git a/game/shared/protocol.cc b/src/game/shared/protocol.cc index 7115807..4c0c894 100644 --- a/game/shared/protocol.cc +++ b/src/game/shared/protocol.cc @@ -1,518 +1,518 @@ -#include "shared/pch.hh"
-
-#include "shared/protocol.hh"
-
-#include "core/io/buffer.hh"
-
-#include "shared/entity/head.hh"
-#include "shared/entity/player.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-
-#include "shared/globals.hh"
-
-static io::ReadBuffer read_buffer;
-static io::WriteBuffer write_buffer;
-
-ENetPacket* protocol::encode(const protocol::StatusRequest& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::StatusRequest::ID);
- write_buffer.write<std::uint32_t>(packet.game_version_major);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::StatusResponse& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::StatusResponse::ID);
- write_buffer.write<std::uint32_t>(packet.game_version_major);
- write_buffer.write<std::uint16_t>(packet.max_players);
- write_buffer.write<std::uint16_t>(packet.num_players);
- write_buffer.write<std::string_view>(packet.motd);
- write_buffer.write<std::uint32_t>(packet.game_version_minor);
- write_buffer.write<std::uint32_t>(packet.game_version_patch);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::LoginRequest& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::LoginRequest::ID);
- write_buffer.write<std::uint32_t>(packet.game_version_major);
- write_buffer.write<std::uint64_t>(packet.voxel_registry_checksum);
- write_buffer.write<std::uint64_t>(packet.item_registry_checksum);
- write_buffer.write<std::uint64_t>(packet.password_hash);
- write_buffer.write<std::string_view>(packet.username.substr(0, protocol::MAX_USERNAME));
- write_buffer.write<std::uint32_t>(packet.game_version_minor);
- write_buffer.write<std::uint32_t>(packet.game_version_patch);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::LoginResponse& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::LoginResponse::ID);
- write_buffer.write<std::uint16_t>(packet.client_index);
- write_buffer.write<std::uint64_t>(packet.client_identity);
- write_buffer.write<std::uint16_t>(packet.server_tickrate);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::Disconnect& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::Disconnect::ID);
- write_buffer.write<std::string_view>(packet.reason);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::ChunkVoxels& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::ChunkVoxels::ID);
- write_buffer.write<std::int32_t>(packet.chunk.x);
- write_buffer.write<std::int32_t>(packet.chunk.y);
- write_buffer.write<std::int32_t>(packet.chunk.z);
- packet.voxels.serialize(write_buffer);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::EntityTransform& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::EntityTransform::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- write_buffer.write<std::int32_t>(packet.chunk.x);
- write_buffer.write<std::int32_t>(packet.chunk.y);
- write_buffer.write<std::int32_t>(packet.chunk.z);
- write_buffer.write<float>(packet.local.x);
- write_buffer.write<float>(packet.local.y);
- write_buffer.write<float>(packet.local.z);
- write_buffer.write<float>(packet.angles.x);
- write_buffer.write<float>(packet.angles.y);
- write_buffer.write<float>(packet.angles.z);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::EntityHead& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::EntityHead::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- write_buffer.write<float>(packet.angles.x);
- write_buffer.write<float>(packet.angles.y);
- write_buffer.write<float>(packet.angles.z);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::EntityVelocity& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::EntityVelocity::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- write_buffer.write<float>(packet.value.x);
- write_buffer.write<float>(packet.value.y);
- write_buffer.write<float>(packet.value.z);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::SpawnPlayer& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::SpawnPlayer::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::ChatMessage& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::ChatMessage::ID);
- write_buffer.write<std::uint16_t>(packet.type);
- write_buffer.write<std::string_view>(packet.sender.substr(0, protocol::MAX_USERNAME));
- write_buffer.write<std::string_view>(packet.message.substr(0, protocol::MAX_CHAT));
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::SetVoxel& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::SetVoxel::ID);
- write_buffer.write<std::int64_t>(packet.vpos.x);
- write_buffer.write<std::int64_t>(packet.vpos.y);
- write_buffer.write<std::int64_t>(packet.vpos.z);
- write_buffer.write<std::uint16_t>(packet.voxel);
- write_buffer.write<std::uint16_t>(packet.flags);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::RemoveEntity& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::RemoveEntity::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::EntityPlayer& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::EntityPlayer::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::ScoreboardUpdate& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::ScoreboardUpdate::ID);
- write_buffer.write<std::uint16_t>(static_cast<std::uint16_t>(packet.names.size()));
- for(const std::string& username : packet.names)
- write_buffer.write<std::string_view>(username.substr(0, protocol::MAX_USERNAME));
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::RequestChunk& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::RequestChunk::ID);
- write_buffer.write<std::int32_t>(packet.cpos.x);
- write_buffer.write<std::int32_t>(packet.cpos.y);
- write_buffer.write<std::int32_t>(packet.cpos.z);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::GenericSound& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::GenericSound::ID);
- write_buffer.write<std::string_view>(packet.sound.substr(0, protocol::MAX_SOUNDNAME));
- write_buffer.write<std::uint8_t>(packet.looping);
- write_buffer.write<float>(packet.pitch);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::EntitySound& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::EntitySound::ID);
- write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity));
- write_buffer.write<std::string_view>(packet.sound.substr(0, protocol::MAX_SOUNDNAME));
- write_buffer.write<std::uint8_t>(packet.looping);
- write_buffer.write<float>(packet.pitch);
- return write_buffer.to_packet(flags);
-}
-
-ENetPacket* protocol::encode(const protocol::DimensionInfo& packet, enet_uint32 flags)
-{
- write_buffer.reset();
- write_buffer.write<std::uint16_t>(protocol::DimensionInfo::ID);
- write_buffer.write<std::string_view>(packet.name);
- write_buffer.write<float>(packet.gravity);
- return write_buffer.to_packet(flags);
-}
-
-void protocol::broadcast(ENetHost* host, ENetPacket* packet)
-{
- if(packet) {
- enet_host_broadcast(host, protocol::CHANNEL, packet);
- }
-}
-
-void protocol::broadcast(ENetHost* host, ENetPacket* packet, ENetPeer* except)
-{
- if(packet) {
- for(unsigned int i = 0U; i < host->peerCount; ++i) {
- if(host->peers[i].state == ENET_PEER_STATE_CONNECTED) {
- if(&host->peers[i] != except) {
- enet_peer_send(&host->peers[i], protocol::CHANNEL, packet);
- }
- }
- }
- }
-}
-
-void protocol::send(ENetPeer* peer, ENetPacket* packet)
-{
- if(packet) {
- enet_peer_send(peer, protocol::CHANNEL, packet);
- }
-}
-
-void protocol::decode(entt::dispatcher& dispatcher, const ENetPacket* packet, ENetPeer* peer)
-{
- read_buffer.reset(packet);
-
- protocol::StatusRequest status_request;
- protocol::StatusResponse status_response;
- protocol::LoginRequest login_request;
- protocol::LoginResponse login_response;
- protocol::Disconnect disconnect;
- protocol::ChunkVoxels chunk_voxels;
- protocol::EntityTransform entity_transform;
- protocol::EntityHead entity_head;
- protocol::EntityVelocity entity_velocity;
- protocol::SpawnPlayer spawn_player;
- protocol::ChatMessage chat_message;
- protocol::SetVoxel set_voxel;
- protocol::RemoveEntity remove_entity;
- protocol::EntityPlayer entity_player;
- protocol::ScoreboardUpdate scoreboard_update;
- protocol::RequestChunk request_chunk;
- protocol::GenericSound generic_sound;
- protocol::EntitySound entity_sound;
- protocol::DimensionInfo dimension_info;
-
- auto id = read_buffer.read<std::uint16_t>();
-
- switch(id) {
- case protocol::StatusRequest::ID:
- status_request.peer = peer;
- status_request.game_version_major = read_buffer.read<std::uint32_t>();
- dispatcher.trigger(status_request);
- break;
-
- case protocol::StatusResponse::ID:
- status_response.peer = peer;
- status_response.game_version_major = read_buffer.read<std::uint32_t>();
- status_response.max_players = read_buffer.read<std::uint16_t>();
- status_response.num_players = read_buffer.read<std::uint16_t>();
- status_response.motd = read_buffer.read<std::string>();
- status_response.game_version_minor = read_buffer.read<std::uint32_t>();
- status_response.game_version_patch = read_buffer.read<std::uint32_t>();
- dispatcher.trigger(status_response);
- break;
-
- case protocol::LoginRequest::ID:
- login_request.peer = peer;
- login_request.game_version_major = read_buffer.read<std::uint32_t>();
- login_request.voxel_registry_checksum = read_buffer.read<std::uint64_t>();
- login_request.item_registry_checksum = read_buffer.read<std::uint64_t>();
- login_request.password_hash = read_buffer.read<std::uint64_t>();
- login_request.username = read_buffer.read<std::string>();
- login_request.game_version_minor = read_buffer.read<std::uint32_t>();
- login_request.game_version_patch = read_buffer.read<std::uint32_t>();
- dispatcher.trigger(login_request);
- break;
-
- case protocol::LoginResponse::ID:
- login_response.peer = peer;
- login_response.client_index = read_buffer.read<std::uint16_t>();
- login_response.client_identity = read_buffer.read<std::uint64_t>();
- login_response.server_tickrate = read_buffer.read<std::uint16_t>();
- dispatcher.trigger(login_response);
- break;
-
- case protocol::Disconnect::ID:
- disconnect.peer = peer;
- disconnect.reason = read_buffer.read<std::string>();
- dispatcher.trigger(disconnect);
- break;
-
- case protocol::ChunkVoxels::ID:
- chunk_voxels.peer = peer;
- chunk_voxels.chunk.x = read_buffer.read<std::int32_t>();
- chunk_voxels.chunk.y = read_buffer.read<std::int32_t>();
- chunk_voxels.chunk.z = read_buffer.read<std::int32_t>();
- chunk_voxels.voxels.deserialize(read_buffer);
- dispatcher.trigger(chunk_voxels);
- break;
-
- case protocol::EntityTransform::ID:
- entity_transform.peer = peer;
- entity_transform.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- entity_transform.chunk.x = read_buffer.read<std::int32_t>();
- entity_transform.chunk.y = read_buffer.read<std::int32_t>();
- entity_transform.chunk.z = read_buffer.read<std::int32_t>();
- entity_transform.local.x = read_buffer.read<float>();
- entity_transform.local.y = read_buffer.read<float>();
- entity_transform.local.z = read_buffer.read<float>();
- entity_transform.angles.x = read_buffer.read<float>();
- entity_transform.angles.y = read_buffer.read<float>();
- entity_transform.angles.z = read_buffer.read<float>();
- dispatcher.trigger(entity_transform);
- break;
-
- case protocol::EntityHead::ID:
- entity_head.peer = peer;
- entity_head.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- entity_head.angles[0] = read_buffer.read<float>();
- entity_head.angles[1] = read_buffer.read<float>();
- entity_head.angles[2] = read_buffer.read<float>();
- dispatcher.trigger(entity_head);
- break;
-
- case protocol::EntityVelocity::ID:
- entity_velocity.peer = peer;
- entity_velocity.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- entity_velocity.value.x = read_buffer.read<float>();
- entity_velocity.value.y = read_buffer.read<float>();
- entity_velocity.value.z = read_buffer.read<float>();
- dispatcher.trigger(entity_velocity);
- break;
-
- case protocol::SpawnPlayer::ID:
- spawn_player.peer = peer;
- spawn_player.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- dispatcher.trigger(spawn_player);
- break;
-
- case protocol::ChatMessage::ID:
- chat_message.peer = peer;
- chat_message.type = read_buffer.read<std::uint16_t>();
- chat_message.sender = read_buffer.read<std::string>();
- chat_message.message = read_buffer.read<std::string>();
- dispatcher.trigger(chat_message);
- break;
-
- case protocol::SetVoxel::ID:
- set_voxel.peer = peer;
- set_voxel.vpos.x = read_buffer.read<std::int64_t>();
- set_voxel.vpos.y = read_buffer.read<std::int64_t>();
- set_voxel.vpos.z = read_buffer.read<std::int64_t>();
- set_voxel.voxel = read_buffer.read<std::uint16_t>();
- set_voxel.flags = read_buffer.read<std::uint16_t>();
- dispatcher.trigger(set_voxel);
- break;
-
- case protocol::RemoveEntity::ID:
- remove_entity.peer = peer;
- remove_entity.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- dispatcher.trigger(remove_entity);
- break;
-
- case protocol::EntityPlayer::ID:
- entity_player.peer = peer;
- entity_player.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- dispatcher.trigger(entity_player);
- break;
-
- case protocol::ScoreboardUpdate::ID:
- scoreboard_update.peer = peer;
- scoreboard_update.names.resize(read_buffer.read<std::uint16_t>());
- for(std::size_t i = 0; i < scoreboard_update.names.size(); ++i)
- scoreboard_update.names[i] = read_buffer.read<std::string>();
- dispatcher.trigger(scoreboard_update);
- break;
-
- case protocol::RequestChunk::ID:
- request_chunk.peer = peer;
- request_chunk.cpos.x = read_buffer.read<std::uint32_t>();
- request_chunk.cpos.y = read_buffer.read<std::uint32_t>();
- request_chunk.cpos.z = read_buffer.read<std::uint32_t>();
- dispatcher.trigger(request_chunk);
- break;
-
- case protocol::GenericSound::ID:
- generic_sound.peer = peer;
- generic_sound.sound = read_buffer.read<std::string>();
- generic_sound.looping = read_buffer.read<std::uint8_t>();
- generic_sound.pitch = read_buffer.read<float>();
- dispatcher.trigger(generic_sound);
- break;
-
- case protocol::EntitySound::ID:
- entity_sound.peer = peer;
- entity_sound.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>());
- entity_sound.sound = read_buffer.read<std::string>();
- entity_sound.looping = read_buffer.read<std::uint8_t>();
- entity_sound.pitch = read_buffer.read<float>();
- dispatcher.trigger(entity_sound);
- break;
-
- case protocol::DimensionInfo::ID:
- dimension_info.peer = peer;
- dimension_info.name = read_buffer.read<std::string>();
- dimension_info.gravity = read_buffer.read<float>();
- dispatcher.trigger(dimension_info);
- break;
- }
-}
-
-ENetPacket* protocol::utils::make_disconnect(std::string_view reason, enet_uint32 flags)
-{
- protocol::Disconnect packet;
- packet.reason = reason;
- return protocol::encode(packet, flags);
-}
-
-ENetPacket* protocol::utils::make_chat_message(std::string_view message, enet_uint32 flags)
-{
- protocol::ChatMessage packet;
- packet.type = protocol::ChatMessage::TEXT_MESSAGE;
- packet.message = message;
- return protocol::encode(packet, flags);
-}
-
-ENetPacket* protocol::utils::make_chunk_voxels(world::Dimension* dimension, entt::entity entity, enet_uint32 flags)
-{
- if(auto component = dimension->chunks.try_get<world::ChunkComponent>(entity)) {
- protocol::ChunkVoxels packet;
- packet.chunk = component->cpos;
- packet.voxels = component->chunk->get_voxels();
- return protocol::encode(packet, flags);
- }
-
- return nullptr;
-}
-
-ENetPacket* protocol::utils::make_entity_head(world::Dimension* dimension, entt::entity entity, enet_uint32 flags)
-{
- if(auto component = dimension->entities.try_get<entity::Head>(entity)) {
- protocol::EntityHead packet;
- packet.entity = entity;
- packet.angles = component->angles;
- return protocol::encode(packet, flags);
- }
-
- return nullptr;
-}
-
-ENetPacket* protocol::utils::make_entity_transform(world::Dimension* dimension, entt::entity entity, enet_uint32 flags)
-{
- if(auto component = dimension->entities.try_get<entity::Transform>(entity)) {
- protocol::EntityTransform packet;
- packet.entity = entity;
- packet.chunk = component->chunk;
- packet.local = component->local;
- packet.angles = component->angles;
- return protocol::encode(packet, flags);
- }
-
- return nullptr;
-}
-
-ENetPacket* protocol::utils::make_entity_velocity(world::Dimension* dimension, entt::entity entity, enet_uint32 flags)
-{
- if(auto component = dimension->entities.try_get<entity::Velocity>(entity)) {
- protocol::EntityVelocity packet;
- packet.entity = entity;
- packet.value = component->value;
- return protocol::encode(packet, flags);
- }
-
- return nullptr;
-}
-
-ENetPacket* protocol::utils::make_entity_player(world::Dimension* dimension, entt::entity entity, enet_uint32 flags)
-{
- if(dimension->entities.any_of<entity::Player>(entity)) {
- protocol::EntityPlayer packet;
- packet.entity = entity;
- return protocol::encode(packet, flags);
- }
-
- return nullptr;
-}
-
-ENetPacket* protocol::utils::make_dimension_info(const world::Dimension* dimension)
-{
- protocol::DimensionInfo packet;
- packet.name = dimension->get_name();
- packet.gravity = dimension->get_gravity();
- return protocol::encode(packet, ENET_PACKET_FLAG_RELIABLE);
-}
+#include "shared/pch.hh" + +#include "shared/protocol.hh" + +#include "core/io/buffer.hh" + +#include "shared/entity/head.hh" +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" +#include "shared/entity/velocity.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" + +#include "shared/globals.hh" + +static io::ReadBuffer read_buffer; +static io::WriteBuffer write_buffer; + +ENetPacket* protocol::encode(const protocol::StatusRequest& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::StatusRequest::ID); + write_buffer.write<std::uint32_t>(packet.game_version_major); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::StatusResponse& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::StatusResponse::ID); + write_buffer.write<std::uint32_t>(packet.game_version_major); + write_buffer.write<std::uint16_t>(packet.max_players); + write_buffer.write<std::uint16_t>(packet.num_players); + write_buffer.write<std::string_view>(packet.motd); + write_buffer.write<std::uint32_t>(packet.game_version_minor); + write_buffer.write<std::uint32_t>(packet.game_version_patch); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::LoginRequest& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::LoginRequest::ID); + write_buffer.write<std::uint32_t>(packet.game_version_major); + write_buffer.write<std::uint64_t>(packet.voxel_registry_checksum); + write_buffer.write<std::uint64_t>(packet.item_registry_checksum); + write_buffer.write<std::uint64_t>(packet.password_hash); + write_buffer.write<std::string_view>(packet.username.substr(0, protocol::MAX_USERNAME)); + write_buffer.write<std::uint32_t>(packet.game_version_minor); + write_buffer.write<std::uint32_t>(packet.game_version_patch); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::LoginResponse& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::LoginResponse::ID); + write_buffer.write<std::uint16_t>(packet.client_index); + write_buffer.write<std::uint64_t>(packet.client_identity); + write_buffer.write<std::uint16_t>(packet.server_tickrate); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::Disconnect& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::Disconnect::ID); + write_buffer.write<std::string_view>(packet.reason); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::ChunkVoxels& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::ChunkVoxels::ID); + write_buffer.write<std::int32_t>(packet.chunk.x); + write_buffer.write<std::int32_t>(packet.chunk.y); + write_buffer.write<std::int32_t>(packet.chunk.z); + packet.voxels.serialize(write_buffer); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::EntityTransform& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::EntityTransform::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + write_buffer.write<std::int32_t>(packet.chunk.x); + write_buffer.write<std::int32_t>(packet.chunk.y); + write_buffer.write<std::int32_t>(packet.chunk.z); + write_buffer.write<float>(packet.local.x); + write_buffer.write<float>(packet.local.y); + write_buffer.write<float>(packet.local.z); + write_buffer.write<float>(packet.angles.x); + write_buffer.write<float>(packet.angles.y); + write_buffer.write<float>(packet.angles.z); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::EntityHead& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::EntityHead::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + write_buffer.write<float>(packet.angles.x); + write_buffer.write<float>(packet.angles.y); + write_buffer.write<float>(packet.angles.z); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::EntityVelocity& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::EntityVelocity::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + write_buffer.write<float>(packet.value.x); + write_buffer.write<float>(packet.value.y); + write_buffer.write<float>(packet.value.z); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::SpawnPlayer& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::SpawnPlayer::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::ChatMessage& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::ChatMessage::ID); + write_buffer.write<std::uint16_t>(packet.type); + write_buffer.write<std::string_view>(packet.sender.substr(0, protocol::MAX_USERNAME)); + write_buffer.write<std::string_view>(packet.message.substr(0, protocol::MAX_CHAT)); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::SetVoxel& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::SetVoxel::ID); + write_buffer.write<std::int64_t>(packet.vpos.x); + write_buffer.write<std::int64_t>(packet.vpos.y); + write_buffer.write<std::int64_t>(packet.vpos.z); + write_buffer.write<std::uint16_t>(packet.voxel); + write_buffer.write<std::uint16_t>(packet.flags); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::RemoveEntity& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::RemoveEntity::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::EntityPlayer& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::EntityPlayer::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::ScoreboardUpdate& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::ScoreboardUpdate::ID); + write_buffer.write<std::uint16_t>(static_cast<std::uint16_t>(packet.names.size())); + for(const std::string& username : packet.names) + write_buffer.write<std::string_view>(username.substr(0, protocol::MAX_USERNAME)); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::RequestChunk& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::RequestChunk::ID); + write_buffer.write<std::int32_t>(packet.cpos.x); + write_buffer.write<std::int32_t>(packet.cpos.y); + write_buffer.write<std::int32_t>(packet.cpos.z); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::GenericSound& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::GenericSound::ID); + write_buffer.write<std::string_view>(packet.sound.substr(0, protocol::MAX_SOUNDNAME)); + write_buffer.write<std::uint8_t>(packet.looping); + write_buffer.write<float>(packet.pitch); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::EntitySound& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::EntitySound::ID); + write_buffer.write<std::uint64_t>(static_cast<std::uint64_t>(packet.entity)); + write_buffer.write<std::string_view>(packet.sound.substr(0, protocol::MAX_SOUNDNAME)); + write_buffer.write<std::uint8_t>(packet.looping); + write_buffer.write<float>(packet.pitch); + return write_buffer.to_packet(flags); +} + +ENetPacket* protocol::encode(const protocol::DimensionInfo& packet, enet_uint32 flags) +{ + write_buffer.reset(); + write_buffer.write<std::uint16_t>(protocol::DimensionInfo::ID); + write_buffer.write<std::string_view>(packet.name); + write_buffer.write<float>(packet.gravity); + return write_buffer.to_packet(flags); +} + +void protocol::broadcast(ENetHost* host, ENetPacket* packet) +{ + if(packet) { + enet_host_broadcast(host, protocol::CHANNEL, packet); + } +} + +void protocol::broadcast(ENetHost* host, ENetPacket* packet, ENetPeer* except) +{ + if(packet) { + for(unsigned int i = 0U; i < host->peerCount; ++i) { + if(host->peers[i].state == ENET_PEER_STATE_CONNECTED) { + if(&host->peers[i] != except) { + enet_peer_send(&host->peers[i], protocol::CHANNEL, packet); + } + } + } + } +} + +void protocol::send(ENetPeer* peer, ENetPacket* packet) +{ + if(packet) { + enet_peer_send(peer, protocol::CHANNEL, packet); + } +} + +void protocol::decode(entt::dispatcher& dispatcher, const ENetPacket* packet, ENetPeer* peer) +{ + read_buffer.reset(packet); + + protocol::StatusRequest status_request; + protocol::StatusResponse status_response; + protocol::LoginRequest login_request; + protocol::LoginResponse login_response; + protocol::Disconnect disconnect; + protocol::ChunkVoxels chunk_voxels; + protocol::EntityTransform entity_transform; + protocol::EntityHead entity_head; + protocol::EntityVelocity entity_velocity; + protocol::SpawnPlayer spawn_player; + protocol::ChatMessage chat_message; + protocol::SetVoxel set_voxel; + protocol::RemoveEntity remove_entity; + protocol::EntityPlayer entity_player; + protocol::ScoreboardUpdate scoreboard_update; + protocol::RequestChunk request_chunk; + protocol::GenericSound generic_sound; + protocol::EntitySound entity_sound; + protocol::DimensionInfo dimension_info; + + auto id = read_buffer.read<std::uint16_t>(); + + switch(id) { + case protocol::StatusRequest::ID: + status_request.peer = peer; + status_request.game_version_major = read_buffer.read<std::uint32_t>(); + dispatcher.trigger(status_request); + break; + + case protocol::StatusResponse::ID: + status_response.peer = peer; + status_response.game_version_major = read_buffer.read<std::uint32_t>(); + status_response.max_players = read_buffer.read<std::uint16_t>(); + status_response.num_players = read_buffer.read<std::uint16_t>(); + status_response.motd = read_buffer.read<std::string>(); + status_response.game_version_minor = read_buffer.read<std::uint32_t>(); + status_response.game_version_patch = read_buffer.read<std::uint32_t>(); + dispatcher.trigger(status_response); + break; + + case protocol::LoginRequest::ID: + login_request.peer = peer; + login_request.game_version_major = read_buffer.read<std::uint32_t>(); + login_request.voxel_registry_checksum = read_buffer.read<std::uint64_t>(); + login_request.item_registry_checksum = read_buffer.read<std::uint64_t>(); + login_request.password_hash = read_buffer.read<std::uint64_t>(); + login_request.username = read_buffer.read<std::string>(); + login_request.game_version_minor = read_buffer.read<std::uint32_t>(); + login_request.game_version_patch = read_buffer.read<std::uint32_t>(); + dispatcher.trigger(login_request); + break; + + case protocol::LoginResponse::ID: + login_response.peer = peer; + login_response.client_index = read_buffer.read<std::uint16_t>(); + login_response.client_identity = read_buffer.read<std::uint64_t>(); + login_response.server_tickrate = read_buffer.read<std::uint16_t>(); + dispatcher.trigger(login_response); + break; + + case protocol::Disconnect::ID: + disconnect.peer = peer; + disconnect.reason = read_buffer.read<std::string>(); + dispatcher.trigger(disconnect); + break; + + case protocol::ChunkVoxels::ID: + chunk_voxels.peer = peer; + chunk_voxels.chunk.x = read_buffer.read<std::int32_t>(); + chunk_voxels.chunk.y = read_buffer.read<std::int32_t>(); + chunk_voxels.chunk.z = read_buffer.read<std::int32_t>(); + chunk_voxels.voxels.deserialize(read_buffer); + dispatcher.trigger(chunk_voxels); + break; + + case protocol::EntityTransform::ID: + entity_transform.peer = peer; + entity_transform.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + entity_transform.chunk.x = read_buffer.read<std::int32_t>(); + entity_transform.chunk.y = read_buffer.read<std::int32_t>(); + entity_transform.chunk.z = read_buffer.read<std::int32_t>(); + entity_transform.local.x = read_buffer.read<float>(); + entity_transform.local.y = read_buffer.read<float>(); + entity_transform.local.z = read_buffer.read<float>(); + entity_transform.angles.x = read_buffer.read<float>(); + entity_transform.angles.y = read_buffer.read<float>(); + entity_transform.angles.z = read_buffer.read<float>(); + dispatcher.trigger(entity_transform); + break; + + case protocol::EntityHead::ID: + entity_head.peer = peer; + entity_head.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + entity_head.angles[0] = read_buffer.read<float>(); + entity_head.angles[1] = read_buffer.read<float>(); + entity_head.angles[2] = read_buffer.read<float>(); + dispatcher.trigger(entity_head); + break; + + case protocol::EntityVelocity::ID: + entity_velocity.peer = peer; + entity_velocity.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + entity_velocity.value.x = read_buffer.read<float>(); + entity_velocity.value.y = read_buffer.read<float>(); + entity_velocity.value.z = read_buffer.read<float>(); + dispatcher.trigger(entity_velocity); + break; + + case protocol::SpawnPlayer::ID: + spawn_player.peer = peer; + spawn_player.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + dispatcher.trigger(spawn_player); + break; + + case protocol::ChatMessage::ID: + chat_message.peer = peer; + chat_message.type = read_buffer.read<std::uint16_t>(); + chat_message.sender = read_buffer.read<std::string>(); + chat_message.message = read_buffer.read<std::string>(); + dispatcher.trigger(chat_message); + break; + + case protocol::SetVoxel::ID: + set_voxel.peer = peer; + set_voxel.vpos.x = read_buffer.read<std::int64_t>(); + set_voxel.vpos.y = read_buffer.read<std::int64_t>(); + set_voxel.vpos.z = read_buffer.read<std::int64_t>(); + set_voxel.voxel = read_buffer.read<std::uint16_t>(); + set_voxel.flags = read_buffer.read<std::uint16_t>(); + dispatcher.trigger(set_voxel); + break; + + case protocol::RemoveEntity::ID: + remove_entity.peer = peer; + remove_entity.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + dispatcher.trigger(remove_entity); + break; + + case protocol::EntityPlayer::ID: + entity_player.peer = peer; + entity_player.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + dispatcher.trigger(entity_player); + break; + + case protocol::ScoreboardUpdate::ID: + scoreboard_update.peer = peer; + scoreboard_update.names.resize(read_buffer.read<std::uint16_t>()); + for(std::size_t i = 0; i < scoreboard_update.names.size(); ++i) + scoreboard_update.names[i] = read_buffer.read<std::string>(); + dispatcher.trigger(scoreboard_update); + break; + + case protocol::RequestChunk::ID: + request_chunk.peer = peer; + request_chunk.cpos.x = read_buffer.read<std::uint32_t>(); + request_chunk.cpos.y = read_buffer.read<std::uint32_t>(); + request_chunk.cpos.z = read_buffer.read<std::uint32_t>(); + dispatcher.trigger(request_chunk); + break; + + case protocol::GenericSound::ID: + generic_sound.peer = peer; + generic_sound.sound = read_buffer.read<std::string>(); + generic_sound.looping = read_buffer.read<std::uint8_t>(); + generic_sound.pitch = read_buffer.read<float>(); + dispatcher.trigger(generic_sound); + break; + + case protocol::EntitySound::ID: + entity_sound.peer = peer; + entity_sound.entity = static_cast<entt::entity>(read_buffer.read<std::uint64_t>()); + entity_sound.sound = read_buffer.read<std::string>(); + entity_sound.looping = read_buffer.read<std::uint8_t>(); + entity_sound.pitch = read_buffer.read<float>(); + dispatcher.trigger(entity_sound); + break; + + case protocol::DimensionInfo::ID: + dimension_info.peer = peer; + dimension_info.name = read_buffer.read<std::string>(); + dimension_info.gravity = read_buffer.read<float>(); + dispatcher.trigger(dimension_info); + break; + } +} + +ENetPacket* protocol::utils::make_disconnect(std::string_view reason, enet_uint32 flags) +{ + protocol::Disconnect packet; + packet.reason = reason; + return protocol::encode(packet, flags); +} + +ENetPacket* protocol::utils::make_chat_message(std::string_view message, enet_uint32 flags) +{ + protocol::ChatMessage packet; + packet.type = protocol::ChatMessage::TEXT_MESSAGE; + packet.message = message; + return protocol::encode(packet, flags); +} + +ENetPacket* protocol::utils::make_chunk_voxels(world::Dimension* dimension, entt::entity entity, enet_uint32 flags) +{ + if(auto component = dimension->chunks.try_get<world::ChunkComponent>(entity)) { + protocol::ChunkVoxels packet; + packet.chunk = component->cpos; + packet.voxels = component->chunk->get_voxels(); + return protocol::encode(packet, flags); + } + + return nullptr; +} + +ENetPacket* protocol::utils::make_entity_head(world::Dimension* dimension, entt::entity entity, enet_uint32 flags) +{ + if(auto component = dimension->entities.try_get<entity::Head>(entity)) { + protocol::EntityHead packet; + packet.entity = entity; + packet.angles = component->angles; + return protocol::encode(packet, flags); + } + + return nullptr; +} + +ENetPacket* protocol::utils::make_entity_transform(world::Dimension* dimension, entt::entity entity, enet_uint32 flags) +{ + if(auto component = dimension->entities.try_get<entity::Transform>(entity)) { + protocol::EntityTransform packet; + packet.entity = entity; + packet.chunk = component->chunk; + packet.local = component->local; + packet.angles = component->angles; + return protocol::encode(packet, flags); + } + + return nullptr; +} + +ENetPacket* protocol::utils::make_entity_velocity(world::Dimension* dimension, entt::entity entity, enet_uint32 flags) +{ + if(auto component = dimension->entities.try_get<entity::Velocity>(entity)) { + protocol::EntityVelocity packet; + packet.entity = entity; + packet.value = component->value; + return protocol::encode(packet, flags); + } + + return nullptr; +} + +ENetPacket* protocol::utils::make_entity_player(world::Dimension* dimension, entt::entity entity, enet_uint32 flags) +{ + if(dimension->entities.any_of<entity::Player>(entity)) { + protocol::EntityPlayer packet; + packet.entity = entity; + return protocol::encode(packet, flags); + } + + return nullptr; +} + +ENetPacket* protocol::utils::make_dimension_info(const world::Dimension* dimension) +{ + protocol::DimensionInfo packet; + packet.name = dimension->get_name(); + packet.gravity = dimension->get_gravity(); + return protocol::encode(packet, ENET_PACKET_FLAG_RELIABLE); +} diff --git a/game/shared/protocol.hh b/src/game/shared/protocol.hh index f0bdff6..b222342 100644 --- a/game/shared/protocol.hh +++ b/src/game/shared/protocol.hh @@ -1,215 +1,215 @@ -#pragma once
-
-#include "shared/world/chunk.hh"
-
-namespace world
-{
-class Dimension;
-} // namespace world
-
-namespace protocol
-{
-constexpr static std::size_t MAX_CHAT = 16384;
-constexpr static std::size_t MAX_USERNAME = 64;
-constexpr static std::size_t MAX_SOUNDNAME = 1024;
-constexpr static std::uint16_t TICKRATE = 60;
-constexpr static std::uint16_t PORT = 43103;
-constexpr static std::uint8_t CHANNEL = 0;
-} // namespace protocol
-
-namespace protocol
-{
-template<std::uint16_t packet_id>
-struct Base {
- constexpr static std::uint16_t ID = packet_id;
- virtual ~Base(void) = default;
- ENetPeer* peer { nullptr };
-};
-} // namespace protocol
-
-namespace protocol
-{
-struct StatusRequest;
-struct StatusResponse;
-struct LoginRequest;
-struct LoginResponse;
-struct Disconnect;
-struct ChunkVoxels;
-struct EntityTransform;
-struct EntityHead;
-struct EntityVelocity;
-struct SpawnPlayer;
-struct ChatMessage;
-struct SetVoxel;
-struct RemoveEntity;
-struct EntityPlayer;
-struct ScoreboardUpdate;
-struct RequestChunk;
-struct GenericSound;
-struct EntitySound;
-struct DimensionInfo;
-} // namespace protocol
-
-namespace protocol
-{
-ENetPacket* encode(const StatusRequest& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const StatusResponse& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const LoginRequest& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const LoginResponse& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const Disconnect& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const ChunkVoxels& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const EntityTransform& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const EntityHead& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const EntityVelocity& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const SpawnPlayer& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const ChatMessage& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const SetVoxel& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const RemoveEntity& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const EntityPlayer& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const ScoreboardUpdate& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const RequestChunk& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const GenericSound& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const EntitySound& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* encode(const DimensionInfo& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-} // namespace protocol
-
-namespace protocol
-{
-void broadcast(ENetHost* host, ENetPacket* packet);
-void broadcast(ENetHost* host, ENetPacket* packet, ENetPeer* except);
-void send(ENetPeer* peer, ENetPacket* packet);
-} // namespace protocol
-
-namespace protocol
-{
-void decode(entt::dispatcher& dispatcher, const ENetPacket* packet, ENetPeer* peer);
-} // namespace protocol
-
-namespace protocol::utils
-{
-ENetPacket* make_disconnect(std::string_view reason, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* make_chat_message(std::string_view message, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-} // namespace protocol::utils
-
-namespace protocol::utils
-{
-ENetPacket* make_chunk_voxels(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-} // namespace protocol::utils
-
-namespace protocol::utils
-{
-ENetPacket* make_entity_head(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* make_entity_transform(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* make_entity_velocity(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* make_entity_player(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE);
-ENetPacket* make_dimension_info(const world::Dimension* dimension);
-} // namespace protocol::utils
-
-struct protocol::StatusRequest final : public protocol::Base<0x0000> {
- std::uint32_t game_version_major; // renamed from 'version' in v16.x.x
-};
-
-struct protocol::StatusResponse final : public protocol::Base<0x0001> {
- std::uint32_t game_version_major; // renamed from 'version' in v16.x.x
- std::uint16_t max_players;
- std::uint16_t num_players;
- std::string motd;
- std::uint32_t game_version_minor { UINT32_MAX }; // added in v16.x.x
- std::uint32_t game_version_patch { UINT32_MAX };
-};
-
-struct protocol::LoginRequest final : public protocol::Base<0x0002> {
- std::uint32_t game_version_major; // renamed from 'version' in v16.x.x
- std::uint64_t voxel_registry_checksum;
- std::uint64_t item_registry_checksum;
- std::uint64_t password_hash;
- std::string username;
- std::uint32_t game_version_minor; // added in v16.x.x
- std::uint32_t game_version_patch;
-};
-
-struct protocol::LoginResponse final : public protocol::Base<0x0003> {
- std::uint16_t client_index;
- std::uint64_t client_identity;
- std::uint16_t server_tickrate;
-};
-
-struct protocol::Disconnect final : public protocol::Base<0x0004> {
- std::string reason;
-};
-
-struct protocol::ChunkVoxels final : public protocol::Base<0x0005> {
- chunk_pos chunk;
- world::VoxelStorage voxels;
-};
-
-struct protocol::EntityTransform final : public protocol::Base<0x0006> {
- entt::entity entity;
- chunk_pos chunk;
- glm::fvec3 local;
- glm::fvec3 angles;
-};
-
-struct protocol::EntityHead final : public protocol::Base<0x0007> {
- entt::entity entity;
- glm::fvec3 angles;
-};
-
-struct protocol::EntityVelocity final : public protocol::Base<0x0008> {
- entt::entity entity;
- glm::fvec3 value;
-};
-
-struct protocol::SpawnPlayer final : public protocol::Base<0x0009> {
- entt::entity entity;
-};
-
-struct protocol::ChatMessage final : public protocol::Base<0x000A> {
- constexpr static std::uint16_t TEXT_MESSAGE = 0x0000;
- constexpr static std::uint16_t PLAYER_JOIN = 0x0001;
- constexpr static std::uint16_t PLAYER_LEAVE = 0x0002;
-
- std::uint16_t type;
- std::string sender;
- std::string message;
-};
-
-struct protocol::SetVoxel final : public protocol::Base<0x000B> {
- voxel_pos vpos;
- voxel_id voxel;
- std::uint16_t flags;
-};
-
-struct protocol::RemoveEntity final : public protocol::Base<0x000C> {
- entt::entity entity;
-};
-
-struct protocol::EntityPlayer final : public protocol::Base<0x000D> {
- entt::entity entity;
-};
-
-struct protocol::ScoreboardUpdate final : public protocol::Base<0x000E> {
- std::vector<std::string> names;
-};
-
-struct protocol::RequestChunk final : public protocol::Base<0x000F> {
- chunk_pos cpos;
-};
-
-struct protocol::GenericSound final : public protocol::Base<0x0010> {
- std::string sound;
- bool looping;
- float pitch;
-};
-
-struct protocol::EntitySound final : public protocol::Base<0x0011> {
- entt::entity entity;
- std::string sound;
- bool looping;
- float pitch;
-};
-
-struct protocol::DimensionInfo final : public protocol::Base<0x0012> {
- std::string name;
- float gravity;
-};
+#pragma once + +#include "shared/world/chunk.hh" + +namespace world +{ +class Dimension; +} // namespace world + +namespace protocol +{ +constexpr static std::size_t MAX_CHAT = 16384; +constexpr static std::size_t MAX_USERNAME = 64; +constexpr static std::size_t MAX_SOUNDNAME = 1024; +constexpr static std::uint16_t TICKRATE = 60; +constexpr static std::uint16_t PORT = 43103; +constexpr static std::uint8_t CHANNEL = 0; +} // namespace protocol + +namespace protocol +{ +template<std::uint16_t packet_id> +struct Base { + constexpr static std::uint16_t ID = packet_id; + virtual ~Base(void) = default; + ENetPeer* peer { nullptr }; +}; +} // namespace protocol + +namespace protocol +{ +struct StatusRequest; +struct StatusResponse; +struct LoginRequest; +struct LoginResponse; +struct Disconnect; +struct ChunkVoxels; +struct EntityTransform; +struct EntityHead; +struct EntityVelocity; +struct SpawnPlayer; +struct ChatMessage; +struct SetVoxel; +struct RemoveEntity; +struct EntityPlayer; +struct ScoreboardUpdate; +struct RequestChunk; +struct GenericSound; +struct EntitySound; +struct DimensionInfo; +} // namespace protocol + +namespace protocol +{ +ENetPacket* encode(const StatusRequest& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const StatusResponse& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const LoginRequest& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const LoginResponse& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const Disconnect& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const ChunkVoxels& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const EntityTransform& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const EntityHead& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const EntityVelocity& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const SpawnPlayer& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const ChatMessage& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const SetVoxel& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const RemoveEntity& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const EntityPlayer& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const ScoreboardUpdate& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const RequestChunk& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const GenericSound& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const EntitySound& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* encode(const DimensionInfo& packet, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +} // namespace protocol + +namespace protocol +{ +void broadcast(ENetHost* host, ENetPacket* packet); +void broadcast(ENetHost* host, ENetPacket* packet, ENetPeer* except); +void send(ENetPeer* peer, ENetPacket* packet); +} // namespace protocol + +namespace protocol +{ +void decode(entt::dispatcher& dispatcher, const ENetPacket* packet, ENetPeer* peer); +} // namespace protocol + +namespace protocol::utils +{ +ENetPacket* make_disconnect(std::string_view reason, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* make_chat_message(std::string_view message, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +} // namespace protocol::utils + +namespace protocol::utils +{ +ENetPacket* make_chunk_voxels(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +} // namespace protocol::utils + +namespace protocol::utils +{ +ENetPacket* make_entity_head(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* make_entity_transform(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* make_entity_velocity(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* make_entity_player(world::Dimension* dimension, entt::entity entity, enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE); +ENetPacket* make_dimension_info(const world::Dimension* dimension); +} // namespace protocol::utils + +struct protocol::StatusRequest final : public protocol::Base<0x0000> { + std::uint32_t game_version_major; // renamed from 'version' in v16.x.x +}; + +struct protocol::StatusResponse final : public protocol::Base<0x0001> { + std::uint32_t game_version_major; // renamed from 'version' in v16.x.x + std::uint16_t max_players; + std::uint16_t num_players; + std::string motd; + std::uint32_t game_version_minor { UINT32_MAX }; // added in v16.x.x + std::uint32_t game_version_patch { UINT32_MAX }; +}; + +struct protocol::LoginRequest final : public protocol::Base<0x0002> { + std::uint32_t game_version_major; // renamed from 'version' in v16.x.x + std::uint64_t voxel_registry_checksum; + std::uint64_t item_registry_checksum; + std::uint64_t password_hash; + std::string username; + std::uint32_t game_version_minor; // added in v16.x.x + std::uint32_t game_version_patch; +}; + +struct protocol::LoginResponse final : public protocol::Base<0x0003> { + std::uint16_t client_index; + std::uint64_t client_identity; + std::uint16_t server_tickrate; +}; + +struct protocol::Disconnect final : public protocol::Base<0x0004> { + std::string reason; +}; + +struct protocol::ChunkVoxels final : public protocol::Base<0x0005> { + chunk_pos chunk; + world::VoxelStorage voxels; +}; + +struct protocol::EntityTransform final : public protocol::Base<0x0006> { + entt::entity entity; + chunk_pos chunk; + glm::fvec3 local; + glm::fvec3 angles; +}; + +struct protocol::EntityHead final : public protocol::Base<0x0007> { + entt::entity entity; + glm::fvec3 angles; +}; + +struct protocol::EntityVelocity final : public protocol::Base<0x0008> { + entt::entity entity; + glm::fvec3 value; +}; + +struct protocol::SpawnPlayer final : public protocol::Base<0x0009> { + entt::entity entity; +}; + +struct protocol::ChatMessage final : public protocol::Base<0x000A> { + constexpr static std::uint16_t TEXT_MESSAGE = 0x0000; + constexpr static std::uint16_t PLAYER_JOIN = 0x0001; + constexpr static std::uint16_t PLAYER_LEAVE = 0x0002; + + std::uint16_t type; + std::string sender; + std::string message; +}; + +struct protocol::SetVoxel final : public protocol::Base<0x000B> { + voxel_pos vpos; + voxel_id voxel; + std::uint16_t flags; +}; + +struct protocol::RemoveEntity final : public protocol::Base<0x000C> { + entt::entity entity; +}; + +struct protocol::EntityPlayer final : public protocol::Base<0x000D> { + entt::entity entity; +}; + +struct protocol::ScoreboardUpdate final : public protocol::Base<0x000E> { + std::vector<std::string> names; +}; + +struct protocol::RequestChunk final : public protocol::Base<0x000F> { + chunk_pos cpos; +}; + +struct protocol::GenericSound final : public protocol::Base<0x0010> { + std::string sound; + bool looping; + float pitch; +}; + +struct protocol::EntitySound final : public protocol::Base<0x0011> { + entt::entity entity; + std::string sound; + bool looping; + float pitch; +}; + +struct protocol::DimensionInfo final : public protocol::Base<0x0012> { + std::string name; + float gravity; +}; diff --git a/game/shared/splash.cc b/src/game/shared/splash.cc index 9d74ba9..4568779 100644 --- a/game/shared/splash.cc +++ b/src/game/shared/splash.cc @@ -1,67 +1,67 @@ -#include "shared/pch.hh"
-
-#include "shared/splash.hh"
-
-#include "core/io/physfs.hh"
-
-constexpr static std::string_view SPLASHES_FILENAME_CLIENT = "misc/splashes_client.txt";
-constexpr static std::string_view SPLASHES_FILENAME_SERVER = "misc/splashes_server.txt";
-constexpr static std::size_t SPLASH_SERVER_MAX_LENGTH = 32;
-
-static std::mt19937_64 splash_random;
-static std::vector<std::string> splash_lines;
-
-static std::string sanitize_line(const std::string& line)
-{
- std::string result;
-
- for(auto chr : line) {
- if(chr != '\r' && chr != '\n') {
- result.push_back(chr);
- }
- }
-
- return result;
-}
-
-static void splash_init_filename(std::string_view filename)
-{
- if(auto file = PHYSFS_openRead(std::string(filename).c_str())) {
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- std::string line;
- std::istringstream stream(source);
-
- while(std::getline(stream, line))
- splash_lines.push_back(sanitize_line(line));
- splash_random.seed(std::random_device()());
- }
- else {
- splash_lines.push_back(std::format("{}: {}", filename, io::physfs_error()));
- splash_random.seed(std::random_device()());
- }
-}
-
-void splash::init_client(void)
-{
- splash_init_filename(SPLASHES_FILENAME_CLIENT);
-}
-
-void splash::init_server(void)
-{
- splash_init_filename(SPLASHES_FILENAME_SERVER);
-
- // Server browser GUI should be able to display
- // these splash messages without text clipping over
- for(int i = 0; i < splash_lines.size(); i++) {
- splash_lines[i] = splash_lines[i].substr(0, SPLASH_SERVER_MAX_LENGTH);
- }
-}
-
-std::string_view splash::get(void)
-{
- std::uniform_int_distribution<std::size_t> dist(0, splash_lines.size() - 1);
- return splash_lines.at(dist(splash_random));
-}
+#include "shared/pch.hh" + +#include "shared/splash.hh" + +#include "core/io/physfs.hh" + +constexpr static std::string_view SPLASHES_FILENAME_CLIENT = "misc/splashes_client.txt"; +constexpr static std::string_view SPLASHES_FILENAME_SERVER = "misc/splashes_server.txt"; +constexpr static std::size_t SPLASH_SERVER_MAX_LENGTH = 32; + +static std::mt19937_64 splash_random; +static std::vector<std::string> splash_lines; + +static std::string sanitize_line(const std::string& line) +{ + std::string result; + + for(auto chr : line) { + if(chr != '\r' && chr != '\n') { + result.push_back(chr); + } + } + + return result; +} + +static void splash_init_filename(std::string_view filename) +{ + if(auto file = PHYSFS_openRead(std::string(filename).c_str())) { + auto source = std::string(PHYSFS_fileLength(file), char(0x00)); + PHYSFS_readBytes(file, source.data(), source.size()); + PHYSFS_close(file); + + std::string line; + std::istringstream stream(source); + + while(std::getline(stream, line)) + splash_lines.push_back(sanitize_line(line)); + splash_random.seed(std::random_device()()); + } + else { + splash_lines.push_back(std::format("{}: {}", filename, io::physfs_error())); + splash_random.seed(std::random_device()()); + } +} + +void splash::init_client(void) +{ + splash_init_filename(SPLASHES_FILENAME_CLIENT); +} + +void splash::init_server(void) +{ + splash_init_filename(SPLASHES_FILENAME_SERVER); + + // Server browser GUI should be able to display + // these splash messages without text clipping over + for(int i = 0; i < splash_lines.size(); i++) { + splash_lines[i] = splash_lines[i].substr(0, SPLASH_SERVER_MAX_LENGTH); + } +} + +std::string_view splash::get(void) +{ + std::uniform_int_distribution<std::size_t> dist(0, splash_lines.size() - 1); + return splash_lines.at(dist(splash_random)); +} diff --git a/game/shared/splash.hh b/src/game/shared/splash.hh index 2572d53..be80cd6 100644 --- a/game/shared/splash.hh +++ b/src/game/shared/splash.hh @@ -1,8 +1,8 @@ -#pragma once
-
-namespace splash
-{
-void init_client(void);
-void init_server(void);
-std::string_view get(void);
-} // namespace splash
+#pragma once + +namespace splash +{ +void init_client(void); +void init_server(void); +std::string_view get(void); +} // namespace splash diff --git a/game/shared/types.hh b/src/game/shared/types.hh index 332eede..792ed0f 100644 --- a/game/shared/types.hh +++ b/src/game/shared/types.hh @@ -1,40 +1,40 @@ -#pragma once
-
-using item_id = std::uint32_t;
-constexpr static item_id NULL_ITEM_ID = UINT32_C(0x00000000);
-constexpr static item_id MAX_ITEM_ID = UINT32_C(0xFFFFFFFF);
-
-using voxel_id = std::uint16_t;
-constexpr static voxel_id NULL_VOXEL_ID = UINT16_C(0x0000);
-constexpr static voxel_id MAX_VOXEL_ID = UINT16_C(0xFFFF);
-
-using chunk_pos = glm::vec<3, std::int32_t>;
-using local_pos = glm::vec<3, std::int16_t>;
-using voxel_pos = glm::vec<3, std::int64_t>;
-
-using chunk_pos_xz = glm::vec<2, chunk_pos::value_type>;
-using local_pos_xz = glm::vec<2, local_pos::value_type>;
-using voxel_pos_xz = glm::vec<2, local_pos::value_type>;
-
-template<>
-struct std::hash<chunk_pos> final {
- constexpr inline std::size_t operator()(const chunk_pos& cpos) const
- {
- std::size_t value = 0;
- value ^= cpos.x * 73856093;
- value ^= cpos.y * 19349663;
- value ^= cpos.z * 83492791;
- return value;
- }
-};
-
-template<>
-struct std::hash<chunk_pos_xz> final {
- constexpr inline std::size_t operator()(const chunk_pos_xz& cwpos) const
- {
- std::size_t value = 0;
- value ^= cwpos.x * 73856093;
- value ^= cwpos.y * 19349663;
- return value;
- }
-};
+#pragma once + +using item_id = std::uint32_t; +constexpr static item_id NULL_ITEM_ID = UINT32_C(0x00000000); +constexpr static item_id MAX_ITEM_ID = UINT32_C(0xFFFFFFFF); + +using voxel_id = std::uint16_t; +constexpr static voxel_id NULL_VOXEL_ID = UINT16_C(0x0000); +constexpr static voxel_id MAX_VOXEL_ID = UINT16_C(0xFFFF); + +using chunk_pos = glm::vec<3, std::int32_t>; +using local_pos = glm::vec<3, std::int16_t>; +using voxel_pos = glm::vec<3, std::int64_t>; + +using chunk_pos_xz = glm::vec<2, chunk_pos::value_type>; +using local_pos_xz = glm::vec<2, local_pos::value_type>; +using voxel_pos_xz = glm::vec<2, local_pos::value_type>; + +template<> +struct std::hash<chunk_pos> final { + constexpr inline std::size_t operator()(const chunk_pos& cpos) const + { + std::size_t value = 0; + value ^= cpos.x * 73856093; + value ^= cpos.y * 19349663; + value ^= cpos.z * 83492791; + return value; + } +}; + +template<> +struct std::hash<chunk_pos_xz> final { + constexpr inline std::size_t operator()(const chunk_pos_xz& cwpos) const + { + std::size_t value = 0; + value ^= cwpos.x * 73856093; + value ^= cwpos.y * 19349663; + return value; + } +}; diff --git a/game/shared/world/CMakeLists.txt b/src/game/shared/world/CMakeLists.txt index db3f370..db3f370 100644 --- a/game/shared/world/CMakeLists.txt +++ b/src/game/shared/world/CMakeLists.txt diff --git a/game/shared/world/chunk.cc b/src/game/shared/world/chunk.cc index f8f7b93..e2d60cb 100644 --- a/game/shared/world/chunk.cc +++ b/src/game/shared/world/chunk.cc @@ -1,72 +1,72 @@ -#include "shared/pch.hh"
-
-#include "shared/world/chunk.hh"
-
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-
-world::Chunk::Chunk(entt::entity entity, Dimension* dimension)
-{
- m_entity = entity;
- m_dimension = dimension;
- m_voxels.fill(NULL_VOXEL_ID);
- m_biome = BIOME_VOID;
-}
-
-const world::Voxel* world::Chunk::get_voxel(const local_pos& lpos) const
-{
- return get_voxel(coord::to_index(lpos));
-}
-
-const world::Voxel* world::Chunk::get_voxel(const std::size_t index) const
-{
- if(index >= CHUNK_VOLUME) {
- return nullptr;
- }
-
- return voxel_registry::find(m_voxels[index]);
-}
-
-void world::Chunk::set_voxel(const Voxel* voxel, const local_pos& lpos)
-{
- set_voxel(voxel, coord::to_index(lpos));
-}
-
-void world::Chunk::set_voxel(const Voxel* voxel, const std::size_t index)
-{
- if(index < CHUNK_VOLUME) {
- m_voxels[index] = voxel ? voxel->get_id() : NULL_VOXEL_ID;
- return;
- }
-}
-
-const world::VoxelStorage& world::Chunk::get_voxels(void) const
-{
- return m_voxels;
-}
-
-void world::Chunk::set_voxels(const VoxelStorage& voxels)
-{
- m_voxels = voxels;
-}
-
-unsigned int world::Chunk::get_biome(void) const
-{
- return m_biome;
-}
-
-void world::Chunk::set_biome(unsigned int biome)
-{
- m_biome = biome;
-}
-
-entt::entity world::Chunk::get_entity(void) const
-{
- return m_entity;
-}
-
-world::Dimension* world::Chunk::get_dimension(void) const
-{
- return m_dimension;
-}
+#include "shared/pch.hh" + +#include "shared/world/chunk.hh" + +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" + +world::Chunk::Chunk(entt::entity entity, Dimension* dimension) +{ + m_entity = entity; + m_dimension = dimension; + m_voxels.fill(NULL_VOXEL_ID); + m_biome = BIOME_VOID; +} + +const world::Voxel* world::Chunk::get_voxel(const local_pos& lpos) const +{ + return get_voxel(coord::to_index(lpos)); +} + +const world::Voxel* world::Chunk::get_voxel(const std::size_t index) const +{ + if(index >= CHUNK_VOLUME) { + return nullptr; + } + + return voxel_registry::find(m_voxels[index]); +} + +void world::Chunk::set_voxel(const Voxel* voxel, const local_pos& lpos) +{ + set_voxel(voxel, coord::to_index(lpos)); +} + +void world::Chunk::set_voxel(const Voxel* voxel, const std::size_t index) +{ + if(index < CHUNK_VOLUME) { + m_voxels[index] = voxel ? voxel->get_id() : NULL_VOXEL_ID; + return; + } +} + +const world::VoxelStorage& world::Chunk::get_voxels(void) const +{ + return m_voxels; +} + +void world::Chunk::set_voxels(const VoxelStorage& voxels) +{ + m_voxels = voxels; +} + +unsigned int world::Chunk::get_biome(void) const +{ + return m_biome; +} + +void world::Chunk::set_biome(unsigned int biome) +{ + m_biome = biome; +} + +entt::entity world::Chunk::get_entity(void) const +{ + return m_entity; +} + +world::Dimension* world::Chunk::get_dimension(void) const +{ + return m_dimension; +} diff --git a/game/shared/world/chunk.hh b/src/game/shared/world/chunk.hh index 4a1e557..7518127 100644 --- a/game/shared/world/chunk.hh +++ b/src/game/shared/world/chunk.hh @@ -1,43 +1,43 @@ -#pragma once
-
-#include "shared/world/voxel_storage.hh"
-
-#include "shared/types.hh"
-
-constexpr static unsigned int BIOME_VOID = 0U;
-
-namespace world
-{
-class Dimension;
-class Voxel;
-} // namespace world
-
-namespace world
-{
-class Chunk final {
-public:
- explicit Chunk(entt::entity entity, Dimension* dimension);
- virtual ~Chunk(void) = default;
-
- const Voxel* get_voxel(const local_pos& lpos) const;
- const Voxel* get_voxel(const std::size_t index) const;
-
- void set_voxel(const Voxel* voxel, const local_pos& lpos);
- void set_voxel(const Voxel* voxel, const std::size_t index);
-
- const VoxelStorage& get_voxels(void) const;
- void set_voxels(const VoxelStorage& voxels);
-
- unsigned int get_biome(void) const;
- void set_biome(unsigned int biome);
-
- entt::entity get_entity(void) const;
- Dimension* get_dimension(void) const;
-
-private:
- entt::entity m_entity;
- Dimension* m_dimension;
- VoxelStorage m_voxels;
- unsigned int m_biome;
-};
-} // namespace world
+#pragma once + +#include "shared/world/voxel_storage.hh" + +#include "shared/types.hh" + +constexpr static unsigned int BIOME_VOID = 0U; + +namespace world +{ +class Dimension; +class Voxel; +} // namespace world + +namespace world +{ +class Chunk final { +public: + explicit Chunk(entt::entity entity, Dimension* dimension); + virtual ~Chunk(void) = default; + + const Voxel* get_voxel(const local_pos& lpos) const; + const Voxel* get_voxel(const std::size_t index) const; + + void set_voxel(const Voxel* voxel, const local_pos& lpos); + void set_voxel(const Voxel* voxel, const std::size_t index); + + const VoxelStorage& get_voxels(void) const; + void set_voxels(const VoxelStorage& voxels); + + unsigned int get_biome(void) const; + void set_biome(unsigned int biome); + + entt::entity get_entity(void) const; + Dimension* get_dimension(void) const; + +private: + entt::entity m_entity; + Dimension* m_dimension; + VoxelStorage m_voxels; + unsigned int m_biome; +}; +} // namespace world diff --git a/game/shared/world/chunk_aabb.hh b/src/game/shared/world/chunk_aabb.hh index d926b55..f07d3e1 100644 --- a/game/shared/world/chunk_aabb.hh +++ b/src/game/shared/world/chunk_aabb.hh @@ -1,10 +1,10 @@ -#pragma once
-
-#include "core/math/aabb.hh"
-
-#include "shared/types.hh"
-
-namespace world
-{
-using ChunkAABB = math::AABB<chunk_pos::value_type>;
-} // namespace world
+#pragma once + +#include "core/math/aabb.hh" + +#include "shared/types.hh" + +namespace world +{ +using ChunkAABB = math::AABB<chunk_pos::value_type>; +} // namespace world diff --git a/game/shared/world/dimension.cc b/src/game/shared/world/dimension.cc index 31a19af..0088753 100644 --- a/game/shared/world/dimension.cc +++ b/src/game/shared/world/dimension.cc @@ -1,187 +1,187 @@ -#include "shared/pch.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/voxel_registry.hh"
-
-#include "shared/coord.hh"
-#include "shared/globals.hh"
-
-world::Dimension::Dimension(std::string_view name, float gravity)
-{
- m_name = name;
- m_gravity = gravity;
-}
-
-world::Dimension::~Dimension(void)
-{
- for(const auto it : m_chunkmap)
- delete it.second;
- entities.clear();
- chunks.clear();
-}
-
-std::string_view world::Dimension::get_name(void) const
-{
- return m_name;
-}
-
-float world::Dimension::get_gravity(void) const
-{
- return m_gravity;
-}
-
-world::Chunk* world::Dimension::create_chunk(const chunk_pos& cpos)
-{
- auto it = m_chunkmap.find(cpos);
-
- if(it != m_chunkmap.cend()) {
- // Chunk already exists
- return it->second;
- }
-
- auto entity = chunks.create();
- auto chunk = new Chunk(entity, this);
-
- auto& component = chunks.emplace<ChunkComponent>(entity);
- component.chunk = chunk;
- component.cpos = cpos;
-
- ChunkCreateEvent event;
- event.dimension = this;
- event.chunk = chunk;
- event.cpos = cpos;
-
- globals::dispatcher.trigger(event);
-
- return m_chunkmap.insert_or_assign(cpos, std::move(chunk)).first->second;
-}
-
-world::Chunk* world::Dimension::find_chunk(entt::entity entity) const
-{
- if(chunks.valid(entity)) {
- return chunks.get<ChunkComponent>(entity).chunk;
- }
- else {
- return nullptr;
- }
-}
-
-world::Chunk* world::Dimension::find_chunk(const chunk_pos& cpos) const
-{
- auto it = m_chunkmap.find(cpos);
-
- if(it != m_chunkmap.cend()) {
- return it->second;
- }
- else {
- return nullptr;
- }
-}
-
-void world::Dimension::remove_chunk(entt::entity entity)
-{
- if(chunks.valid(entity)) {
- auto& component = chunks.get<ChunkComponent>(entity);
- m_chunkmap.erase(component.cpos);
- chunks.destroy(entity);
- }
-}
-
-void world::Dimension::remove_chunk(const chunk_pos& cpos)
-{
- auto it = m_chunkmap.find(cpos);
-
- if(it != m_chunkmap.cend()) {
- chunks.destroy(it->second->get_entity());
- m_chunkmap.erase(it);
- }
-}
-
-void world::Dimension::remove_chunk(Chunk* chunk)
-{
- if(chunk) {
- const auto& component = chunks.get<ChunkComponent>(chunk->get_entity());
- m_chunkmap.erase(component.cpos);
- chunks.destroy(chunk->get_entity());
- }
-}
-
-const world::Voxel* world::Dimension::get_voxel(const voxel_pos& vpos) const
-{
- auto cpos = coord::to_chunk(vpos);
- auto lpos = coord::to_local(vpos);
-
- if(auto chunk = find_chunk(cpos)) {
- return chunk->get_voxel(lpos);
- }
-
- return nullptr;
-}
-
-const world::Voxel* world::Dimension::get_voxel(const chunk_pos& cpos, const local_pos& lpos) const
-{
- // This allows accessing get_voxel with negative
- // local coordinates that usually would result in an
- // out-of-range values; this is useful for per-voxel update logic
- return get_voxel(coord::to_voxel(cpos, lpos));
-}
-
-bool world::Dimension::set_voxel(const Voxel* voxel, const voxel_pos& vpos)
-{
- auto cpos = coord::to_chunk(vpos);
- auto lpos = coord::to_local(vpos);
-
- if(auto chunk = find_chunk(cpos)) {
- if(auto old_voxel = chunk->get_voxel(lpos)) {
- if(old_voxel != voxel) {
- // Notify the old voxel that it is
- // being replaced with a different voxel
- old_voxel->on_remove(this, vpos);
- }
- }
-
- chunk->set_voxel(voxel, lpos);
-
- if(voxel) {
- // If we're not placing air, notify the
- // new voxel that it has been placed
- voxel->on_place(this, vpos);
- }
-
- VoxelSetEvent event;
- event.dimension = this;
- event.voxel = voxel;
- event.cpos = cpos;
- event.lpos = lpos;
- event.chunk = chunk;
-
- globals::dispatcher.trigger(event);
-
- return true;
- }
-
- return false;
-}
-
-bool world::Dimension::set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos)
-{
- // This allows accessing set_voxel with negative
- // local coordinates that usually would result in an
- // out-of-range values; this is useful for per-voxel update logic
- return set_voxel(voxel, coord::to_voxel(cpos, lpos));
-}
-
-void world::Dimension::init(io::ConfigMap& config)
-{
-}
-
-void world::Dimension::init_late(std::uint64_t global_seed)
-{
-}
-
-bool world::Dimension::generate(const chunk_pos& cpos, VoxelStorage& voxels)
-{
- return false;
-}
+#include "shared/pch.hh" + +#include "shared/world/dimension.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/globals.hh" + +world::Dimension::Dimension(std::string_view name, float gravity) +{ + m_name = name; + m_gravity = gravity; +} + +world::Dimension::~Dimension(void) +{ + for(const auto it : m_chunkmap) + delete it.second; + entities.clear(); + chunks.clear(); +} + +std::string_view world::Dimension::get_name(void) const +{ + return m_name; +} + +float world::Dimension::get_gravity(void) const +{ + return m_gravity; +} + +world::Chunk* world::Dimension::create_chunk(const chunk_pos& cpos) +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + // Chunk already exists + return it->second; + } + + auto entity = chunks.create(); + auto chunk = new Chunk(entity, this); + + auto& component = chunks.emplace<ChunkComponent>(entity); + component.chunk = chunk; + component.cpos = cpos; + + ChunkCreateEvent event; + event.dimension = this; + event.chunk = chunk; + event.cpos = cpos; + + globals::dispatcher.trigger(event); + + return m_chunkmap.insert_or_assign(cpos, std::move(chunk)).first->second; +} + +world::Chunk* world::Dimension::find_chunk(entt::entity entity) const +{ + if(chunks.valid(entity)) { + return chunks.get<ChunkComponent>(entity).chunk; + } + else { + return nullptr; + } +} + +world::Chunk* world::Dimension::find_chunk(const chunk_pos& cpos) const +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + return it->second; + } + else { + return nullptr; + } +} + +void world::Dimension::remove_chunk(entt::entity entity) +{ + if(chunks.valid(entity)) { + auto& component = chunks.get<ChunkComponent>(entity); + m_chunkmap.erase(component.cpos); + chunks.destroy(entity); + } +} + +void world::Dimension::remove_chunk(const chunk_pos& cpos) +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + chunks.destroy(it->second->get_entity()); + m_chunkmap.erase(it); + } +} + +void world::Dimension::remove_chunk(Chunk* chunk) +{ + if(chunk) { + const auto& component = chunks.get<ChunkComponent>(chunk->get_entity()); + m_chunkmap.erase(component.cpos); + chunks.destroy(chunk->get_entity()); + } +} + +const world::Voxel* world::Dimension::get_voxel(const voxel_pos& vpos) const +{ + auto cpos = coord::to_chunk(vpos); + auto lpos = coord::to_local(vpos); + + if(auto chunk = find_chunk(cpos)) { + return chunk->get_voxel(lpos); + } + + return nullptr; +} + +const world::Voxel* world::Dimension::get_voxel(const chunk_pos& cpos, const local_pos& lpos) const +{ + // This allows accessing get_voxel with negative + // local coordinates that usually would result in an + // out-of-range values; this is useful for per-voxel update logic + return get_voxel(coord::to_voxel(cpos, lpos)); +} + +bool world::Dimension::set_voxel(const Voxel* voxel, const voxel_pos& vpos) +{ + auto cpos = coord::to_chunk(vpos); + auto lpos = coord::to_local(vpos); + + if(auto chunk = find_chunk(cpos)) { + if(auto old_voxel = chunk->get_voxel(lpos)) { + if(old_voxel != voxel) { + // Notify the old voxel that it is + // being replaced with a different voxel + old_voxel->on_remove(this, vpos); + } + } + + chunk->set_voxel(voxel, lpos); + + if(voxel) { + // If we're not placing air, notify the + // new voxel that it has been placed + voxel->on_place(this, vpos); + } + + VoxelSetEvent event; + event.dimension = this; + event.voxel = voxel; + event.cpos = cpos; + event.lpos = lpos; + event.chunk = chunk; + + globals::dispatcher.trigger(event); + + return true; + } + + return false; +} + +bool world::Dimension::set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos) +{ + // This allows accessing set_voxel with negative + // local coordinates that usually would result in an + // out-of-range values; this is useful for per-voxel update logic + return set_voxel(voxel, coord::to_voxel(cpos, lpos)); +} + +void world::Dimension::init(io::ConfigMap& config) +{ +} + +void world::Dimension::init_late(std::uint64_t global_seed) +{ +} + +bool world::Dimension::generate(const chunk_pos& cpos, VoxelStorage& voxels) +{ + return false; +} diff --git a/game/shared/world/dimension.hh b/src/game/shared/world/dimension.hh index 58e0765..6549bf6 100644 --- a/game/shared/world/dimension.hh +++ b/src/game/shared/world/dimension.hh @@ -1,101 +1,101 @@ -#pragma once
-
-#include "shared/const.hh"
-#include "shared/types.hh"
-
-namespace io
-{
-class ConfigMap;
-} // namespace io
-
-namespace world
-{
-class Chunk;
-class Voxel;
-class VoxelStorage;
-} // namespace world
-
-namespace world
-{
-using dimension_entropy_map = std::array<std::uint64_t, CHUNK_AREA>;
-using dimension_height_map = std::array<voxel_pos::value_type, CHUNK_AREA>;
-} // namespace world
-
-namespace world
-{
-class Dimension {
-public:
- explicit Dimension(std::string_view name, float gravity);
- virtual ~Dimension(void);
-
- std::string_view get_name(void) const;
- float get_gravity(void) const;
-
-public:
- Chunk* create_chunk(const chunk_pos& cpos);
- Chunk* find_chunk(entt::entity entity) const;
- Chunk* find_chunk(const chunk_pos& cpos) const;
-
- void remove_chunk(entt::entity entity);
- void remove_chunk(const chunk_pos& cpos);
- void remove_chunk(Chunk* chunk);
-
-public:
- const Voxel* get_voxel(const voxel_pos& vpos) const;
- const Voxel* get_voxel(const chunk_pos& cpos, const local_pos& lpos) const;
-
- bool set_voxel(const Voxel* voxel, const voxel_pos& vpos);
- bool set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos);
-
-public:
- virtual void init(io::ConfigMap& config);
- virtual void init_late(std::uint64_t global_seed);
- virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels);
-
-public:
- entt::registry chunks;
- entt::registry entities;
-
-private:
- std::string m_name;
- emhash8::HashMap<chunk_pos, Chunk*> m_chunkmap;
- float m_gravity;
-};
-} // namespace world
-
-namespace world
-{
-struct ChunkComponent final {
- chunk_pos cpos;
- Chunk* chunk;
-};
-} // namespace world
-
-namespace world
-{
-struct ChunkCreateEvent final {
- Dimension* dimension;
- chunk_pos cpos;
- Chunk* chunk;
-};
-
-struct ChunkDestroyEvent final {
- Dimension* dimension;
- chunk_pos cpos;
- Chunk* chunk;
-};
-
-struct ChunkUpdateEvent final {
- Dimension* dimension;
- chunk_pos cpos;
- Chunk* chunk;
-};
-
-struct VoxelSetEvent final {
- Dimension* dimension;
- const Voxel* voxel;
- chunk_pos cpos;
- local_pos lpos;
- Chunk* chunk;
-};
-} // namespace world
+#pragma once + +#include "shared/const.hh" +#include "shared/types.hh" + +namespace io +{ +class ConfigMap; +} // namespace io + +namespace world +{ +class Chunk; +class Voxel; +class VoxelStorage; +} // namespace world + +namespace world +{ +using dimension_entropy_map = std::array<std::uint64_t, CHUNK_AREA>; +using dimension_height_map = std::array<voxel_pos::value_type, CHUNK_AREA>; +} // namespace world + +namespace world +{ +class Dimension { +public: + explicit Dimension(std::string_view name, float gravity); + virtual ~Dimension(void); + + std::string_view get_name(void) const; + float get_gravity(void) const; + +public: + Chunk* create_chunk(const chunk_pos& cpos); + Chunk* find_chunk(entt::entity entity) const; + Chunk* find_chunk(const chunk_pos& cpos) const; + + void remove_chunk(entt::entity entity); + void remove_chunk(const chunk_pos& cpos); + void remove_chunk(Chunk* chunk); + +public: + const Voxel* get_voxel(const voxel_pos& vpos) const; + const Voxel* get_voxel(const chunk_pos& cpos, const local_pos& lpos) const; + + bool set_voxel(const Voxel* voxel, const voxel_pos& vpos); + bool set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos); + +public: + virtual void init(io::ConfigMap& config); + virtual void init_late(std::uint64_t global_seed); + virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels); + +public: + entt::registry chunks; + entt::registry entities; + +private: + std::string m_name; + emhash8::HashMap<chunk_pos, Chunk*> m_chunkmap; + float m_gravity; +}; +} // namespace world + +namespace world +{ +struct ChunkComponent final { + chunk_pos cpos; + Chunk* chunk; +}; +} // namespace world + +namespace world +{ +struct ChunkCreateEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct ChunkDestroyEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct ChunkUpdateEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct VoxelSetEvent final { + Dimension* dimension; + const Voxel* voxel; + chunk_pos cpos; + local_pos lpos; + Chunk* chunk; +}; +} // namespace world diff --git a/game/shared/world/feature.cc b/src/game/shared/world/feature.cc index 8fe95f1..2468473 100644 --- a/game/shared/world/feature.cc +++ b/src/game/shared/world/feature.cc @@ -1,75 +1,75 @@ -#include "shared/pch.hh"
-
-#include "shared/world/feature.hh"
-
-#include "shared/world/chunk.hh"
-#include "shared/world/dimension.hh"
-#include "shared/world/voxel.hh"
-
-#include "shared/coord.hh"
-
-void world::Feature::place(const voxel_pos& vpos, Dimension* dimension) const
-{
- for(const auto [rpos, voxel, overwrite] : (*this)) {
- auto it_vpos = vpos + rpos;
- auto it_cpos = coord::to_chunk(it_vpos);
-
- if(auto chunk = dimension->create_chunk(it_cpos)) {
- auto it_lpos = coord::to_local(it_vpos);
- auto it_index = coord::to_index(it_lpos);
-
- if(chunk->get_voxel(it_index) && !overwrite) {
- // There is something in the way
- // and the called intentionally requested
- // we do not force feature to overwrite voxels
- continue;
- }
-
- chunk->set_voxel(voxel, it_index);
- }
- }
-}
-
-void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const
-{
- for(const auto [rpos, voxel, overwrite] : (*this)) {
- auto it_vpos = vpos + rpos;
- auto it_cpos = coord::to_chunk(it_vpos);
-
- if(it_cpos == cpos) {
- auto it_lpos = coord::to_local(it_vpos);
- auto it_index = coord::to_index(it_lpos);
-
- if(chunk.get_voxel(it_index) && !overwrite) {
- // There is something in the way
- // and the called intentionally requested
- // we do not force feature to overwrite voxels
- continue;
- }
-
- chunk.set_voxel(voxel, it_index);
- }
- }
-}
-
-void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const
-{
- for(const auto [rpos, voxel, overwrite] : (*this)) {
- auto it_vpos = vpos + rpos;
- auto it_cpos = coord::to_chunk(it_vpos);
-
- if(it_cpos == cpos) {
- auto it_lpos = coord::to_local(it_vpos);
- auto it_index = coord::to_index(it_lpos);
-
- if(voxels[it_index] && !overwrite) {
- // There is something in the way
- // and the called intentionally requested
- // we do not force feature to overwrite voxels
- continue;
- }
-
- voxels[it_index] = voxel ? voxel->get_id() : NULL_VOXEL_ID;
- }
- }
-}
+#include "shared/pch.hh" + +#include "shared/world/feature.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" +#include "shared/world/voxel.hh" + +#include "shared/coord.hh" + +void world::Feature::place(const voxel_pos& vpos, Dimension* dimension) const +{ + for(const auto [rpos, voxel, overwrite] : (*this)) { + auto it_vpos = vpos + rpos; + auto it_cpos = coord::to_chunk(it_vpos); + + if(auto chunk = dimension->create_chunk(it_cpos)) { + auto it_lpos = coord::to_local(it_vpos); + auto it_index = coord::to_index(it_lpos); + + if(chunk->get_voxel(it_index) && !overwrite) { + // There is something in the way + // and the called intentionally requested + // we do not force feature to overwrite voxels + continue; + } + + chunk->set_voxel(voxel, it_index); + } + } +} + +void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const +{ + for(const auto [rpos, voxel, overwrite] : (*this)) { + auto it_vpos = vpos + rpos; + auto it_cpos = coord::to_chunk(it_vpos); + + if(it_cpos == cpos) { + auto it_lpos = coord::to_local(it_vpos); + auto it_index = coord::to_index(it_lpos); + + if(chunk.get_voxel(it_index) && !overwrite) { + // There is something in the way + // and the called intentionally requested + // we do not force feature to overwrite voxels + continue; + } + + chunk.set_voxel(voxel, it_index); + } + } +} + +void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const +{ + for(const auto [rpos, voxel, overwrite] : (*this)) { + auto it_vpos = vpos + rpos; + auto it_cpos = coord::to_chunk(it_vpos); + + if(it_cpos == cpos) { + auto it_lpos = coord::to_local(it_vpos); + auto it_index = coord::to_index(it_lpos); + + if(voxels[it_index] && !overwrite) { + // There is something in the way + // and the called intentionally requested + // we do not force feature to overwrite voxels + continue; + } + + voxels[it_index] = voxel ? voxel->get_id() : NULL_VOXEL_ID; + } + } +} diff --git a/game/shared/world/feature.hh b/src/game/shared/world/feature.hh index a543632..0d28b20 100644 --- a/game/shared/world/feature.hh +++ b/src/game/shared/world/feature.hh @@ -1,25 +1,25 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world
-{
-class Chunk;
-class Dimension;
-class Voxel;
-class VoxelStorage;
-} // namespace world
-
-namespace world
-{
-class Feature final : public std::vector<std::tuple<voxel_pos, const Voxel*, bool>> {
-public:
- Feature(void) = default;
- virtual ~Feature(void) = default;
-
-public:
- void place(const voxel_pos& vpos, Dimension* dimension) const;
- void place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const;
- void place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const;
-};
-} // namespace world
+#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Chunk; +class Dimension; +class Voxel; +class VoxelStorage; +} // namespace world + +namespace world +{ +class Feature final : public std::vector<std::tuple<voxel_pos, const Voxel*, bool>> { +public: + Feature(void) = default; + virtual ~Feature(void) = default; + +public: + void place(const voxel_pos& vpos, Dimension* dimension) const; + void place(const voxel_pos& vpos, const chunk_pos& cpos, Chunk& chunk) const; + void place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const; +}; +} // namespace world diff --git a/game/shared/world/item.cc b/src/game/shared/world/item.cc index 5e60609..5e60609 100644 --- a/game/shared/world/item.cc +++ b/src/game/shared/world/item.cc diff --git a/game/shared/world/item.hh b/src/game/shared/world/item.hh index ffa7f5c..ffa7f5c 100644 --- a/game/shared/world/item.hh +++ b/src/game/shared/world/item.hh diff --git a/game/shared/world/item_registry.cc b/src/game/shared/world/item_registry.cc index 4e0932c..d89abe9 100644 --- a/game/shared/world/item_registry.cc +++ b/src/game/shared/world/item_registry.cc @@ -1,68 +1,68 @@ -#include "shared/pch.hh"
-
-#include "shared/world/item_registry.hh"
-
-#include "core/math/crc64.hh"
-
-#include "shared/world/voxel_registry.hh"
-
-static std::uint64_t registry_checksum = 0U;
-std::unordered_map<std::string, item_id> world::item_registry::names = {};
-std::vector<std::unique_ptr<world::Item>> world::item_registry::items = {};
-
-static void recalculate_checksum(void)
-{
- registry_checksum = 0U;
-
- for(const auto& item : world::item_registry::items) {
- registry_checksum = item->get_checksum(registry_checksum);
- }
-}
-
-world::Item* world::item_registry::register_item(const ItemBuilder& builder)
-{
- assert(builder.get_name().size());
- assert(nullptr == find(builder.get_name()));
-
- const auto id = static_cast<item_id>(1 + items.size());
-
- std::unique_ptr<Item> item(builder.build(id));
- names.emplace(std::string(builder.get_name()), id);
- items.push_back(std::move(item));
-
- recalculate_checksum();
-
- return items.back().get();
-}
-
-world::Item* world::item_registry::find(std::string_view name)
-{
- const auto it = names.find(std::string(name));
-
- if(it == names.end()) {
- return nullptr;
- }
-
- return items[it->second - 1].get();
-}
-
-world::Item* world::item_registry::find(const item_id item)
-{
- if(item == NULL_ITEM_ID || item > items.size()) {
- return nullptr;
- }
-
- return items[item - 1].get();
-}
-
-void world::item_registry::purge(void)
-{
- registry_checksum = 0U;
- items.clear();
- names.clear();
-}
-
-std::uint64_t world::item_registry::get_checksum(void)
-{
- return registry_checksum;
-}
+#include "shared/pch.hh" + +#include "shared/world/item_registry.hh" + +#include "core/math/crc64.hh" + +#include "shared/world/voxel_registry.hh" + +static std::uint64_t registry_checksum = 0U; +std::unordered_map<std::string, item_id> world::item_registry::names = {}; +std::vector<std::unique_ptr<world::Item>> world::item_registry::items = {}; + +static void recalculate_checksum(void) +{ + registry_checksum = 0U; + + for(const auto& item : world::item_registry::items) { + registry_checksum = item->get_checksum(registry_checksum); + } +} + +world::Item* world::item_registry::register_item(const ItemBuilder& builder) +{ + assert(builder.get_name().size()); + assert(nullptr == find(builder.get_name())); + + const auto id = static_cast<item_id>(1 + items.size()); + + std::unique_ptr<Item> item(builder.build(id)); + names.emplace(std::string(builder.get_name()), id); + items.push_back(std::move(item)); + + recalculate_checksum(); + + return items.back().get(); +} + +world::Item* world::item_registry::find(std::string_view name) +{ + const auto it = names.find(std::string(name)); + + if(it == names.end()) { + return nullptr; + } + + return items[it->second - 1].get(); +} + +world::Item* world::item_registry::find(const item_id item) +{ + if(item == NULL_ITEM_ID || item > items.size()) { + return nullptr; + } + + return items[item - 1].get(); +} + +void world::item_registry::purge(void) +{ + registry_checksum = 0U; + items.clear(); + names.clear(); +} + +std::uint64_t world::item_registry::get_checksum(void) +{ + return registry_checksum; +} diff --git a/game/shared/world/item_registry.hh b/src/game/shared/world/item_registry.hh index b4c9fda..a841a2d 100644 --- a/game/shared/world/item_registry.hh +++ b/src/game/shared/world/item_registry.hh @@ -1,26 +1,26 @@ -#pragma once
-
-#include "shared/world/item.hh"
-
-namespace world::item_registry
-{
-extern std::unordered_map<std::string, item_id> names;
-extern std::vector<std::unique_ptr<Item>> items;
-} // namespace world::item_registry
-
-namespace world::item_registry
-{
-Item* register_item(const ItemBuilder& builder);
-Item* find(std::string_view name);
-Item* find(const item_id item);
-} // namespace world::item_registry
-
-namespace world::item_registry
-{
-void purge(void);
-} // namespace world::item_registry
-
-namespace world::item_registry
-{
-std::uint64_t get_checksum(void);
-} // namespace world::item_registry
+#pragma once + +#include "shared/world/item.hh" + +namespace world::item_registry +{ +extern std::unordered_map<std::string, item_id> names; +extern std::vector<std::unique_ptr<Item>> items; +} // namespace world::item_registry + +namespace world::item_registry +{ +Item* register_item(const ItemBuilder& builder); +Item* find(std::string_view name); +Item* find(const item_id item); +} // namespace world::item_registry + +namespace world::item_registry +{ +void purge(void); +} // namespace world::item_registry + +namespace world::item_registry +{ +std::uint64_t get_checksum(void); +} // namespace world::item_registry diff --git a/game/shared/world/ray_dda.cc b/src/game/shared/world/ray_dda.cc index af1ab3b..d6383b9 100644 --- a/game/shared/world/ray_dda.cc +++ b/src/game/shared/world/ray_dda.cc @@ -1,107 +1,107 @@ -#include "shared/pch.hh"
-
-#include "shared/world/ray_dda.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-world::RayDDA::RayDDA(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos,
- const glm::fvec3& direction)
-{
- reset(dimension, start_chunk, start_fpos, direction);
-}
-
-world::RayDDA::RayDDA(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos,
- const glm::fvec3& direction)
-{
- reset(dimension, start_chunk, start_fpos, direction);
-}
-
-void world::RayDDA::reset(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos,
- const glm::fvec3& direction)
-{
- this->dimension = dimension;
- this->start_chunk = start_chunk;
- this->start_fpos = start_fpos;
- this->direction = direction;
-
- this->delta_dist.x = direction.x ? glm::abs(1.0f / direction.x) : std::numeric_limits<float>::max();
- this->delta_dist.y = direction.y ? glm::abs(1.0f / direction.y) : std::numeric_limits<float>::max();
- this->delta_dist.z = direction.z ? glm::abs(1.0f / direction.z) : std::numeric_limits<float>::max();
-
- this->distance = 0.0f;
- this->vpos = coord::to_voxel(start_chunk, start_fpos);
- this->vnormal = voxel_pos(0, 0, 0);
-
- // Need this for initial direction calculations
- auto lpos = coord::to_local(start_fpos);
-
- if(direction.x < 0.0f) {
- this->side_dist.x = this->delta_dist.x * (start_fpos.x - lpos.x);
- this->vstep.x = voxel_pos::value_type(-1);
- }
- else {
- this->side_dist.x = this->delta_dist.x * (lpos.x + 1.0f - start_fpos.x);
- this->vstep.x = voxel_pos::value_type(+1);
- }
-
- if(direction.y < 0.0f) {
- this->side_dist.y = this->delta_dist.y * (start_fpos.y - lpos.y);
- this->vstep.y = voxel_pos::value_type(-1);
- }
- else {
- this->side_dist.y = this->delta_dist.y * (lpos.y + 1.0f - start_fpos.y);
- this->vstep.y = voxel_pos::value_type(+1);
- }
-
- if(direction.z < 0.0f) {
- this->side_dist.z = this->delta_dist.z * (start_fpos.z - lpos.z);
- this->vstep.z = voxel_pos::value_type(-1);
- }
- else {
- this->side_dist.z = this->delta_dist.z * (lpos.z + 1.0f - start_fpos.z);
- this->vstep.z = voxel_pos::value_type(+1);
- }
-}
-
-void world::RayDDA::reset(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos,
- const glm::fvec3& direction)
-{
- reset(&dimension, start_chunk, start_fpos, direction);
-}
-
-const world::Voxel* world::RayDDA::step(void)
-{
- if(side_dist.x < side_dist.z) {
- if(side_dist.x < side_dist.y) {
- vnormal = voxel_pos(-vstep.x, 0, 0);
- distance = side_dist.x;
- side_dist.x += delta_dist.x;
- vpos.x += vstep.x;
- }
- else {
- vnormal = voxel_pos(0, -vstep.y, 0);
- distance = side_dist.y;
- side_dist.y += delta_dist.y;
- vpos.y += vstep.y;
- }
- }
- else {
- if(side_dist.z < side_dist.y) {
- vnormal = voxel_pos(0, 0, -vstep.z);
- distance = side_dist.z;
- side_dist.z += delta_dist.z;
- vpos.z += vstep.z;
- }
- else {
- vnormal = voxel_pos(0, -vstep.y, 0);
- distance = side_dist.y;
- side_dist.y += delta_dist.y;
- vpos.y += vstep.y;
- }
- }
-
- // This is slower than I want it to be
- return dimension->get_voxel(vpos);
-}
+#include "shared/pch.hh" + +#include "shared/world/ray_dda.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +world::RayDDA::RayDDA(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(dimension, start_chunk, start_fpos, direction); +} + +world::RayDDA::RayDDA(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(dimension, start_chunk, start_fpos, direction); +} + +void world::RayDDA::reset(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + this->dimension = dimension; + this->start_chunk = start_chunk; + this->start_fpos = start_fpos; + this->direction = direction; + + this->delta_dist.x = direction.x ? glm::abs(1.0f / direction.x) : std::numeric_limits<float>::max(); + this->delta_dist.y = direction.y ? glm::abs(1.0f / direction.y) : std::numeric_limits<float>::max(); + this->delta_dist.z = direction.z ? glm::abs(1.0f / direction.z) : std::numeric_limits<float>::max(); + + this->distance = 0.0f; + this->vpos = coord::to_voxel(start_chunk, start_fpos); + this->vnormal = voxel_pos(0, 0, 0); + + // Need this for initial direction calculations + auto lpos = coord::to_local(start_fpos); + + if(direction.x < 0.0f) { + this->side_dist.x = this->delta_dist.x * (start_fpos.x - lpos.x); + this->vstep.x = voxel_pos::value_type(-1); + } + else { + this->side_dist.x = this->delta_dist.x * (lpos.x + 1.0f - start_fpos.x); + this->vstep.x = voxel_pos::value_type(+1); + } + + if(direction.y < 0.0f) { + this->side_dist.y = this->delta_dist.y * (start_fpos.y - lpos.y); + this->vstep.y = voxel_pos::value_type(-1); + } + else { + this->side_dist.y = this->delta_dist.y * (lpos.y + 1.0f - start_fpos.y); + this->vstep.y = voxel_pos::value_type(+1); + } + + if(direction.z < 0.0f) { + this->side_dist.z = this->delta_dist.z * (start_fpos.z - lpos.z); + this->vstep.z = voxel_pos::value_type(-1); + } + else { + this->side_dist.z = this->delta_dist.z * (lpos.z + 1.0f - start_fpos.z); + this->vstep.z = voxel_pos::value_type(+1); + } +} + +void world::RayDDA::reset(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(&dimension, start_chunk, start_fpos, direction); +} + +const world::Voxel* world::RayDDA::step(void) +{ + if(side_dist.x < side_dist.z) { + if(side_dist.x < side_dist.y) { + vnormal = voxel_pos(-vstep.x, 0, 0); + distance = side_dist.x; + side_dist.x += delta_dist.x; + vpos.x += vstep.x; + } + else { + vnormal = voxel_pos(0, -vstep.y, 0); + distance = side_dist.y; + side_dist.y += delta_dist.y; + vpos.y += vstep.y; + } + } + else { + if(side_dist.z < side_dist.y) { + vnormal = voxel_pos(0, 0, -vstep.z); + distance = side_dist.z; + side_dist.z += delta_dist.z; + vpos.z += vstep.z; + } + else { + vnormal = voxel_pos(0, -vstep.y, 0); + distance = side_dist.y; + side_dist.y += delta_dist.y; + vpos.y += vstep.y; + } + } + + // This is slower than I want it to be + return dimension->get_voxel(vpos); +} diff --git a/game/shared/world/ray_dda.hh b/src/game/shared/world/ray_dda.hh index 110e3d4..0f548ba 100644 --- a/game/shared/world/ray_dda.hh +++ b/src/game/shared/world/ray_dda.hh @@ -1,38 +1,38 @@ -#pragma once
-
-#include "shared/types.hh"
-
-namespace world
-{
-class Dimension;
-class Voxel;
-} // namespace world
-
-namespace world
-{
-class RayDDA final {
-public:
- RayDDA(void) = default;
- explicit RayDDA(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction);
- explicit RayDDA(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction);
-
- void reset(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction);
- void reset(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction);
-
- const Voxel* step(void);
-
-public:
- const Dimension* dimension;
- chunk_pos start_chunk;
- glm::fvec3 start_fpos;
- glm::fvec3 direction;
-
- glm::fvec3 delta_dist;
- glm::fvec3 side_dist;
- voxel_pos vstep;
-
- double distance;
- voxel_pos vnormal;
- voxel_pos vpos;
-};
-} // namespace world
+#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Dimension; +class Voxel; +} // namespace world + +namespace world +{ +class RayDDA final { +public: + RayDDA(void) = default; + explicit RayDDA(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + explicit RayDDA(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + + void reset(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + void reset(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + + const Voxel* step(void); + +public: + const Dimension* dimension; + chunk_pos start_chunk; + glm::fvec3 start_fpos; + glm::fvec3 direction; + + glm::fvec3 delta_dist; + glm::fvec3 side_dist; + voxel_pos vstep; + + double distance; + voxel_pos vnormal; + voxel_pos vpos; +}; +} // namespace world diff --git a/game/shared/world/voxel.cc b/src/game/shared/world/voxel.cc index 21fe62c..21fe62c 100644 --- a/game/shared/world/voxel.cc +++ b/src/game/shared/world/voxel.cc diff --git a/game/shared/world/voxel.hh b/src/game/shared/world/voxel.hh index 6013962..6013962 100644 --- a/game/shared/world/voxel.hh +++ b/src/game/shared/world/voxel.hh diff --git a/game/shared/world/voxel_registry.cc b/src/game/shared/world/voxel_registry.cc index 573a606..fae83fa 100644 --- a/game/shared/world/voxel_registry.cc +++ b/src/game/shared/world/voxel_registry.cc @@ -1,64 +1,64 @@ -#include "shared/pch.hh"
-
-#include "shared/world/voxel_registry.hh"
-
-static std::uint64_t registry_checksum = 0U;
-emhash8::HashMap<std::string, voxel_id> world::voxel_registry::names;
-std::vector<std::unique_ptr<world::Voxel>> world::voxel_registry::voxels;
-
-static void recalculate_checksum(void)
-{
- registry_checksum = 0U;
-
- for(const auto& voxel : world::voxel_registry::voxels) {
- registry_checksum = voxel->get_checksum(registry_checksum);
- }
-}
-
-world::Voxel* world::voxel_registry::register_voxel(const VoxelBuilder& builder)
-{
- assert(builder.get_name().size());
- assert(nullptr == find(builder.get_name()));
-
- const auto id = static_cast<voxel_id>(1 + voxels.size());
-
- std::unique_ptr<Voxel> voxel(builder.build(id));
- names.emplace(std::string(builder.get_name()), id);
- voxels.push_back(std::move(voxel));
-
- recalculate_checksum();
-
- return voxels.back().get();
-}
-
-world::Voxel* world::voxel_registry::find(std::string_view name)
-{
- const auto it = names.find(std::string(name));
-
- if(it == names.end()) {
- return nullptr;
- }
-
- return voxels[it->second - 1].get();
-}
-
-world::Voxel* world::voxel_registry::find(voxel_id id)
-{
- if(id == NULL_VOXEL_ID || id > voxels.size()) {
- return nullptr;
- }
-
- return voxels[id - 1].get();
-}
-
-void world::voxel_registry::purge(void)
-{
- registry_checksum = 0U;
- voxels.clear();
- names.clear();
-}
-
-std::uint64_t world::voxel_registry::get_checksum(void)
-{
- return registry_checksum;
-}
+#include "shared/pch.hh" + +#include "shared/world/voxel_registry.hh" + +static std::uint64_t registry_checksum = 0U; +emhash8::HashMap<std::string, voxel_id> world::voxel_registry::names; +std::vector<std::unique_ptr<world::Voxel>> world::voxel_registry::voxels; + +static void recalculate_checksum(void) +{ + registry_checksum = 0U; + + for(const auto& voxel : world::voxel_registry::voxels) { + registry_checksum = voxel->get_checksum(registry_checksum); + } +} + +world::Voxel* world::voxel_registry::register_voxel(const VoxelBuilder& builder) +{ + assert(builder.get_name().size()); + assert(nullptr == find(builder.get_name())); + + const auto id = static_cast<voxel_id>(1 + voxels.size()); + + std::unique_ptr<Voxel> voxel(builder.build(id)); + names.emplace(std::string(builder.get_name()), id); + voxels.push_back(std::move(voxel)); + + recalculate_checksum(); + + return voxels.back().get(); +} + +world::Voxel* world::voxel_registry::find(std::string_view name) +{ + const auto it = names.find(std::string(name)); + + if(it == names.end()) { + return nullptr; + } + + return voxels[it->second - 1].get(); +} + +world::Voxel* world::voxel_registry::find(voxel_id id) +{ + if(id == NULL_VOXEL_ID || id > voxels.size()) { + return nullptr; + } + + return voxels[id - 1].get(); +} + +void world::voxel_registry::purge(void) +{ + registry_checksum = 0U; + voxels.clear(); + names.clear(); +} + +std::uint64_t world::voxel_registry::get_checksum(void) +{ + return registry_checksum; +} diff --git a/game/shared/world/voxel_registry.hh b/src/game/shared/world/voxel_registry.hh index 5ba2aed..a1e0eee 100644 --- a/game/shared/world/voxel_registry.hh +++ b/src/game/shared/world/voxel_registry.hh @@ -1,26 +1,26 @@ -#pragma once
-
-#include "shared/world/voxel.hh"
-
-namespace world::voxel_registry
-{
-extern emhash8::HashMap<std::string, voxel_id> names;
-extern std::vector<std::unique_ptr<Voxel>> voxels;
-} // namespace world::voxel_registry
-
-namespace world::voxel_registry
-{
-Voxel* register_voxel(const VoxelBuilder& builder);
-Voxel* find(std::string_view name);
-Voxel* find(voxel_id id);
-} // namespace world::voxel_registry
-
-namespace world::voxel_registry
-{
-void purge(void);
-} // namespace world::voxel_registry
-
-namespace world::voxel_registry
-{
-std::uint64_t get_checksum(void);
-} // namespace world::voxel_registry
+#pragma once + +#include "shared/world/voxel.hh" + +namespace world::voxel_registry +{ +extern emhash8::HashMap<std::string, voxel_id> names; +extern std::vector<std::unique_ptr<Voxel>> voxels; +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +Voxel* register_voxel(const VoxelBuilder& builder); +Voxel* find(std::string_view name); +Voxel* find(voxel_id id); +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +void purge(void); +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +std::uint64_t get_checksum(void); +} // namespace world::voxel_registry diff --git a/game/shared/world/voxel_storage.cc b/src/game/shared/world/voxel_storage.cc index 75013b4..68e261c 100644 --- a/game/shared/world/voxel_storage.cc +++ b/src/game/shared/world/voxel_storage.cc @@ -1,48 +1,48 @@ -#include "shared/pch.hh"
-
-#include "shared/world/voxel_storage.hh"
-
-#include "core/io/buffer.hh"
-
-void world::VoxelStorage::serialize(io::WriteBuffer& buffer) const
-{
- auto bound = mz_compressBound(sizeof(VoxelStorage));
- auto zdata = std::vector<unsigned char>(bound);
-
- VoxelStorage net_storage;
-
- for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) {
- // Convert voxel indices into network byte order;
- // We're going to compress them but we still want
- // the order to be consistent across all the platforms
- net_storage[i] = ENET_HOST_TO_NET_16(at(i));
- }
-
- mz_compress(zdata.data(), &bound, reinterpret_cast<unsigned char*>(net_storage.data()), sizeof(VoxelStorage));
-
- buffer.write<std::uint64_t>(bound);
-
- // Write all the compressed data into the buffer
- for(std::size_t i = 0; i < bound; buffer.write<std::uint8_t>(zdata[i++])) {
- // empty
- }
-}
-
-void world::VoxelStorage::deserialize(io::ReadBuffer& buffer)
-{
- auto size = static_cast<mz_ulong>(sizeof(VoxelStorage));
- auto bound = static_cast<mz_ulong>(buffer.read<std::uint64_t>());
- auto zdata = std::vector<unsigned char>(bound);
-
- // Read all the compressed data from the buffer
- for(std::size_t i = 0; i < bound; zdata[i++] = buffer.read<std::uint8_t>()) {
- // empty
- }
-
- mz_uncompress(reinterpret_cast<unsigned char*>(data()), &size, zdata.data(), bound);
-
- for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) {
- // Convert voxel indices back into the host byte order
- at(i) = ENET_NET_TO_HOST_16(at(i));
- }
-}
+#include "shared/pch.hh" + +#include "shared/world/voxel_storage.hh" + +#include "core/io/buffer.hh" + +void world::VoxelStorage::serialize(io::WriteBuffer& buffer) const +{ + auto bound = mz_compressBound(sizeof(VoxelStorage)); + auto zdata = std::vector<unsigned char>(bound); + + VoxelStorage net_storage; + + for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { + // Convert voxel indices into network byte order; + // We're going to compress them but we still want + // the order to be consistent across all the platforms + net_storage[i] = ENET_HOST_TO_NET_16(at(i)); + } + + mz_compress(zdata.data(), &bound, reinterpret_cast<unsigned char*>(net_storage.data()), sizeof(VoxelStorage)); + + buffer.write<std::uint64_t>(bound); + + // Write all the compressed data into the buffer + for(std::size_t i = 0; i < bound; buffer.write<std::uint8_t>(zdata[i++])) { + // empty + } +} + +void world::VoxelStorage::deserialize(io::ReadBuffer& buffer) +{ + auto size = static_cast<mz_ulong>(sizeof(VoxelStorage)); + auto bound = static_cast<mz_ulong>(buffer.read<std::uint64_t>()); + auto zdata = std::vector<unsigned char>(bound); + + // Read all the compressed data from the buffer + for(std::size_t i = 0; i < bound; zdata[i++] = buffer.read<std::uint8_t>()) { + // empty + } + + mz_uncompress(reinterpret_cast<unsigned char*>(data()), &size, zdata.data(), bound); + + for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { + // Convert voxel indices back into the host byte order + at(i) = ENET_NET_TO_HOST_16(at(i)); + } +} diff --git a/game/shared/world/voxel_storage.hh b/src/game/shared/world/voxel_storage.hh index 98e85a3..ac7f03d 100644 --- a/game/shared/world/voxel_storage.hh +++ b/src/game/shared/world/voxel_storage.hh @@ -1,20 +1,20 @@ -#pragma once
-
-#include "shared/const.hh"
-#include "shared/types.hh"
-
-namespace io
-{
-class ReadBuffer;
-class WriteBuffer;
-} // namespace io
-
-namespace world
-{
-class VoxelStorage final : public std::array<voxel_id, CHUNK_VOLUME> {
-public:
- using std::array<voxel_id, CHUNK_VOLUME>::array;
- void serialize(io::WriteBuffer& buffer) const;
- void deserialize(io::ReadBuffer& buffer);
-};
-} // namespace world
+#pragma once + +#include "shared/const.hh" +#include "shared/types.hh" + +namespace io +{ +class ReadBuffer; +class WriteBuffer; +} // namespace io + +namespace world +{ +class VoxelStorage final : public std::array<voxel_id, CHUNK_VOLUME> { +public: + using std::array<voxel_id, CHUNK_VOLUME>::array; + void serialize(io::WriteBuffer& buffer) const; + void deserialize(io::ReadBuffer& buffer); +}; +} // namespace world diff --git a/tools/build-unix.sh b/tools/build-unix.sh deleted file mode 100755 index ad1edd2..0000000 --- a/tools/build-unix.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -cmake -B build/unix/${1:-Debug} -DCMAKE_BUILD_TYPE=${1:-Debug} || exit 1 -cmake --build build/unix/${1:-Debug} --config ${1:-Debug} --parallel $(nproc) || exit 1 -exit 0 diff --git a/tools/build-win32.sh b/tools/build-win32.sh deleted file mode 100644 index af152fc..0000000 --- a/tools/build-win32.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -cmake -B build/win32 -A Win32 -DCMAKE_BUILD_TYPE=${1:-Debug} || exit 1 -cmake --build build/win32 --config ${1:-Debug} --parallel || exit 1 -exit 0 diff --git a/tools/build-win64.sh b/tools/build-win64.sh deleted file mode 100644 index 50ca07a..0000000 --- a/tools/build-win64.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -cmake -B build/win64 -A x64 -DCMAKE_BUILD_TYPE=${1:-Debug} || exit 1 -cmake --build build/win64 --config ${1:-Debug} --parallel || exit 1 -exit 0 diff --git a/tools/pack-unix.sh b/tools/pack-unix.sh deleted file mode 100644 index cbadee4..0000000 --- a/tools/pack-unix.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -${SHELL} tools/build-unix.sh Release || exit 1 -cpack --config build/unix/CPackConfig.cmake -G ZIP || exit 1 -exit 0 diff --git a/tools/pack-win32.sh b/tools/pack-win32.sh deleted file mode 100644 index 351df9d..0000000 --- a/tools/pack-win32.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -${SHELL} tools/build-win32.sh Release || exit 1 -cpack --config build/win32/CPackConfig.cmake -G ZIP || exit 1 -exit 0 diff --git a/tools/pack-win64.sh b/tools/pack-win64.sh deleted file mode 100644 index 5cb5404..0000000 --- a/tools/pack-win64.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/sh -cd $(dirname $(dirname ${0})) || exit 1 -${SHELL} tools/build-win64.sh Release || exit 1 -cpack --config build/win64/CPackConfig.cmake -G ZIP || exit 1 -exit 0 |
