├── .github ├── FUNDING.yml └── workflows │ └── build-cmake.yml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── _config.yml ├── carnage3d_logo.png ├── cmake ├── Carnage3D.cmake ├── FindBox2D.cmake └── FindGLEW.cmake ├── docs ├── CorrectionsToCDS.txt ├── Sprites.txt ├── miami_objects.txt ├── nyc_objects.txt └── ped.txt ├── gamedata ├── config │ ├── inputs.json.default │ └── sys_config.json.default ├── entities │ ├── gta_objects.json │ ├── ped_animations.json │ ├── pedestrians.json │ └── weapons.json ├── fonts │ ├── cousine_regular.ttf │ ├── karla_regular.ttf │ └── nunito_regular.ttf └── shaders │ ├── city_mesh.glsl │ ├── debug.glsl │ ├── gui.glsl │ ├── particle.glsl │ ├── sprites.glsl │ └── texture_color.glsl ├── premake5.lua ├── screenshots ├── SplitScreenTest.png └── WorksOnLinux.png ├── src ├── .clang-format ├── AiCharacterController.cpp ├── AiCharacterController.h ├── AiManager.cpp ├── AiManager.h ├── AiPedestrianBehavior.cpp ├── AiPedestrianBehavior.h ├── AudioDataStream.cpp ├── AudioDataStream.h ├── AudioDevice.cpp ├── AudioDevice.h ├── AudioListener.h ├── AudioManager.cpp ├── AudioManager.h ├── AudioSampleArchive.cpp ├── AudioSampleArchive.h ├── AudioSource.cpp ├── AudioSource.h ├── Box2D │ ├── Box2D.vcxproj │ └── Box2D.vcxproj.filters ├── Box2D_Helpers.h ├── BroadcastEventsManager.cpp ├── BroadcastEventsManager.h ├── CMakeLists.txt ├── CameraController.h ├── Carnage3D.sln ├── Carnage3D.vcxproj ├── Carnage3D.vcxproj.filters ├── CarnageGame.cpp ├── CarnageGame.h ├── CharacterController.cpp ├── CharacterController.h ├── Collider.cpp ├── Collider.h ├── Collision.cpp ├── Collision.h ├── CommonTypes.cpp ├── CommonTypes.h ├── Console.cpp ├── Console.h ├── ConsoleVar.cpp ├── ConsoleVar.h ├── ConsoleWindow.cpp ├── ConsoleWindow.h ├── Convert.h ├── DamageInfo.cpp ├── DamageInfo.h ├── DebugRenderer.cpp ├── DebugRenderer.h ├── DebugWindow.cpp ├── DebugWindow.h ├── Decoration.cpp ├── Decoration.h ├── Explosion.cpp ├── Explosion.h ├── FileSystem.cpp ├── FileSystem.h ├── FollowCameraController.cpp ├── FollowCameraController.h ├── Font.cpp ├── Font.h ├── FontManager.cpp ├── FontManager.h ├── FreeLookCameraController.cpp ├── FreeLookCameraController.h ├── GLFW │ ├── GLFW.vcxproj │ ├── GLFW.vcxproj.filters │ ├── cocoa_init.m │ ├── cocoa_joystick.h │ ├── cocoa_joystick.m │ ├── cocoa_monitor.m │ ├── cocoa_platform.h │ ├── cocoa_time.c │ ├── cocoa_window.m │ ├── context.c │ ├── egl_context.c │ ├── egl_context.h │ ├── glfw3.h │ ├── glfw3.pc.in │ ├── glfw3Config.cmake.in │ ├── glfw3native.h │ ├── glfw_config.h │ ├── glfw_config.h.in │ ├── glx_context.c │ ├── glx_context.h │ ├── init.c │ ├── input.c │ ├── internal.h │ ├── linux_joystick.c │ ├── linux_joystick.h │ ├── mappings.h │ ├── mappings.h.in │ ├── monitor.c │ ├── nsgl_context.h │ ├── nsgl_context.m │ ├── null_init.c │ ├── null_joystick.c │ ├── null_joystick.h │ ├── null_monitor.c │ ├── null_platform.h │ ├── null_window.c │ ├── osmesa_context.c │ ├── osmesa_context.h │ ├── posix_thread.c │ ├── posix_thread.h │ ├── posix_time.c │ ├── posix_time.h │ ├── vulkan.c │ ├── wgl_context.c │ ├── wgl_context.h │ ├── win32_init.c │ ├── win32_joystick.c │ ├── win32_joystick.h │ ├── win32_monitor.c │ ├── win32_platform.h │ ├── win32_thread.c │ ├── win32_time.c │ ├── win32_window.c │ ├── window.c │ ├── wl_init.c │ ├── wl_monitor.c │ ├── wl_platform.h │ ├── wl_window.c │ ├── x11_init.c │ ├── x11_monitor.c │ ├── x11_platform.h │ ├── x11_window.c │ ├── xkb_unicode.c │ └── xkb_unicode.h ├── GameCamera.cpp ├── GameCamera.h ├── GameCheatsWindow.cpp ├── GameCheatsWindow.h ├── GameDefs.h ├── GameMapHelpers.cpp ├── GameMapHelpers.h ├── GameMapManager.cpp ├── GameMapManager.h ├── GameObject.cpp ├── GameObject.h ├── GameObjectHelpers.h ├── GameObjectsManager.cpp ├── GameObjectsManager.h ├── GameParams.cpp ├── GameParams.h ├── GameTextsManager.cpp ├── GameTextsManager.h ├── GameplayGamestate.cpp ├── GameplayGamestate.h ├── GenericGamestate.cpp ├── GenericGamestate.h ├── GpuBuffer.cpp ├── GpuBuffer.h ├── GpuProgram.cpp ├── GpuProgram.h ├── GpuTexture2D.cpp ├── GpuTexture2D.h ├── GpuTextureArray2D.cpp ├── GpuTextureArray2D.h ├── GraphicsContext.h ├── GraphicsDefs.h ├── GraphicsDevice.cpp ├── GraphicsDevice.h ├── GuiContext.cpp ├── GuiContext.h ├── GuiDefs.h ├── GuiManager.cpp ├── GuiManager.h ├── GuiScreen.h ├── HUD.cpp ├── HUD.h ├── HumanPlayer.cpp ├── HumanPlayer.h ├── ImGuiHelpers.h ├── ImGuiManager.cpp ├── ImGuiManager.h ├── InputActionsMapping.cpp ├── InputActionsMapping.h ├── InputsDefs.h ├── InputsManager.cpp ├── InputsManager.h ├── Main.cpp ├── MainMenuGamestate.cpp ├── MainMenuGamestate.h ├── MapRenderer.cpp ├── MapRenderer.h ├── MemoryManager.cpp ├── MemoryManager.h ├── Obstacle.cpp ├── Obstacle.h ├── OpenALDefs.h ├── OpenGLDefs.h ├── ParticleDefs.h ├── ParticleEffect.cpp ├── ParticleEffect.h ├── ParticleEffectsManager.cpp ├── ParticleEffectsManager.h ├── ParticleRenderdata.cpp ├── ParticleRenderdata.h ├── Pedestrian.cpp ├── Pedestrian.h ├── PedestrianInfo.cpp ├── PedestrianInfo.h ├── PedestrianStates.cpp ├── PedestrianStates.h ├── PhysicsBody.cpp ├── PhysicsBody.h ├── PhysicsDefs.h ├── PhysicsManager.cpp ├── PhysicsManager.h ├── PixelsArray.cpp ├── PixelsArray.h ├── Projectile.cpp ├── Projectile.h ├── RenderProgram.cpp ├── RenderProgram.h ├── RenderingManager.cpp ├── RenderingManager.h ├── SfxDefs.h ├── SfxEmitter.cpp ├── SfxEmitter.h ├── Sprite2D.cpp ├── Sprite2D.h ├── SpriteAnimation.cpp ├── SpriteAnimation.h ├── SpriteBatch.cpp ├── SpriteBatch.h ├── SpriteManager.cpp ├── SpriteManager.h ├── StyleData.cpp ├── StyleData.h ├── System.cpp ├── System.h ├── TimeManager.cpp ├── TimeManager.h ├── TrafficManager.cpp ├── TrafficManager.h ├── Transform.h ├── TrimeshBuffer.cpp ├── TrimeshBuffer.h ├── Vehicle.cpp ├── Vehicle.h ├── VertexFormats.h ├── Weapon.cpp ├── Weapon.h ├── WeaponInfo.cpp ├── WeaponInfo.h ├── WeatherManager.cpp ├── WeatherManager.h ├── cJSON.cpp ├── cJSON.h ├── common_utils.h ├── cvars.h ├── enum_utils.h ├── enums_impl.cpp ├── game_version.h ├── geometries.inl ├── handle.h ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui_demo.cpp ├── imgui_draw.cpp ├── imgui_internal.h ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h ├── imstb_truetype.h ├── intrusive_list.h ├── iostream_utils.h ├── json_document.cpp ├── json_document.h ├── macro.h ├── math_defs.h ├── math_utils.h ├── mem_allocators.cpp ├── mem_allocators.h ├── memory_istream.h ├── noncopyable.h ├── object_pool.h ├── path_utils.cpp ├── path_utils.h ├── randomizer.h ├── rtti.h ├── stb_image_write.h ├── stb_rect_pack.cpp ├── stb_rect_pack.h ├── stb_sprintf.h ├── std_image.h ├── stdafx.cpp ├── stdafx.h ├── strings.cpp ├── strings.h ├── wave_utils.cpp └── wave_utils.h ├── wasm ├── build.bat └── build.py └── web ├── carnage3D.data ├── carnage3D.js ├── carnage3D.wasm └── carnage3D_wasm.html /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://bank.gov.ua/en/about/support-the-armed-forces"] 2 | -------------------------------------------------------------------------------- /.github/workflows/build-cmake.yml: -------------------------------------------------------------------------------- 1 | name: Build with cmake 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - cmake/** 8 | - src/** 9 | - third_party/** 10 | - CMakeLists.txt 11 | 12 | pull_request: 13 | paths: 14 | - cmake/** 15 | - src/** 16 | - third_party/** 17 | - CMakeLists.txt 18 | 19 | workflow_dispatch: 20 | 21 | jobs: 22 | ubuntu: 23 | name: "Ubuntu (${{ matrix.compiler.cc }})" 24 | runs-on: ubuntu-latest 25 | 26 | strategy: 27 | fail-fast: false 28 | matrix: 29 | compiler: 30 | - {cc: gcc, cxx: g++} 31 | - {cc: clang, cxx: clang++} 32 | 33 | steps: 34 | - uses: actions/checkout@v2 35 | with: 36 | submodules: true 37 | 38 | - name: Update apt 39 | run: sudo apt update 40 | 41 | - name: Install dependencies 42 | run: sudo apt install --yes cmake libglew-dev libglfw3-dev libglm-dev libopenal-dev xorg-dev 43 | 44 | - name: Install clang 45 | run: sudo apt install --yes clang 46 | if: ${{ matrix.compiler.cc == 'clang' }} 47 | 48 | - name: cmake 49 | uses: ashutoshvarma/action-cmake-build@master 50 | with: 51 | build-dir: ${{ github.workspace }}/build 52 | cc: ${{ matrix.compiler.cc }} 53 | cxx: ${{ matrix.compiler.cxx }} 54 | build-type: Release 55 | configure-options: -DWITH_BOX2D=Yes 56 | parallel: 2 57 | 58 | macos: 59 | name: "macOS (${{ matrix.compiler.cc }}, box2d: ${{ matrix.with_box2d }})" 60 | runs-on: macos-latest 61 | 62 | strategy: 63 | fail-fast: false 64 | matrix: 65 | with_box2d: [yes, no] 66 | compiler: 67 | - {cc: clang, cxx: clang++} 68 | 69 | steps: 70 | - uses: actions/checkout@v2 71 | with: 72 | submodules: true 73 | 74 | - name: Install dependencies 75 | run: brew install glew glfw3 glm 76 | 77 | - name: Install Box2D 78 | run: brew install box2d 79 | if: ${{ matrix.with_box2d == 'no' }} 80 | 81 | - name: cmake 82 | uses: ashutoshvarma/action-cmake-build@master 83 | with: 84 | build-dir: ${{ github.workspace }}/build 85 | cc: ${{ matrix.compiler.cc }} 86 | cxx: ${{ matrix.compiler.cxx }} 87 | build-type: Release 88 | configure-options: -DWITH_BOX2D=${{ matrix.with_box2d }} 89 | parallel: 2 90 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Debug/ 2 | Release/ 3 | .vs/ 4 | .idea/ 5 | .build/ 6 | build/ 7 | third_party/ 8 | gamedata/config/*.json 9 | gamedata/demoversions/ 10 | bin/ 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/Box2D"] 2 | path = third_party/Box2D 3 | url = https://github.com/erincatto/Box2D.git -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: bionic 2 | language: cpp 3 | compiler: clang 4 | before_install: 5 | - sudo apt-get update 6 | - sudo apt-get install -y libxml2-dev 7 | - sudo apt install libglew-dev libglfw3-dev libglm-dev libgl1-mesa-dev xorg-dev clang cmake 8 | - sudo apt-get install libopenal-dev 9 | script: 10 | - make 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 4 | 5 | option(WITH_BOX2D "Build with bundled Box 2D" ON) 6 | 7 | project(carnage3d) 8 | include(Carnage3D) 9 | 10 | set(CMAKE_DISABLE_SOURCE_CHANGES ON) 11 | set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) 12 | 13 | add_compile_options(-Wall -Werror -Wimplicit-fallthrough=0 -pipe -fvisibility=hidden) 14 | 15 | set(CMAKE_CXX_FLAGS_PERFORMANCE "${CMAKE_CXX_FLAGS_RELEASE} -march=native") 16 | 17 | if(CMAKE_COMPILER_IS_GNUCXX) 18 | add_compile_options(-fno-strict-aliasing) 19 | endif() 20 | 21 | if(WITH_BOX2D) 22 | message(STATUS "With bundled Box 2D: YES") 23 | else() 24 | message(STATUS "With bundled Box 2D: NO") 25 | endif() 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 jericho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CPUS := $(shell nproc) 2 | PREMAKE_BIN := $(shell which premake5) 3 | ifeq (, $(PREMAKE_BIN)) 4 | PREMAKE_BIN = .build/premake5 5 | endif 6 | 7 | all: build_release 8 | true 9 | 10 | build_sanitize: box2d premake 11 | $(PREMAKE_BIN) gmake --cc=clang --sanitize 12 | make -C .build config=debug_x86_64 -j$(CPUS) 13 | test -d bin || mkdir bin 14 | cp .build/bin/x86_64/Debug/carnage3d bin/carnage3d-debug 15 | 16 | build_debug: box2d premake 17 | $(PREMAKE_BIN) gmake --cc=clang 18 | make -C .build config=debug_x86_64 -j$(CPUS) 19 | test -d bin || mkdir bin 20 | cp .build/bin/x86_64/Debug/carnage3d bin/carnage3d-debug 21 | 22 | build_release: box2d premake 23 | $(PREMAKE_BIN) gmake --cc=clang 24 | make -C .build config=release_x86_64 -j$(CPUS) 25 | test -d bin || mkdir bin 26 | cp .build/bin/x86_64/Release/carnage3d bin/carnage3d-release 27 | 28 | get_demoversion: 29 | mkdir -p gamedata/demoversions 30 | cd gamedata/demoversions 31 | wget "https://web.archive.org/web/20200930091556/https://www.rockstargames.com/gta/demos/gtaects.zip" -O gamedata/demoversions/gtaects.zip 32 | unzip gamedata/demoversions/gtaects.zip -d gamedata/demoversions 33 | 34 | clean: 35 | $(PREMAKE_BIN) gmake --cc=clang 36 | rm -rf third_party/Box2D/build 37 | make -C .build clean 38 | 39 | run: 40 | ./bin/carnage3d-release 41 | 42 | run_demoversion: 43 | ./bin/carnage3d-release -mapname SANB.CMP -gtadata "gamedata/demoversions/GTAECTS/GTADATA" 44 | 45 | builddir: 46 | test -d .build || mkdir .build 47 | 48 | premake: builddir 49 | test -e $(PREMAKE_BIN) || (cd .build && \ 50 | wget https://github.com/premake/premake-core/releases/download/v5.0.0-beta1/premake-5.0.0-beta1-linux.tar.gz && \ 51 | tar xzf premake-5.0.0-beta1-linux.tar.gz && \ 52 | rm premake-5.0.0-beta1-linux.tar.gz) 53 | 54 | box2d: 55 | cd third_party/Box2D && \ 56 | mkdir -p build && cd build && \ 57 | cmake -DCMAKE_BUILD_TYPE=Release -DBOX2D_BUILD_DOCS=Off -DBOX2D_BUILD_UNIT_TESTS=Off -DBOX2D_BUILD_TESTBED=Off .. && \ 58 | cmake --build . 59 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | 2 | __Minor or non-blocker features TODO list__ 3 | 4 | - [ ] Add mirrored doors for some cars 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /carnage3d_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/carnage3d_logo.png -------------------------------------------------------------------------------- /cmake/Carnage3D.cmake: -------------------------------------------------------------------------------- 1 | add_subdirectory(src) 2 | add_executable(carnage3d ${CARNAGE3D_SRC}) 3 | 4 | set_target_properties(carnage3d PROPERTIES CXX_STANDARD 17) 5 | set_target_properties(carnage3d PROPERTIES CXX_STANDARD_REQUIRED ON) 6 | 7 | target_precompile_headers(carnage3d PUBLIC src/stdafx.h) 8 | 9 | if(APPLE) 10 | add_definitions(-D"GL_SILENCE_DEPRECATION") 11 | endif() 12 | find_package(OpenAL REQUIRED) 13 | 14 | if(WITH_BOX2D) 15 | set(BOX2D_BUILD_UNIT_TESTS OFF CACHE BOOL "Skip tests") 16 | set(BOX2D_BUILD_TESTBED OFF CACHE BOOL "Skip testbed") 17 | 18 | add_subdirectory(third_party/Box2D) 19 | 20 | target_include_directories(carnage3d PUBLIC "third_party/Box2D/include/") 21 | target_link_libraries(carnage3d "${CMAKE_BINARY_DIR}/third_party/Box2D/bin/libbox2d.a") 22 | 23 | add_dependencies(carnage3d box2d) 24 | else() 25 | find_package(Box2D 2.4.0 REQUIRED) 26 | target_include_directories(carnage3d PUBLIC ${BOX2D_INCLUDE_DIR}) 27 | target_link_libraries(carnage3d ${BOX2D_LIBRARY}) 28 | endif() 29 | 30 | find_package(OpenGL REQUIRED) 31 | find_package(GLEW REQUIRED) 32 | find_package(glfw3 REQUIRED) 33 | find_package(glm REQUIRED) 34 | 35 | if(NOT(APPLE)) 36 | target_link_libraries(carnage3d stdc++fs) 37 | endif() 38 | 39 | target_include_directories(carnage3d PUBLIC ${OPENAL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}) 40 | target_link_libraries(carnage3d glfw ${GLEW_LIBRARY} ${OPENAL_LIBRARY} ${OPENGL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 41 | -------------------------------------------------------------------------------- /cmake/FindBox2D.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the Box2D library 2 | # BOX2D_FOUND - system has BOX2D 3 | # BOX2D_INCLUDE_DIR - the BOX2D include directory 4 | # BOX2D_LIBRARY - the BOX2D library 5 | 6 | FIND_PATH(BOX2D_INCLUDE_DIR NAMES box2d/box2d.h) 7 | FIND_LIBRARY(BOX2D_LIBRARY NAMES libbox2d.a libbox2d.so) 8 | INCLUDE(FindPackageHandleStandardArgs) 9 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Box2D DEFAULT_MSG BOX2D_LIBRARY BOX2D_INCLUDE_DIR) 10 | MARK_AS_ADVANCED(BOX2D_LIBRARY BOX2D_INCLUDE_DIR) 11 | -------------------------------------------------------------------------------- /cmake/FindGLEW.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the GLEW library 2 | # GLEW_FOUND - system has GLEW 3 | # GLEW_INCLUDE_DIR - the GLEW include directory 4 | # GLEW_LIBRARY - the GLEW library 5 | 6 | FIND_PATH(GLEW_INCLUDE_DIR NAMES GL/glew.h) 7 | SET(_GLEW_STATIC_LIBS libGLEW.a libglew32.a) 8 | SET(_GLEW_SHARED_LIBS libGLEW.dll.a libglew32.dll.a GLEW glew32) 9 | IF(USE_STATIC_LIBS) 10 | FIND_LIBRARY(GLEW_LIBRARY NAMES ${_GLEW_STATIC_LIBS} ${_GLEW_SHARED_LIBS}) 11 | ELSE() 12 | FIND_LIBRARY(GLEW_LIBRARY NAMES ${_GLEW_SHARED_LIBS} ${_GLEW_STATIC_LIBS}) 13 | ENDIF() 14 | INCLUDE(FindPackageHandleStandardArgs) 15 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_DIR) 16 | MARK_AS_ADVANCED(GLEW_LIBRARY GLEW_INCLUDE_DIR) 17 | -------------------------------------------------------------------------------- /gamedata/config/inputs.json.default: -------------------------------------------------------------------------------- 1 | { 2 | "player1": 3 | { 4 | "gamepad_id": "Gamepad1", 5 | "actions": 6 | [ 7 | // common 8 | {"action":"NextWeapon", "keycode":"x", "gpbutton":"LeftBumper"}, 9 | {"action":"PrevWeapon", "keycode":"z", "gpbutton":"RightBumper"}, 10 | // on foot 11 | {"action":"TurnLeft", "keycode":"Left", "gpbutton":"Left"}, 12 | {"action":"TurnRight", "keycode":"Right", "gpbutton":"Right"}, 13 | {"action":"Jump", "keycode":"Space", "gpbutton":"LeftTrigger"}, 14 | {"action":"WalkBackward", "keycode":"Down", "gpbutton":"Down"}, 15 | {"action":"Run", "keycode":"Up", "gpbutton":"Up"}, 16 | {"action":"Shoot", "keycode":"LCtrl", "gpbutton":"B"}, 17 | {"action":"EnterCar", "keycode":"Enter", "gpbutton":"X"}, 18 | {"action":"EnterCarAsPassenger", "keycode":"f", "gpbutton":"A"}, 19 | {"action":"Special", "keycode":"Tab"}, 20 | // in car 21 | {"action":"HandBrake", "keycode":"Space", "gpbutton":"Y"}, 22 | {"action":"Accelerate", "keycode":"Up", "gpbutton":"Up"}, 23 | {"action":"Reverse", "keycode":"Down", "gpbutton":"Down"}, 24 | {"action":"SteerLeft", "keycode":"Left", "gpbutton":"Left"}, 25 | {"action":"SteerRight", "keycode":"Right", "gpbutton":"Right"}, 26 | {"action":"Horn", "keycode":"Tab", "gpbutton":"A"}, 27 | {"action":"LeaveCar", "keycode":"Enter", "gpbutton":"X"} 28 | ] 29 | }, 30 | "player2": 31 | { 32 | "gamepad_id": "Gamepad2" 33 | }, 34 | "player3": 35 | { 36 | "gamepad_id": "Gamepad3" 37 | }, 38 | "player4": 39 | { 40 | "gamepad_id": "Gamepad4" 41 | } 42 | } -------------------------------------------------------------------------------- /gamedata/config/sys_config.json.default: -------------------------------------------------------------------------------- 1 | { 2 | "r_screenDims": "1024 768", 3 | "r_fullscreen": "false", 4 | "r_vsync": "true", 5 | "r_texFiltering": "false", 6 | "g_physicsFps": "60.000", 7 | "mem_enableFrameHeapAllocator": "true", 8 | "a_audioActive": "true", 9 | "g_gtadata": "" 10 | } -------------------------------------------------------------------------------- /gamedata/entities/pedestrians.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ped_type": "player1", 4 | "remap_index": -1, 5 | "fears": [] 6 | }, 7 | { 8 | "ped_type": "player2", 9 | "remap_index": 0, // fixed remap index 10 | "fears": [] 11 | }, 12 | { 13 | "ped_type": "player3", 14 | "remap_index": 1, // fixed remap index 15 | "fears": [] 16 | }, 17 | { 18 | "ped_type": "player4", 19 | "remap_index": 2, // fixed remap index 20 | "fears": [] 21 | }, 22 | { 23 | "ped_type": "civilian", 24 | "remap_type": "random_civilian", 25 | "fears": ["gunShots", "explosions", "deadPeds"] 26 | }, 27 | { 28 | "ped_type": "police", 29 | "remap_index": -1, 30 | "fears": [] 31 | }, 32 | { 33 | "ped_type": "hare_krishnas_gang", 34 | "remap_index": 18, // fixed remap index 35 | "fears": ["gunShots", "explosions", "deadPeds"] 36 | }, 37 | { 38 | "ped_type": "medical", 39 | "remap_index": 0, 40 | "fears": ["gunShots", "explosions", "deadPeds"] 41 | }, 42 | { 43 | "ped_type": "fireman", 44 | "remap_index": 1, 45 | "fears": ["gunShots", "explosions", "deadPeds"] 46 | } 47 | ] -------------------------------------------------------------------------------- /gamedata/fonts/cousine_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/gamedata/fonts/cousine_regular.ttf -------------------------------------------------------------------------------- /gamedata/fonts/karla_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/gamedata/fonts/karla_regular.ttf -------------------------------------------------------------------------------- /gamedata/fonts/nunito_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/gamedata/fonts/nunito_regular.ttf -------------------------------------------------------------------------------- /gamedata/shaders/city_mesh.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | uniform usampler2D tex_1; // block frames table 8 | uniform usampler2D tex_2; // palette indices table 9 | 10 | // attributes 11 | in vec3 in_pos0; 12 | in vec3 in_texcoord0; 13 | in uint in_color0; // remap index 14 | in uint in_color1; // transparency flag 15 | 16 | // pass to fragment shader 17 | out vec2 Texcoord; 18 | flat out float Transparency; 19 | flat out float BlockTextureIndex; 20 | flat out float PaletteIndex; 21 | 22 | const float MeshHeightModifier = -0.15; // shift the geometry level slightly below the sprites to remove the zfighting 23 | 24 | // entry point 25 | void main() 26 | { 27 | Texcoord = in_texcoord0.xy; 28 | Transparency = float(in_color1); 29 | 30 | // get real block tile index 31 | BlockTextureIndex = float(texelFetch(tex_1, ivec2(int(in_texcoord0.z + 0.5), 0), 0).r); 32 | 33 | // get palette index for block tile 34 | PaletteIndex = float(texelFetch(tex_2, ivec2(int(4.0 * BlockTextureIndex + float(in_color0)), 0), 0).r); 35 | 36 | vec4 vertexPosition = view_projection_matrix * vec4( 37 | in_pos0.x, 38 | in_pos0.y + MeshHeightModifier, 39 | in_pos0.z, 1.0); 40 | 41 | gl_Position = vertexPosition; 42 | } 43 | 44 | #endif 45 | 46 | ////////////////////////////////////////////////////////////////////////// 47 | #ifdef FRAGMENT_SHADER 48 | 49 | uniform usampler2DArray tex_0; // block texture 50 | uniform sampler2D tex_3; // palettes table 51 | 52 | // passed from vertex shader 53 | in vec2 Texcoord; 54 | flat in float Transparency; 55 | flat in float BlockTextureIndex; 56 | flat in float PaletteIndex; 57 | 58 | // result 59 | out vec4 FinalColor; 60 | 61 | vec4 fetchBlockTexel(vec2 tc) 62 | { 63 | // get color index in palette 64 | float pal_color = float(texture(tex_0, vec3(tc.x, tc.y, BlockTextureIndex)).r); 65 | 66 | if (Transparency > 0.5 && pal_color < 0.5) // transparent 67 | discard; 68 | 69 | vec4 texelColor = texelFetch(tex_3, ivec2(int(pal_color), int(PaletteIndex)), 0); 70 | texelColor.a = 1.0; 71 | return texelColor; 72 | } 73 | 74 | // entry point 75 | void main() 76 | { 77 | vec4 texelColor = fetchBlockTexel(Texcoord); 78 | FinalColor = clamp(texelColor, 0.0, 1.0); 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /gamedata/shaders/debug.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | 8 | // attributes 9 | in vec3 in_pos0; 10 | in vec4 in_color0; 11 | 12 | // pass to fragment shader 13 | out vec4 FragColor; 14 | 15 | // entry point 16 | void main() 17 | { 18 | FragColor = in_color0; 19 | 20 | vec4 vertexPosition = view_projection_matrix * vec4(in_pos0, 1.0); 21 | gl_Position = vertexPosition; 22 | } 23 | 24 | #endif 25 | 26 | ////////////////////////////////////////////////////////////////////////// 27 | #ifdef FRAGMENT_SHADER 28 | 29 | // passed from vertex shader 30 | in vec4 FragColor; 31 | 32 | // result 33 | out vec4 FinalColor; 34 | 35 | // entry point 36 | void main() 37 | { 38 | FinalColor = FragColor; 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /gamedata/shaders/gui.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | 8 | // attributes 9 | in vec2 in_pos0; 10 | in vec2 in_texcoord0; 11 | in vec4 in_color0; 12 | 13 | // pass to fragment shader 14 | out vec2 Texcoord; 15 | out vec4 FragColor; 16 | 17 | // entry point 18 | void main() 19 | { 20 | Texcoord = in_texcoord0; 21 | FragColor = in_color0; 22 | 23 | vec4 vertexPosition = view_projection_matrix * vec4(in_pos0, 0.0, 1.0); 24 | gl_Position = vertexPosition; 25 | } 26 | 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////// 30 | #ifdef FRAGMENT_SHADER 31 | 32 | uniform sampler2D tex_0; 33 | 34 | // passed from vertex shader 35 | in vec2 Texcoord; 36 | in vec4 FragColor; 37 | 38 | // result 39 | out vec4 FinalColor; 40 | 41 | // entry point 42 | void main() 43 | { 44 | vec4 pixelColor = texture(tex_0, Texcoord) * FragColor; 45 | FinalColor = pixelColor; 46 | } 47 | 48 | #endif -------------------------------------------------------------------------------- /gamedata/shaders/particle.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | uniform vec3 camera_position; 8 | 9 | // attributes 10 | in vec4 in_pos0; // position + size 11 | in vec4 in_color0; 12 | 13 | // pass to fragment shader 14 | out vec4 FragColor; 15 | 16 | // local constants 17 | const float minPointScale = 0.1; 18 | const float maxPointScale = 0.7; 19 | const float maxDistance = 50.0; 20 | 21 | // entry point 22 | void main() 23 | { 24 | FragColor = in_color0; 25 | 26 | float distanceFromCamera = distance(in_pos0.xyz, camera_position); 27 | float pointScale = 1.0 - (distanceFromCamera / maxDistance); 28 | pointScale = clamp(pointScale, minPointScale, maxPointScale); 29 | 30 | gl_PointSize = in_pos0.w * pointScale; 31 | gl_Position = view_projection_matrix * vec4(in_pos0.xyz, 1.0); 32 | } 33 | 34 | #endif 35 | 36 | ////////////////////////////////////////////////////////////////////////// 37 | #ifdef FRAGMENT_SHADER 38 | 39 | uniform sampler2D tex_0; 40 | 41 | // passed from vertex shader 42 | in vec4 FragColor; 43 | 44 | // result 45 | out vec4 FinalColor; 46 | 47 | // entry point 48 | void main() 49 | { 50 | FinalColor = FragColor; 51 | } 52 | 53 | #endif -------------------------------------------------------------------------------- /gamedata/shaders/sprites.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | 8 | // attributes 9 | in vec3 in_pos0; 10 | in vec2 in_texcoord0; 11 | in uint in_color0; // palette index 12 | in uvec2 in_textureSize; // sprite texture size in pixels 13 | 14 | // pass to fragment shader 15 | out vec2 Texcoord; 16 | out vec3 Position; 17 | flat out uint PaletteIndex; 18 | out vec2 SpriteTextureSize; 19 | out vec2 SpriteTexelSize; 20 | 21 | // entry point 22 | void main() 23 | { 24 | Texcoord = in_texcoord0; 25 | Position = in_pos0; 26 | PaletteIndex = in_color0; 27 | SpriteTextureSize = vec2(in_textureSize); 28 | SpriteTexelSize = vec2(1.0 / SpriteTextureSize.x, 1.0 / SpriteTextureSize.y); 29 | 30 | vec4 vertexPosition = view_projection_matrix * vec4(in_pos0, 1.0); 31 | gl_Position = vertexPosition; 32 | } 33 | 34 | #endif 35 | 36 | ////////////////////////////////////////////////////////////////////////// 37 | #ifdef FRAGMENT_SHADER 38 | 39 | uniform usampler2D tex_0; 40 | uniform sampler2D tex_3; // palettes table 41 | 42 | // passed from vertex shader 43 | in vec2 Texcoord; 44 | in vec3 Position; 45 | flat in uint PaletteIndex; 46 | in vec2 SpriteTextureSize; 47 | in vec2 SpriteTexelSize; 48 | 49 | // result 50 | out vec4 FinalColor; 51 | 52 | vec4 fetchSpriteTexel(vec2 tc) 53 | { 54 | // get color index in palette 55 | float pal_color = float(texture(tex_0, tc).r); 56 | 57 | if (pal_color < 0.5) // transparent 58 | discard; 59 | 60 | // fetch pixel color 61 | vec4 texelColor = texelFetch(tex_3, ivec2(int(pal_color), int(PaletteIndex)), 0); 62 | texelColor.a = 1.0; 63 | return texelColor; 64 | } 65 | 66 | // entry point 67 | void main() 68 | { 69 | vec4 texelColor = fetchSpriteTexel(Texcoord); 70 | FinalColor = clamp(texelColor, 0.0, 1.0); 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /gamedata/shaders/texture_color.glsl: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | #ifdef VERTEX_SHADER 4 | 5 | // constants 6 | uniform mat4 view_projection_matrix; 7 | 8 | // attributes 9 | in vec3 in_pos0; 10 | in vec2 in_texcoord0; 11 | in vec4 in_color0; 12 | 13 | // pass to fragment shader 14 | out vec2 Texcoord; 15 | out vec4 FragColor; 16 | out vec3 Position; 17 | 18 | // entry point 19 | void main() 20 | { 21 | Texcoord = in_texcoord0; 22 | Position = in_pos0; 23 | FragColor = in_color0; 24 | 25 | vec4 vertexPosition = view_projection_matrix * vec4(in_pos0, 1.0); 26 | gl_Position = vertexPosition; 27 | } 28 | 29 | #endif 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | #ifdef FRAGMENT_SHADER 33 | 34 | uniform sampler2D tex_0; 35 | 36 | // passed from vertex shader 37 | in vec2 Texcoord; 38 | in vec4 FragColor; 39 | in vec3 Position; 40 | 41 | // result 42 | out vec4 FinalColor; 43 | 44 | // entry point 45 | void main() 46 | { 47 | vec4 pixelColor = texture(tex_0, Texcoord); 48 | //if (pixelColor.a < 1.0) // old school alpha test 49 | // discard; 50 | 51 | FinalColor = clamp(pixelColor, 0.0, 1.0); 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | newoption { 2 | trigger = "sanitize", 3 | description = "enable sanitizers" 4 | } 5 | 6 | workspace "carnage3d" 7 | location '.build' 8 | configurations { "Debug", "Release" } 9 | cppdialect 'C++17' 10 | 11 | configuration { "linux", "gmake" } 12 | buildoptions { "-Wno-switch" } 13 | 14 | if _OPTIONS["sanitize"] then 15 | buildoptions { "-fsanitize=address", "-fsanitize=undefined" } 16 | linkoptions { "-fsanitize=address", "-fsanitize=undefined" } 17 | end 18 | 19 | filter 'system:linux' 20 | platforms { 'x86_64' } 21 | 22 | project "GLFW" 23 | kind "StaticLib" 24 | language "C" 25 | files 26 | { 27 | "src/GLFW/internal.h", 28 | "src/GLFWglfw_config.h", 29 | "src/GLFW/glfw3.h", 30 | "src/GLFW/glfw3native.h", 31 | "src/GLFW/context.c", 32 | "src/GLFW/init.c", 33 | "src/GLFW/input.c", 34 | "src/GLFW/monitor.c", 35 | "src/GLFW/vulkan.c", 36 | "src/GLFW/window.c", 37 | "src/GLFW/x11_platform.h", 38 | "src/GLFW/xkb_unicode.h", 39 | "src/GLFW/linux_joystick.h", 40 | "src/GLFW/posix_time.h", 41 | "src/GLFW/glx_context.h", 42 | "src/GLFW/egl_context.h", 43 | "src/GLFW/x11_init.c", 44 | "src/GLFW/x11_monitor.c", 45 | "src/GLFW/x11_window.c", 46 | "src/GLFW/glx_context.h", 47 | "src/GLFW/glx_context.c", 48 | "src/GLFW/glext.h", 49 | "src/GLFW/xkb_unicode.c", 50 | "src/GLFW/linux_joystick.c", 51 | "src/GLFW/posix_time.c", 52 | "src/GLFW/glx_context.c", 53 | "src/GLFW/egl_context.c", 54 | "src/GLFW/posix_thread.h", 55 | "src/GLFW/posix_thread.c", 56 | "src/GLFW/osmesa_context.c", 57 | "src/GLFW/osmesa_context.h" 58 | } 59 | includedirs { "GLFW" } 60 | links { "GL", "GLEW", "stdc++fs", "X11", "Xrandr", "Xinerama", "Xcursor", "pthread", "dl" } 61 | 62 | filter { "configurations:Debug" } 63 | defines { "DEBUG", "_DEBUG" } 64 | symbols "On" 65 | 66 | filter { "configurations:Release" } 67 | defines { "NDEBUG" } 68 | optimize "On" 69 | 70 | project "carnage3d" 71 | kind "WindowedApp" 72 | language "C++" 73 | pchheader "src/stdafx.h" 74 | pchsource "src/stdafx.cpp" 75 | files 76 | { 77 | "src/*.h", 78 | "src/*.cpp" 79 | } 80 | includedirs { "third_party/Box2D/include" } 81 | includedirs { "GLFW" } 82 | links { "GL", "GLEW", "stdc++fs", "openal", "box2d", "X11", "Xrandr", "Xinerama", "Xcursor", "pthread", "dl", "GLFW" } 83 | 84 | filter { "configurations:Debug" } 85 | defines { "DEBUG", "_DEBUG" } 86 | symbols "On" 87 | libdirs { "third_party/Box2D/build/bin" } 88 | 89 | filter { "configurations:Release" } 90 | defines { "NDEBUG" } 91 | optimize "On" 92 | libdirs { "third_party/Box2D/build/bin" } 93 | -------------------------------------------------------------------------------- /screenshots/SplitScreenTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/screenshots/SplitScreenTest.png -------------------------------------------------------------------------------- /screenshots/WorksOnLinux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/screenshots/WorksOnLinux.png -------------------------------------------------------------------------------- /src/.clang-format: -------------------------------------------------------------------------------- 1 | IndentWidth: 4 2 | TabWidth: 4 3 | UseTab: Never 4 | -------------------------------------------------------------------------------- /src/AiCharacterController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CharacterController.h" 4 | #include "Pedestrian.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | enum ePedestrianAiMode 9 | { 10 | ePedestrianAiMode_None, 11 | ePedestrianAiMode_Disabled, 12 | ePedestrianAiMode_Wandering, 13 | ePedestrianAiMode_Panic, 14 | ePedestrianAiMode_DrivingCar, 15 | ePedestrianAiMode_FollowTarget, 16 | }; 17 | 18 | enum ePedestrianAiState 19 | { 20 | ePedestrianAiState_Idle, 21 | ePedestrianAiState_RunToLocation, 22 | ePedestrianAiState_WalkToLocation, 23 | }; 24 | 25 | enum PedestrianAiFlags 26 | { 27 | PedestrianAiFlags_None = 0, 28 | 29 | PedestrianAiFlags_LemmingBehavior = BIT(0), // can suicide 30 | PedestrianAiFlags_FollowHumanCharacter = BIT(1), 31 | }; 32 | 33 | decl_enum_as_flags(PedestrianAiFlags); 34 | 35 | ////////////////////////////////////////////////////////////////////////// 36 | 37 | // defines ai character controller 38 | class AiCharacterController final: public CharacterController 39 | { 40 | public: 41 | AiCharacterController(Pedestrian* character); 42 | 43 | // process controller logic 44 | void DebugDraw(DebugRenderer& debugRender) override; 45 | void OnCharacterUpdateFrame() override; 46 | 47 | void ChangeAiFlags(PedestrianAiFlags enableFlags, PedestrianAiFlags disableFlags); 48 | bool HasAiFlags(PedestrianAiFlags aiFlags) const; 49 | 50 | // objectives 51 | void FollowPedestrian(Pedestrian* pedestrian); 52 | 53 | private: 54 | void UpdatePanic(); 55 | void UpdateWandering(); 56 | void UpdateDrivingCar(); 57 | void UpdateFollowTarget(); 58 | 59 | void StartPanic(); 60 | void StartWandering(); 61 | void StartDrivingCar(); 62 | void StartFollowTarget(); 63 | 64 | bool TryFollowHumanCharacterNearby(); 65 | 66 | // walk/run 67 | bool ChooseWalkWaypoint(bool isPanic); 68 | bool ContinueWalkToWaypoint(float distance); 69 | 70 | // drive 71 | bool ChooseDriveWaypoint(); 72 | bool ContinueDriveToWaypoint(); 73 | void StopDriving(); 74 | 75 | // utility 76 | bool ScanForThreats(); 77 | bool ScanForGunshots(); 78 | bool ScanForExplosions(); 79 | 80 | private: 81 | ePedestrianAiMode mAiMode = ePedestrianAiMode_None; 82 | ePedestrianAiState mAiState = ePedestrianAiState_Idle; 83 | 84 | glm::vec2 mDestinationPoint; 85 | float mDefaultNearDistance; 86 | 87 | PedestrianAiFlags mAiFlags = PedestrianAiFlags_None; 88 | 89 | PedestrianHandle mFollowPedestrian; 90 | float mFollowNearDistance; 91 | float mFollowFarDistance; 92 | 93 | bool mRunToTarget = false; 94 | }; -------------------------------------------------------------------------------- /src/AiManager.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AiManager.h" 3 | #include "AiCharacterController.h" 4 | #include "Pedestrian.h" 5 | 6 | AiManager gAiManager; 7 | 8 | AiManager::AiManager() 9 | { 10 | } 11 | 12 | void AiManager::UpdateFrame() 13 | { 14 | // update all character controllers 15 | bool hasInactiveControllers = false; 16 | for (size_t iController = 0, Count = mCharacterControllers.size(); iController < Count; ++iController) 17 | { 18 | AiCharacterController* currController = mCharacterControllers[iController]; 19 | if (!currController->IsControllerActive()) 20 | { 21 | SafeDelete(mCharacterControllers[iController]); 22 | hasInactiveControllers = true; 23 | } 24 | } 25 | if (hasInactiveControllers) 26 | { 27 | cxx::erase_elements(mCharacterControllers, nullptr); 28 | } 29 | } 30 | 31 | void AiManager::DebugDraw(DebugRenderer& debugRender) 32 | { 33 | for (AiCharacterController* currAi: mCharacterControllers) 34 | { 35 | currAi->DebugDraw(debugRender); 36 | } 37 | } 38 | 39 | void AiManager::ReleaseAiControllers() 40 | { 41 | for (AiCharacterController* currController: mCharacterControllers) 42 | { 43 | delete currController; 44 | } 45 | 46 | mCharacterControllers.clear(); 47 | } 48 | 49 | AiCharacterController* AiManager::CreateAiController(Pedestrian* pedestrian) 50 | { 51 | if (pedestrian == nullptr) 52 | { 53 | debug_assert(false); 54 | return nullptr; 55 | } 56 | 57 | if (pedestrian->mController) 58 | { 59 | debug_assert(false); 60 | return nullptr; 61 | } 62 | 63 | AiCharacterController* controller = new AiCharacterController(pedestrian); 64 | mCharacterControllers.push_back(controller); 65 | return controller; 66 | } 67 | 68 | void AiManager::ReleaseAiController(AiCharacterController* controller) 69 | { 70 | if (controller == nullptr) 71 | { 72 | debug_assert(false); 73 | return; 74 | } 75 | 76 | cxx::erase_elements(mCharacterControllers, controller); 77 | delete controller; 78 | } 79 | -------------------------------------------------------------------------------- /src/AiManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class AiCharacterController; 4 | class DebugRenderer; 5 | 6 | // Artificial Intelligence manager class 7 | class AiManager final: public cxx::noncopyable 8 | { 9 | public: 10 | AiManager(); 11 | 12 | // Update all ai character controllers 13 | void UpdateFrame(); 14 | void DebugDraw(DebugRenderer& debugRender); 15 | 16 | // Create ai controller for character 17 | // @param pedestrian: Character to control 18 | AiCharacterController* CreateAiController(Pedestrian* pedestrian); 19 | 20 | // Destroy ai character controller 21 | void ReleaseAiControllers(); 22 | void ReleaseAiController(AiCharacterController* controller); 23 | 24 | private: 25 | std::vector mCharacterControllers; 26 | }; 27 | 28 | extern AiManager gAiManager; -------------------------------------------------------------------------------- /src/AiPedestrianBehavior.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AiPedestrianBehavior.h" 3 | #include "Pedestrian.h" 4 | 5 | AiPedestrianBehavior::AiPedestrianBehavior(AiCharacterController* aiController) 6 | : mAiController(aiController) 7 | { 8 | debug_assert(mAiController); 9 | } 10 | 11 | AiPedestrianBehavior::~AiPedestrianBehavior() 12 | { 13 | } 14 | 15 | void AiPedestrianBehavior::ActivateBehavior() 16 | { 17 | OnActivateBehavior(); 18 | } 19 | 20 | void AiPedestrianBehavior::ShutdownBehavior() 21 | { 22 | OnShutdownBehavior(); 23 | } 24 | 25 | void AiPedestrianBehavior::UpdateBehavior() 26 | { 27 | } 28 | 29 | void AiPedestrianBehavior::OnActivateBehavior() 30 | { 31 | } 32 | 33 | void AiPedestrianBehavior::OnShutdownBehavior() 34 | { 35 | } -------------------------------------------------------------------------------- /src/AiPedestrianBehavior.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class AiCharacterController; 4 | 5 | class AiPedestrianBehavior: public cxx::noncopyable 6 | { 7 | public: 8 | AiPedestrianBehavior(AiCharacterController* aiController); 9 | virtual ~AiPedestrianBehavior(); 10 | 11 | void ActivateBehavior(); 12 | void ShutdownBehavior(); 13 | void UpdateBehavior(); 14 | 15 | protected: 16 | // overridables 17 | virtual void OnActivateBehavior(); 18 | virtual void OnShutdownBehavior(); 19 | 20 | protected: 21 | 22 | protected: 23 | AiCharacterController* mAiController = nullptr; 24 | }; -------------------------------------------------------------------------------- /src/AudioDataStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Interface class of streaming audio data 4 | class AudioDataStream: public cxx::noncopyable 5 | { 6 | public: 7 | virtual ~AudioDataStream() 8 | { 9 | } 10 | 11 | // get media format info 12 | virtual int GetChannelsCount() const = 0; 13 | virtual int GetSampleRate() const = 0; 14 | virtual int GetSampleBits() const = 0; 15 | virtual int GetSamplesCount() const = 0; 16 | 17 | // reading pcm samples data from stream 18 | virtual int ReadPCMSamples(int samples, void* buffer) = 0; 19 | virtual bool SeekPCMFromBeg(int samples) = 0; 20 | virtual bool SeekPCMFromEnd(int samples) = 0; 21 | virtual bool SeekPCMFromCur(int samples) = 0; 22 | virtual bool EndOfStream() const = 0; 23 | }; 24 | 25 | // open audio stream 26 | extern AudioDataStream* OpenAudioFileStream(const char* fileName); -------------------------------------------------------------------------------- /src/AudioDevice.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AudioSource.h" 4 | #include "AudioListener.h" 5 | #include "OpenALDefs.h" 6 | 7 | // Hardware audio device 8 | class AudioDevice final: public cxx::noncopyable 9 | { 10 | friend class AudioSource; 11 | 12 | public: 13 | // readonly 14 | AudioDeviceCaps mDeviceCaps; 15 | 16 | public: 17 | ~AudioDevice(); 18 | 19 | // Setup audio device internal resources 20 | bool Initialize(); 21 | void Deinit(); 22 | bool IsInitialized() const; 23 | 24 | // Update active audio sources 25 | void UpdateFrame(); 26 | 27 | // Setup device params 28 | bool SetMasterVolume(float gainValue); 29 | 30 | // Create virtual audio listener instance 31 | AudioListener* CreateAudioListener(); 32 | 33 | // Create sample buffer instance 34 | AudioSampleBuffer* CreateSampleBuffer(int sampleRate, int bitsPerSample, int channelsCount, int dataLength, const void* bufferData); 35 | AudioSampleBuffer* CreateSampleBuffer(); 36 | 37 | // Create audio source instance 38 | AudioSource* CreateAudioSource(); 39 | 40 | // Free virtual audio listener instance 41 | void DestroyAudioListener(AudioListener* audioListener); 42 | 43 | // Free sample buffer instance, it should not be used by anyone at this point 44 | // @param audioBuffer: Pointer 45 | void DestroySampleBuffer(AudioSampleBuffer* audioBuffer); 46 | 47 | // Free audio source instance, does not destroys attached audio buffer 48 | // @param audioInstance: Pointer 49 | void DestroyAudioSource(AudioSource* audioSource); 50 | 51 | private: 52 | void QueryAudioDeviceCaps(); 53 | void UpdateSourcesPositions(); 54 | 55 | // Find sample buffer by internal identifier 56 | AudioSampleBuffer* GetSampleBufferWithID(unsigned int bufferID) const; 57 | 58 | // Find source by internal identifier 59 | AudioSource* GetAudioSourceWithID(unsigned int sourceID) const; 60 | 61 | private: 62 | ALCcontext* mContext = nullptr; 63 | ALCdevice* mDevice = nullptr; 64 | // allocated objects 65 | std::vector mAllListeners; 66 | std::vector mAllSources; 67 | std::vector mAllBuffers; 68 | // objects pools 69 | cxx::object_pool mBuffersPool; 70 | cxx::object_pool mSourcesPool; 71 | }; 72 | 73 | extern AudioDevice gAudioDevice; -------------------------------------------------------------------------------- /src/AudioListener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Represents audio listener in 3d space 4 | class AudioListener final: public cxx::noncopyable 5 | { 6 | friend class AudioDevice; 7 | 8 | public: 9 | // readonly 10 | glm::vec3 mPosition; 11 | 12 | public: 13 | AudioListener() 14 | : mPosition(0.0f, 0.0f, 1.0f) 15 | { 16 | } 17 | // Set audio listener position in 3d space 18 | void SetPosition(const glm::vec3& position) 19 | { 20 | mPosition = position; 21 | } 22 | void SetPosition2(const glm::vec2& position) 23 | { 24 | mPosition.x = position.x; 25 | mPosition.y = position.y; 26 | } 27 | }; -------------------------------------------------------------------------------- /src/AudioSampleArchive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SfxDefs.h" 4 | 5 | // Contains audio entries within SDT/RAW archive 6 | class AudioSampleArchive final: public cxx::noncopyable 7 | { 8 | public: 9 | 10 | // Audio entry information within archive 11 | struct SampleEntry 12 | { 13 | unsigned int mDataOffset = 0; 14 | unsigned int mDataLength = 0; 15 | unsigned int mSampleRate = 0; 16 | unsigned int mBitsPerSample = 0; 17 | unsigned int mChannelsCount = 0; 18 | unsigned char* mData = nullptr; 19 | }; 20 | 21 | public: 22 | AudioSampleArchive() = default; 23 | ~AudioSampleArchive(); 24 | 25 | // Load audio entries from archive 26 | // @param archiveName: Achive name without extension 27 | bool LoadArchive(const std::string& archiveName); 28 | void FreeArchive(); 29 | bool IsLoaded() const; 30 | 31 | // Reading audio entries 32 | bool GetEntryInfo(int entryIndex, SampleEntry& output) const; 33 | bool GetEntryData(int entryIndex, SampleEntry& output); 34 | int GetEntriesCount() const; 35 | 36 | // Unload entry data from memory 37 | void FreeEntryData(int entryIndex); 38 | 39 | // Save all audio entries to wav files 40 | void DumpSounds(const std::string& outputDirectory); 41 | 42 | private: 43 | std::vector mAudioEntries; 44 | std::ifstream mRawDataStream; 45 | }; -------------------------------------------------------------------------------- /src/Box2D_Helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameObject.h" 4 | #include "PhysicsBody.h" 5 | #include "Collider.h" 6 | 7 | // b2Vec <- -> glm::vec2 conversion 8 | 9 | ////////////////////////////////////////////////////////////////////////// 10 | 11 | inline glm::vec2 convert_vec2(const b2Vec2& vector_value) 12 | { 13 | return { vector_value.x, vector_value.y }; 14 | } 15 | 16 | inline b2Vec2 convert_vec2(const glm::vec2& vector_value) 17 | { 18 | return { vector_value.x, vector_value.y }; 19 | } 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | inline Collider* b2Fixture_get_collider(b2Fixture* fixture) 24 | { 25 | debug_assert(fixture); 26 | Collider* collisionShape = (Collider*) fixture->GetUserData().pointer; 27 | 28 | return collisionShape; 29 | } 30 | 31 | inline PhysicsBody* b2Fixture_get_physics_body(b2Fixture* fixture) 32 | { 33 | debug_assert(fixture); 34 | 35 | PhysicsBody* physicsBoxy = (PhysicsBody*) fixture->GetBody()->GetUserData().pointer; 36 | return physicsBoxy; 37 | } 38 | 39 | inline GameObject* b2Fixture_get_game_object(b2Fixture* fixture) 40 | { 41 | debug_assert(fixture); 42 | 43 | PhysicsBody* physicsBoxy = (PhysicsBody*) fixture->GetBody()->GetUserData().pointer; 44 | GameObject* gameObject = nullptr; 45 | if (physicsBoxy) 46 | { 47 | gameObject = physicsBoxy->mGameObject; 48 | } 49 | return gameObject; 50 | } 51 | 52 | ////////////////////////////////////////////////////////////////////////// 53 | -------------------------------------------------------------------------------- /src/BroadcastEventsManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "GameObject.h" 5 | #include "Pedestrian.h" 6 | 7 | ////////////////////////////////////////////////////////////////////////// 8 | 9 | // When something is happening on game map broadcast event gets fired up 10 | enum eBroadcastEvent 11 | { 12 | eBroadcastEvent_GunShot, 13 | eBroadcastEvent_PedestrianInjured, 14 | eBroadcastEvent_PedestrianDead, 15 | eBroadcastEvent_StealCar, 16 | eBroadcastEvent_Explosion, 17 | eBroadcastEvent_CarBurns, 18 | 19 | eBroadcastEvent_StartDriveCar, 20 | eBroadcastEvent_StopDriveCar, 21 | }; 22 | 23 | decl_enum_strings(eBroadcastEvent); 24 | 25 | ////////////////////////////////////////////////////////////////////////// 26 | 27 | enum eBroadcastEventSubject 28 | { 29 | eBroadcastEventSubject_None, 30 | eBroadcastEventSubject_Pedestrian, 31 | eBroadcastEventSubject_Vehicle, 32 | eBroadcastEventSubject_Object 33 | }; 34 | 35 | decl_enum_strings(eBroadcastEventSubject); 36 | 37 | ////////////////////////////////////////////////////////////////////////// 38 | 39 | // Broadcast event data 40 | struct BroadcastEvent 41 | { 42 | public: 43 | BroadcastEvent() = default; 44 | 45 | public: 46 | eBroadcastEvent mEventType; 47 | eBroadcastEventSubject mEventSubject; 48 | 49 | float mEventTimestamp; // time when event was created 50 | float mEventDurationTime; // how long event lives, seconds 51 | 52 | glm::vec2 mPosition; // position in the world where event did happen, meters 53 | 54 | GameObjectHandle mSubject; // object that was affected 55 | PedestrianHandle mCharacter; // character which causes event 56 | }; 57 | 58 | ////////////////////////////////////////////////////////////////////////// 59 | 60 | // Broadcast events manager 61 | class BroadcastEventsManager final: public cxx::noncopyable 62 | { 63 | public: 64 | BroadcastEventsManager(); 65 | 66 | void ClearEvents(); 67 | void UpdateFrame(); 68 | // broadcasting event 69 | void RegisterEvent(eBroadcastEvent eventType, GameObject* subject, Pedestrian* character, float durationTime); 70 | void RegisterEvent(eBroadcastEvent eventType, const glm::vec2& position, float durationTime); 71 | // Finds event with specific type but don't removes it from list 72 | bool PeekEvent(eBroadcastEvent eventType, BroadcastEvent& outputEventData) const; 73 | bool PeekClosestEvent(eBroadcastEvent eventType, const glm::vec2& position, BroadcastEvent& outputEventData) const; 74 | // Finds event with specific type and removes it from list 75 | bool GetEvent(eBroadcastEvent eventType, BroadcastEvent& outputEventData); 76 | bool GetClosestEvent(eBroadcastEvent eventType, const glm::vec2& position, BroadcastEvent& outputEventData); 77 | 78 | private: 79 | std::vector mEventsList; 80 | }; 81 | 82 | extern BroadcastEventsManager gBroadcastEvents; -------------------------------------------------------------------------------- /src/CameraController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class GameCamera; 4 | 5 | // base camera controller interface 6 | class CameraController 7 | { 8 | public: 9 | virtual ~CameraController() 10 | { 11 | } 12 | // reset camera and controller both to default state 13 | virtual void Setup(GameCamera* gameCamera) 14 | { 15 | } 16 | // handle camera controller logic 17 | virtual void UpdateFrame() 18 | { 19 | } 20 | // handle input events 21 | // @param inputEvent: Event data 22 | virtual void InputEvent(KeyInputEvent& inputEvent) 23 | { 24 | } 25 | virtual void InputEvent(MouseButtonInputEvent& inputEvent) 26 | { 27 | } 28 | virtual void InputEvent(MouseMovedInputEvent& inputEvent) 29 | { 30 | } 31 | virtual void InputEvent(MouseScrollInputEvent& inputEvent) 32 | { 33 | } 34 | virtual void InputEventLost() 35 | { 36 | } 37 | 38 | public: 39 | GameCamera* mCamera = nullptr; 40 | }; -------------------------------------------------------------------------------- /src/Carnage3D.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.645 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Carnage3D", "Carnage3D.vcxproj", "{169827B7-D0C3-481E-900C-A57549CBD984}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {4A74163F-7D76-46EB-92BF-05C50173D846} = {4A74163F-7D76-46EB-92BF-05C50173D846} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Box2D", "Box2D\Box2D.vcxproj", "{8701FDAE-68BB-4D20-851B-9E7B1B5DAE62}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLFW", "GLFW\GLFW.vcxproj", "{4A74163F-7D76-46EB-92BF-05C50173D846}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x86 = Debug|x86 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {169827B7-D0C3-481E-900C-A57549CBD984}.Debug|x86.ActiveCfg = Debug|Win32 22 | {169827B7-D0C3-481E-900C-A57549CBD984}.Debug|x86.Build.0 = Debug|Win32 23 | {169827B7-D0C3-481E-900C-A57549CBD984}.Release|x86.ActiveCfg = Release|Win32 24 | {169827B7-D0C3-481E-900C-A57549CBD984}.Release|x86.Build.0 = Release|Win32 25 | {8701FDAE-68BB-4D20-851B-9E7B1B5DAE62}.Debug|x86.ActiveCfg = Debug|Win32 26 | {8701FDAE-68BB-4D20-851B-9E7B1B5DAE62}.Debug|x86.Build.0 = Debug|Win32 27 | {8701FDAE-68BB-4D20-851B-9E7B1B5DAE62}.Release|x86.ActiveCfg = Release|Win32 28 | {8701FDAE-68BB-4D20-851B-9E7B1B5DAE62}.Release|x86.Build.0 = Release|Win32 29 | {4A74163F-7D76-46EB-92BF-05C50173D846}.Debug|x86.ActiveCfg = Debug|Win32 30 | {4A74163F-7D76-46EB-92BF-05C50173D846}.Debug|x86.Build.0 = Debug|Win32 31 | {4A74163F-7D76-46EB-92BF-05C50173D846}.Release|x86.ActiveCfg = Release|Win32 32 | {4A74163F-7D76-46EB-92BF-05C50173D846}.Release|x86.Build.0 = Release|Win32 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | GlobalSection(ExtensibilityGlobals) = postSolution 38 | SolutionGuid = {0A5A8077-FC9D-40E3-941D-784212401FCE} 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /src/CarnageGame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameMapManager.h" 4 | #include "GameObjectsManager.h" 5 | #include "HumanPlayer.h" 6 | #include "GameplayGamestate.h" 7 | #include "MainMenuGamestate.h" 8 | 9 | // top level game application controller 10 | class CarnageGame final: public InputEventsHandler 11 | { 12 | friend class GameplayGamestate; 13 | friend class MainMenuGamestate; 14 | 15 | public: 16 | cxx::randomizer mGameRand; 17 | 18 | // readonly 19 | GenericGamestate* mCurrentGamestate = nullptr; 20 | HumanPlayer* mHumanPlayers[GAME_MAX_PLAYERS]; 21 | 22 | public: 23 | // Setup resources and switch to initial game state 24 | bool Initialize(); 25 | 26 | // Cleanup current state and finish game 27 | void Deinit(); 28 | 29 | // Common processing 30 | void UpdateFrame(); 31 | 32 | // override InputEventsHandler 33 | void InputEvent(KeyInputEvent& inputEvent) override; 34 | void InputEvent(MouseButtonInputEvent& inputEvent) override; 35 | void InputEvent(MouseMovedInputEvent& inputEvent) override; 36 | void InputEvent(MouseScrollInputEvent& inputEvent) override; 37 | void InputEvent(KeyCharEvent& inputEvent) override; 38 | void InputEvent(GamepadInputEvent& inputEvent) override; 39 | void InputEventLost() override; 40 | 41 | // Current game state 42 | bool IsMenuGameState() const; 43 | bool IsInGameState() const; 44 | 45 | // Initialize player data 46 | void SetupHumanPlayer(int playerIndex, Pedestrian* pedestrian); 47 | void DeleteHumanPlayer(int playerIndex); 48 | 49 | void SetupScreenLayout(); 50 | 51 | // Get index or human player in players list 52 | // @returns -1 on error 53 | int GetHumanPlayerIndex(Pedestrian* pedestrian) const; 54 | int GetHumanPlayersCount() const; 55 | 56 | private: 57 | bool SetInputActionsFromConfig(); 58 | bool DetectGameVersion(); 59 | 60 | std::string GetTextsLanguageFileName(const std::string& languageID) const; 61 | 62 | bool StartScenario(const std::string& mapName); 63 | void ShutdownCurrentScenario(); 64 | 65 | void SetCurrentGamestate(GenericGamestate* gamestate); 66 | 67 | void ProcessDebugCvars(); 68 | 69 | private: 70 | GameplayGamestate mGameplayGamestate; 71 | MainMenuGamestate mMainMenuGamestate; 72 | }; 73 | 74 | extern CarnageGame gCarnageGame; -------------------------------------------------------------------------------- /src/CharacterController.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CharacterController.h" 3 | #include "Pedestrian.h" 4 | #include "Vehicle.h" 5 | #include "DebugRenderer.h" 6 | 7 | CharacterController::CharacterController(Pedestrian* character, eCharacterControllerType controllerType) 8 | : mControllerType(controllerType) 9 | { 10 | AssignCharacter(character); 11 | } 12 | 13 | CharacterController::~CharacterController() 14 | { 15 | AssignCharacter(nullptr); 16 | } 17 | 18 | void CharacterController::AssignCharacter(Pedestrian* character) 19 | { 20 | if (mCharacter == character) 21 | return; 22 | 23 | if (mCharacter) 24 | { 25 | debug_assert(mCharacter->mController == this); 26 | mCharacter->mController = nullptr; 27 | } 28 | mCharacter = character; 29 | if (mCharacter) 30 | { 31 | debug_assert(mCharacter->mController == nullptr); 32 | mCharacter->mController = this; 33 | } 34 | mCtlState.Clear(); 35 | } 36 | 37 | void CharacterController::OnCharacterUpdateFrame() 38 | { 39 | // do nothing 40 | } 41 | 42 | void CharacterController::DebugDraw(DebugRenderer& debugRender) 43 | { 44 | // do nothing 45 | } 46 | 47 | bool CharacterController::IsControllerActive() const 48 | { 49 | return mCharacter != nullptr; 50 | } -------------------------------------------------------------------------------- /src/CharacterController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "DamageInfo.h" 5 | 6 | class DebugRenderer; 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | enum eCharacterControllerType 11 | { 12 | eCharacterControllerType_Null, 13 | eCharacterControllerType_Ai, 14 | eCharacterControllerType_Human 15 | }; 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | // Generic character controller class 20 | class CharacterController: public cxx::noncopyable 21 | { 22 | public: 23 | // readonly 24 | Pedestrian* mCharacter = nullptr; // controllable character 25 | PedestrianCtlState mCtlState; 26 | eCharacterControllerType mControllerType; 27 | 28 | public: 29 | CharacterController(Pedestrian* character, eCharacterControllerType controllerType); 30 | virtual ~CharacterController(); 31 | 32 | void AssignCharacter(Pedestrian* character); 33 | bool IsControllerActive() const; 34 | 35 | bool IsControllerTypeAi() const { return mControllerType == eCharacterControllerType_Ai; } 36 | bool IsControllerTypeHuman() const { return mControllerType == eCharacterControllerType_Human; } 37 | 38 | // Process controller logic 39 | virtual void DebugDraw(DebugRenderer& debugRender); 40 | // Events 41 | virtual void OnCharacterUpdateFrame(); 42 | }; -------------------------------------------------------------------------------- /src/Collider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PhysicsDefs.h" 4 | 5 | class Collider final: public cxx::noncopyable 6 | { 7 | friend class PhysicsManager; 8 | friend class PhysicsBody; 9 | 10 | public: 11 | // readonly 12 | GameObject* mGameObject; // owner game object 13 | PhysicsBody* mPhysicsBody; // owner physics body 14 | CollisionShape mShapeData; 15 | 16 | public: 17 | Collider(PhysicsBody* physicsBody, const CollisionShape& shapeData, const PhysicsMaterial& shapeMaterial, 18 | CollisionGroup shapeCollisionGroup, 19 | CollisionGroup shapeCollidesWith, ColliderFlags shapeFlags); 20 | 21 | // Propertry setters 22 | void SetShapeMaterial(const PhysicsMaterial& shapeMaterial); 23 | void SetShapeCollisionGroup(CollisionGroup collisionGroup, CollisionGroup collidesWith); 24 | 25 | // Properties getters 26 | void GetShapeMaterial(PhysicsMaterial& shapeMaterial) const; 27 | void GetShapeCollisionGroup(CollisionGroup& collisionGroup, CollisionGroup& collidesWith) const; 28 | 29 | // Shape flags 30 | void SetShapeCollisionFlags(ColliderFlags flags); 31 | void ChangeShapeCollisionFlags(ColliderFlags enableFlags, ColliderFlags disableFlags); 32 | void GetShapeCollisionFlags(ColliderFlags& flags) const; 33 | 34 | private: 35 | void DestroyFixture(); 36 | 37 | private: 38 | b2Fixture* mBox2Fixture = nullptr; 39 | }; -------------------------------------------------------------------------------- /src/Collision.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PhysicsDefs.h" 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | // contact between objects colliders 8 | class Contact 9 | { 10 | friend class PhysicsManager; 11 | friend class Collision; 12 | 13 | public: 14 | // readonly 15 | Collider* mThisCollider = nullptr; 16 | Collider* mThatCollider = nullptr; 17 | 18 | GameObject* mThisObject = nullptr; 19 | GameObject* mThatObject = nullptr; 20 | 21 | ContactPoint mContactPoints[MaxCollisionContactPoints]; 22 | int mContactPointsCount = 0; 23 | 24 | public: 25 | Contact() = default; 26 | 27 | bool GetRelativeVelocity(int contactPointIndex, glm::vec2& outputVelocity) const; 28 | bool GetRelativeVelocity(glm::vec2& outputVelocity) const; 29 | bool HasContactPoints() const; 30 | 31 | private: 32 | void SetupWithBox2Data(b2Contact* contact, b2Fixture* thisFixture, b2Fixture* thatFixture); 33 | }; 34 | 35 | ////////////////////////////////////////////////////////////////////////// 36 | 37 | // collision between objects colliders 38 | class Collision 39 | { 40 | friend class PhysicsManager; 41 | 42 | public: 43 | // readonly 44 | Contact mContactInfo; 45 | public: 46 | Collision() = default; 47 | // Get total impulse applied to collider pair to resolve collision 48 | // Sometimes it is 0, for example, when multiple objects are spawned in one place 49 | inline float GetContactImpulse() const 50 | { 51 | return mContactImpulse; 52 | } 53 | private: 54 | void SetupWithBox2Data(b2Contact* contact, b2Fixture* thisFixture, b2Fixture* thatFixture, const b2ContactImpulse* contactImpulse); 55 | 56 | private: 57 | float mContactImpulse = 0.0f; 58 | }; 59 | 60 | ////////////////////////////////////////////////////////////////////////// 61 | 62 | // collision between map and object collider 63 | class MapCollision 64 | { 65 | friend class PhysicsManager; 66 | 67 | public: 68 | // readonly 69 | Collider* mThisCollider = nullptr; 70 | GameObject* mThisObject = nullptr; 71 | const MapBlockInfo* mMapBlockInfo = nullptr; 72 | 73 | ContactPoint mContactPoints[MaxCollisionContactPoints]; 74 | int mContactPointsCount = 0; 75 | 76 | public: 77 | MapCollision() = default; 78 | 79 | bool HasContactPoints() const; 80 | // Get total impulse applied to collider to resolve collision 81 | // Sometimes it is 0, for example, when object spawned in wall 82 | inline float GetContactImpulse() const 83 | { 84 | return mContactImpulse; 85 | } 86 | private: 87 | void SetupWithBox2Data(b2Contact* contact, b2Fixture* objectFixture, const MapBlockInfo* mapBlockInfo, const b2ContactImpulse* contactImpulse); 88 | 89 | private: 90 | float mContactImpulse = 0.0f; 91 | }; -------------------------------------------------------------------------------- /src/CommonTypes.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CommonTypes.h" 3 | 4 | const glm::vec3 SceneAxisX (1.0f, 0.0f, 0.0f); 5 | const glm::vec3 SceneAxisY (0.0f, 1.0f, 0.0f); 6 | const glm::vec3 SceneAxisZ (0.0f, 0.0f, 1.0f); 7 | 8 | const Color32 Color32_Red (0xFF,0x00,0x00,0xFF); 9 | const Color32 Color32_Green (0x00,0xFF,0x00,0xFF); 10 | const Color32 Color32_DarkGreen (0x00,0x80,0x00,0xFF); 11 | const Color32 Color32_Orange (0xFF,0xA5,0x00,0xFF); 12 | const Color32 Color32_Blue (0x00,0x00,0xFF,0xFF); 13 | const Color32 Color32_SkyBlue (0x87,0xCE,0xEB,0xFF); 14 | const Color32 Color32_DarkBlue (0x00,0x00,0xA0,0xFF); 15 | const Color32 Color32_White (0xFF,0xFF,0xFF,0xFF); 16 | const Color32 Color32_Black (0x00,0x00,0x00,0xFF); 17 | const Color32 Color32_Cyan (0x00,0xFF,0xFF,0xFF); 18 | const Color32 Color32_Yellow (0xFF,0xFF,0x00,0xFF); 19 | const Color32 Color32_Gray (0xC6,0xC6,0xC6,0xFF); 20 | const Color32 Color32_DarkGray (0x80,0x80,0x80,0xFF); 21 | const Color32 Color32_GrimGray (0x35,0x35,0x35,0xFF); 22 | const Color32 Color32_Brown (0x8E,0x51,0x29,0xFF); 23 | const Color32 Color32_NULL (0, 0, 0, 0); -------------------------------------------------------------------------------- /src/Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CommonTypes.h" 4 | 5 | // forwards 6 | class Cvar; 7 | 8 | // represents console system that handles debug commands 9 | class Console final: public cxx::noncopyable 10 | { 11 | public: 12 | // readonly 13 | std::deque mLines; 14 | std::vector mCvarsList; 15 | 16 | public: 17 | // Setup internal resources, returns false on error 18 | bool Initialize(); 19 | void Deinit(); 20 | void RegisterGlobalVariables(); 21 | 22 | // Write text message in console 23 | void LogMessage(eLogMessage messageCat, const char* format, ...); 24 | 25 | // Clear all console text messages 26 | void Flush(); 27 | 28 | // parse and execute commands 29 | // @param commands: Commands string 30 | void ExecuteCommands(const char* commands); 31 | 32 | // Register or unregister console variable 33 | // @returns false on error 34 | bool RegisterVariable(Cvar* consoleVariable); 35 | bool UnregisterVariable(Cvar* consoleVariable); 36 | }; 37 | 38 | extern Console gConsole; -------------------------------------------------------------------------------- /src/ConsoleWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DebugWindow.h" 4 | 5 | struct ImGuiInputTextCallbackData; 6 | 7 | // defines debug console window as part of imgui system 8 | class ConsoleWindow final: public DebugWindow 9 | { 10 | public: 11 | bool mAutoScroll = true; 12 | bool mScrollToBottom = false; 13 | 14 | public: 15 | ConsoleWindow(); 16 | 17 | // process logic 18 | // @param deltaTime: Time passed since previous update 19 | void DoUI(ImGuiIO& imguiContext) override; 20 | 21 | private: 22 | // internals 23 | int TextEditCallback(ImGuiInputTextCallbackData* data); 24 | void Exec(); 25 | void MoveInputToHistory(); 26 | 27 | private: 28 | std::string mInputString; 29 | std::deque mHistory; 30 | int mHistoryPos = -1; // -1: new line, 0..History.Size-1 browsing history. 31 | }; 32 | 33 | extern ConsoleWindow gDebugConsoleWindow; -------------------------------------------------------------------------------- /src/DamageInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "WeaponInfo.h" 5 | #include "Collision.h" 6 | 7 | // Game object damage type 8 | enum eDamageCause 9 | { 10 | eDamageCause_Gravity, // fall from height 11 | eDamageCause_Electricity, // rails 12 | eDamageCause_Flame, 13 | eDamageCause_Water, 14 | eDamageCause_Collision, // physics contact between two object 15 | eDamageCause_MapCollision, // physics contact with map blocks or walls 16 | eDamageCause_Explosion, 17 | eDamageCause_ExplosionChain, 18 | eDamageCause_Bullet, 19 | eDamageCause_Punch, 20 | eDamageCause_CarHit, 21 | }; 22 | 23 | // Game object damage information 24 | struct DamageInfo 25 | { 26 | public: 27 | DamageInfo() = default; 28 | 29 | // @param object: Source object, it is optional 30 | void SetFallDamage(float fallHeight); 31 | void SetElectricityDamage(); 32 | void SetFireDamage(GameObject* object); 33 | void SetDamage(const WeaponInfo& weaponInfo, GameObject* object); 34 | void SetWaterDamage(); 35 | void SetCollisionDamage(const Collision& collisionInfo); 36 | void SetCollisionDamage(const MapCollision& collisionInfo); 37 | void SetExplosionDamage(GameObject* object); 38 | void SetExplosionChainDamage(GameObject* object); 39 | void SetBulletDamage(GameObject* object); 40 | void SetPunchDamage(GameObject* object); 41 | void SetCarHitDamage(GameObject* carObject); 42 | 43 | void Clear(); 44 | 45 | Pedestrian* GetDamageCauser() const; 46 | 47 | public: 48 | // depending on cause of damage object reaction may vary 49 | eDamageCause mDamageCause = eDamageCause_Punch; 50 | 51 | // object which cause damage, optional 52 | GameObject* mSourceObject = nullptr; 53 | 54 | // collision specific data 55 | ContactPoint mContactPoint; 56 | float mContactImpulse = 0.0f; 57 | float mFallHeight = 0.0f; // has meaning only if fall 58 | }; -------------------------------------------------------------------------------- /src/DebugWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "DebugWindow.h" 3 | #include "ImGuiManager.h" 4 | 5 | DebugWindow::DebugWindow(const char* windowName) 6 | : mWindowName(windowName) 7 | , mWindowShown() 8 | , mDebugWindowsListNode(this) 9 | { 10 | // check name 11 | #ifdef _DEBUG 12 | for (DebugWindow* currWindow: GetDebugWindowsList()) 13 | { 14 | debug_assert(strcmp(currWindow->mWindowName, mWindowName) != 0); 15 | } 16 | #endif 17 | GetDebugWindowsList().insert(&mDebugWindowsListNode); 18 | } 19 | 20 | DebugWindow::~DebugWindow() 21 | { 22 | GetDebugWindowsList().remove(&mDebugWindowsListNode); 23 | } -------------------------------------------------------------------------------- /src/DebugWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // forwards 4 | struct ImGuiIO; 5 | 6 | // base class for all debug windows 7 | class DebugWindow: public cxx::noncopyable 8 | { 9 | friend class ImGuiManager; 10 | 11 | static cxx::intrusive_list& GetDebugWindowsList() 12 | { 13 | static cxx::intrusive_list AllDebugWindows; 14 | return AllDebugWindows; 15 | } 16 | 17 | // linked list of all debug windows exists in program 18 | cxx::intrusive_node mDebugWindowsListNode; 19 | 20 | public: 21 | // @param windowName: Unique name, must be statically allocated 22 | DebugWindow(const char* windowName); 23 | virtual ~DebugWindow(); 24 | 25 | // process window state 26 | // @param imguiContext: Internal imgui context 27 | virtual void DoUI(ImGuiIO& imguiContext) = 0; 28 | 29 | inline void ToggleWindowShown() 30 | { 31 | mWindowShown = !mWindowShown; 32 | } 33 | 34 | public: 35 | const char* mWindowName; 36 | bool mWindowShown; 37 | }; -------------------------------------------------------------------------------- /src/Decoration.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Decoration.h" 3 | #include "TimeManager.h" 4 | #include "SpriteManager.h" 5 | 6 | Decoration::Decoration(GameObjectID id, GameObjectInfo* gameObjectDesc) 7 | : GameObject(eGameObjectClass_Decoration, id) 8 | , mMoveVelocity() 9 | , mAnimationState() 10 | { 11 | if (gameObjectDesc) 12 | { 13 | mAnimationState.mAnimDesc = gameObjectDesc->mAnimationData; 14 | mDrawSprite.mDrawOrder = gameObjectDesc->mDrawOrder; 15 | } 16 | } 17 | 18 | void Decoration::UpdateFrame() 19 | { 20 | float deltaTime = gTimeManager.mGameFrameDelta; 21 | if (mAnimationState.UpdateFrame(deltaTime)) 22 | { 23 | SetSprite(mAnimationState.GetSpriteIndex(), 0); 24 | } 25 | 26 | glm::vec3 newPosition = mTransform.mPosition + (mMoveVelocity * deltaTime); 27 | if (newPosition != mTransform.mPosition) 28 | { 29 | SetTransform(newPosition, mTransform.mOrientation); 30 | } 31 | 32 | if (mLifeDuration > 0 && !mAnimationState.IsActive()) 33 | { 34 | MarkForDeletion(); 35 | } 36 | } 37 | 38 | void Decoration::DebugDraw(DebugRenderer& debugRender) 39 | { 40 | } 41 | 42 | void Decoration::HandleSpawn() 43 | { 44 | mRemapClut = 0; 45 | 46 | mAnimationState.ClearState(); 47 | mAnimationState.PlayAnimation(eSpriteAnimLoop_FromStart); 48 | 49 | SetSprite(mAnimationState.GetSpriteIndex(), 0); 50 | } 51 | 52 | void Decoration::SetLifeDuration(int numCycles) 53 | { 54 | mLifeDuration = numCycles; 55 | mAnimationState.SetMaxRepeatCycles(numCycles); 56 | } 57 | 58 | void Decoration::SetDrawOrder(eSpriteDrawOrder drawOrder) 59 | { 60 | mDrawSprite.mDrawOrder = drawOrder; 61 | } 62 | 63 | void Decoration::SetScale(float scale) 64 | { 65 | mDrawSprite.mScale = scale; 66 | RefreshDrawSprite(); 67 | } 68 | 69 | void Decoration::SetMoveVelocity(const glm::vec3& moveVelocity) 70 | { 71 | mMoveVelocity = moveVelocity; 72 | } 73 | -------------------------------------------------------------------------------- /src/Decoration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameObject.h" 4 | 5 | class Decoration final: public GameObject 6 | { 7 | friend class GameObjectsManager; 8 | 9 | public: 10 | Decoration(GameObjectID id, GameObjectInfo* desc); 11 | 12 | // override GameObject 13 | void UpdateFrame() override; 14 | void DebugDraw(DebugRenderer& debugRender) override; 15 | void HandleSpawn() override; 16 | 17 | // Setup current position and rotation 18 | void SetScale(float scale); 19 | void SetLifeDuration(int numAnimationCycles); 20 | 21 | // Set decoration move in direction 22 | // @param moveVelocity: Move velocity, meters per second 23 | void SetMoveVelocity(const glm::vec3& moveVelocity); 24 | 25 | // Change current draw order for decoration object 26 | void SetDrawOrder(eSpriteDrawOrder drawOrder); 27 | 28 | private: 29 | SpriteAnimation mAnimationState; 30 | glm::vec3 mMoveVelocity; 31 | int mLifeDuration = 0; // number of animation cycles before decoration will be deleted, or 0 for endless lifetime 32 | }; -------------------------------------------------------------------------------- /src/Explosion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameObject.h" 4 | 5 | class Explosion final: public GameObject 6 | { 7 | friend class GameObjectsManager; 8 | 9 | public: 10 | // readonly 11 | eExplosionType mExplosionType = eExplosionType_Rocket; 12 | GameObjectHandle mExplodingObject; 13 | PedestrianHandle mExplosionCauser; 14 | 15 | public: 16 | // ctor 17 | // @param explodingObject: Object that exploded 18 | // @param causer: Pedestrian causing explosion 19 | // @param explosionType: Type identifier 20 | Explosion(GameObject* explodingObject, Pedestrian* causer, eExplosionType explosionType); 21 | 22 | // override GameObject 23 | void UpdateFrame() override; 24 | void DebugDraw(DebugRenderer& debugRender) override; 25 | void HandleSpawn() override; 26 | 27 | private: 28 | void DamageObjectInContact(); 29 | void DamagePedsNearby(bool enableInstantKill); 30 | void DamageCarsNearby(); 31 | 32 | private: 33 | SpriteAnimation mAnimationState; 34 | int mUpdatesCounter = 0; 35 | }; -------------------------------------------------------------------------------- /src/FileSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // file system manager 4 | class FileSystem final: public cxx::noncopyable 5 | { 6 | public: 7 | // standard places paths 8 | std::string mExecutablePath; 9 | std::string mExecutableDirectory; 10 | std::string mWorkingDirectoryPath; 11 | std::vector mSearchPlaces; 12 | std::vector mGameMapsList; 13 | 14 | public: 15 | // Setup filesystem internal resources 16 | bool Initialize(); 17 | 18 | // Free allocated resources 19 | void Deinit(); 20 | 21 | // Init gta gamedata files location 22 | bool SetupGtaDataLocation(); 23 | 24 | // Add search place directory 25 | // @param searchPlace: Path 26 | void AddSearchPlace(const std::string& searchPlace); 27 | 28 | // Open text or binary file stream for reading operations 29 | // @param objectName: File name 30 | // @param instream: Output stream 31 | bool OpenBinaryFile(const std::string& objectName, std::ifstream& instream); 32 | bool OpenTextFile(const std::string& objectName, std::ifstream& instream); 33 | 34 | // Create text or binary file stream for write operations 35 | bool CreateBinaryFile(const std::string& objectName, std::ofstream& outstream); 36 | bool CreateTextFile(const std::string& objectName, std::ofstream& outstream); 37 | 38 | // Load whole text file content to std string 39 | // @param objectName: File name 40 | // @param output: Content 41 | bool ReadTextFile(const std::string& objectName, std::string& output); 42 | 43 | // Load whole binary file content to std vector 44 | bool ReadBinaryFile(const std::string& objectName, std::vector& output); 45 | 46 | // Load or save json config document 47 | bool ReadConfig(const std::string& filePath, cxx::json_document& configDocument); 48 | bool SaveConfig(const std::string& filePath, const cxx::json_document& configDocument); 49 | 50 | // Test whether file exists 51 | // @param objectName: File name 52 | bool IsFileExists(const std::string& objectName); 53 | 54 | // Test whether directory exists 55 | // @param objectName: Directory name 56 | bool IsDirectoryExists(const std::string& objectName); 57 | 58 | // Find file within search places and get full path to it 59 | // @param objectName: File name 60 | // @param fullPath: Out full path 61 | bool GetFullPathToFile(const std::string& objectName, std::string& fullPath) const; 62 | bool GetFullPathToDirectory(const std::string& objectName, std::string& fullPath) const; 63 | 64 | private: 65 | // Gather all gta maps within gamedata 66 | bool ScanGtaMaps(); 67 | }; 68 | 69 | extern FileSystem gFiles; -------------------------------------------------------------------------------- /src/FollowCameraController.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FollowCameraController.h" 3 | #include "PhysicsBody.h" 4 | #include "CarnageGame.h" 5 | #include "Pedestrian.h" 6 | #include "TimeManager.h" 7 | 8 | FollowCameraController::FollowCameraController() 9 | : mStartupCameraHeight(32.0f) 10 | , mFollowPedCameraHeight(20.0f) 11 | , mFollowPedCameraCatchSpeed(20.0f) 12 | , mScrollHeightOffset() 13 | { 14 | } 15 | 16 | void FollowCameraController::Setup(GameCamera* gameCamera) 17 | { 18 | debug_assert(gameCamera); 19 | mCamera = gameCamera; 20 | 21 | // compute aspect ratio 22 | float screenAspect = (mCamera->mViewportRect.h > 0) ? ((mCamera->mViewportRect.w * 1.0f) / (mCamera->mViewportRect.h * 1.0f)) : 1.0f; 23 | 24 | // set camera defaults 25 | mCamera->SetIdentity(); 26 | mCamera->SetPerspectiveProjection(screenAspect, 55.0f, 0.1f, 1000.0f); 27 | 28 | if (mFollowPedestrian) 29 | { 30 | glm::vec3 position = mFollowPedestrian->mTransformSmooth.mPosition; 31 | mCamera->SetPosition({position.x, position.y + mStartupCameraHeight, position.z}); 32 | } 33 | else 34 | { 35 | mCamera->SetPosition({0.0f, mStartupCameraHeight, 0.0f}); 36 | } 37 | mCamera->SetTopDownOrientation(); 38 | } 39 | 40 | void FollowCameraController::UpdateFrame() 41 | { 42 | if (mFollowPedestrian == nullptr) 43 | return; 44 | 45 | glm::vec3 position = mFollowPedestrian->mTransformSmooth.mPosition; 46 | position.y = position.y + (mFollowPedCameraHeight + mScrollHeightOffset); 47 | 48 | float catchSpeed = mFollowPedCameraCatchSpeed; 49 | // todo: temporary implementation 50 | if (mFollowPedestrian->IsCarPassenger()) 51 | { 52 | glm::vec2 carVelocity = mFollowPedestrian->mCurrentCar->mPhysicsBody->GetLinearVelocity(); 53 | float carSpeed = glm::length(carVelocity); 54 | carVelocity = glm::normalize(carVelocity); 55 | position.x += (carVelocity.x * carSpeed * 0.35f); // todo: magic numbers 56 | position.z += (carVelocity.y * carSpeed * 0.35f); // todo: magic numbers 57 | catchSpeed *= 0.3f; // todo: magic numbers 58 | } 59 | 60 | float deltaTime = gTimeManager.mGameFrameDelta; 61 | if (glm::length(mCamera->mPosition - position) > 0.01f) 62 | { 63 | position = mCamera->mPosition + (position - mCamera->mPosition) * catchSpeed * deltaTime; 64 | mCamera->SetPosition(position); 65 | } 66 | } 67 | 68 | void FollowCameraController::InputEvent(KeyInputEvent& inputEvent) 69 | { 70 | } 71 | 72 | void FollowCameraController::InputEvent(MouseButtonInputEvent& inputEvent) 73 | { 74 | } 75 | 76 | void FollowCameraController::InputEvent(MouseMovedInputEvent& inputEvent) 77 | { 78 | } 79 | 80 | void FollowCameraController::InputEvent(MouseScrollInputEvent& inputEvent) 81 | { 82 | mScrollHeightOffset = glm::clamp(mScrollHeightOffset - inputEvent.mScrollY, -3.0f, 23.0f); 83 | } 84 | 85 | void FollowCameraController::SetFollowTarget(Pedestrian* pedestrian) 86 | { 87 | mFollowPedestrian = pedestrian; 88 | } 89 | 90 | void FollowCameraController::InputEventLost() 91 | { 92 | } 93 | -------------------------------------------------------------------------------- /src/FollowCameraController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CameraController.h" 4 | 5 | class FollowCameraController final: public CameraController 6 | { 7 | public: 8 | FollowCameraController(); 9 | 10 | void SetFollowTarget(Pedestrian* pedestrian); 11 | 12 | // reset scene camera to defaults 13 | void Setup(GameCamera* gameCamera) override; 14 | 15 | // process events and advance controller logic for single frame 16 | void UpdateFrame() override; 17 | 18 | // process input event 19 | // @param inputEvent: Event data 20 | void InputEvent(KeyInputEvent& inputEvent) override; 21 | void InputEvent(MouseButtonInputEvent& inputEvent) override; 22 | void InputEvent(MouseMovedInputEvent& inputEvent) override; 23 | void InputEvent(MouseScrollInputEvent& inputEvent) override; 24 | void InputEventLost() override; 25 | 26 | private: 27 | // parameters 28 | float mStartupCameraHeight; // meters 29 | float mFollowPedCameraHeight; // meters 30 | float mScrollHeightOffset; // meters 31 | float mFollowPedCameraCatchSpeed; // meters per second 32 | 33 | Pedestrian* mFollowPedestrian = nullptr; 34 | }; -------------------------------------------------------------------------------- /src/Font.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GuiDefs.h" 4 | 5 | // Drawable font instance 6 | class Font final: public cxx::noncopyable 7 | { 8 | public: 9 | const std::string mFontName; 10 | 11 | public: 12 | Font(const std::string& fontName); 13 | ~Font(); 14 | 15 | // Loads or unloads font isntance 16 | bool LoadFromFile(); 17 | void Unload(); 18 | 19 | // Test whether font resource is loaded 20 | bool IsLoaded() const; 21 | 22 | // Set base character code 23 | void SetFontBaseCharCode(int charCode); 24 | 25 | // Simple draw text characters on screen 26 | // @param guiContext: Context 27 | // @param text: Source string 28 | // @param position: Screen position in pixels 29 | // @param maxSize: Max text size in pixels 30 | void DrawString(GuiContext& guiContext, const std::string& text, const Point& position, int paletteIndex); 31 | void DrawString(GuiContext& guiContext, const std::string& text, const Point& position, const Point& maxSize, int paletteIndex); 32 | 33 | // Get font line height in pixels 34 | int GetLineHeight() const; 35 | 36 | // Calculcate string dimensions, will process newlines and tabulations 37 | // @param text: Source string 38 | // @param maxSize: Text max size in pixels 39 | // @param outputSize: Text dimensions in pixels 40 | void MeasureString(const std::string& text, Point& outputSize) const; 41 | void MeasureString(const std::string& text, const Point& maxSize, Point& outputSize) const; 42 | 43 | // Dump font characters to specified folder, for debug purposes only 44 | void DumpCharacters(const std::string& outputPath); 45 | 46 | private: 47 | bool CreateFontAtlas(); 48 | 49 | private: 50 | 51 | struct RawCharacter 52 | { 53 | unsigned char mCharWidth = 0; 54 | unsigned char* mCharData = nullptr; 55 | }; 56 | 57 | struct RawFontData 58 | { 59 | Palette256 mPalette; 60 | std::vector mRawCharacters; 61 | }; 62 | 63 | std::vector mCharacters; 64 | RawFontData mFontData; 65 | GpuTexture2D* mFontTexture = nullptr; 66 | 67 | int mBaseCharCode = 0; 68 | int mLineHeight = 0; 69 | }; -------------------------------------------------------------------------------- /src/FontManager.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FontManager.h" 3 | #include "Font.h" 4 | 5 | FontManager gFontManager; 6 | 7 | bool FontManager::Initialize() 8 | { 9 | return true; 10 | } 11 | 12 | void FontManager::Deinit() 13 | { 14 | for (auto& currFont: mFontsCache) 15 | { 16 | delete currFont.second; 17 | } 18 | mFontsCache.clear(); 19 | } 20 | 21 | Font* FontManager::GetFont(const std::string& fontName) 22 | { 23 | Font* fontInstance = nullptr; 24 | 25 | auto find_iterator = mFontsCache.find(fontName); 26 | if (find_iterator != mFontsCache.end()) 27 | { 28 | fontInstance = find_iterator->second; 29 | } 30 | 31 | if (fontInstance == nullptr) // cache miss 32 | { 33 | fontInstance = new Font(fontName); 34 | mFontsCache[fontName] = fontInstance; 35 | } 36 | 37 | debug_assert(fontInstance); 38 | if (!fontInstance->IsLoaded()) 39 | { 40 | if (!fontInstance->LoadFromFile()) 41 | { 42 | gConsole.LogMessage(eLogMessage_Warning, "Cannot load font '%s'", fontName.c_str()); 43 | } 44 | } 45 | 46 | return fontInstance; 47 | } 48 | 49 | void FontManager::FlushAllFonts() 50 | { 51 | for (auto& currFont: mFontsCache) 52 | { 53 | currFont.second->Unload(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/FontManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GuiDefs.h" 4 | 5 | // This class implements caching mechanism for font resources 6 | class FontManager final: public cxx::noncopyable 7 | { 8 | public: 9 | // Initialize font manager internal resources 10 | bool Initialize(); 11 | 12 | // Flush all currently cached fonts 13 | void Deinit(); 14 | 15 | // Flush all currently loaded fonts 16 | void FlushAllFonts(); 17 | 18 | // Finds font instance within cache and force it to load 19 | // @param fontName: Font name 20 | // @returns font instance which might be not loaded in case of error 21 | Font* GetFont(const std::string& fontName); 22 | 23 | private: 24 | std::map mFontsCache; 25 | }; 26 | 27 | extern FontManager gFontManager; -------------------------------------------------------------------------------- /src/FreeLookCameraController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CameraController.h" 4 | 5 | class FreeLookCameraController final: public CameraController 6 | { 7 | public: 8 | // reset scene camera to defaults 9 | void Setup(GameCamera* gameCamera) override; 10 | 11 | // process events and advance controller logic for single frame 12 | void UpdateFrame() override; 13 | 14 | // process input event 15 | // @param inputEvent: Event data 16 | void InputEvent(KeyInputEvent& inputEvent) override; 17 | void InputEvent(MouseButtonInputEvent& inputEvent) override; 18 | void InputEvent(MouseMovedInputEvent& inputEvent) override; 19 | void InputEvent(MouseScrollInputEvent& inputEvent) override; 20 | void InputEventLost() override; 21 | 22 | private: 23 | void ClearConstrols(); 24 | 25 | private: 26 | bool mMoveLeft, mMoveRight; 27 | bool mMoveForward, mMoveBackward; 28 | int mLastMouseX, mLastMouseY; 29 | int mRotateDeltaX, mRotateDeltaY; 30 | bool mMouseDragCamera; 31 | float mMoveSpeed = 20.0f; // meters per second 32 | }; 33 | -------------------------------------------------------------------------------- /src/GLFW/GLFW.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/GLFW/cocoa_joystick.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 Cocoa - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2006-2017 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns 33 | #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE 34 | 35 | #define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X" 36 | 37 | // Cocoa-specific per-joystick data 38 | // 39 | typedef struct _GLFWjoystickNS 40 | { 41 | IOHIDDeviceRef device; 42 | CFMutableArrayRef axes; 43 | CFMutableArrayRef buttons; 44 | CFMutableArrayRef hats; 45 | } _GLFWjoystickNS; 46 | 47 | 48 | void _glfwInitJoysticksNS(void); 49 | void _glfwTerminateJoysticksNS(void); 50 | 51 | -------------------------------------------------------------------------------- /src/GLFW/cocoa_time.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 macOS - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2009-2016 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #include "internal.h" 28 | 29 | #include 30 | 31 | 32 | ////////////////////////////////////////////////////////////////////////// 33 | ////// GLFW internal API ////// 34 | ////////////////////////////////////////////////////////////////////////// 35 | 36 | // Initialise timer 37 | // 38 | void _glfwInitTimerNS(void) 39 | { 40 | mach_timebase_info_data_t info; 41 | mach_timebase_info(&info); 42 | 43 | _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer; 44 | } 45 | 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | ////// GLFW platform API ////// 49 | ////////////////////////////////////////////////////////////////////////// 50 | 51 | uint64_t _glfwPlatformGetTimerValue(void) 52 | { 53 | return mach_absolute_time(); 54 | } 55 | 56 | uint64_t _glfwPlatformGetTimerFrequency(void) 57 | { 58 | return _glfw.timer.ns.frequency; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/GLFW/glfw3.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 4 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 5 | 6 | Name: GLFW 7 | Description: A multi-platform library for OpenGL, window and input 8 | Version: @GLFW_VERSION_FULL@ 9 | URL: https://www.glfw.org/ 10 | Requires.private: @GLFW_PKG_DEPS@ 11 | Libs: -L${libdir} -l@GLFW_LIB_NAME@ 12 | Libs.private: @GLFW_PKG_LIBS@ 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /src/GLFW/glfw3Config.cmake.in: -------------------------------------------------------------------------------- 1 | include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake") 2 | -------------------------------------------------------------------------------- /src/GLFW/glfw_config.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.1 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2010 Camilla Berglund 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | // As glfw_config.h.in, this file is used by CMake to produce the 27 | // glfw_config.h configuration header file. If you are adding a feature 28 | // requiring conditional compilation, this is where to add the macro. 29 | //======================================================================== 30 | // As glfw_config.h, this file defines compile-time option macros for a 31 | // specific platform and development environment. If you are using the 32 | // GLFW CMake files, modify glfw_config.h.in instead of this file. If you 33 | // are using your own build system, make this file define the appropriate 34 | // macros in whatever way is suitable. 35 | //======================================================================== 36 | 37 | #if defined(_WIN32) 38 | #define _GLFW_WIN32 39 | #define _GLFW_WGL 40 | #endif 41 | 42 | #if defined(__APPLE__) 43 | #define _GLFW_COCOA 44 | #define _GLFW_NSGL 45 | //#define _GLFW_USE_CHDIR 46 | #define _GLFW_USE_MENUBAR 47 | #endif 48 | 49 | #if !(defined(_WIN32) || defined(__APPLE__)) 50 | #define _GLFW_X11 51 | #define _GLFW_GLX 52 | #endif 53 | 54 | #define _GLFW_USE_OPENGL 55 | -------------------------------------------------------------------------------- /src/GLFW/glfw_config.h.in: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2010-2016 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | // As glfw_config.h.in, this file is used by CMake to produce the 27 | // glfw_config.h configuration header file. If you are adding a feature 28 | // requiring conditional compilation, this is where to add the macro. 29 | //======================================================================== 30 | // As glfw_config.h, this file defines compile-time option macros for a 31 | // specific platform and development environment. If you are using the 32 | // GLFW CMake files, modify glfw_config.h.in instead of this file. If you 33 | // are using your own build system, make this file define the appropriate 34 | // macros in whatever way is suitable. 35 | //======================================================================== 36 | 37 | // Define this to 1 if building GLFW for X11 38 | #cmakedefine _GLFW_X11 39 | // Define this to 1 if building GLFW for Win32 40 | #cmakedefine _GLFW_WIN32 41 | // Define this to 1 if building GLFW for Cocoa 42 | #cmakedefine _GLFW_COCOA 43 | // Define this to 1 if building GLFW for Wayland 44 | #cmakedefine _GLFW_WAYLAND 45 | // Define this to 1 if building GLFW for OSMesa 46 | #cmakedefine _GLFW_OSMESA 47 | 48 | // Define this to 1 if building as a shared library / dynamic library / DLL 49 | #cmakedefine _GLFW_BUILD_DLL 50 | // Define this to 1 to use Vulkan loader linked statically into application 51 | #cmakedefine _GLFW_VULKAN_STATIC 52 | 53 | // Define this to 1 to force use of high-performance GPU on hybrid systems 54 | #cmakedefine _GLFW_USE_HYBRID_HPG 55 | 56 | // Define this to 1 if xkbcommon supports the compose key 57 | #cmakedefine HAVE_XKBCOMMON_COMPOSE_H 58 | // Define this to 1 if the libc supports memfd_create() 59 | #cmakedefine HAVE_MEMFD_CREATE 60 | 61 | -------------------------------------------------------------------------------- /src/GLFW/linux_joystick.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 Linux - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2014 Jonas Ådahl 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs 32 | #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs 33 | 34 | #define _GLFW_PLATFORM_MAPPING_NAME "Linux" 35 | 36 | // Linux-specific joystick data 37 | // 38 | typedef struct _GLFWjoystickLinux 39 | { 40 | int fd; 41 | char path[PATH_MAX]; 42 | int keyMap[KEY_CNT - BTN_MISC]; 43 | int absMap[ABS_CNT]; 44 | struct input_absinfo absInfo[ABS_CNT]; 45 | int hats[4][2]; 46 | } _GLFWjoystickLinux; 47 | 48 | // Linux-specific joystick API data 49 | // 50 | typedef struct _GLFWlibraryLinux 51 | { 52 | int inotify; 53 | int watch; 54 | regex_t regex; 55 | GLFWbool dropped; 56 | } _GLFWlibraryLinux; 57 | 58 | 59 | GLFWbool _glfwInitJoysticksLinux(void); 60 | void _glfwTerminateJoysticksLinux(void); 61 | void _glfwDetectJoystickConnectionLinux(void); 62 | 63 | -------------------------------------------------------------------------------- /src/GLFW/nsgl_context.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 macOS - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2009-2019 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #if MAC_OS_X_VERSION_MAX_ALLOWED < 101400 28 | #define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval 29 | #define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity 30 | #endif 31 | 32 | #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl 33 | #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl 34 | 35 | #include 36 | 37 | 38 | // NSGL-specific per-context data 39 | // 40 | typedef struct _GLFWcontextNSGL 41 | { 42 | id pixelFormat; 43 | id object; 44 | CVDisplayLinkRef displayLink; 45 | atomic_int swapInterval; 46 | int swapIntervalsPassed; 47 | id swapIntervalCond; 48 | 49 | } _GLFWcontextNSGL; 50 | 51 | // NSGL-specific global data 52 | // 53 | typedef struct _GLFWlibraryNSGL 54 | { 55 | // dlopen handle for OpenGL.framework (for glfwGetProcAddress) 56 | CFBundleRef framework; 57 | 58 | } _GLFWlibraryNSGL; 59 | 60 | 61 | GLFWbool _glfwInitNSGL(void); 62 | void _glfwTerminateNSGL(void); 63 | GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, 64 | const _GLFWctxconfig* ctxconfig, 65 | const _GLFWfbconfig* fbconfig); 66 | void _glfwDestroyContextNSGL(_GLFWwindow* window); 67 | void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window); 68 | 69 | -------------------------------------------------------------------------------- /src/GLFW/null_init.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2016 Google Inc. 5 | // Copyright (c) 2016-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include "internal.h" 29 | 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | ////// GLFW platform API ////// 33 | ////////////////////////////////////////////////////////////////////////// 34 | 35 | int _glfwPlatformInit(void) 36 | { 37 | _glfwInitTimerPOSIX(); 38 | return GLFW_TRUE; 39 | } 40 | 41 | void _glfwPlatformTerminate(void) 42 | { 43 | _glfwTerminateOSMesa(); 44 | } 45 | 46 | const char* _glfwPlatformGetVersionString(void) 47 | { 48 | return _GLFW_VERSION_NUMBER " null OSMesa"; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/GLFW/null_joystick.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2016-2017 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #include "internal.h" 28 | 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | ////// GLFW platform API ////// 32 | ////////////////////////////////////////////////////////////////////////// 33 | 34 | int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) 35 | { 36 | return GLFW_FALSE; 37 | } 38 | 39 | void _glfwPlatformUpdateGamepadGUID(char* guid) 40 | { 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/GLFW/null_joystick.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2006-2017 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs 28 | #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs 29 | 30 | #define _GLFW_PLATFORM_MAPPING_NAME "" 31 | 32 | -------------------------------------------------------------------------------- /src/GLFW/null_monitor.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2016 Google Inc. 5 | // Copyright (c) 2016-2019 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include "internal.h" 29 | 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | ////// GLFW platform API ////// 33 | ////////////////////////////////////////////////////////////////////////// 34 | 35 | void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) 36 | { 37 | } 38 | 39 | void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) 40 | { 41 | } 42 | 43 | void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, 44 | float* xscale, float* yscale) 45 | { 46 | if (xscale) 47 | *xscale = 1.f; 48 | if (yscale) 49 | *yscale = 1.f; 50 | } 51 | 52 | void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, 53 | int* xpos, int* ypos, 54 | int* width, int* height) 55 | { 56 | } 57 | 58 | GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) 59 | { 60 | return NULL; 61 | } 62 | 63 | void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) 64 | { 65 | } 66 | 67 | GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) 68 | { 69 | return GLFW_FALSE; 70 | } 71 | 72 | void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) 73 | { 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/GLFW/null_platform.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2016 Google Inc. 5 | // Copyright (c) 2016-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include 29 | 30 | #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null 31 | 32 | #define _GLFW_PLATFORM_CONTEXT_STATE 33 | #define _GLFW_PLATFORM_MONITOR_STATE 34 | #define _GLFW_PLATFORM_CURSOR_STATE 35 | #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE 36 | #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE 37 | #define _GLFW_EGL_CONTEXT_STATE 38 | #define _GLFW_EGL_LIBRARY_CONTEXT_STATE 39 | 40 | #include "osmesa_context.h" 41 | #include "posix_time.h" 42 | #include "posix_thread.h" 43 | #include "null_joystick.h" 44 | 45 | #if defined(_GLFW_WIN32) 46 | #define _glfw_dlopen(name) LoadLibraryA(name) 47 | #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle) 48 | #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name) 49 | #else 50 | #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) 51 | #define _glfw_dlclose(handle) dlclose(handle) 52 | #define _glfw_dlsym(handle, name) dlsym(handle, name) 53 | #endif 54 | 55 | // Null-specific per-window data 56 | // 57 | typedef struct _GLFWwindowNull 58 | { 59 | int width; 60 | int height; 61 | } _GLFWwindowNull; 62 | 63 | -------------------------------------------------------------------------------- /src/GLFW/posix_thread.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 POSIX - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2002-2006 Marcus Geelnard 5 | // Copyright (c) 2006-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include 29 | 30 | #define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix 31 | #define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix 32 | 33 | 34 | // POSIX-specific thread local storage data 35 | // 36 | typedef struct _GLFWtlsPOSIX 37 | { 38 | GLFWbool allocated; 39 | pthread_key_t key; 40 | 41 | } _GLFWtlsPOSIX; 42 | 43 | // POSIX-specific mutex data 44 | // 45 | typedef struct _GLFWmutexPOSIX 46 | { 47 | GLFWbool allocated; 48 | pthread_mutex_t handle; 49 | 50 | } _GLFWmutexPOSIX; 51 | 52 | -------------------------------------------------------------------------------- /src/GLFW/posix_time.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 POSIX - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2002-2006 Marcus Geelnard 5 | // Copyright (c) 2006-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include "internal.h" 29 | 30 | #include 31 | #include 32 | 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | ////// GLFW internal API ////// 36 | ////////////////////////////////////////////////////////////////////////// 37 | 38 | // Initialise timer 39 | // 40 | void _glfwInitTimerPOSIX(void) 41 | { 42 | #if defined(CLOCK_MONOTONIC) 43 | struct timespec ts; 44 | 45 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 46 | { 47 | _glfw.timer.posix.monotonic = GLFW_TRUE; 48 | _glfw.timer.posix.frequency = 1000000000; 49 | } 50 | else 51 | #endif 52 | { 53 | _glfw.timer.posix.monotonic = GLFW_FALSE; 54 | _glfw.timer.posix.frequency = 1000000; 55 | } 56 | } 57 | 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | ////// GLFW platform API ////// 61 | ////////////////////////////////////////////////////////////////////////// 62 | 63 | uint64_t _glfwPlatformGetTimerValue(void) 64 | { 65 | #if defined(CLOCK_MONOTONIC) 66 | if (_glfw.timer.posix.monotonic) 67 | { 68 | struct timespec ts; 69 | clock_gettime(CLOCK_MONOTONIC, &ts); 70 | return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; 71 | } 72 | else 73 | #endif 74 | { 75 | struct timeval tv; 76 | gettimeofday(&tv, NULL); 77 | return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; 78 | } 79 | } 80 | 81 | uint64_t _glfwPlatformGetTimerFrequency(void) 82 | { 83 | return _glfw.timer.posix.frequency; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/GLFW/posix_time.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 POSIX - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2002-2006 Marcus Geelnard 5 | // Copyright (c) 2006-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix 29 | 30 | #include 31 | 32 | 33 | // POSIX-specific global timer data 34 | // 35 | typedef struct _GLFWtimerPOSIX 36 | { 37 | GLFWbool monotonic; 38 | uint64_t frequency; 39 | 40 | } _GLFWtimerPOSIX; 41 | 42 | 43 | void _glfwInitTimerPOSIX(void); 44 | 45 | -------------------------------------------------------------------------------- /src/GLFW/win32_joystick.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 Win32 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2006-2017 Camilla Löwy 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | #define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32 28 | #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy 29 | 30 | #define _GLFW_PLATFORM_MAPPING_NAME "Windows" 31 | 32 | // Joystick element (axis, button or slider) 33 | // 34 | typedef struct _GLFWjoyobjectWin32 35 | { 36 | int offset; 37 | int type; 38 | } _GLFWjoyobjectWin32; 39 | 40 | // Win32-specific per-joystick data 41 | // 42 | typedef struct _GLFWjoystickWin32 43 | { 44 | _GLFWjoyobjectWin32* objects; 45 | int objectCount; 46 | IDirectInputDevice8W* device; 47 | DWORD index; 48 | GUID guid; 49 | } _GLFWjoystickWin32; 50 | 51 | 52 | void _glfwInitJoysticksWin32(void); 53 | void _glfwTerminateJoysticksWin32(void); 54 | void _glfwDetectJoystickConnectionWin32(void); 55 | void _glfwDetectJoystickDisconnectionWin32(void); 56 | 57 | -------------------------------------------------------------------------------- /src/GLFW/win32_time.c: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 Win32 - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2002-2006 Marcus Geelnard 5 | // Copyright (c) 2006-2017 Camilla Löwy 6 | // 7 | // This software is provided 'as-is', without any express or implied 8 | // warranty. In no event will the authors be held liable for any damages 9 | // arising from the use of this software. 10 | // 11 | // Permission is granted to anyone to use this software for any purpose, 12 | // including commercial applications, and to alter it and redistribute it 13 | // freely, subject to the following restrictions: 14 | // 15 | // 1. The origin of this software must not be misrepresented; you must not 16 | // claim that you wrote the original software. If you use this software 17 | // in a product, an acknowledgment in the product documentation would 18 | // be appreciated but is not required. 19 | // 20 | // 2. Altered source versions must be plainly marked as such, and must not 21 | // be misrepresented as being the original software. 22 | // 23 | // 3. This notice may not be removed or altered from any source 24 | // distribution. 25 | // 26 | //======================================================================== 27 | 28 | #include "internal.h" 29 | 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | ////// GLFW internal API ////// 33 | ////////////////////////////////////////////////////////////////////////// 34 | 35 | // Initialise timer 36 | // 37 | void _glfwInitTimerWin32(void) 38 | { 39 | uint64_t frequency; 40 | 41 | if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) 42 | { 43 | _glfw.timer.win32.hasPC = GLFW_TRUE; 44 | _glfw.timer.win32.frequency = frequency; 45 | } 46 | else 47 | { 48 | _glfw.timer.win32.hasPC = GLFW_FALSE; 49 | _glfw.timer.win32.frequency = 1000; 50 | } 51 | } 52 | 53 | 54 | ////////////////////////////////////////////////////////////////////////// 55 | ////// GLFW platform API ////// 56 | ////////////////////////////////////////////////////////////////////////// 57 | 58 | uint64_t _glfwPlatformGetTimerValue(void) 59 | { 60 | if (_glfw.timer.win32.hasPC) 61 | { 62 | uint64_t value; 63 | QueryPerformanceCounter((LARGE_INTEGER*) &value); 64 | return value; 65 | } 66 | else 67 | return (uint64_t) timeGetTime(); 68 | } 69 | 70 | uint64_t _glfwPlatformGetTimerFrequency(void) 71 | { 72 | return _glfw.timer.win32.frequency; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/GLFW/xkb_unicode.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW 3.3 Linux - www.glfw.org 3 | //------------------------------------------------------------------------ 4 | // Copyright (c) 2014 Jonas Ådahl 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. 9 | // 10 | // Permission is granted to anyone to use this software for any purpose, 11 | // including commercial applications, and to alter it and redistribute it 12 | // freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would 17 | // be appreciated but is not required. 18 | // 19 | // 2. Altered source versions must be plainly marked as such, and must not 20 | // be misrepresented as being the original software. 21 | // 22 | // 3. This notice may not be removed or altered from any source 23 | // distribution. 24 | // 25 | //======================================================================== 26 | 27 | long _glfwKeySym2Unicode(unsigned int keysym); 28 | 29 | -------------------------------------------------------------------------------- /src/GameCheatsWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DebugWindow.h" 4 | 5 | class GameCheatsWindow: public DebugWindow 6 | { 7 | public: 8 | bool mEnableMapCollisions; 9 | bool mEnableGravity; 10 | bool mEnableBlocksAnimation; 11 | bool mEnableDebugDraw; 12 | bool mEnableDrawDecorations = true; 13 | bool mEnableDrawObstacles = true; 14 | bool mEnableDrawPedestrians = true; 15 | bool mEnableDrawVehicles = true; 16 | bool mEnableDrawCityMesh = true; 17 | bool mEnableTrafficPedsGeneration = true; 18 | bool mEnableTrafficCarsGeneration = false; 19 | 20 | public: 21 | GameCheatsWindow(); 22 | 23 | private: 24 | // process window state 25 | // @param deltaTime: Time since last frame 26 | void DoUI(ImGuiIO& imguiContext) override; 27 | 28 | void CreateCarNearby(VehicleInfo* carStyle, Pedestrian* pedestrian); 29 | }; 30 | 31 | extern GameCheatsWindow gGameCheatsWindow; -------------------------------------------------------------------------------- /src/GameMapHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "VertexFormats.h" 5 | 6 | // defines map mesh data 7 | template 8 | struct MeshData 9 | { 10 | public: 11 | MeshData() = default; 12 | inline void Clear() 13 | { 14 | mBlocksVertices.clear(); 15 | mBlocksIndices.clear(); 16 | } 17 | public: 18 | std::vector mBlocksVertices; 19 | std::vector mBlocksIndices; 20 | }; 21 | 22 | using CityMeshData = MeshData; 23 | 24 | class GameMapManager; 25 | class GameMapHelpers final 26 | { 27 | public: 28 | // construct mesh for specified city area and layer 29 | // @param cityScape: City scape data 30 | // @param area: Target map rect 31 | // @param layerIndex: Target map layer, see MAP_LAYERS_COUNT 32 | // @param meshData: Output mesh data 33 | static bool BuildMapMesh(GameMapManager& city, const Rect& area, int layerIndex, CityMeshData& meshData); 34 | static bool BuildMapMesh(GameMapManager& city, const Rect& area, CityMeshData& meshData); 35 | 36 | // compute height for specific block slope type 37 | // @param slopeType: Slope type 38 | // @param x, y: Position within block [0, 1] 39 | // @return slope height specified in map units [0, 1] 40 | static float GetSlopeHeight(int slopeType, float x, float y); 41 | 42 | private: 43 | // internals 44 | static void PutBlockFace(GameMapManager& city, CityMeshData& meshData, int x, int y, int z, eBlockFace face, const MapBlockInfo* blockInfo); 45 | }; -------------------------------------------------------------------------------- /src/GameObjectHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameObject.h" 4 | #include "Decoration.h" 5 | #include "Explosion.h" 6 | #include "Obstacle.h" 7 | #include "Pedestrian.h" 8 | #include "Projectile.h" 9 | #include "Vehicle.h" 10 | 11 | ////////////////////////////////////////////////////////////////////////// 12 | // Safe cast base to derived game object class 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | inline Decoration* ToDecoration(GameObject* gameObject) 16 | { 17 | Decoration* objectPointer = nullptr; 18 | if (gameObject && gameObject->IsDecorationClass()) 19 | { 20 | objectPointer = static_cast(gameObject); 21 | } 22 | return objectPointer; 23 | } 24 | 25 | inline Pedestrian* ToPedestrian(GameObject* gameObject) 26 | { 27 | Pedestrian* objectPointer = nullptr; 28 | if (gameObject && gameObject->IsPedestrianClass()) 29 | { 30 | objectPointer = static_cast(gameObject); 31 | } 32 | return objectPointer; 33 | } 34 | 35 | inline Explosion* ToExplosion(GameObject* gameObject) 36 | { 37 | Explosion* objectPointer = nullptr; 38 | if (gameObject && gameObject->IsExplosionClass()) 39 | { 40 | objectPointer = static_cast(gameObject); 41 | } 42 | return objectPointer; 43 | } 44 | 45 | inline Obstacle* ToObstacle(GameObject* gameObject) 46 | { 47 | Obstacle* objectPointer = nullptr; 48 | if (gameObject && gameObject->IsObstacleClass()) 49 | { 50 | objectPointer = static_cast(gameObject); 51 | } 52 | return objectPointer; 53 | } 54 | 55 | inline Projectile* ToProjectile(GameObject* gameObject) 56 | { 57 | Projectile* objectPointer = nullptr; 58 | if (gameObject && gameObject->IsProjectileClass()) 59 | { 60 | objectPointer = static_cast(gameObject); 61 | } 62 | return objectPointer; 63 | } 64 | 65 | inline Vehicle* ToVehicle(GameObject* gameObject) 66 | { 67 | Vehicle* objectPointer = nullptr; 68 | if (gameObject && gameObject->IsVehicleClass()) 69 | { 70 | objectPointer = static_cast(gameObject); 71 | } 72 | return objectPointer; 73 | } 74 | 75 | ////////////////////////////////////////////////////////////////////////// 76 | 77 | inline bool IsSameClass(GameObject* gameObjectA, GameObject* gameObjectB, eGameObjectClass gameObjectsClass) 78 | { 79 | if (gameObjectA && gameObjectB) 80 | { 81 | return (gameObjectA->mClassID == gameObjectB->mClassID) && 82 | (gameObjectA->mClassID == gameObjectsClass); 83 | } 84 | return false; 85 | } 86 | 87 | inline bool IsSameClass(GameObject* objectA, GameObject* objectB, GameObject* objectC, eGameObjectClass gameObjectsClass) 88 | { 89 | if (objectA && objectB && objectC) 90 | { 91 | return (objectA->mClassID == objectB->mClassID) && 92 | (objectA->mClassID == objectC->mClassID) && 93 | (objectA->mClassID == gameObjectsClass); 94 | } 95 | return false; 96 | } 97 | 98 | ////////////////////////////////////////////////////////////////////////// -------------------------------------------------------------------------------- /src/GameParams.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GameParams.h" 3 | 4 | GameParams gGameParams; 5 | 6 | GameParams::GameParams() 7 | { 8 | SetToDefaults(); 9 | } 10 | 11 | void GameParams::SetToDefaults() 12 | { 13 | // todo: move to config 14 | 15 | // game - commons 16 | mGamePlayerRespawnTime = 6.0f; 17 | mGameRailwaysDamageDelay = 1.5f; 18 | 19 | // pedestrians 20 | mPedestrianBoundsSphereRadius = Convert::MapUnitsToMeters(0.10f); 21 | mPedestrianTurnSpeed = 260.0f; 22 | mPedestrianTurnSpeedSlideOnCar = 120.0f; 23 | mPedestrianSlideOnCarSpeed = Convert::MapUnitsToMeters(1.2f); 24 | mPedestrianWalkSpeed = Convert::MapUnitsToMeters(0.5f); 25 | mPedestrianRunSpeed = Convert::MapUnitsToMeters(1.5f); 26 | mPedestrianSpotTheCarDistance = Convert::MapUnitsToMeters(3.0f); 27 | mPedestrianKnockedDownTime = 3.0f; 28 | mPedestrianFallDeathHeight = Convert::MapUnitsToMeters(2.0f); 29 | mPedestrianDrowningTime = 0.05f; 30 | mPedestrianBurnDuration = 4.0f; 31 | mPedestrianMaxArmor = 3; 32 | // traffic - common 33 | mTrafficGenHareKrishnasTime = 60.0f; 34 | // traffic - pedestrians 35 | mTrafficGenMaxPeds = 20; 36 | mTrafficGenPedsChance = 50; 37 | mTrafficGenPedsMaxDistance = 2; 38 | mTrafficGenPedsCooldownTime = 1.5f; 39 | // traffic - cars 40 | mTrafficGenMaxCars = 12; 41 | mTrafficGenCarsChance = 65; 42 | mTrafficGenCarsMaxDistance = 4; 43 | mTrafficGenCarsCooldownTime = 3.0f; 44 | // explosion 45 | mExplosionRadius = Convert::MapUnitsToMeters(1.0f); 46 | // vehicles 47 | mCarBurnDuration = 20.0f; 48 | mCarSpeedPassengerCanEnter = 8.0f; 49 | mCarExplosionChainDelayTime = 0.5f; 50 | // broadcast events 51 | mBroadcastGunShotEventDuration = 1.0f; 52 | mBroadcastExplosionEventDuration = 1.5f; 53 | // ai 54 | mAiReactOnGunshotsDistance = Convert::MapUnitsToMeters(4.0f); 55 | mAiReactOnExplosionsDistance = Convert::MapUnitsToMeters(5.0f); 56 | // hud 57 | mHudBigFontMessageShowDuration = 3.0f; 58 | mHudCarNameShowDuration = 3.0f; 59 | mHudDistrictNameShowDuration = 3.0f; 60 | // collision 61 | mSparksOnCarsContactThreshold = 60.0f; 62 | } -------------------------------------------------------------------------------- /src/GameTextsManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/src/GameTextsManager.cpp -------------------------------------------------------------------------------- /src/GameTextsManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Class is responsible for reading and storing game messages 4 | class GameTextsManager final: public cxx::noncopyable 5 | { 6 | public: 7 | bool Initialize(); 8 | void Deinit(); 9 | 10 | // Loads game texts from source file 11 | bool LoadTexts(const std::string& fileName); 12 | 13 | // Find game text by text identifier 14 | // @returns default error message on nothing found 15 | const std::string& GetText(const std::string& textID) const; 16 | 17 | private: 18 | std::map mStrings; 19 | std::string mErrorString; 20 | }; 21 | 22 | extern GameTextsManager gGameTexts; -------------------------------------------------------------------------------- /src/GameplayGamestate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GenericGamestate.h" 4 | 5 | // Main game 6 | class GameplayGamestate: public GenericGamestate 7 | { 8 | public: 9 | GameplayGamestate() = default; 10 | 11 | // override GenericGamestate 12 | void OnGamestateEnter() override; 13 | void OnGamestateLeave() override; 14 | void OnGamestateFrame() override; 15 | void OnGamestateInputEvent(KeyInputEvent& inputEvent) override; 16 | void OnGamestateInputEvent(MouseButtonInputEvent& inputEvent) override; 17 | void OnGamestateInputEvent(MouseMovedInputEvent& inputEvent) override; 18 | void OnGamestateInputEvent(MouseScrollInputEvent& inputEvent) override; 19 | void OnGamestateInputEvent(KeyCharEvent& inputEvent) override; 20 | void OnGamestateInputEvent(GamepadInputEvent& inputEvent) override; 21 | void OnGamestateInputEventLost() override; 22 | void OnGamestateBroadcastEvent(const BroadcastEvent& broadcastEvent) override; 23 | 24 | private: 25 | void OnHumanPlayerDie(int playerIndex); 26 | void OnHumanPlayerStartDriveCar(int playerIndex); 27 | }; -------------------------------------------------------------------------------- /src/GenericGamestate.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GenericGamestate.h" 3 | 4 | GenericGamestate::~GenericGamestate() 5 | { 6 | // do nothing 7 | } 8 | 9 | void GenericGamestate::OnGamestateEnter() 10 | { 11 | // do nothing 12 | } 13 | 14 | void GenericGamestate::OnGamestateLeave() 15 | { 16 | // do nothing 17 | } 18 | 19 | void GenericGamestate::OnGamestateFrame() 20 | { 21 | // do nothing 22 | } 23 | 24 | void GenericGamestate::OnGamestateInputEvent(KeyInputEvent& inputEvent) 25 | { 26 | // do nothing 27 | } 28 | 29 | void GenericGamestate::OnGamestateInputEvent(MouseButtonInputEvent& inputEvent) 30 | { 31 | // do nothing 32 | } 33 | 34 | void GenericGamestate::OnGamestateInputEvent(MouseMovedInputEvent& inputEvent) 35 | { 36 | // do nothing 37 | } 38 | 39 | void GenericGamestate::OnGamestateInputEvent(MouseScrollInputEvent& inputEvent) 40 | { 41 | // do nothing 42 | } 43 | 44 | void GenericGamestate::OnGamestateInputEvent(KeyCharEvent& inputEvent) 45 | { 46 | // do nothing 47 | } 48 | 49 | void GenericGamestate::OnGamestateInputEvent(GamepadInputEvent& inputEvent) 50 | { 51 | // do nothing 52 | } 53 | 54 | void GenericGamestate::OnGamestateInputEventLost() 55 | { 56 | // do nothing 57 | } 58 | 59 | void GenericGamestate::OnGamestateBroadcastEvent(const BroadcastEvent& broadcastEvent) 60 | { 61 | // do nothing 62 | } 63 | -------------------------------------------------------------------------------- /src/GenericGamestate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "BroadcastEventsManager.h" 5 | 6 | // Gamestate controller base class 7 | class GenericGamestate 8 | { 9 | public: 10 | GenericGamestate() = default; 11 | virtual ~GenericGamestate(); 12 | 13 | // enter or exit gamestate 14 | virtual void OnGamestateEnter(); 15 | virtual void OnGamestateLeave(); 16 | 17 | // process gamestate frame logic 18 | virtual void OnGamestateFrame(); 19 | 20 | // process gamestate input events 21 | virtual void OnGamestateInputEvent(KeyInputEvent& inputEvent); 22 | virtual void OnGamestateInputEvent(MouseButtonInputEvent& inputEvent); 23 | virtual void OnGamestateInputEvent(MouseMovedInputEvent& inputEvent); 24 | virtual void OnGamestateInputEvent(MouseScrollInputEvent& inputEvent); 25 | virtual void OnGamestateInputEvent(KeyCharEvent& inputEvent); 26 | virtual void OnGamestateInputEvent(GamepadInputEvent& inputEvent); 27 | virtual void OnGamestateInputEventLost(); 28 | 29 | // process game event 30 | virtual void OnGamestateBroadcastEvent(const BroadcastEvent& broadcastEvent); 31 | }; -------------------------------------------------------------------------------- /src/GpuBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | 5 | // defines hardware vertices/indices buffer object 6 | class GpuBuffer final: public cxx::noncopyable 7 | { 8 | public: 9 | // public for convenience, don't change these fields directly 10 | GpuBufferHandle mResourceHandle; 11 | eBufferContent mContent; 12 | eBufferUsage mUsageHint; 13 | unsigned int mBufferLength; // user requested length, bytes 14 | unsigned int mBufferCapacity; // actually allocated length, bytes 15 | 16 | public: 17 | // @param bufferContent: Content type stored in buffer, cannot be changed 18 | GpuBuffer(GraphicsContext& graphicsContext, eBufferContent bufferContent); 19 | ~GpuBuffer(); 20 | 21 | // Will drop buffer data and allocate new chunk of gpu memory 22 | // @param bufferUsage: Usage hint of buffer 23 | // @param theLength: Data length 24 | // @param dataBuffer: Initial data, optional 25 | // @returns false if out of memory 26 | bool Setup(eBufferUsage bufferUsage, unsigned int bufferLength, const void* dataBuffer); 27 | 28 | // Upload source data to buffer replacing old content 29 | // @param dataOffset: Offset within buffer to write in bytes 30 | // @param dataLength: Size of data to write in bytes 31 | // @param dataSource: Source data 32 | bool SubData(unsigned int dataOffset, unsigned int dataLength, const void* dataSource); 33 | 34 | // Resize buffer and save all uploaded data, works only for growth and does nothing if new size less then current capacity 35 | // @param newLength: New buffer size 36 | bool Resize(unsigned int newLength); 37 | 38 | // Map hardware buffer content to process memory 39 | // @param accessBits: Desired data access policy 40 | // @return Pointer to buffer data or null on fail 41 | void* Lock(BufferAccessBits accessBits); 42 | 43 | template 44 | inline TElement* LockData(BufferAccessBits accessBits) 45 | { 46 | return static_cast(Lock(accessBits)); 47 | } 48 | 49 | // Unmap buffer object data source 50 | // @return false on fail, indicates that buffer should be reload 51 | bool Unlock(); 52 | 53 | // Will drop buffer data and allocate new chunk of gpu memory of same size 54 | // This is used in 'orphaning' technique 55 | void Invalidate(); 56 | 57 | // Test whether index or vertex attributes data is currently bound - depends on content 58 | bool IsBufferBound() const; 59 | 60 | // Test whether buffer is created 61 | bool IsBufferInited() const; 62 | 63 | private: 64 | void SetUnbound(); 65 | 66 | private: 67 | GraphicsContext& mGraphicsContext; 68 | }; -------------------------------------------------------------------------------- /src/GpuTexture2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | 5 | // defines hardware 2d texture object 6 | class GpuTexture2D final: public cxx::noncopyable 7 | { 8 | public: 9 | // public for convenience, don't change these fields directly 10 | GpuTextureHandle mResourceHandle; 11 | eTextureFilterMode mFiltering; 12 | eTextureWrapMode mRepeating; 13 | Point mSize; 14 | eTextureFormat mFormat; 15 | 16 | public: 17 | GpuTexture2D(GraphicsContext& graphicsContext); 18 | ~GpuTexture2D(); 19 | 20 | // Create texture of specified format and upload pixels data, no mipmaps 21 | // @param textureFormat: Format 22 | // @param sizex, sizey: Texture dimensions, must be POT! 23 | // @param sourceData: Source data buffer 24 | bool Setup(eTextureFormat textureFormat, int sizex, int sizey, const void* sourceData); 25 | 26 | // Uploads pixels data 27 | // @param mipLevel: Specifies the level-of-detail number; level 0 is the base image level 28 | // @param xoffset, yoffset: Specifies a texel offset within the texture array 29 | // @param sizex, sizey: Specifies the size of the texture subimage 30 | // @param sourceData: Specifies a pointer to the source data 31 | bool Upload(int mipLevel, int xoffset, int yoffset, int sizex, int sizey, const void* sourceData); 32 | bool Upload(const void* sourceData); 33 | 34 | // Set texture filter and wrap parameters 35 | // @param filtering: Filtering mode 36 | // @param repeating: Addressing mode 37 | void SetSamplerState(eTextureFilterMode filtering, eTextureWrapMode repeating); 38 | 39 | // Test whether texture is currently bound at specified texture unit 40 | // @param unitIndex: Index of texture unit 41 | bool IsTextureBound(eTextureUnit textureUnit) const; 42 | bool IsTextureBound() const; 43 | 44 | // Test whether texture is created 45 | bool IsTextureInited() const; 46 | 47 | private: 48 | void SetSamplerStateImpl(eTextureFilterMode filtering, eTextureWrapMode repeating); 49 | void SetUnbound(); 50 | 51 | private: 52 | GraphicsContext& mGraphicsContext; 53 | }; -------------------------------------------------------------------------------- /src/GpuTextureArray2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | 5 | // defines hardware 2d texture object 6 | class GpuTextureArray2D final: public cxx::noncopyable 7 | { 8 | public: 9 | // public for convenience, don't change these fields directly 10 | GpuTextureHandle mResourceHandle; 11 | eTextureFilterMode mFiltering; 12 | eTextureWrapMode mRepeating; 13 | Point mSize; 14 | int mLayersCount; 15 | eTextureFormat mFormat; 16 | 17 | public: 18 | GpuTextureArray2D(GraphicsContext& graphicsContext); 19 | ~GpuTextureArray2D(); 20 | 21 | // Create texture of specified format and upload pixels data, no mipmaps 22 | // @param textureFormat: Format 23 | // @param sizex, sizey: Texture dimensions, must be POT! 24 | // @param layersCount: Number of textures in array 25 | // @param sourceData: Source data buffer, all layers must be specified if not null 26 | bool Setup(eTextureFormat textureFormat, int sizex, int sizey, int layersCount, const void* sourceData); 27 | 28 | // Uploads pixels data for layers, size of source bitmap should match current texture dimensions 29 | // @param startLayerIndex: First layer index 30 | // @param layersCount: Number of layers to upload 31 | // @param sourceData: Source data buffer 32 | bool Upload(int startLayerIndex, int layersCount, const void* sourceData); 33 | 34 | // Set texture filter and wrap parameters 35 | // @param filtering: Filtering mode 36 | // @param repeating: Addressing mode 37 | void SetSamplerState(eTextureFilterMode filtering, eTextureWrapMode repeating); 38 | 39 | // Test whether texture is currently bound at specified texture unit 40 | // @param unitIndex: Index of texture unit 41 | bool IsTextureBound(eTextureUnit textureUnit) const; 42 | bool IsTextureBound() const; 43 | 44 | // Test whether texture is created 45 | bool IsTextureInited() const; 46 | 47 | private: 48 | void SetSamplerStateImpl(eTextureFilterMode filtering, eTextureWrapMode repeating); 49 | void SetUnbound(); 50 | 51 | private: 52 | GraphicsContext& mGraphicsContext; 53 | }; -------------------------------------------------------------------------------- /src/GraphicsContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | 5 | // GraphicsContext represents current graphics device state which is low-level and 6 | // does not intended for direct usage 7 | 8 | class GraphicsContext 9 | { 10 | public: 11 | GraphicsContext() 12 | : mCurrentBuffers() 13 | , mCurrentTextureUnit(eTextureUnit_0) 14 | , mCurrentTextures() 15 | , mCurrentProgram() 16 | , mVaoHandle() 17 | { 18 | } 19 | public: 20 | 21 | struct TextureUnitState 22 | { 23 | // note: mutual exclusion is used for different texture types 24 | GpuTexture2D* mTexture2D = nullptr; 25 | GpuTextureArray2D* mTextureArray2D = nullptr; 26 | }; 27 | 28 | GpuVertexArrayHandle mVaoHandle; 29 | GpuBuffer* mCurrentBuffers[eBufferContent_COUNT]; 30 | GpuProgram* mCurrentProgram; 31 | eTextureUnit mCurrentTextureUnit; 32 | TextureUnitState mCurrentTextures[eTextureUnit_COUNT]; 33 | }; -------------------------------------------------------------------------------- /src/GuiContext.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GuiContext.h" 3 | 4 | bool GuiContext::EnterChildClipArea(const Rect& rcLocal) 5 | { 6 | Rect newCliprect = rcLocal; 7 | TransformClipRect(newCliprect); 8 | 9 | Rect currentCliprect = gGraphicsDevice.mScissorBox; 10 | 11 | newCliprect = newCliprect.GetIntersection(currentCliprect); 12 | if (newCliprect.h < 1 || newCliprect.w < 1) 13 | return false; 14 | 15 | mClipRectsStack.push_back(currentCliprect); 16 | if (newCliprect != currentCliprect) 17 | { 18 | mSpriteBatch.Flush(); 19 | gGraphicsDevice.SetScissorRect(newCliprect); 20 | } 21 | return true; 22 | } 23 | 24 | void GuiContext::LeaveChildClipArea() 25 | { 26 | if (mClipRectsStack.empty()) 27 | { 28 | debug_assert(false); 29 | return; 30 | } 31 | 32 | Rect prevCliprect = mClipRectsStack.back(); 33 | mClipRectsStack.pop_back(); 34 | 35 | Rect currentCliprect = gGraphicsDevice.mScissorBox; 36 | 37 | if (currentCliprect != prevCliprect) 38 | { 39 | mSpriteBatch.Flush(); 40 | gGraphicsDevice.SetScissorRect(prevCliprect); 41 | } 42 | } 43 | 44 | void GuiContext::TransformClipRect(Rect& rectangle) const 45 | { 46 | rectangle.x += mCamera.mViewportRect.x; 47 | rectangle.y = gGraphicsDevice.mScreenResolution.y - (mCamera.mViewportRect.y + rectangle.y + rectangle.h); 48 | // rectangle.y = gGraphicsDevice.mScreenResolution.y - (rectangle.y + rectangle.h); 49 | 50 | //rectangle.y = gGraphicsDevice.mScreenResolution.y - (rectangle.y + mCamera.mViewportRect.y + rectangle.h); 51 | //rectangle.y -= gGraphicsDevice.mScreenResolution.y - (rectangle.y + rectangle.h); 52 | } 53 | -------------------------------------------------------------------------------- /src/GuiContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GuiDefs.h" 4 | 5 | class GuiContext 6 | { 7 | public: 8 | GameCamera2D& mCamera; 9 | SpriteBatch& mSpriteBatch; 10 | 11 | float mUiScale = 1.0f; 12 | 13 | public: 14 | GuiContext(GameCamera2D& camera, SpriteBatch& spriteBatch) 15 | : mCamera(camera) 16 | , mSpriteBatch(spriteBatch) 17 | { 18 | } 19 | 20 | // helpers 21 | inline int GetScreenSizex() const { return mCamera.mViewportRect.w; } 22 | inline int GetScreenSizey() const { return mCamera.mViewportRect.h; } 23 | 24 | // convert 25 | inline void NormalizedToScreenPoint(float xcoord, float ycoord, int& outx, int& outy) const 26 | { 27 | outx = static_cast(mCamera.mViewportRect.w * xcoord); 28 | outy = static_cast(mCamera.mViewportRect.h * ycoord); 29 | } 30 | inline void ScreenPointToNormalized(int xcoord, int ycoord, float& outx, float& outy) const 31 | { 32 | debug_assert(mCamera.mViewportRect.w); 33 | debug_assert(mCamera.mViewportRect.h); 34 | 35 | outx = (xcoord * 1.0f) / mCamera.mViewportRect.w; 36 | outy = (ycoord * 1.0f) / mCamera.mViewportRect.h; 37 | } 38 | 39 | bool EnterChildClipArea(const Rect& rcLocal); 40 | void LeaveChildClipArea(); 41 | 42 | private: 43 | void TransformClipRect(Rect& rectangle) const; 44 | 45 | private: 46 | std::vector mClipRectsStack; 47 | }; -------------------------------------------------------------------------------- /src/GuiDefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class GameCamera2D; 4 | class GuiContext; 5 | class Font; 6 | 7 | enum eHUDMessageType 8 | { 9 | eHUDMessageType_Pager, 10 | eHUDMessageType_Help, 11 | eHUDMessageType_Mission, 12 | eHUDMessageType_BombCost, 13 | eHUDMessageType_COUNT 14 | }; 15 | 16 | enum eHUDBigFontMessage 17 | { 18 | eHUDBigFontMessage_MissionComplete, 19 | eHUDBigFontMessage_MissionFailed, 20 | eHUDBigFontMessage_KillFrenzy, 21 | eHUDBigFontMessage_FrenzyFailed, 22 | eHUDBigFontMessage_ExtraLifeBonus, 23 | eHUDBigFontMessage_Gouranga, 24 | eHUDBigFontMessage_YouGotIt, 25 | eHUDBigFontMessage_FrenzyPassed, 26 | eHUDBigFontMessage_BonusLost, 27 | eHUDBigFontMessage_Busted, 28 | eHUDBigFontMessage_Wasted, 29 | eHUDBigFontMessage_GoGoGo, 30 | eHUDBigFontMessage_COUNT 31 | }; 32 | 33 | // HUD message data 34 | struct HUDMessageData 35 | { 36 | eHUDMessageType mMessageType {}; 37 | std::string mMessageText; 38 | }; -------------------------------------------------------------------------------- /src/GuiManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameCamera.h" 4 | #include "SpriteBatch.h" 5 | #include "GuiScreen.h" 6 | 7 | // manages all graphical user interface operation 8 | class GuiManager final: public InputEventsHandler 9 | { 10 | public: 11 | // setup/free internal resources 12 | bool Initialize(); 13 | void Deinit(); 14 | 15 | void RenderFrame(); 16 | void UpdateFrame(); 17 | 18 | // manage gui screens 19 | void AttachScreen(GuiScreen* screen); 20 | void DetachScreen(GuiScreen* screen); 21 | 22 | // override InputEventsHandler 23 | void InputEvent(MouseMovedInputEvent& inputEvent) override; 24 | void InputEvent(MouseScrollInputEvent& inputEvent) override; 25 | void InputEvent(MouseButtonInputEvent& inputEvent) override; 26 | void InputEvent(KeyInputEvent& inputEvent) override; 27 | void InputEvent(KeyCharEvent& inputEvent) override; 28 | void InputEvent(GamepadInputEvent& inputEvent) override; 29 | 30 | private: 31 | SpriteBatch mSpriteBatch; 32 | GameCamera2D mCamera2D; 33 | std::vector mScreensList; 34 | }; 35 | 36 | extern GuiManager gGuiManager; -------------------------------------------------------------------------------- /src/GuiScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class GuiContext; 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | class GuiScreen: public cxx::noncopyable 8 | { 9 | public: 10 | Rect mScreenArea; 11 | 12 | public: 13 | GuiScreen() = default; 14 | virtual ~GuiScreen() 15 | { 16 | } 17 | // update frame 18 | virtual void UpdateScreen() 19 | { 20 | } 21 | // render frame 22 | virtual void DrawScreen(GuiContext& context) 23 | { 24 | } 25 | }; 26 | 27 | ////////////////////////////////////////////////////////////////////////// -------------------------------------------------------------------------------- /src/ImGuiHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "imgui.h" 4 | 5 | namespace ImGui 6 | { 7 | inline void HorzSpacing(float spacingSize = 10.0f) 8 | { 9 | Dummy(ImVec2(0.0f, spacingSize)); 10 | } 11 | inline void VertSpacing(float spacingSize = 10.0f) 12 | { 13 | Dummy(ImVec2(spacingSize, 0.0f)); 14 | } 15 | } -------------------------------------------------------------------------------- /src/ImGuiManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "imgui.h" 4 | #include "TrimeshBuffer.h" 5 | 6 | class ImGuiManager final: public InputEventsHandler 7 | { 8 | public: 9 | // setup/free internal resources 10 | bool Initialize(); 11 | void Deinit(); 12 | bool IsInitialized() const; 13 | 14 | void RenderFrame(); 15 | void UpdateFrame(); 16 | 17 | // override InputEventsHandler 18 | void InputEvent(MouseMovedInputEvent& inputEvent) override; 19 | void InputEvent(MouseScrollInputEvent& inputEvent) override; 20 | void InputEvent(MouseButtonInputEvent& inputEvent) override; 21 | void InputEvent(KeyInputEvent& inputEvent) override; 22 | void InputEvent(KeyCharEvent& inputEvent) override; 23 | void InputEvent(GamepadInputEvent& inputEvent) override; 24 | 25 | private: 26 | // internals 27 | bool AddFontFromExternalFile(ImGuiIO& imguiIO, const char* fontFile, float fontSize); 28 | void SetupStyle(ImGuiIO& imguiIO); 29 | 30 | private: 31 | TrimeshBuffer mTrimeshBuffer; 32 | }; 33 | 34 | extern ImGuiManager gImGuiManager; -------------------------------------------------------------------------------- /src/InputActionsMapping.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "InputsDefs.h" 4 | 5 | // Contains input actions mapping for human player 6 | class InputActionsMapping 7 | { 8 | public: 9 | InputActionsMapping(); 10 | 11 | // Setup actions mapping from config node 12 | void LoadConfig(cxx::json_document_node& configNode); 13 | void SaveConfig(cxx::json_document_node& configNode); 14 | 15 | void SetDefaults(); 16 | void Clear(); 17 | 18 | // Get action mapped to input keycode or gamepad button 19 | // @returns eInputAction_null if no action is mapped to input key 20 | eInputAction GetAction(eInputActionsGroup group, eKeycode keycode) const; 21 | eInputAction GetAction(eInputActionsGroup group, eGamepadButton gpButton) const; 22 | 23 | // Set action mapped to input keycode or gamepad button 24 | void SetAction(eInputActionsGroup group, eKeycode keycode, eInputAction action); 25 | void SetAction(eInputActionsGroup group, eGamepadButton gpButton, eInputAction action); 26 | 27 | // Get input group by action identifier 28 | eInputActionsGroup GetInputActionsGroup(eInputAction action) const; 29 | 30 | public: 31 | // readonly 32 | struct ActionsByGroup 33 | { 34 | eInputAction mActions[eInputActionsGroup_COUNT]; 35 | }; 36 | ActionsByGroup mKeycodeActions[eKeycode_COUNT]; // key to action mapping 37 | ActionsByGroup mGpButtonActions[eGamepadButton_COUNT]; // gamepad button to action mapping 38 | 39 | struct ActionToKey 40 | { 41 | eKeycode mKeycode; 42 | eGamepadButton mGpButton; 43 | }; 44 | ActionToKey mActionToKeys[eInputAction_COUNT]; 45 | 46 | eGamepadID mGamepadID = eGamepadID_Gamepad1; 47 | }; -------------------------------------------------------------------------------- /src/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | #if OS_NAME == OS_WINDOWS 6 | _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 7 | #endif 8 | gSystem.Run(argc - 1, argv + 1); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /src/MainMenuGamestate.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "MainMenuGamestate.h" 3 | 4 | void MainMenuGamestate::OnGamestateEnter() 5 | { 6 | } 7 | 8 | void MainMenuGamestate::OnGamestateLeave() 9 | { 10 | } 11 | 12 | void MainMenuGamestate::OnGamestateFrame() 13 | { 14 | } 15 | 16 | void MainMenuGamestate::OnGamestateInputEvent(KeyInputEvent& inputEvent) 17 | { 18 | } 19 | 20 | void MainMenuGamestate::OnGamestateInputEvent(MouseButtonInputEvent& inputEvent) 21 | { 22 | } 23 | 24 | void MainMenuGamestate::OnGamestateInputEvent(MouseMovedInputEvent& inputEvent) 25 | { 26 | } 27 | 28 | void MainMenuGamestate::OnGamestateInputEvent(MouseScrollInputEvent& inputEvent) 29 | { 30 | } 31 | 32 | void MainMenuGamestate::OnGamestateInputEvent(KeyCharEvent& inputEvent) 33 | { 34 | } 35 | 36 | void MainMenuGamestate::OnGamestateInputEvent(GamepadInputEvent& inputEvent) 37 | { 38 | } 39 | 40 | void MainMenuGamestate::OnGamestateInputEventLost() 41 | { 42 | } -------------------------------------------------------------------------------- /src/MainMenuGamestate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GenericGamestate.h" 4 | 5 | class MainMenuGamestate: public GenericGamestate 6 | { 7 | public: 8 | MainMenuGamestate() = default; 9 | 10 | // override GenericGamestate 11 | void OnGamestateEnter() override; 12 | void OnGamestateLeave() override; 13 | void OnGamestateFrame() override; 14 | void OnGamestateInputEvent(KeyInputEvent& inputEvent) override; 15 | void OnGamestateInputEvent(MouseButtonInputEvent& inputEvent) override; 16 | void OnGamestateInputEvent(MouseMovedInputEvent& inputEvent) override; 17 | void OnGamestateInputEvent(MouseScrollInputEvent& inputEvent) override; 18 | void OnGamestateInputEvent(KeyCharEvent& inputEvent) override; 19 | void OnGamestateInputEvent(GamepadInputEvent& inputEvent) override; 20 | void OnGamestateInputEventLost() override; 21 | 22 | private: 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /src/MapRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SpriteBatch.h" 4 | #include "GameDefs.h" 5 | 6 | class DebugRenderer; 7 | 8 | // map renderer statistics info 9 | struct MapRenderStats 10 | { 11 | public: 12 | MapRenderStats() = default; 13 | void FrameBegin(); 14 | void FrameEnd(); 15 | 16 | public: 17 | int mBlockChunksDrawnCount = 0; // per frame 18 | int mSpritesDrawnCount = 0; // per frame 19 | 20 | unsigned int mRenderFramesCounter = 0; // gets incremented on every frame 21 | }; 22 | 23 | // renders map mesh, peds, cars and map objects 24 | class MapRenderer final: public cxx::noncopyable 25 | { 26 | public: 27 | MapRenderStats mRenderStats; 28 | 29 | public: 30 | bool Initialize(); 31 | void Deinit(); 32 | void RenderFrameBegin(); 33 | void RenderFrame(GameCamera* renderview); 34 | void DebugDraw(DebugRenderer& debugRender); 35 | void RenderFrameEnd(); 36 | void BuildMapMesh(); 37 | 38 | private: 39 | void DrawCityMesh(GameCamera* renderview); 40 | void DrawGameObject(GameCamera* renderview, GameObject* gameObject); 41 | void PreDrawGameObject(GameObject* gameObject); 42 | 43 | private: 44 | enum 45 | { 46 | BlocksBatchDims = 22, // 22 x 22 x 6 blocks per batch 47 | ExtraBlocksPerSide = 4, 48 | BlocksBatchesPerSide = ((MAP_DIMENSIONS + (ExtraBlocksPerSide * 2)) + BlocksBatchDims - 1) / BlocksBatchDims, 49 | BlocksBatchCount = BlocksBatchesPerSide * BlocksBatchesPerSide, 50 | }; 51 | struct MapBlocksChunk 52 | { 53 | cxx::aabbox_t mBounds; // for culling 54 | // index/vertex data offset in vbo 55 | unsigned int mIndicesStart = 0, mIndicesCount = 0; 56 | unsigned int mVerticesStart = 0, mVerticesCount = 0; 57 | }; 58 | MapBlocksChunk mMapBlocksChunks[BlocksBatchCount]; 59 | 60 | GpuBuffer* mCityMeshBufferV; 61 | GpuBuffer* mCityMeshBufferI; 62 | 63 | SpriteBatch mSpriteBatch; 64 | }; -------------------------------------------------------------------------------- /src/MemoryManager.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "MemoryManager.h" 3 | #include "cvars.h" 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | const int SysMemoryFrameHeapSize = 12 * 1024 * 1024; 8 | 9 | ////////////////////////////////////////////////////////////////////////// 10 | 11 | MemoryManager gMemoryManager; 12 | 13 | bool MemoryManager::Initialize() 14 | { 15 | gConsole.LogMessage(eLogMessage_Info, "Init MemoryManager"); 16 | 17 | if (gCvarMemEnableFrameHeapAllocator.mValue) 18 | { 19 | gConsole.LogMessage(eLogMessage_Info, "Frame heap memory size: %d", SysMemoryFrameHeapSize); 20 | 21 | mFrameHeapAllocator = new cxx::linear_memory_allocator; 22 | if (!mFrameHeapAllocator->init_allocator(SysMemoryFrameHeapSize)) 23 | { 24 | gConsole.LogMessage(eLogMessage_Warning, "Fail to allocate frame heap memory buffer"); 25 | SafeDelete(mFrameHeapAllocator); 26 | } 27 | else 28 | { 29 | // setup out of memory handler 30 | mFrameHeapAllocator->mOutOfMemoryProc = [](unsigned int allocateBytes) 31 | { 32 | gConsole.LogMessage(eLogMessage_Warning, "Cannot allocate %d bytes on frame heap", allocateBytes); 33 | debug_assert(false); 34 | }; 35 | } 36 | } 37 | else 38 | { 39 | gConsole.LogMessage(eLogMessage_Info, "Frame heap memory disabled"); 40 | } 41 | 42 | mHeapAllocator = new cxx::heap_memory_allocator; 43 | mHeapAllocator->init_allocator(0); 44 | 45 | mHeapAllocator->mOutOfMemoryProc = [](unsigned int allocateBytes) 46 | { 47 | gConsole.LogMessage(eLogMessage_Warning, "Cannot allocate %d bytes", allocateBytes); 48 | debug_assert(false); 49 | }; 50 | 51 | return true; 52 | } 53 | 54 | void MemoryManager::Deinit() 55 | { 56 | SafeDelete(mFrameHeapAllocator); 57 | SafeDelete(mHeapAllocator); 58 | } 59 | 60 | void MemoryManager::FlushFrameHeapMemory() 61 | { 62 | if (mFrameHeapAllocator) 63 | { 64 | mFrameHeapAllocator->reset(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/MemoryManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mem_allocators.h" 4 | 5 | // defines system memory manager class 6 | class MemoryManager final: public cxx::noncopyable 7 | { 8 | public: 9 | // allocates and deallocates frame heap memory 10 | 11 | // it's intended for objects that only should exist for a short period of time 12 | // all allocated memory most likely will be invalidated at start of next frame 13 | cxx::memory_allocator* mFrameHeapAllocator = nullptr; 14 | 15 | cxx::memory_allocator* mHeapAllocator = nullptr; // standard heap memory allocator 16 | 17 | public: 18 | // setup memory manager internal resources 19 | // @returns false on error 20 | bool Initialize(); 21 | 22 | void Deinit(); 23 | 24 | // will reset previously allocated frame heap memory 25 | void FlushFrameHeapMemory(); 26 | }; 27 | 28 | extern MemoryManager gMemoryManager; -------------------------------------------------------------------------------- /src/Obstacle.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Obstacle.h" 3 | #include "TimeManager.h" 4 | #include "SpriteManager.h" 5 | 6 | Obstacle::Obstacle(GameObjectID id, GameObjectInfo* desc) 7 | : GameObject(eGameObjectClass_Obstacle, id) 8 | , mGameObjectDesc(desc) 9 | { 10 | debug_assert(mGameObjectDesc); 11 | if (mGameObjectDesc) 12 | { 13 | mDrawSprite.mDrawOrder = mGameObjectDesc->mDrawOrder; 14 | } 15 | } 16 | 17 | void Obstacle::UpdateFrame() 18 | { 19 | float deltaTime = gTimeManager.mGameFrameDelta; 20 | if (mAnimationState.UpdateFrame(deltaTime)) 21 | { 22 | SetSprite(mAnimationState.GetSpriteIndex(), 0); 23 | } 24 | } 25 | 26 | void Obstacle::DebugDraw(DebugRenderer& debugRender) 27 | { 28 | } 29 | 30 | void Obstacle::HandleSpawn() 31 | { 32 | debug_assert(mGameObjectDesc); 33 | 34 | mRemapClut = 0; 35 | 36 | mAnimationState.Clear(); 37 | mAnimationState.mAnimDesc = mGameObjectDesc->mAnimationData; 38 | 39 | //mAnimationState.PlayAnimation(eSpriteAnimLoop_FromStart); 40 | 41 | SetSprite(mAnimationState.GetSpriteIndex(), 0); 42 | } 43 | -------------------------------------------------------------------------------- /src/Obstacle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameObject.h" 4 | 5 | class Obstacle final: public GameObject 6 | { 7 | friend class GameObjectsManager; 8 | 9 | public: 10 | Obstacle(GameObjectID id, GameObjectInfo* desc); 11 | 12 | // override GameObject 13 | void UpdateFrame() override; 14 | void DebugDraw(DebugRenderer& debugRender) override; 15 | void HandleSpawn() override; 16 | 17 | private: 18 | SpriteAnimation mAnimationState; 19 | GameObjectInfo* mGameObjectDesc = nullptr; 20 | }; -------------------------------------------------------------------------------- /src/OpenALDefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if OS_NAME == OS_MACOS 4 | #include 5 | #include 6 | #else 7 | #include 8 | #include 9 | #endif 10 | 11 | // checks current openal error code 12 | #ifdef _DEBUG 13 | #define alCheckError()\ 14 | {\ 15 | ALenum errcode = ::alGetError();\ 16 | if (errcode != AL_NO_ERROR)\ 17 | {\ 18 | gConsole.LogMessage(eLogMessage_Error, "OpenAL error detected in %s, code 0x%04X", __FUNCTION__, errcode);\ 19 | gConsole.LogMessage(eLogMessage_Error, "(%s)", ::alGetString(errcode)); \ 20 | debug_assert(false); \ 21 | }\ 22 | } 23 | #else 24 | #define alCheckError() 25 | #endif 26 | 27 | // resets current openal error code 28 | inline void alClearError() 29 | { 30 | for (ALenum alErrorCode = ::alGetError(); alErrorCode != AL_NO_ERROR; alErrorCode = ::alGetError()) 31 | { 32 | } 33 | } 34 | 35 | // Audio device capabilities 36 | struct AudioDeviceCaps 37 | { 38 | public: 39 | AudioDeviceCaps() = default; 40 | 41 | public: 42 | int mMaxSourcesMono = 0; 43 | int mMaxSourcesStereo = 0; 44 | }; 45 | -------------------------------------------------------------------------------- /src/ParticleEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ParticleDefs.h" 4 | 5 | // forwards 6 | class ParticleRenderdata; 7 | 8 | enum eParticleEffectState 9 | { 10 | eParticleEffectState_Initial, // effect is waiting to be configured and launched 11 | eParticleEffectState_Active, // effect is emitting particles 12 | eParticleEffectState_Stopping, // no longer emitting new particles, but some is still alive 13 | eParticleEffectState_Done, // effect is inactive 14 | }; 15 | 16 | // particles generator class 17 | class ParticleEffect final: public cxx::noncopyable 18 | { 19 | friend class RenderingManager; 20 | 21 | public: 22 | ParticleEffect() = default; 23 | ~ParticleEffect(); 24 | 25 | void UpdateFrame(); 26 | void DebugDraw(DebugRenderer& debugRender); 27 | 28 | // Effect control 29 | void StartEffect(); 30 | void StopEffect(); 31 | void ClearEffect(); 32 | 33 | // Manually spawn particles 34 | bool PutParticle(const glm::vec3& position); 35 | bool PutParticle(const glm::vec3& position, const glm::vec3& velocity); 36 | 37 | // Whether or not effect is in active state 38 | bool IsEffectInactive() const; 39 | bool IsEffectActive() const; 40 | 41 | // Setup main particle effect parameters 42 | void GetEffectParameters(ParticleEffectParams& effectParams) const; 43 | void SetEffectParameters(const ParticleEffectParams& effectParams); 44 | 45 | // Setup emitter shape parameters 46 | void GetEmitterShape(ParticleEmitterShape& emitterShape) const; 47 | void SetEmitterShape(const ParticleEmitterShape& emitterShape); 48 | 49 | private: 50 | void ResetParticles(); 51 | // returns false if particle dead 52 | bool UpdateParticle(Particle& particle, float deltaTime); 53 | void SpawnParticle(Particle& particle); 54 | 55 | void UpdateAliveParticles(float deltaTime); 56 | void GenerateNewParticles(); 57 | 58 | void SetRenderdata(ParticleRenderdata* renderdata); 59 | 60 | private: 61 | ParticleEffectParams mEffectParams; 62 | ParticleEmitterShape mEmitterShapeParams; 63 | eParticleEffectState mEffectState = eParticleEffectState_Initial; 64 | std::vector mParticles; 65 | float mParticleTimer = 0.0f; 66 | float mActivityTimer = 0.0f; 67 | int mAliveParticlesCount = 0; 68 | ParticleRenderdata* mRenderdata = nullptr; // renderdata is owned by particle renderer 69 | }; -------------------------------------------------------------------------------- /src/ParticleEffectsManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ParticleEffect.h" 4 | 5 | // Particle effects manager class 6 | class ParticleEffectsManager final: public cxx::noncopyable 7 | { 8 | public: 9 | // readonly 10 | std::vector mParticleEffects; 11 | 12 | public: 13 | ParticleEffectsManager(); 14 | 15 | void EnterWorld(); 16 | void ClearWorld(); 17 | void UpdateFrame(); 18 | void DebugDraw(DebugRenderer& debugRender); 19 | 20 | // Create new particle effect on game scene 21 | ParticleEffect* CreateParticleEffect(const ParticleEffectParams& effectParams, const ParticleEmitterShape& emitterShape); 22 | 23 | // Free particle effect object 24 | // @param particleEffect: Object to destroy, pointer becomes invalid 25 | void DestroyParticleEffect(ParticleEffect* particleEffect); 26 | void DestroyParticleEffects(); 27 | 28 | // sparks effect 29 | void StartCarSparks(const glm::vec3& position, int numSparks); 30 | void StartCarSparks(const glm::vec3& position, const glm::vec3& velocity, int numSparks); 31 | 32 | bool IsCarSparksEffectEnabled() const; 33 | 34 | private: 35 | void CreateSparksParticleEffect(); 36 | 37 | private: 38 | // persistent effects 39 | ParticleEffect* mSparksEffect = nullptr; 40 | }; 41 | 42 | extern ParticleEffectsManager gParticleManager; -------------------------------------------------------------------------------- /src/ParticleRenderdata.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ParticleRenderdata.h" 3 | 4 | void ParticleRenderdata::Invalidate() 5 | { 6 | mIsInvalidated = true; 7 | } 8 | 9 | bool ParticleRenderdata::PrepareVertexbuffer(int vertexbufferSize) 10 | { 11 | if (vertexbufferSize == 0) 12 | return true; 13 | 14 | if (mVertexBuffer == nullptr) 15 | { 16 | mVertexBuffer = gGraphicsDevice.CreateBuffer(eBufferContent_Vertices, eBufferUsage_Stream, vertexbufferSize, nullptr); 17 | if (mVertexBuffer == nullptr) 18 | return false; 19 | 20 | return true; 21 | } 22 | 23 | return mVertexBuffer->Setup(eBufferUsage_Stream, vertexbufferSize, nullptr); 24 | } 25 | 26 | void ParticleRenderdata::DestroyVertexbuffer() 27 | { 28 | if (mVertexBuffer) 29 | { 30 | gGraphicsDevice.DestroyBuffer(mVertexBuffer); 31 | mVertexBuffer = nullptr; 32 | } 33 | } 34 | 35 | void ParticleRenderdata::ResetInvalidated() 36 | { 37 | mIsInvalidated = false; 38 | } 39 | -------------------------------------------------------------------------------- /src/ParticleRenderdata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GpuBuffer.h" 4 | 5 | // Renderdata is associated with particle effect instance 6 | class ParticleRenderdata final: public cxx::noncopyable 7 | { 8 | friend class RenderingManager; 9 | 10 | public: 11 | void Invalidate(); 12 | void ResetInvalidated(); 13 | private: 14 | bool PrepareVertexbuffer(int vertexbufferSize); 15 | void DestroyVertexbuffer(); 16 | private: 17 | GpuBuffer* mVertexBuffer = nullptr; 18 | bool mIsInvalidated = false; 19 | }; -------------------------------------------------------------------------------- /src/PedestrianInfo.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "PedestrianInfo.h" 3 | 4 | void PedestrianInfo::AddFears(PedestrianFearFlags fearFlags) 5 | { 6 | mFearFlags = mFearFlags | fearFlags; 7 | } 8 | 9 | void PedestrianInfo::RemoveFears(PedestrianFearFlags fearFlags) 10 | { 11 | mFearFlags = (mFearFlags & ~fearFlags); 12 | } 13 | 14 | bool PedestrianInfo::SetupFromConfg(cxx::json_document_node configNode) 15 | { 16 | Clear(); 17 | 18 | if (!cxx::json_get_attribute(configNode, "ped_type", mTypeID)) 19 | { 20 | gConsole.LogMessage(eLogMessage_Warning, "Unknown pedestrian type ID"); 21 | return false; 22 | } 23 | 24 | if (cxx::json_node_string remapTypeNode = configNode["remap_type"]) 25 | { 26 | std::string remapTypeString = remapTypeNode.get_value(); 27 | if (remapTypeString == "random_civilian") 28 | { 29 | mRemapType = ePedestrianRemapType_RandomCivilian; 30 | } 31 | } 32 | cxx::json_get_attribute(configNode, "remap_index", mRemapIndex); 33 | 34 | // read fears 35 | if (cxx::json_node_array fearsNode = configNode["fears"]) 36 | { 37 | for (cxx::json_node_string currFear = fearsNode.first_child(); 38 | currFear; currFear = currFear.next_sibling()) 39 | { 40 | std::string fearName = currFear.get_value(); 41 | 42 | if (fearName == "players") 43 | { 44 | AddFears(PedestrianFearFlags_Players); 45 | continue; 46 | } 47 | 48 | if (fearName == "police") 49 | { 50 | AddFears(PedestrianFearFlags_Police); 51 | continue; 52 | } 53 | 54 | if (fearName == "gunShots") 55 | { 56 | AddFears(PedestrianFearFlags_GunShots); 57 | continue; 58 | } 59 | 60 | if (fearName == "explosions") 61 | { 62 | AddFears(PedestrianFearFlags_Explosions); 63 | continue; 64 | } 65 | 66 | if (fearName == "deadPeds") 67 | { 68 | AddFears(PedestrianFearFlags_DeadPeds); 69 | continue; 70 | } 71 | 72 | debug_assert(false); 73 | gConsole.LogMessage(eLogMessage_Warning, "Unknown pedestrian fear flag '%s'", fearName.c_str()); 74 | } 75 | } 76 | 77 | return true; 78 | } 79 | 80 | void PedestrianInfo::Clear() 81 | { 82 | mTypeID = ePedestrianType_Civilian; 83 | mFearFlags = PedestrianFearFlags_None; 84 | mRemapIndex = NO_REMAP; 85 | mRemapType = ePedestrianRemapType_Index; 86 | } -------------------------------------------------------------------------------- /src/PedestrianInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Pedestrian types 4 | enum ePedestrianType 5 | { 6 | ePedestrianType_Player1, 7 | ePedestrianType_Player2, 8 | ePedestrianType_Player3, 9 | ePedestrianType_Player4, 10 | ePedestrianType_Civilian, 11 | ePedestrianType_Police, 12 | ePedestrianType_HareKrishnasGang, 13 | ePedestrianType_Medical, 14 | ePedestrianType_Fireman, 15 | ePedestrianType_COUNT 16 | }; 17 | 18 | decl_enum_strings(ePedestrianType); 19 | 20 | enum PedestrianFearFlags 21 | { 22 | PedestrianFearFlags_None = 0, 23 | PedestrianFearFlags_Players = BIT(0), 24 | PedestrianFearFlags_Police = BIT(1), 25 | PedestrianFearFlags_GunShots = BIT(2), 26 | PedestrianFearFlags_Explosions = BIT(3), 27 | PedestrianFearFlags_DeadPeds = BIT(4), 28 | }; 29 | 30 | decl_enum_as_flags(PedestrianFearFlags); 31 | 32 | enum ePedestrianRemapType 33 | { 34 | ePedestrianRemapType_Index, 35 | ePedestrianRemapType_RandomCivilian, 36 | }; 37 | 38 | // Contains properties for specific pedestrian type 39 | struct PedestrianInfo 40 | { 41 | public: 42 | PedestrianInfo() = default; 43 | 44 | // Load pedestrian info from json node 45 | bool SetupFromConfg(cxx::json_document_node configNode); 46 | 47 | // Reset pedestrian info to default state 48 | void Clear(); 49 | 50 | // Whether pedestrian has specific fears 51 | bool HasFear_Players() const 52 | { 53 | return (mFearFlags & PedestrianFearFlags_Players) > 0; 54 | } 55 | bool HasFear_Police() const 56 | { 57 | return (mFearFlags & PedestrianFearFlags_Police) > 0; 58 | } 59 | bool HasFear_GunShots() const 60 | { 61 | return (mFearFlags & PedestrianFearFlags_GunShots) > 0; 62 | } 63 | bool HasFear_Explosions() const 64 | { 65 | return (mFearFlags & PedestrianFearFlags_Explosions) > 0; 66 | } 67 | bool HasFear_DeadPeds() const 68 | { 69 | return (mFearFlags & PedestrianFearFlags_DeadPeds) > 0; 70 | } 71 | 72 | void AddFears(PedestrianFearFlags fearFlags); 73 | void RemoveFears(PedestrianFearFlags fearFlags); 74 | 75 | public: 76 | ePedestrianType mTypeID = ePedestrianType_Civilian; 77 | PedestrianFearFlags mFearFlags = PedestrianFearFlags_None; 78 | ePedestrianRemapType mRemapType = ePedestrianRemapType_Index; 79 | int mRemapIndex = NO_REMAP; // valid if ePedestrianRemapType_Index 80 | }; -------------------------------------------------------------------------------- /src/PixelsArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // defines bitmap in system memory 4 | class PixelsArray final: public cxx::noncopyable 5 | { 6 | public: 7 | eTextureFormat mFormat = eTextureFormat_Null; 8 | 9 | int mSizex = 0; 10 | int mSizey = 0; 11 | unsigned char* mData = nullptr; 12 | 13 | public: 14 | ~PixelsArray(); 15 | 16 | // Allocates array of pixels of specified format and dimensions 17 | // @param format: Format 18 | // @param sizex, sizey: Dimensions 19 | // @param allocator: Custom memory allocator, optional 20 | bool Create(eTextureFormat format, int sizex, int sizey, cxx::memory_allocator* allocator = nullptr); 21 | 22 | // Free allocated memory 23 | void Cleanup(); 24 | 25 | // Load bitmap from external file 26 | // Note that filesystem must be initialized otherwise error occurs 27 | // @param fileName: File name 28 | // @param forceFormat: Explicit format conversion, optional 29 | // @param allocator: Custom memory allocator, optional 30 | bool LoadFromFile(const std::string& fileName, eTextureFormat forceFormat = eTextureFormat_Null, cxx::memory_allocator* allocator = nullptr); 31 | 32 | // Save bitmap content to external file 33 | // Note that filesystem must be initialized otherwise error occurs 34 | // @param fileName: File name 35 | bool SaveToFile(const std::string& fileName); 36 | 37 | // Fill bitmap with checkerboard pattern, does not allocate memory 38 | // @returns false if bitmap null 39 | bool FillWithCheckerBoard(); 40 | 41 | // Fill bitmap with solid color, does not allocate memory 42 | // @returns false if bitmap null 43 | bool FillWithColor(Color32 color); 44 | 45 | // Test whether bitmap has pixels 46 | bool HasContent() const; 47 | 48 | // Save pixels of specified format to external file 49 | // @param fileName: File name 50 | // @param format: Format of pixels array 51 | // @param sizex, sizey: Picture dimensions 52 | // @param pixels: Source data 53 | static bool SaveToFile(const std::string& fileName, eTextureFormat format, int sizex, int sizey, unsigned char* pixels); 54 | 55 | private: 56 | void SetPixelsAllocator(cxx::memory_allocator* allocator); 57 | 58 | private: 59 | cxx::memory_allocator* mPixelsAllocator = nullptr; 60 | }; -------------------------------------------------------------------------------- /src/Projectile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WeaponInfo.h" 4 | #include "GameObject.h" 5 | #include "PhysicsBody.h" 6 | 7 | class Projectile final: public GameObject 8 | { 9 | friend class GameObjectsManager; 10 | 11 | public: 12 | // readonly 13 | WeaponInfo* mWeaponInfo = nullptr; 14 | PedestrianHandle mShooter; 15 | 16 | public: 17 | Projectile(WeaponInfo* weaponInfo, Pedestrian* shooter); 18 | 19 | // override GameObject 20 | void UpdateFrame() override; 21 | void SimulationStep() override; 22 | void DebugDraw(DebugRenderer& debugRender) override; 23 | void HandleSpawn() override; 24 | bool ShouldCollide(GameObject* otherObject) const override; 25 | void HandleCollisionWithMap(const MapCollision& collision) override; 26 | 27 | private: 28 | void ClearCurrentHit(); 29 | 30 | private: 31 | SpriteAnimation mAnimationState; 32 | glm::vec3 mStartPosition; 33 | 34 | bool mHitSomething = false; 35 | GameObjectHandle mHitObject; // null if hit wall 36 | ContactPoint mHitPoint; 37 | }; -------------------------------------------------------------------------------- /src/RenderProgram.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | 5 | // defines base class for render program 6 | class RenderProgram: public cxx::noncopyable 7 | { 8 | public: 9 | const char* const mSourceFileName; // immutable 10 | 11 | // public for convenience, should not be modified directly 12 | GpuProgram* mGpuProgram = nullptr; 13 | 14 | public: 15 | // @param srcFileName: File name of shader source, should be static string 16 | RenderProgram(const char* srcFileName); 17 | virtual ~RenderProgram(); 18 | 19 | // loading and uloading routines, returns false on error 20 | bool Initialize(); 21 | bool Reinitialize(); 22 | void Deinit(); 23 | 24 | // test whether program is initialized and currently active 25 | bool IsProgramInited() const; 26 | bool IsActive() const; 27 | 28 | // activate or deactivate render program 29 | void Activate(); 30 | void Deactivate(); 31 | 32 | // will update projection and view parameters of render program 33 | // the matrices stored in game camera class, make sure compute them first 34 | void UploadCameraTransformMatrices(GameCamera& gameCamera); 35 | void UploadCameraTransformMatrices(GameCamera2D& gameCamera); 36 | 37 | protected: 38 | // overridable 39 | virtual void InitUniformParameters(); 40 | virtual void BindUniformParameters(); 41 | }; -------------------------------------------------------------------------------- /src/RenderingManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicsDefs.h" 4 | #include "RenderProgram.h" 5 | #include "MapRenderer.h" 6 | #include "DebugRenderer.h" 7 | #include "ParticleEffect.h" 8 | 9 | // master render system, it is intended to manage rendering pipeline of the game 10 | class RenderingManager final: public cxx::noncopyable 11 | { 12 | public: 13 | RenderProgram mDefaultTexColorProgram; 14 | RenderProgram mCityMeshProgram; 15 | RenderProgram mGuiTexColorProgram; 16 | RenderProgram mSpritesProgram; 17 | RenderProgram mDebugProgram; 18 | RenderProgram mParticleProgram; 19 | 20 | MapRenderer mMapRenderer; 21 | 22 | std::vector mActiveRenderViews; 23 | 24 | public: 25 | RenderingManager(); 26 | 27 | // First time render system initialization 28 | // All shaders, buffers and other graphics resources might be loaded here 29 | // Return false on error 30 | bool Initialize(); 31 | 32 | // System finalization 33 | // All loaded graphics resources must be destroyed here 34 | void Deinit(); 35 | 36 | // Render game frame routine 37 | void RenderFrame(); 38 | 39 | // Force reload all render programs 40 | void ReloadRenderPrograms(); 41 | 42 | void AttachRenderView(GameCamera* renderview); 43 | void DetachRenderView(GameCamera* renderview); 44 | 45 | // Register particle effect for rendering 46 | void RegisterParticleEffect(ParticleEffect* particleEffect); 47 | void UnregisterParticleEffect(ParticleEffect* particleEffect); 48 | 49 | private: 50 | void RenderParticleEffects(GameCamera* renderview); 51 | void RenderParticleEffect(GameCamera* renderview, ParticleEffect* particleEffect); 52 | 53 | private: 54 | bool InitRenderPrograms(); 55 | void FreeRenderPrograms(); 56 | 57 | private: 58 | DebugRenderer mDebugRenderer; 59 | }; 60 | 61 | extern RenderingManager gRenderManager; -------------------------------------------------------------------------------- /src/SfxEmitter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SfxDefs.h" 4 | 5 | // forwards 6 | class GameObject; 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | // Loaded audio effect 11 | class SfxSample 12 | { 13 | friend class AudioManager; 14 | friend class SfxChannel; 15 | friend class SfxEmitter; 16 | 17 | public: 18 | SfxSample(eSfxSampleType sfxType, SfxSampleIndex sfxIndex, AudioSampleBuffer* sampleBuffer); 19 | ~SfxSample(); 20 | 21 | private: 22 | eSfxSampleType mSfxType; 23 | SfxSampleIndex mSfxIndex; 24 | AudioSampleBuffer* mSampleBuffer; 25 | }; 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | 29 | // Audio emitter will emit sounds at specific location 30 | class SfxEmitter final: public cxx::noncopyable 31 | { 32 | friend class AudioManager; 33 | 34 | private: 35 | 36 | ////////////////////////////////////////////////////////////////////////// 37 | 38 | // virtual audio channel state 39 | struct SfxChannel 40 | { 41 | AudioSource* mHardwareSource = nullptr; // channel is only active when source set 42 | SfxSample* mSfxSample = nullptr; 43 | SfxFlags mSfxFlags = SfxFlags_None; 44 | // audio params 45 | float mPitchValue = 1.0f; 46 | float mGainValue = 1.0f; 47 | }; 48 | 49 | ////////////////////////////////////////////////////////////////////////// 50 | 51 | public: 52 | // readonly 53 | GameObject* mGameObject = nullptr; // optional 54 | 55 | public: 56 | SfxEmitter(GameObject* gameObject, SfxEmitterFlags emitterFlags); 57 | ~SfxEmitter(); 58 | 59 | // Free emitter 60 | void ReleaseEmitter(bool stopSounds); 61 | 62 | void UpdateEmitterParams(const glm::vec3& emitterPosition); 63 | void UpdateSounds(); 64 | 65 | void StopAllSounds(); 66 | void PauseAllSounds(); 67 | void ResumeAllSounds(); 68 | 69 | bool StartSound(int ichannel, SfxSample* sfxSample, SfxFlags sfxFlags); 70 | bool StopSound(int ichannel); 71 | bool PauseSound(int ichannel); 72 | bool ResumeSound(int ichannel); 73 | bool SetPitch(int ichannel, float pitchValue); 74 | bool SetGain(int ichannel, float gainValue); 75 | 76 | bool IsPlaying(int ichannel) const; 77 | bool IsPaused(int ichannel) const; 78 | 79 | bool IsAutoreleaseEmitter() const; 80 | bool IsActiveEmitter() const; 81 | 82 | private: 83 | std::vector mAudioChannels; 84 | glm::vec3 mEmitterPosition; 85 | SfxEmitterFlags mEmitterFlags = SfxEmitterFlags_None; 86 | }; -------------------------------------------------------------------------------- /src/Sprite2D.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Sprite2D.h" 3 | 4 | void Sprite2D::Clear() 5 | { 6 | mTexture = nullptr; 7 | 8 | mTextureRegion.Clear(); 9 | 10 | mOriginMode = eSpriteOrigin_Center; 11 | mDrawOrder = eSpriteDrawOrder_Background; 12 | mPosition.x = 0.0f; 13 | mPosition.y = 0.0f; 14 | mHeight = 0.0f; 15 | mScale = MAP_SPRITE_SCALE; 16 | mPaletteIndex = 0; 17 | 18 | mRotateAngle.set_zero(); 19 | } 20 | 21 | void Sprite2D::GetCorners(glm::vec2 positions[4]) const 22 | { 23 | glm::vec2 spriteSize = GetSpriteSize(); 24 | 25 | positions[0] = GetOriginPoint(); 26 | 27 | positions[1].x = positions[0].x + spriteSize.x; 28 | positions[1].y = positions[0].y; 29 | 30 | positions[2].x = positions[0].x; 31 | positions[2].y = positions[0].y + spriteSize.y; 32 | 33 | positions[3].x = positions[1].x; 34 | positions[3].y = positions[2].y; 35 | 36 | mRotateAngle.to_degrees_normalize_360(); 37 | if (mRotateAngle) // has rotation 38 | { 39 | for (int icorner = 0; icorner < 4; ++icorner) 40 | { 41 | glm::vec2 posTransformed = glm::rotate(positions[icorner], mRotateAngle.to_radians()); 42 | positions[icorner] = mPosition + posTransformed; 43 | } 44 | } 45 | else 46 | { 47 | for (int icorner = 0; icorner < 4; ++icorner) 48 | { 49 | positions[icorner] += mPosition; 50 | } 51 | } 52 | } 53 | 54 | void Sprite2D::GetApproximateBounds(cxx::aabbox2d_t& bounds) const 55 | { 56 | glm::vec2 spriteSize = GetSpriteSize(); 57 | glm::vec2 origin; 58 | 59 | float maxsize = std::max(spriteSize.x, spriteSize.y); 60 | if (mOriginMode == eSpriteOrigin_Center) 61 | { 62 | origin.x = origin.y = (-maxsize * 0.5f); 63 | } 64 | else 65 | { 66 | origin.x = origin.y = 0.0f; 67 | } 68 | 69 | bounds.mMin = mPosition + origin; 70 | bounds.mMax.x = (bounds.mMin.x + maxsize); 71 | bounds.mMax.y = (bounds.mMin.y + maxsize); 72 | } 73 | -------------------------------------------------------------------------------- /src/Sprite2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | 5 | // defines sprite data 6 | struct Sprite2D 7 | { 8 | public: 9 | Sprite2D() = default; 10 | 11 | // Compute origin position which is depends on current mode 12 | inline glm::vec2 GetOriginPoint() const 13 | { 14 | glm::vec2 origin; 15 | if (mOriginMode == eSpriteOrigin_Center) 16 | { 17 | origin.x = (-mTextureRegion.mRectangle.w * mScale) * 0.5f; 18 | origin.y = (-mTextureRegion.mRectangle.h * mScale) * 0.5f; 19 | } 20 | else 21 | { 22 | origin.x = 0.0f; 23 | origin.y = 0.0f; 24 | } 25 | return origin; 26 | } 27 | 28 | // Compute size 29 | inline glm::vec2 GetSpriteSize() const 30 | { 31 | return { 32 | mTextureRegion.mRectangle.w * mScale, 33 | mTextureRegion.mRectangle.h * mScale 34 | }; 35 | } 36 | 37 | // Compute sprite corner position 38 | void GetCorners(glm::vec2 positions[4]) const; 39 | 40 | // Compute very inaccurate yet fast bounding box for sprite 41 | void GetApproximateBounds(cxx::aabbox2d_t& bounds) const; 42 | 43 | // Clear sprite data 44 | void Clear(); 45 | 46 | // Whether sprite graphics is not specified 47 | inline operator bool () const { return mTexture != nullptr; } 48 | 49 | public: 50 | GpuTexture2D* mTexture = nullptr; 51 | TextureRegion mTextureRegion; 52 | 53 | glm::vec2 mPosition; 54 | cxx::angle_t mRotateAngle; 55 | 56 | float mHeight = 0.0f; // z order 57 | float mScale = MAP_SPRITE_SCALE; 58 | 59 | unsigned short mPaletteIndex = 0; 60 | 61 | eSpriteOriginMode mOriginMode = eSpriteOrigin_Center; 62 | eSpriteDrawOrder mDrawOrder = eSpriteDrawOrder_Background; 63 | }; 64 | 65 | const int Sizeof_Sprite2D = sizeof(Sprite2D); -------------------------------------------------------------------------------- /src/SpriteBatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | #include "TrimeshBuffer.h" 5 | #include "Sprite2D.h" 6 | 7 | enum eSpritesSortMode 8 | { 9 | eSpritesSortMode_None, 10 | eSpritesSortMode_Height, 11 | eSpritesSortMode_DrawOrder, 12 | eSpritesSortMode_HeightAndDrawOrder, 13 | }; 14 | 15 | // defines renderer class for 2d sprites 16 | class SpriteBatch final: public cxx::noncopyable 17 | { 18 | public: 19 | 20 | enum DepthAxis { DepthAxis_Y, DepthAxis_Z }; 21 | 22 | // init/deinit internal resources of sprite batch 23 | bool Initialize(); 24 | void Deinit(); 25 | 26 | void BeginBatch(DepthAxis depthAxis, eSpritesSortMode sortMode); 27 | 28 | // sort and then render all sprites in current batch 29 | void Flush(); 30 | 31 | // discard all batched sprites 32 | void Clear(); 33 | 34 | // add sprite to batch but does not draw it immediately 35 | // @param sourceSprite: Source sprite data 36 | void DrawSprite(const Sprite2D& sourceSprite); 37 | 38 | private: 39 | void GenerateSpritesBatches(); 40 | void RenderSpritesBatches(); 41 | void SortSprites(); 42 | 43 | private: 44 | // single batch of drawing sprites 45 | struct DrawSpriteBatch 46 | { 47 | unsigned int mFirstVertex; 48 | unsigned int mFirstIndex; 49 | unsigned int mVertexCount; 50 | unsigned int mIndexCount; 51 | GpuTexture2D* mSpriteTexture; 52 | }; 53 | // all sprites stored as is until they needs to be flushed 54 | std::vector mSpritesList; 55 | 56 | // draw data buffers 57 | std::vector mDrawVertices; 58 | std::vector mDrawIndices; 59 | 60 | std::vector mBatchesList; 61 | TrimeshBuffer mTrimeshBuffer; 62 | 63 | DepthAxis mDepthAxis = DepthAxis_Y; 64 | eSpritesSortMode mSortMode = eSpritesSortMode_None; 65 | }; -------------------------------------------------------------------------------- /src/System.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Common system specific stuff collected in System class 4 | class System final: public cxx::noncopyable 5 | { 6 | public: 7 | // Initialize game subsystems and run main loop 8 | void Run(int argc, char *argv[]); 9 | 10 | // Abnormal application shutdown due to critical failure 11 | void Terminate(); 12 | 13 | // Set application exit request flag, execution will be interrupted soon 14 | void QuitRequest(); 15 | 16 | // Get real time seconds since system started 17 | double GetSystemSeconds() const; 18 | 19 | private: 20 | void Initialize(int argc, char *argv[]); 21 | void Deinit(bool isTermination); 22 | bool ExecuteFrame(); 23 | void ParseStartupParams(int argc, char *argv[]); 24 | 25 | // Save/Load configuration to/from external file 26 | bool LoadConfiguration(); 27 | bool SaveConfiguration(); 28 | 29 | private: 30 | bool mQuitRequested; 31 | }; 32 | 33 | extern System gSystem; -------------------------------------------------------------------------------- /src/TimeManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class TimeManager: public cxx::noncopyable 4 | { 5 | public: 6 | // readonly 7 | float mSystemTime = 0.0f; 8 | float mSystemFrameDelta = 0.0f; 9 | 10 | float mGameTime = 0.0f; 11 | float mGameFrameDelta = 0.0f; 12 | float mGameTimeScale = 1.0f; 13 | 14 | float mUiTime = 0.0f; 15 | float mUiFrameDelta = 0.0f; 16 | float mUiTimeScale = 1.0f; 17 | 18 | float mMinFramerate = 24.0f; // gta1 game speed 19 | float mMaxFramerate = 120.0f; 20 | 21 | public: 22 | // Setup manager internal resources 23 | bool Initialize(); 24 | void Deinit(); 25 | 26 | void UpdateFrame(); 27 | 28 | // Set fps limitations 29 | void SetMinFramerate(float framesPerSecond); 30 | void SetMaxFramerate(float framesPerSecond); 31 | 32 | // Scale game time, timeScale to 1.0 means no scale applied 33 | void SetGameTimeScale(float timeScale); 34 | void SetUiTimeScale(float timeScale); 35 | 36 | private: 37 | double mMaxFrameDelta = 0.0f; 38 | double mMinFrameDelta = 0.0f; 39 | double mLastFrameTimestamp = 0.0f; 40 | }; 41 | 42 | extern TimeManager gTimeManager; -------------------------------------------------------------------------------- /src/TrafficManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class DebugRenderer; 4 | 5 | // This class generates randomly wander pedestrians and vehicles on currently visible area on map 6 | class TrafficManager final: public cxx::noncopyable 7 | { 8 | friend class GameCheatsWindow; 9 | 10 | public: 11 | TrafficManager(); 12 | 13 | // Start or stop traffic generators 14 | void StartupTraffic(); 15 | void CleanupTraffic(); 16 | 17 | void UpdateFrame(); 18 | void DebugDraw(DebugRenderer& debugRender); 19 | 20 | int CountTrafficPedestrians() const; 21 | int CountTrafficCars() const; 22 | 23 | private: 24 | // traffic pedestrians generation 25 | void GeneratePeds(); 26 | void GenerateTrafficPeds(int pedsCount, GameCamera& view); 27 | void RemoveOffscreenPeds(); 28 | int GetPedsToGenerateCount(GameCamera& view) const; 29 | 30 | // traffic cars generation 31 | void GenerateCars(); 32 | void GenerateTrafficCars(int carsCount, GameCamera& view); 33 | void RemoveOffscreenCars(); 34 | int GetCarsToGenerateCount(GameCamera& view) const; 35 | 36 | // traffic objects generation 37 | Pedestrian* GenerateRandomTrafficCarDriver(Vehicle* vehicle); 38 | Pedestrian* GenerateRandomTrafficPedestrian(int posx, int posy, int posz); 39 | Pedestrian* GenerateHareKrishnas(int posx, int posy, int posz); 40 | Vehicle* GenerateRandomTrafficCar(int posx, int posy, int posz); 41 | 42 | // attempt to remove traffic pedestrian or vehicle 43 | bool TryRemoveTrafficPed(Pedestrian* ped); 44 | bool TryRemoveTrafficCar(Vehicle* car); 45 | 46 | private: 47 | float mLastGenPedsTime = 0.0; 48 | float mLastGenCarsTime = 0.0f; 49 | float mLastGenHareKrishnasTime = 0.0f; 50 | 51 | // buffers 52 | struct CandidatePos 53 | { 54 | int mMapX; 55 | int mMapY; 56 | int mMapLayer; 57 | }; 58 | std::vector mCandidatePosArray; 59 | }; 60 | 61 | extern TrafficManager gTrafficManager; -------------------------------------------------------------------------------- /src/TrimeshBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TrimeshBuffer.h" 3 | #include "GpuBuffer.h" 4 | 5 | TrimeshBuffer::~TrimeshBuffer() 6 | { 7 | debug_assert(mIndexBuffer == nullptr); 8 | debug_assert(mVertexBuffer == nullptr); 9 | } 10 | 11 | void TrimeshBuffer::SetVertices(unsigned int dataLength, const void* dataSource) 12 | { 13 | if (mVertexBuffer == nullptr) 14 | { 15 | mVertexBuffer = gGraphicsDevice.CreateBuffer(eBufferContent_Vertices, eBufferUsage_Stream, dataLength, dataSource); 16 | debug_assert(mVertexBuffer); 17 | return; 18 | } 19 | 20 | if (!mVertexBuffer->Setup(eBufferUsage_Stream, dataLength, dataSource)) 21 | { 22 | debug_assert(false); 23 | } 24 | } 25 | 26 | void TrimeshBuffer::SetIndices(unsigned int dataLength, const void* dataSource) 27 | { 28 | if (mIndexBuffer == nullptr) 29 | { 30 | mIndexBuffer = gGraphicsDevice.CreateBuffer(eBufferContent_Indices, eBufferUsage_Stream, dataLength, dataSource); 31 | debug_assert(mIndexBuffer); 32 | return; 33 | } 34 | 35 | if (!mIndexBuffer->Setup(eBufferUsage_Stream, dataLength, dataSource)) 36 | { 37 | debug_assert(false); 38 | } 39 | } 40 | 41 | void TrimeshBuffer::Bind(const VertexFormat& vertexFormat) 42 | { 43 | debug_assert(mVertexBuffer); 44 | if (mVertexBuffer == nullptr) 45 | return; 46 | 47 | gGraphicsDevice.BindVertexBuffer(mVertexBuffer, vertexFormat); 48 | gGraphicsDevice.BindIndexBuffer(mIndexBuffer); 49 | } 50 | 51 | void TrimeshBuffer::Deinit() 52 | { 53 | if (mIndexBuffer) 54 | { 55 | gGraphicsDevice.DestroyBuffer(mIndexBuffer); 56 | mIndexBuffer = nullptr; 57 | } 58 | if (mVertexBuffer) 59 | { 60 | gGraphicsDevice.DestroyBuffer(mVertexBuffer); 61 | mVertexBuffer = nullptr; 62 | } 63 | } -------------------------------------------------------------------------------- /src/TrimeshBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class TrimeshBuffer final: public cxx::noncopyable 4 | { 5 | public: 6 | TrimeshBuffer() = default; 7 | ~TrimeshBuffer(); 8 | 9 | void SetVertices(unsigned int dataLength, const void* dataSource); 10 | void SetIndices(unsigned int dataLength, const void* dataSource); 11 | void Bind(const VertexFormat& vertexFormat); 12 | void Deinit(); 13 | 14 | public: 15 | GpuBuffer* mVertexBuffer = nullptr; 16 | GpuBuffer* mIndexBuffer = nullptr; 17 | }; -------------------------------------------------------------------------------- /src/Weapon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WeaponInfo.h" 4 | 5 | // Class stores all weapon related states info 6 | class Weapon final 7 | { 8 | public: 9 | // readonly 10 | eWeaponState mWeaponState = eWeaponState_OutOfAmmunition; 11 | eWeaponID mWeaponID = eWeapon_Fists; 12 | 13 | float mLastFireTime = 0.0f; 14 | int mAmmunition = 0; 15 | int mShotsCounter = 0; 16 | 17 | public: 18 | Weapon() = default; 19 | WeaponInfo* GetWeaponInfo() const; 20 | 21 | // One time weapon initialization 22 | void Setup(eWeaponID weaponID, int ammunition); 23 | void UpdateFrame(); 24 | void ClearLastFireTime(); 25 | void ClearShotsCounter(); 26 | 27 | // Try to make shot from weapon, depending on current state it might fail 28 | bool Fire(Pedestrian* shooter); 29 | 30 | // Change weapons current ammunition amount 31 | // @param ammunition: New amount 32 | void SetAmmunition(int ammunition); 33 | void AddAmmunition(int ammunition); 34 | void DecAmmunition(int ammunition); 35 | 36 | bool IsUsesAmmunition() const; 37 | 38 | // Current weapon state shortcuts 39 | bool IsOutOfAmmunition() const; 40 | bool IsReadyToFire() const; 41 | bool IsReloading() const; 42 | 43 | private: 44 | bool IsReloadingTime() const; 45 | }; 46 | -------------------------------------------------------------------------------- /src/WeaponInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameDefs.h" 4 | 5 | // weapon type description 6 | class WeaponInfo 7 | { 8 | public: 9 | WeaponInfo() = default; 10 | 11 | // Load weapon info from json node 12 | bool SetupFromConfg(cxx::json_document_node configNode); 13 | 14 | // Reset weapon info to default state 15 | void Clear(); 16 | 17 | // Get projectile spawn point offset relative pedestrian center 18 | // @param offset: Output offset, meters 19 | bool GetProjectileOffsetForAnimation(ePedestrianAnimID animID, glm::vec2& offset) const; 20 | 21 | // Shortcuts 22 | bool IsMelee() const { return mFireTypeID == eWeaponFireType_Melee; } 23 | bool IsRange() const { return mFireTypeID == eWeaponFireType_Projectile; } 24 | 25 | // causes death 26 | bool IsLethal() const { return mWeaponID != eWeapon_Fists; } 27 | 28 | bool IsBulletDamage() const 29 | { 30 | return (mFireTypeID == eWeaponFireType_Projectile) && (mProjectileTypeID == eProjectileType_Bullet); 31 | } 32 | // burn rather kill instantly 33 | bool IsFireDamage() const 34 | { 35 | return (mFireTypeID == eWeaponFireType_Projectile) && (mProjectileTypeID == eProjectileType_Flame); 36 | } 37 | // explodes when hit 38 | bool IsExplosionDamage() const 39 | { 40 | return (mFireTypeID == eWeaponFireType_Projectile) && (mProjectileTypeID == eProjectileType_Missile); 41 | } 42 | 43 | public: 44 | eWeaponID mWeaponID = eWeapon_Fists; 45 | 46 | eWeaponFireType mFireTypeID = eWeaponFireType_Melee; 47 | eProjectileType mProjectileTypeID = eProjectileType_Bullet; // only used if firetype is projectile 48 | 49 | struct ProjectileOffset 50 | { 51 | ePedestrianAnimID mAnimationID; 52 | glm::vec2 mOffset2; // relatipe to pedestrian center, meters 53 | }; 54 | std::vector mProjectileOffsets; 55 | 56 | float mBaseHitRange = 1.0f; // how far weapon can damage, for projectiles this is fly distance 57 | float mBaseFireRate = 1.0f; // num shots per seconds 58 | float mProjectileSize = 1.0f; // radius of projectile bounding sphere, meters 59 | float mProjectileSpeed = 1.0f; // how fast projectile moves, meters 60 | int mShotsPerClip = 1; // how much shots can be done for single ammo point 61 | int mProjectileHitEffect = GameObjectType_Null; 62 | int mProjectileHitObjectSound = -1; // level sfx 63 | int mProjectileObject = GameObjectType_BulletProjectile; 64 | int mBaseMaxAmmo = 0; // max ammo, 0 is unlimited 65 | int mShotSound = -1; // level sfx 66 | int mSpriteIndex = 0; 67 | }; -------------------------------------------------------------------------------- /src/WeatherManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ParticleEffect.h" 4 | #include "GameDefs.h" 5 | 6 | // Weather effects manager 7 | class WeatherManager final: public cxx::noncopyable 8 | { 9 | public: 10 | void EnterWorld(); 11 | void ClearWorld(); 12 | void UpdateFrame(); 13 | void DebugDraw(DebugRenderer& debugRender); 14 | 15 | bool IsWeatherEffectsEnabled() const; 16 | 17 | private: 18 | void ChangeWeather(eWeatherEffect weather); 19 | void CleanupWeather(); 20 | 21 | void GetParticleEffectParams(eWeatherEffect weather, ParticleEffectParams& params) const; 22 | void GetParticleEffectShape(eWeatherEffect weather, ParticleEmitterShape& shape) const; 23 | 24 | private: 25 | ParticleEffect* mParticleEffect = nullptr; 26 | }; 27 | 28 | extern WeatherManager gWeatherManager; -------------------------------------------------------------------------------- /src/game_version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GAME_VERSION_MAJOR 0 4 | #define GAME_VERSION_MINOR 0 5 | #define GAME_VERSION_BUILD 4 6 | 7 | #define STRINGIZE_NX(A) #A 8 | #define STRINGIZE(A) STRINGIZE_NX(A) 9 | 10 | #define GAME_TITLE "Carnage3D " STRINGIZE(GAME_VERSION_MAJOR) "." STRINGIZE(GAME_VERSION_MINOR) "." STRINGIZE(GAME_VERSION_BUILD) -------------------------------------------------------------------------------- /src/geometries.inl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | 6 | 7 | } // namespace cxx -------------------------------------------------------------------------------- /src/iostream_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | 6 | template 7 | inline bool read_from_stream(std::istream& instream, TValue& outputValue) 8 | { 9 | if (!instream.read(reinterpret_cast(&outputValue), sizeof(outputValue))) 10 | return false; 11 | 12 | return true; 13 | } 14 | 15 | } // namespace cxx 16 | 17 | // helpers 18 | #define READ_DATA(instream, destination, datatype) \ 19 | { \ 20 | datatype _$data; \ 21 | if (!cxx::read_from_stream(instream, _$data)) \ 22 | return false; \ 23 | \ 24 | destination = _$data; \ 25 | } 26 | 27 | #define READ_I8(instream, destination) READ_DATA(instream, destination, unsigned char) 28 | #define READ_SI8(instream, destination) READ_DATA(instream, destination, char) 29 | #define READ_I16(instream, destination) READ_DATA(instream, destination, unsigned short) 30 | #define READ_SI16(instream, destination) READ_DATA(instream, destination, short) 31 | #define READ_SI32(instream, destination) READ_DATA(instream, destination, int) 32 | #define READ_BOOL(instream, destination) \ 33 | { \ 34 | unsigned char _$data; \ 35 | if (!cxx::read_from_stream(instream, _$data)) \ 36 | return false; \ 37 | \ 38 | destination = _$data > 0; \ 39 | } 40 | 41 | #define READ_FIXEDF32(instream, destination) \ 42 | { \ 43 | int _$data; \ 44 | if (!cxx::read_from_stream(instream, _$data)) \ 45 | return false; \ 46 | \ 47 | destination = _$data / 65536.0f; \ 48 | } -------------------------------------------------------------------------------- /src/macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define OS_WINDOWS 1 4 | #define OS_LINUX 2 5 | #define OS_UNIX 3 6 | #define OS_MACOS 4 7 | #define OS_UNKNOWN 0 8 | 9 | #if defined(_WIN32) 10 | #define OS_NAME OS_WINDOWS 11 | #elif defined(__APPLE__) 12 | #define OS_NAME OS_MACOS 13 | #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) 14 | #define OS_NAME OS_LINUX 15 | #else 16 | #define OS_NAME OS_UNKNOWN 17 | #endif 18 | 19 | #if OS_NAME == OS_WINDOWS 20 | #define _CRT_SECURE_NO_WARNINGS 21 | #define _SCL_SECURE_NO_WARNINGS 22 | 23 | #ifdef _DEBUG 24 | #define _CRTDBG_MAP_ALLOC 25 | #include 26 | #endif 27 | 28 | #elif OS_NAME == OS_LINUX 29 | #include 30 | #elif OS_NAME == OS_MACOS 31 | #include 32 | #endif 33 | 34 | #ifdef _DEBUG 35 | #if OS_NAME == OS_WINDOWS 36 | #define debug_assert(expr) _ASSERTE(expr) 37 | #define release_assert(expr) 38 | #else 39 | #define debug_assert(expr) assert(expr) 40 | #define release_assert(expr) 41 | #endif 42 | #else 43 | #define debug_assert(expr) 44 | #define release_assert(expr) 45 | #endif 46 | 47 | #if OS_NAME == OS_WINDOWS 48 | #define cxx_stricmp _stricmp 49 | #define cxx_strnicmp _strnicmp 50 | #else 51 | #include 52 | #define cxx_stricmp strcasecmp 53 | #define cxx_strnicmp strncasecmp 54 | #endif 55 | 56 | #define BIT(i) (1U << (i)) 57 | -------------------------------------------------------------------------------- /src/mem_allocators.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | // callback proc on overflow 6 | using mem_allocator_out_of_memory_proc = void (*)(unsigned int allocation_size_bytes); 7 | 8 | // defines memory allocator interface 9 | class memory_allocator: public cxx::noncopyable 10 | { 11 | public: 12 | virtual ~memory_allocator() 13 | { 14 | } 15 | // setup allocator 16 | // @returns false on error 17 | virtual bool init_allocator(unsigned int bufferSizeTotal) = 0; 18 | 19 | // allocate at least dataLength bytes of memory 20 | // @param dataLength: Data length 21 | // @returns nullptr on out of memory 22 | virtual void* allocate(unsigned int dataLength) = 0; 23 | 24 | // reallocate previously allocated memory 25 | // @param dataPointer: Pointer 26 | // @param dataLength: New length 27 | // @returns nullptr on out of memory 28 | virtual void* reallocate(void* dataPointer, unsigned int dataLength) = 0; 29 | 30 | // deallocate memory 31 | // @param dataPointer: Pointer 32 | virtual void deallocate(void* dataPointer) = 0; 33 | 34 | // some allocators does not frees anything but rather resets free memory cursor 35 | virtual void reset() 36 | { 37 | } 38 | public: 39 | mem_allocator_out_of_memory_proc mOutOfMemoryProc; 40 | }; 41 | 42 | // defines implementation of linear memory allocator 43 | class linear_memory_allocator: public memory_allocator 44 | { 45 | public: 46 | ~linear_memory_allocator(); 47 | 48 | // setup allocator 49 | bool init_allocator(unsigned int bufferSizeTotal) override; 50 | 51 | // allocate at least dataLength bytes of memory 52 | void* allocate(unsigned int dataLength) override; 53 | 54 | // reallocate previously allocated memory 55 | void* reallocate(void* dataPointer, unsigned int dataLength) override; 56 | 57 | // deallocate memory 58 | // does nothing 59 | void deallocate(void* dataPointer) override; 60 | 61 | // reset allocations 62 | void reset() override; 63 | 64 | private: 65 | unsigned int mMemorySizeTotal = 0; 66 | unsigned int mMemorySizeUsed = 0; 67 | unsigned int mMemorySizeFree = 0; 68 | unsigned char* mMemoryBuffer = nullptr; 69 | }; 70 | 71 | // defines standard heap allocator implementation 72 | class heap_memory_allocator: public memory_allocator 73 | { 74 | public: 75 | // setup allocator 76 | bool init_allocator(unsigned int bufferSizeTotal) override; 77 | 78 | // allocate at least dataLength bytes of memory 79 | void* allocate(unsigned int dataLength) override; 80 | 81 | // reallocate previously allocated memory 82 | void* reallocate(void* dataPointer, unsigned int dataLength) override; 83 | 84 | // deallocate memory 85 | // does nothing 86 | void deallocate(void* dataPointer) override; 87 | }; 88 | 89 | } // namespace cxx -------------------------------------------------------------------------------- /src/noncopyable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | // noncopyable 6 | struct noncopyable 7 | { 8 | public: 9 | noncopyable() = default; 10 | ~noncopyable() = default; 11 | 12 | noncopyable(const noncopyable&) = delete; 13 | noncopyable& operator = (const noncopyable&) = delete; 14 | }; 15 | 16 | } // namespace cxx -------------------------------------------------------------------------------- /src/path_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | using enum_files_proc = std::function; 6 | 7 | // extract parent directory for element 8 | // @param sourcePath: Path 9 | std::string get_parent_directory(std::string pathto); 10 | 11 | // extract file name without extension 12 | // @param sourcePath: Path 13 | std::string get_name_without_extension(std::string pathto); 14 | 15 | // extract file name with extension 16 | // @param sourcePath: Path 17 | std::string get_file_name(std::string pathto); 18 | 19 | // extract file extension 20 | // @param sourcePath: Path 21 | std::string get_file_extension(std::string pathto); 22 | 23 | // get full path to executable 24 | std::string get_executable_path(); 25 | 26 | // test whether file exists in os 27 | // @param sourcePath: Path 28 | bool is_file_exists(std::string pathto); 29 | 30 | // test whether directory exists in os 31 | // @param sourcePath: Path 32 | bool is_directory_exists(std::string pathto); 33 | 34 | // create directories in path 35 | bool ensure_path_exists(std::string pathto); 36 | 37 | // enumerate files and directories at specific location 38 | // @param pathto: Location 39 | // @param enumproc: Enumeration callback 40 | void enum_files(std::string pathto, enum_files_proc enumproc); 41 | void enum_files_recursive(std::string pathto, enum_files_proc enumproc); 42 | 43 | } // namespace cxx -------------------------------------------------------------------------------- /src/randomizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cxx 6 | { 7 | // defines pseudo random number generator based on Mersenne Twister 19937 generator 8 | class randomizer 9 | { 10 | public: 11 | randomizer(unsigned int seed = 0) 12 | : mGeneratorEngine(seed) 13 | { 14 | } 15 | 16 | // set random seed 17 | // @param randomSeed: Seed 18 | inline void set_seed(unsigned int randomSeed) 19 | { 20 | mGeneratorEngine.seed(randomSeed); 21 | } 22 | 23 | // generate random integer 24 | // @param maxInt: Max int 25 | // @param minInt: Min int 26 | inline int generate_int() 27 | { 28 | return std::uniform_int_distribution(0, INT_MAX)(mGeneratorEngine); 29 | } 30 | 31 | inline int generate_int(int maxInt) 32 | { 33 | debug_assert(maxInt >= 0); 34 | return std::uniform_int_distribution(0, maxInt)(mGeneratorEngine); 35 | } 36 | 37 | inline int generate_int(int minInt, int maxInt) 38 | { 39 | if (minInt == maxInt) 40 | return minInt; 41 | 42 | debug_assert(maxInt > minInt); 43 | return std::uniform_int_distribution(minInt, maxInt)(mGeneratorEngine); 44 | } 45 | 46 | inline bool random_chance(int chance) 47 | { 48 | int currChance = generate_int(1, 100); 49 | return (chance >= currChance); 50 | } 51 | 52 | // generate random float in range [0; 1] 53 | inline float generate_float() 54 | { 55 | return std::uniform_real_distribution(0.0f, 1.0f)(mGeneratorEngine); 56 | } 57 | 58 | inline float generate_float(float minFloat, float maxFloat) 59 | { 60 | if (minFloat == maxFloat) 61 | return minFloat; 62 | 63 | debug_assert(maxFloat > minFloat); 64 | return std::uniform_real_distribution(minFloat, maxFloat)(mGeneratorEngine); 65 | } 66 | 67 | // shuffle container elements 68 | template 69 | inline void shuffle(TContainer& container) 70 | { 71 | std::shuffle(std::begin(container), std::end(container), mGeneratorEngine); 72 | } 73 | 74 | private: 75 | std::mt19937 mGeneratorEngine; 76 | }; 77 | 78 | } // namespace cxx -------------------------------------------------------------------------------- /src/stb_rect_pack.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #define STB_RECT_PACK_IMPLEMENTATION 4 | #include "stb_rect_pack.h" -------------------------------------------------------------------------------- /src/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" -------------------------------------------------------------------------------- /src/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "macro.h" 4 | 5 | #ifdef _UNICODE 6 | #error Unicode is unsupported! 7 | #endif 8 | #ifdef UNICODE 9 | #error Unicode is unsupported! 10 | #endif 11 | 12 | #if OS_NAME == OS_WINDOWS 13 | #define WIN32_LEAN_AND_MEAN 14 | #define NOMINMAX 15 | #include 16 | #include // for multimedia timers 17 | #elif OS_NAME == OS_LINUX || OS_NAME == OS_MACOS 18 | #include 19 | #include 20 | #endif 21 | 22 | #ifdef __EMSCRIPTEN__ 23 | #include 24 | #define GLFW_INCLUDE_ES3 25 | #endif 26 | 27 | #pragma warning ( disable : 4351 ) // new behavior: elements of array will be default initialized 28 | #pragma warning ( disable : 4201 ) // nonstandard extension used: nameless struct/union 29 | #pragma warning ( disable : 4100 ) // unreferenced formal parameter 30 | 31 | #include 32 | 33 | // stdlib 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | // opengl 54 | #include 55 | #if OS_NAME == OS_MACOS 56 | #include 57 | #else 58 | #include 59 | #endif 60 | #include "GLFW/glfw3.h" 61 | 62 | // glm 63 | #define GLM_ENABLE_EXPERIMENTAL 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | 72 | // physics 73 | #include 74 | 75 | // lib 76 | #include "common_utils.h" 77 | #include "rtti.h" 78 | #include "enum_utils.h" 79 | #include "math_defs.h" 80 | #include "math_utils.h" 81 | #include "handle.h" 82 | #include "intrusive_list.h" 83 | #include "memory_istream.h" 84 | #include "noncopyable.h" 85 | #include "object_pool.h" 86 | #include "randomizer.h" 87 | #include "strings.h" 88 | #include "path_utils.h" 89 | #include "json_document.h" 90 | #include "mem_allocators.h" 91 | #include "iostream_utils.h" 92 | 93 | #include "game_version.h" 94 | // app 95 | #include "CommonTypes.h" 96 | #include "Console.h" 97 | #include "InputsManager.h" 98 | #include "System.h" 99 | #include "FileSystem.h" 100 | #include "GraphicsDevice.h" 101 | #include "GameCamera.h" 102 | #include "SpriteAnimation.h" 103 | #include "GameParams.h" 104 | #include "GameMapHelpers.h" 105 | #include "GuiManager.h" 106 | #include "PixelsArray.h" 107 | #include "GameDefs.h" 108 | #include "Convert.h" 109 | -------------------------------------------------------------------------------- /src/wave_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cxx 4 | { 5 | // simple pcm audio data reader from wave file 6 | class wave_reader final: public noncopyable 7 | { 8 | public: 9 | // readonly 10 | int mChannelsCount = 0; 11 | int mSampleRate = 0; 12 | int mSampleBits = 0; 13 | int mSamplesCount = 0; 14 | unsigned int mAudioDataLength = 0; // in bytes 15 | 16 | public: 17 | wave_reader(std::istream& inputStream); 18 | 19 | bool parse_audio(); 20 | bool audio_present() const; 21 | 22 | // read pcm audio data 23 | // @param samplesCount: samples count to read 24 | // @parm buffer: Destination buffer 25 | // @returns Samples count copied to buffer 26 | int read_pcm_samples(int samplesCount, void* buffer); 27 | 28 | // @param samples: Samples count 29 | bool seek_pcm_beg(int samples); 30 | bool seek_pcm_end(int samples); 31 | bool seek_pcm_cur(int samples); 32 | 33 | bool end_of_stream() const; 34 | 35 | private: 36 | void clear(); 37 | 38 | private: 39 | std::istream& mInputStream; 40 | std::streampos mAudioDataStart; 41 | std::streampos mAudioDataEnd; 42 | }; 43 | 44 | } // namespace cxx -------------------------------------------------------------------------------- /wasm/build.bat: -------------------------------------------------------------------------------- 1 | cd /d %SDKDIR%/emsdk 2 | call emsdk_env.bat 3 | python %~dp0build.py %~dp0 -------------------------------------------------------------------------------- /wasm/build.py: -------------------------------------------------------------------------------- 1 | import os, sys, subprocess 2 | from subprocess import Popen 3 | 4 | script_directory = os.path.abspath(sys.argv[1]); 5 | root_directory = os.path.normpath(os.path.join(script_directory, '..')) 6 | 7 | output_object = os.path.join(root_directory, 'bin', 'wasm', 'carnage3D.html') 8 | 9 | sdk_root_path = os.environ['SDKDIR']; 10 | print ('SDK: ' + sdk_root_path) 11 | 12 | glm_root_path = os.path.join(sdk_root_path, 'GLM/include') 13 | 14 | os.chdir(root_directory) 15 | print ('Root: ' + root_directory) 16 | 17 | args = ['em++'] 18 | 19 | def scan_sources(sub_path): 20 | full_path = os.path.join(root_directory, sub_path) 21 | for name in os.listdir(full_path): 22 | if name.endswith('.cpp'): 23 | args.append(os.path.join(sub_path, name)) 24 | 25 | scan_sources('src') 26 | scan_sources('third_party/Box2D/Box2D/Collision/Shapes') 27 | scan_sources('third_party/Box2D/Box2D/Collision') 28 | scan_sources('third_party/Box2D/Box2D/Common') 29 | scan_sources('third_party/Box2D/Box2D/Dynamics/Contacts') 30 | scan_sources('third_party/Box2D/Box2D/Dynamics/Joints') 31 | scan_sources('third_party/Box2D/Box2D/Dynamics') 32 | 33 | args.append('-O2') 34 | args.append('-o ' + output_object) 35 | args.append('-std=c++11') 36 | args.append('-s WASM=1') 37 | args.append('-s USE_GLFW=3') 38 | args.append('-s FULL_ES3=1') 39 | args.append('-s EXIT_RUNTIME=1') 40 | args.append('-s ALLOW_MEMORY_GROWTH=1') 41 | args.append('-I third_party/Box2D') 42 | args.append('-I ' + glm_root_path) 43 | args.append('--preload-file gamedata') 44 | 45 | commandline = (' '.join(args)) 46 | print (commandline) 47 | 48 | process = Popen(commandline, shell = True) 49 | stdout, stderr = process.communicate() -------------------------------------------------------------------------------- /web/carnage3D.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/web/carnage3D.data -------------------------------------------------------------------------------- /web/carnage3D.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codenamecpp/carnage3d/1cddd91e5f696cc05be57e3532c04ddc1b37d63f/web/carnage3D.wasm --------------------------------------------------------------------------------