Rearrangements; Audio support

This commit is contained in:
2025-08-30 21:06:56 +03:00
parent 503db60c60
commit 657107b4ae
30 changed files with 95935 additions and 57 deletions

1
.gitattributes vendored
View File

@@ -3,3 +3,4 @@
*.vrm filter=lfs diff=lfs merge=lfs -text
*.vroid filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text

10
.vscode/settings.json vendored
View File

@@ -1,7 +1,13 @@
{
"cmake.generator": "Unix Makefiles",
"cmake.configureSettings": {
"CMAKE_PREFIX_PATH": "/media/slapin/library/ogre/ogre-sdk"
"CMAKE_PREFIX_PATH": "/media/slapin/library/ogre3/ogre-sdk",
"CMAKE_VERBOSE_MAKEFILE": "ON"
},
"cmake.buildDirectory": "${workspaceFolder}/build-vscode"
"cmake.buildDirectory": "${workspaceFolder}/build-vscode",
"files.associations": {
"istream": "cpp",
"variant": "cpp",
"tuple": "cpp"
}
}

View File

@@ -25,10 +25,6 @@ set(CREATE_DIRECTORIES
#)
file(GLOB TERRAIN_SRC ${CMAKE_SOURCE_DIR}/src/terrain/*.cpp)
file(GLOB WATER_SRC ${CMAKE_SOURCE_DIR}/water/*.cpp)
set(CHARACTERS_SRC
${CMAKE_SOURCE_DIR}/src/characters/character.cpp
${CMAKE_SOURCE_DIR}/src/characters/controller.cpp
)
# The COMPONENTS part checks that OGRE was built the way we need it
# The CONFIG flag makes sure we get OGRE instead of OGRE-next
@@ -39,6 +35,7 @@ find_package(assimp REQUIRED CONFIG)
find_package(Bullet)
find_package(OgreProcedural REQUIRED CONFIG)
find_package(pugixml REQUIRED CONFIG)
find_package(flecs REQUIRED CONFIG)
add_library(fix::assimp INTERFACE IMPORTED)
set_target_properties(fix::assimp PROPERTIES
@@ -70,23 +67,54 @@ set_target_properties(fix::pugixml PROPERTIES
add_subdirectory(src/lua)
add_subdirectory(src/characters)
add_subdirectory(src/gamedata)
add_subdirectory(src/miniaudio)
add_subdirectory(src/sound)
add_subdirectory(audio/gui)
# add the source files as usual
add_executable(0_Bootstrap Bootstrap.cpp)
# this also sets the includes and pulls third party dependencies
target_link_libraries(0_Bootstrap OgreBites OgreBullet OgrePaging ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY} ${ASSIMP_LIBRARIES})
target_link_libraries(0_Bootstrap OgreBites OgreBullet OgrePaging ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY} ${ASSIMP_LIBRARIES}
-static-libgcc
-static-libstdc++
-Wl,--as-needed
)
add_dependencies(0_Bootstrap stage_files import_vrm)
add_executable(Editor Editor.cpp ${TERRAIN_SRC} ${WATER_SRC} ${CHARACTERS_SRC})
target_link_libraries(Editor OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
add_executable(Editor Editor.cpp ${TERRAIN_SRC} ${WATER_SRC})
target_link_libraries(Editor OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}
controller
-static-libgcc
-static-libstdc++
-Wl,--as-needed
)
add_dependencies(Editor stage_files import_buildings import_water_stuff import_vehicles import_vrm)
add_executable(Game Game.cpp ${TERRAIN_SRC} ${WATER_SRC} ${CHARACTERS_SRC})
target_link_libraries(Game OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
add_dependencies(Game stage_files import_buildings import_water_stuff import_vehicles import_vrm)
add_executable(Game Game.cpp ${TERRAIN_SRC} ${WATER_SRC})
target_include_directories(Game PRIVATE src/gamedata)
target_link_libraries(Game OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator
OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY}
${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}
controller
GameData
sound
flecs::flecs_static
-static-libgcc
-static-libstdc++
-Wl,--as-needed
)
add_dependencies(Game stage_files import_buildings import_water_stuff import_vehicles import_vrm audio_data_gui)
add_executable(Procedural Procedural.cpp ${TERRAIN_SRC})
target_link_libraries(Procedural OgreBites OgreBullet OgrePaging OgreTerrain OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
target_link_libraries(Procedural OgreBites OgreBullet OgrePaging OgreTerrain
OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY}
${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}
-static-libgcc
-static-libstdc++
-Wl,--as-needed
)
add_dependencies(Procedural stage_files import_buildings)
file(GLOB BUILDINGS_SRC ${CMAKE_SOURCE_DIR}/assets/blender/buildings/*.blend)
set(BUILDING_OUTPUT_FILES)
@@ -105,7 +133,6 @@ foreach(BUILDING_FILE ${BUILDINGS_SRC})
list(APPEND BUILDING_OUTPUT_FILES ${BUILDING_OUTPUT_FILE})
endforeach()
add_custom_target(import_buildings ALL DEPENDS ${BUILDING_OUTPUT_FILES})
file(GLOB VEHICLES_SRC ${CMAKE_SOURCE_DIR}/assets/blender/vehicles/*.blend)
set(VEHICLE_OUTPUT_FILES)
@@ -138,7 +165,11 @@ list(APPEND WATER_STUFF ${CMAKE_BINARY_DIR}/water/sea.glb)
add_custom_target(import_water_stuff ALL DEPENDS ${WATER_STUFF})
add_executable(TerrainTest terrain.cpp ${TERRAIN_SRC})
target_link_libraries(TerrainTest OgreBites OgreBullet OgrePaging OgreTerrain lua ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
target_link_libraries(TerrainTest OgreBites OgreBullet OgrePaging OgreTerrain lua ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}
-static-libgcc
-static-libstdc++
-Wl,--as-needed
)
target_include_directories(TerrainTest PRIVATE . src/terrain src/lua src/lua/lua-5.4.8/src)
if(OGRE_STATIC)
target_link_libraries(TerrainTest fix::assimp pugixml)

View File

@@ -13,6 +13,8 @@
#include "src/terrain/terrain.h"
#include "water/water.h"
#include "src/characters/controller.h"
#include "GameData.h"
#include "sound.h"
class App;
class SkyRenderer : public Ogre::SceneManager::Listener {
protected:
@@ -268,7 +270,6 @@ class App : public OgreBites::ApplicationContext {
App *mApp;
public:
Ogre::Vector3 motion;
bool gui_active;
Ogre::Timer fps_timer;
bool fast;
@@ -282,6 +283,7 @@ class App : public OgreBites::ApplicationContext {
}
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
{
bool updated = false;
if (gui_active)
return false;
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
@@ -292,38 +294,12 @@ class App : public OgreBites::ApplicationContext {
return true;
}
return false;
if (evt.keysym.sym == OgreBites::SDLK_SPACE) {
mApp->dump_water();
}
if (evt.keysym.sym == 'w')
motion.z = -1.0f;
if (evt.keysym.sym == 's')
motion.z = 1.0f;
if (evt.keysym.sym == 'a')
motion.x = -1.0f;
if (evt.keysym.sym == 'd')
motion.x = 1.0f;
if (evt.keysym.sym == OgreBites::SDLK_LSHIFT)
fast = true;
// std::cout << "motion: " << motion << "\n";
return true;
}
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
{
if (gui_active)
return false;
return false;
if (evt.keysym.sym == 'w' && motion.z < 0.0f)
motion.z = 0.0f;
if (evt.keysym.sym == 's' && motion.z > 0.0f)
motion.z = 0.0f;
if (evt.keysym.sym == 'a' && motion.x < 0.0f)
motion.x = 0.0f;
if (evt.keysym.sym == 'd' && motion.x > 0.0f)
motion.x = 0.0f;
if (evt.keysym.sym == OgreBites::SDLK_LSHIFT)
fast = false;
return true;
}
bool mouseMoved(const OgreBites::MouseMotionEvent &evt)
{
@@ -367,8 +343,10 @@ class App : public OgreBites::ApplicationContext {
update(evt.timeSinceLastFrame);
if (mApp->getCharacterController() && gui_active)
mApp->getCharacterController()->disableUpdates();
else if (mApp->getCharacterController() && !gui_active && mApp->isTerrainReady()) {
OgreAssert(mApp->isTerrainReady(), "terrain is not ready");
else if (mApp->getCharacterController() &&
!gui_active && mApp->isTerrainReady()) {
OgreAssert(mApp->isTerrainReady(),
"terrain is not ready");
mApp->getCharacterController()->enableUpdates();
}
if (!gui_active) {
@@ -408,6 +386,9 @@ public:
// getRenderWindow());
mDbgDraw.reset(new Ogre::Bullet::DebugDrawer(
mScnMgr->getRootSceneNode(), mDynWorld->getBtWorld()));
ECS::setup();
Sound::setup();
Sound::ding();
}
void locateResources() override
{
@@ -555,7 +536,8 @@ public:
void updateTerrain(float delta)
{
Ogre::Vector3 pos = mCharacterController->getPosition();
if (!mTerrainReady && m_terrain.isLoadedAt(pos) && mCharacterController->checkGround()) {
if (!mTerrainReady && m_terrain.isLoadedAt(pos) &&
mCharacterController->checkGround()) {
std::cout << "terrain ready\n";
mTerrainReady = true;
}
@@ -575,6 +557,7 @@ public:
void updateWorld(float delta)
{
mDynWorld->getBtWorld()->stepSimulation(delta, 4);
ECS::update(delta);
}
void updateWater(float delta)
{

28
audio/gui/CMakeLists.txt Normal file
View File

@@ -0,0 +1,28 @@
project(audio)
set(SOUNDS
click_2.wav
click.wav
load.wav
misc_menu_2.wav
misc_menu_3.wav
misc_menu_4.wav
misc_menu.wav
misc_sound.wav
negative_2.wav
negative.wav
positive.wav
save.wav
sharp_echo.wav
)
set(DST_SOUNDS)
foreach(SOUND_FILE ${SOUNDS})
set(FILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_FILE})
set(FILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/${SOUND_FILE})
add_custom_command(OUTPUT ${FILE_OUT}
COMMAND ${CMAKE_COMMAND} -E copy ${FILE_IN} ${FILE_OUT}
DEPENDS ${FILE_IN}
)
list(APPEND DST_SOUNDS ${FILE_OUT})
endforeach()
add_custom_target(audio_data_gui ALL DEPENDS ${DST_SOUNDS})

BIN
audio/gui/click.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/click_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/load.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/misc_menu.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/misc_menu_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/misc_menu_3.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/misc_menu_4.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/misc_sound.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/negative.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/negative_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/positive.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/save.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/gui/sharp_echo.wav (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -74,3 +74,6 @@ FileSystem=lua-scripts
[Characters]
FileSystem=./characters/male
FileSystem=./characters/female
[Audio]
FileSystem=./audio/gui

View File

@@ -0,0 +1,5 @@
project(characters)
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain CONFIG)
add_library(controller STATIC controller.cpp)
target_link_libraries(controller PUBLIC OgreMain OgreBites PRIVATE GameData)
target_include_directories(controller PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -1,5 +1,6 @@
#include <iostream>
#include <OgreMath.h>
#include "GameData.h"
#include "character.h"
#include "controller.h"
#if 0
@@ -227,14 +228,11 @@ void CharacterController::setupBody()
}
mGhostObject->setCollisionFlags(
btCollisionObject::CF_KINEMATIC_OBJECT |
btCollisionObject::CF_NO_CONTACT_RESPONSE );
btCollisionObject::CF_NO_CONTACT_RESPONSE);
mGhostObject->setActivationState(DISABLE_DEACTIVATION);
mWorld->attachCollisionObject(mGhostObject, mBodyEnt,
1,
0x7FFFFFF);
mController =
new Ogre::Bullet::KinematicMotionSimple(mGhostObject,
mBodyNode);
mWorld->attachCollisionObject(mGhostObject, mBodyEnt, 1, 0x7FFFFFF);
mController = new Ogre::Bullet::KinematicMotionSimple(mGhostObject,
mBodyNode);
OgreAssert(mGhostObject, "Need GhostObject");
OgreAssert(mController, "Need controller");
mWorld->getBtWorld()->addAction(mController);
@@ -380,6 +378,7 @@ void CharacterController::setupAnimations()
}
bool CharacterController::keyPressed(const OgreBites::KeyboardEvent &evt)
{
ECS::Input &input = ECS::get().get_mut<ECS::Input>();
OgreBites::Keycode key = evt.keysym.sym;
if (key == 'q' && (mAnimID == ANIM_IDLE)) {
/* ... */
@@ -551,10 +550,9 @@ void CharacterController::updateAnimations(Ogre::Real delta)
}
fadeAnimations(delta);
}
struct EntityCollisionListener
{
const Ogre::MovableObject* entity;
Ogre::Bullet::CollisionListener* listener;
struct EntityCollisionListener {
const Ogre::MovableObject *entity;
Ogre::Bullet::CollisionListener *listener;
};
void CharacterController::updateRootMotion(Ogre::Real delta)
{
@@ -572,7 +570,8 @@ void CharacterController::updateRootMotion(Ogre::Real delta)
gvelocity += gravity * delta;
velocity += gvelocity;
Ogre::Vector3 rotMotion = velocity * delta;
btVector3 currentPosition = mGhostObject->getWorldTransform().getOrigin();
btVector3 currentPosition =
mGhostObject->getWorldTransform().getOrigin();
is_on_floor = mController->isOnFloor();
penetration = mController->isPenetrating();
if (is_on_floor)

View File

@@ -0,0 +1,5 @@
project(gamedata)
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain CONFIG)
add_library(GameData STATIC GameData.cpp)
target_link_libraries(GameData PUBLIC OgreMain OgreBullet flecs::flecs_static)
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

29
src/gamedata/GameData.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <Ogre.h>
#include "GameData.h"
namespace ECS
{
static flecs::world ecs;
CharacterModule::CharacterModule(flecs::world &ecs)
{
ecs.component<Input>();
ecs.add<Input>();
ecs.system("HandleInput").kind(flecs::OnUpdate).run([](flecs::iter &it) {
/* handle input */
});
}
void setup()
{
ecs.add<GameData>();
ecs.import <CharacterModule>();
}
void update(float delta)
{
ecs.progress(delta);
}
flecs::world &get()
{
return ecs;
}
}

36
src/gamedata/GameData.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef GAMEDATA_H
#define GAMEDATA_H
#include <OgreBullet.h>
#include <flecs.h>
namespace ECS
{
struct GameData {
flecs::entity player;
};
struct Vector3 {
float x;
float y;
float z;
};
struct Input {
Vector3 motion;
bool fast;
Input()
: motion({ 0, 0, 0 })
, fast(false)
{
}
};
struct CharacterBody {
btPairCachingGhostObject *mGhostObject;
btCompoundShape *mCollisionShape;
Ogre::Bullet::DynamicsWorld *mWorld;
};
struct CharacterModule {
CharacterModule(flecs::world &ecs);
};
void setup();
void update(float delta);
flecs::world &get();
}
#endif

View File

@@ -0,0 +1,3 @@
project(miniaudio)
add_library(miniaudio STATIC miniaudio.c)
target_include_directories(miniaudio PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,2 @@
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"

95648
src/miniaudio/miniaudio.h Normal file

File diff suppressed because it is too large Load Diff

5
src/sound/CMakeLists.txt Normal file
View File

@@ -0,0 +1,5 @@
project(sound)
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain CONFIG)
add_library(sound STATIC sound.cpp)
target_link_libraries(sound PRIVATE miniaudio PUBLIC OgreMain)
target_include_directories(sound PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

47
src/sound/sound.cpp Normal file
View File

@@ -0,0 +1,47 @@
#include <iostream>
#include <miniaudio.h>
#include <Ogre.h>
#include <OgreResourceGroupManager.h>
#include "sound.h"
namespace Sound
{
static ma_decoder decoder;
static ma_device_config deviceConfig;
static ma_device device;
static ma_engine engine;
std::vector<ma_sound> psound_data;
std::map<Ogre::String, int> psounds;
void setup()
{
int i;
ma_result result;
result = ma_engine_init(NULL, &engine);
OgreAssert(result == MA_SUCCESS, "MiniAudio init failed");
Ogre::FileInfoListPtr sounds =
Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(
"Audio", "*.wav");
psound_data.resize(sounds->size());
for (i = 0; i < sounds->size(); i++) {
Ogre::FileInfo fi = sounds->at(i);
Ogre::String path =
fi.archive->getName() + "/" + fi.path + fi.filename;
std::cout << "sound: " << path << "\n";
std::cout << "sound: " << fi.basename << "\n";
ma_sound_init_from_file(&engine, path.c_str(), 0, NULL, NULL,
&psound_data[i]);
psounds[fi.basename] = i;
}
}
void ding()
{
ma_sound &sound = psound_data[psounds["load.wav"]];
if (ma_sound_is_playing(&sound) && ma_sound_at_end(&sound)) {
ma_sound_stop(&sound);
ma_sound_seek_to_pcm_frame(&sound, 0);
} else if (ma_sound_is_playing(&sound))
return;
ma_sound_start(&sound);
}
}
/* nothing */

8
src/sound/sound.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef SOUND_H_
#define SOUND_H_
namespace Sound
{
void setup();
void ding();
}
#endif