From: Daniel Karbach Date: Thu, 6 Aug 2015 09:03:46 +0000 (+0200) Subject: state management and control X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=afd253b2dd10fdf2d4655d3d4a5766e6aa8c1a2c;p=blank.git state management and control --- diff --git a/src/app/Application.hpp b/src/app/Application.hpp index 9732349..bae8435 100644 --- a/src/app/Application.hpp +++ b/src/app/Application.hpp @@ -1,34 +1,20 @@ #ifndef BLANK_APP_APPLICATION_HPP_ #define BLANK_APP_APPLICATION_HPP_ -#include "Assets.hpp" -#include "FrameCounter.hpp" -#include "../ai/Spawner.hpp" -#include "../audio/Audio.hpp" -#include "../graphics/Viewport.hpp" -#include "../ui/Interface.hpp" -#include "../world/World.hpp" - #include +#include namespace blank { +class Environment; +class State; class Window; class Application { public: - struct Config { - bool vsync = true; - bool doublebuf = true; - int multisampling = 1; - - Interface::Config interface = Interface::Config(); - World::Config world = World::Config(); - }; - - Application(Window &, const Config &); + explicit Application(Environment &); ~Application(); Application(const Application &) = delete; @@ -48,25 +34,22 @@ public: /// process all events in SDL's queue void HandleEvents(); + void Handle(const SDL_Event &); void Handle(const SDL_WindowEvent &); /// integrate to the next step with dt milliseconds passed void Update(int dt); /// push the current state to display void Render(); -private: - Window &window; - Viewport viewport; - Assets assets; - Audio audio; - FrameCounter counter; + void PushState(State *); + State *PopState(); + State *SwitchState(State *); + State &GetState(); + bool HasState() const noexcept; - World world; - Interface interface; - - Spawner spawner; - - bool running; +private: + Environment &env; + std::stack states; }; diff --git a/src/app/Environment.hpp b/src/app/Environment.hpp new file mode 100644 index 0000000..b465bfb --- /dev/null +++ b/src/app/Environment.hpp @@ -0,0 +1,33 @@ +#ifndef BLANK_APP_ENVIRONMENT_HPP_ +#define BLANK_APP_ENVIRONMENT_HPP_ + +#include "Assets.hpp" +#include "FrameCounter.hpp" +#include "StateControl.hpp" +#include "../audio/Audio.hpp" +#include "../graphics/Viewport.hpp" + + +namespace blank { + +class Window; + +struct Environment { + + Audio audio; + Viewport viewport; + Window &window; + + Assets assets; + FrameCounter counter; + + StateControl state; + + + explicit Environment(Window &win); + +}; + +} + +#endif diff --git a/src/app/Runtime.cpp b/src/app/Runtime.cpp deleted file mode 100644 index 6a4c783..0000000 --- a/src/app/Runtime.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "Runtime.hpp" - -#include "init.hpp" - -#include -#include -#include - -using namespace std; - - -namespace blank { - -Runtime::Runtime() noexcept -: name("blank") -, mode(NORMAL) -, n(0) -, t(0) -, config() { - -} - - -void Runtime::ReadArgs(int argc, const char *const *argv) { - if (argc <= 0) return; - name = argv[0]; - - bool options = true; - bool error = false; - - for (int i = 1; i < argc; ++i) { - const char *arg = argv[i]; - if (!arg || arg[0] == '\0') { - cerr << "warning: found empty argument at position " << i << endl; - continue; - } - if (options && arg[0] == '-') { - if (arg[1] == '\0') { - cerr << "warning: incomplete option list at position " << i << endl; - } else if (arg[1] == '-') { - if (arg[2] == '\0') { - // stopper - options = false; - } else { - // long option - if (strcmp(arg + 2, "no-vsync") == 0) { - config.vsync = false; - } else if (strcmp(arg + 2, "no-keyboard") == 0) { - config.interface.keyboard_disabled = true; - } else if (strcmp(arg + 2, "no-mouse") == 0) { - config.interface.mouse_disabled = true; - } else if (strcmp(arg + 2, "no-hud") == 0) { - config.interface.visual_disabled = true; - } else if (strcmp(arg + 2, "no-audio") == 0) { - config.interface.audio_disabled = true; - } else { - cerr << "unknown option " << arg << endl; - error = true; - } - } - } else { - // short options - for (int j = 1; arg[j] != '\0'; ++j) { - switch (arg[j]) { - case 'd': - config.doublebuf = false; - break; - case 'm': - ++i; - if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { - cerr << "missing argument to -m" << endl; - error = true; - } else { - config.multisampling = strtoul(argv[i], nullptr, 10); - } - break; - case 'n': - ++i; - if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { - cerr << "missing argument to -n" << endl; - error = true; - } else { - n = strtoul(argv[i], nullptr, 10); - } - break; - case 's': - ++i; - if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { - cerr << "missing argument to -s" << endl; - error = true; - } else { - config.world.gen.solid_seed = strtoul(argv[i], nullptr, 10); - config.world.gen.type_seed = config.world.gen.solid_seed; - } - break; - case 't': - ++i; - if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { - cerr << "missing argument to -t" << endl; - error = true; - } else { - t = strtoul(argv[i], nullptr, 10); - } - break; - case '-': - // stopper - options = false; - break; - default: - cerr << "unknown option " << arg[j] << endl; - error = true; - break; - } - } - } - } else { - cerr << "unable to interpret argument " - << i << " (" << arg << ")" << endl; - error = true; - } - } - - if (error) { - mode = ERROR; - return; - } - - if (n > 0) { - if (t > 0) { - mode = FIXED_FRAME_LIMIT; - } else { - mode = FRAME_LIMIT; - } - } else if (t > 0) { - mode = TIME_LIMIT; - } else { - mode = NORMAL; - } -} - -int Runtime::Execute() { - if (mode == ERROR) { - return 1; - } - - Init init(config.doublebuf, config.multisampling); - Application app(init.window, config); - switch (mode) { - default: - case NORMAL: - app.Run(); - break; - case FRAME_LIMIT: - app.RunN(n); - break; - case TIME_LIMIT: - app.RunT(t); - break; - case FIXED_FRAME_LIMIT: - app.RunS(n, t); - break; - } - return 0; -} - -} diff --git a/src/app/Runtime.hpp b/src/app/Runtime.hpp index ee0b4a0..036b8db 100644 --- a/src/app/Runtime.hpp +++ b/src/app/Runtime.hpp @@ -1,7 +1,8 @@ #ifndef BLANK_RUNTIME_HPP_ #define BLANK_RUNTIME_HPP_ -#include "Application.hpp" +#include "../ui/Interface.hpp" +#include "../world/World.hpp" #include @@ -25,6 +26,15 @@ public: ERROR, }; + struct Config { + bool vsync = true; + bool doublebuf = true; + int multisampling = 1; + + Interface::Config interface = Interface::Config(); + World::Config world = World::Config(); + }; + Runtime() noexcept; void ReadArgs(int argc, const char *const *argv); @@ -36,7 +46,7 @@ private: Mode mode; std::size_t n; std::size_t t; - Application::Config config; + Config config; }; diff --git a/src/app/State.hpp b/src/app/State.hpp new file mode 100644 index 0000000..2bdd41b --- /dev/null +++ b/src/app/State.hpp @@ -0,0 +1,23 @@ +#ifndef BLANK_APP_STATE_HPP_ +#define BLANK_APP_STATE_HPP_ + +#include + + +namespace blank { + +class Viewport; + +struct State { + + virtual void Handle(const SDL_Event &) = 0; + + virtual void Update(int dt) = 0; + + virtual void Render(Viewport &) = 0; + +}; + +}; + +#endif diff --git a/src/app/StateControl.hpp b/src/app/StateControl.hpp new file mode 100644 index 0000000..818bce5 --- /dev/null +++ b/src/app/StateControl.hpp @@ -0,0 +1,52 @@ +#ifndef BLANK_APP_STATECONTROL_HPP_ +#define BLANK_APP_STATECONTROL_HPP_ + +#include + + +namespace blank { + +class Application; +class State; + +class StateControl { + +public: + void Push(State *s) { + cue.emplace(PUSH, s); + } + + void Switch(State *s) { + cue.emplace(SWITCH, s); + } + + void Pop() { + cue.emplace(POP); + } + + void PopAll() { + cue.emplace(POP_ALL); + } + + + void Commit(Application &); + +private: + enum Command { + PUSH, + SWITCH, + POP, + POP_ALL, + }; + struct Memo { + State *state; + Command cmd; + explicit Memo(Command c, State *s = nullptr): state(s), cmd(c) { } + }; + std::queue cue; + +}; + +} + +#endif diff --git a/src/app/WorldState.cpp b/src/app/WorldState.cpp new file mode 100644 index 0000000..6ca9959 --- /dev/null +++ b/src/app/WorldState.cpp @@ -0,0 +1,67 @@ +#include "WorldState.hpp" + +#include "Environment.hpp" + +#include + + +namespace blank { + +WorldState::WorldState( + Environment &env, + const Interface::Config &ic, + const World::Config &wc +) +: env(env) +, world(wc) +, spawner(world) +, interface(ic, env, world) { + +} + + +void WorldState::Handle(const SDL_Event &event) { + switch (event.type) { + case SDL_KEYDOWN: + interface.HandlePress(event.key); + break; + case SDL_KEYUP: + interface.HandleRelease(event.key); + break; + case SDL_MOUSEBUTTONDOWN: + interface.HandlePress(event.button); + break; + case SDL_MOUSEBUTTONUP: + interface.HandleRelease(event.button); + break; + case SDL_MOUSEMOTION: + interface.Handle(event.motion); + break; + case SDL_MOUSEWHEEL: + interface.Handle(event.wheel); + break; + default: + break; + } +} + +void WorldState::Update(int dt) { + interface.Update(dt); + spawner.Update(dt); + world.Update(dt); + + glm::mat4 trans = world.Player().Transform(Chunk::Pos(0, 0, 0)); + glm::vec3 dir(trans * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)); + glm::vec3 up(trans * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)); + env.audio.Position(world.Player().Position()); + env.audio.Velocity(world.Player().Velocity()); + env.audio.Orientation(dir, up); + +} + +void WorldState::Render(Viewport &viewport) { + world.Render(viewport); + interface.Render(viewport); +} + +} diff --git a/src/app/WorldState.hpp b/src/app/WorldState.hpp new file mode 100644 index 0000000..38922ff --- /dev/null +++ b/src/app/WorldState.hpp @@ -0,0 +1,38 @@ +#ifndef BLANK_APP_WORLDSTATE_HPP_ +#define BLANK_APP_WORLDSTATE_HPP_ + +#include "State.hpp" +#include "../ai/Spawner.hpp" +#include "../ui/Interface.hpp" +#include "../world/World.hpp" + + +namespace blank { + +class Environment; + +class WorldState +: public State { + +public: + WorldState( + Environment &, + const Interface::Config &, + const World::Config & + ); + + void Handle(const SDL_Event &) override; + void Update(int dt) override; + void Render(Viewport &) override; + +private: + Environment &env; + World world; + Spawner spawner; + Interface interface; + +}; + +} + +#endif diff --git a/src/app/app.cpp b/src/app/app.cpp index 86c90d8..420dee7 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1,6 +1,9 @@ #include "Application.hpp" #include "Assets.hpp" +#include "Environment.hpp" #include "FrameCounter.hpp" +#include "State.hpp" +#include "StateControl.hpp" #include "init.hpp" #include "../audio/Sound.hpp" @@ -14,41 +17,22 @@ using std::string; -namespace { - -string get_asset_path() { - char *base = SDL_GetBasePath(); - string assets(base); - assets += "assets/"; - SDL_free(base); - return assets; -} - -} - namespace blank { -Application::Application(Window &win, const Config &config) -: window(win) -, viewport() -, assets(get_asset_path()) -, audio() -, counter() -, world(config.world) -, interface(config.interface, assets, audio, counter, world) -, spawner(world) -, running(false) { - viewport.VSync(config.vsync); +Application::Application(Environment &e) +: env(e) +, states() { + } Application::~Application() { - audio.StopAll(); + env.audio.StopAll(); } void Application::RunN(size_t n) { Uint32 last = SDL_GetTicks(); - for (size_t i = 0; i < n; ++i) { + for (size_t i = 0; HasState() && i < n; ++i) { Uint32 now = SDL_GetTicks(); int delta = now - last; Loop(delta); @@ -59,7 +43,7 @@ void Application::RunN(size_t n) { void Application::RunT(size_t t) { Uint32 last = SDL_GetTicks(); Uint32 finish = last + t; - while (last < finish) { + while (HasState() && last < finish) { Uint32 now = SDL_GetTicks(); int delta = now - last; Loop(delta); @@ -68,17 +52,16 @@ void Application::RunT(size_t t) { } void Application::RunS(size_t n, size_t t) { - for (size_t i = 0; i < n; ++i) { + for (size_t i = 0; HasState() && i < n; ++i) { Loop(t); } } void Application::Run() { - running = true; Uint32 last = SDL_GetTicks(); - window.GrabMouse(); - while (running) { + env.window.GrabMouse(); + while (HasState()) { Uint32 now = SDL_GetTicks(); int delta = now - last; Loop(delta); @@ -87,60 +70,51 @@ void Application::Run() { } void Application::Loop(int dt) { - counter.EnterFrame(); + env.counter.EnterFrame(); HandleEvents(); + if (!HasState()) return; Update(dt); + env.state.Commit(*this); + if (!HasState()) return; Render(); - counter.ExitFrame(); + env.counter.ExitFrame(); } void Application::HandleEvents() { - counter.EnterHandle(); + env.counter.EnterHandle(); SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - interface.HandlePress(event.key); - break; - case SDL_KEYUP: - interface.HandleRelease(event.key); - break; - case SDL_MOUSEBUTTONDOWN: - interface.HandlePress(event.button); - break; - case SDL_MOUSEBUTTONUP: - interface.HandleRelease(event.button); - break; - case SDL_MOUSEMOTION: - interface.Handle(event.motion); - break; - case SDL_MOUSEWHEEL: - interface.Handle(event.wheel); - break; - case SDL_QUIT: - running = false; - break; - case SDL_WINDOWEVENT: - Handle(event.window); - break; - default: - break; - } + while (HasState() && SDL_PollEvent(&event)) { + Handle(event); + env.state.Commit(*this); + } + env.counter.ExitHandle(); +} + +void Application::Handle(const SDL_Event &event) { + switch (event.type) { + case SDL_QUIT: + env.state.PopAll(); + break; + case SDL_WINDOWEVENT: + Handle(event.window); + break; + default: + GetState().Handle(event); + break; } - counter.ExitHandle(); } void Application::Handle(const SDL_WindowEvent &event) { switch (event.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: - window.GrabMouse(); + env.window.GrabMouse(); break; case SDL_WINDOWEVENT_FOCUS_LOST: - window.ReleaseMouse(); + env.window.ReleaseMouse(); break; case SDL_WINDOWEVENT_RESIZED: - viewport.Resize(event.data1, event.data2); + env.viewport.Resize(event.data1, event.data2); break; default: break; @@ -148,32 +122,74 @@ void Application::Handle(const SDL_WindowEvent &event) { } void Application::Update(int dt) { - counter.EnterUpdate(); - interface.Update(dt); - spawner.Update(dt); - world.Update(dt); - - glm::mat4 trans = world.Player().Transform(Chunk::Pos(0, 0, 0)); - glm::vec3 dir(trans * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)); - glm::vec3 up(trans * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)); - audio.Position(world.Player().Position()); - audio.Velocity(world.Player().Velocity()); - audio.Orientation(dir, up); - - counter.ExitUpdate(); + env.counter.EnterUpdate(); + if (HasState()) { + GetState().Update(dt); + } + env.counter.ExitUpdate(); } void Application::Render() { // gl implementation may (and will probably) delay vsync blocking until // the first write after flipping, which is this clear call - viewport.Clear(); - counter.EnterRender(); + env.viewport.Clear(); + env.counter.EnterRender(); + + if (HasState()) { + GetState().Render(env.viewport); + } + + env.counter.ExitRender(); + env.window.Flip(); +} - world.Render(viewport); - interface.Render(viewport); - counter.ExitRender(); - window.Flip(); +void Application::PushState(State *s) { + states.emplace(s); +} + +State *Application::PopState() { + State *s = states.top(); + states.pop(); + return s; +} + +State *Application::SwitchState(State *s_new) { + State *s_old = states.top(); + states.top() = s_new; + return s_old; +} + +State &Application::GetState() { + return *states.top(); +} + +bool Application::HasState() const noexcept { + return !states.empty(); +} + + +void StateControl::Commit(Application &app) { + while (!cue.empty()) { + Memo m(cue.front()); + cue.pop(); + switch (m.cmd) { + case PUSH: + app.PushState(m.state); + break; + case SWITCH: + app.SwitchState(m.state); + break; + case POP: + app.PopState(); + break; + case POP_ALL: + while (app.HasState()) { + app.PopState(); + } + break; + } + } } diff --git a/src/app/runtime.cpp b/src/app/runtime.cpp new file mode 100644 index 0000000..37cca50 --- /dev/null +++ b/src/app/runtime.cpp @@ -0,0 +1,201 @@ +#include "Application.hpp" +#include "Environment.hpp" +#include "Runtime.hpp" +#include "WorldState.hpp" + +#include "init.hpp" + +#include +#include +#include +#include + +using namespace std; + + +namespace { + +string get_asset_path() { + char *base = SDL_GetBasePath(); + string assets(base); + assets += "assets/"; + SDL_free(base); + return assets; +} + +} + +namespace blank { + +Environment::Environment(Window &win) +: audio() +, viewport() +, window(win) +, assets(get_asset_path()) +, counter() { + +} + + +Runtime::Runtime() noexcept +: name("blank") +, mode(NORMAL) +, n(0) +, t(0) +, config() { + +} + + +void Runtime::ReadArgs(int argc, const char *const *argv) { + if (argc <= 0) return; + name = argv[0]; + + bool options = true; + bool error = false; + + for (int i = 1; i < argc; ++i) { + const char *arg = argv[i]; + if (!arg || arg[0] == '\0') { + cerr << "warning: found empty argument at position " << i << endl; + continue; + } + if (options && arg[0] == '-') { + if (arg[1] == '\0') { + cerr << "warning: incomplete option list at position " << i << endl; + } else if (arg[1] == '-') { + if (arg[2] == '\0') { + // stopper + options = false; + } else { + // long option + if (strcmp(arg + 2, "no-vsync") == 0) { + config.vsync = false; + } else if (strcmp(arg + 2, "no-keyboard") == 0) { + config.interface.keyboard_disabled = true; + } else if (strcmp(arg + 2, "no-mouse") == 0) { + config.interface.mouse_disabled = true; + } else if (strcmp(arg + 2, "no-hud") == 0) { + config.interface.visual_disabled = true; + } else if (strcmp(arg + 2, "no-audio") == 0) { + config.interface.audio_disabled = true; + } else { + cerr << "unknown option " << arg << endl; + error = true; + } + } + } else { + // short options + for (int j = 1; arg[j] != '\0'; ++j) { + switch (arg[j]) { + case 'd': + config.doublebuf = false; + break; + case 'm': + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to -m" << endl; + error = true; + } else { + config.multisampling = strtoul(argv[i], nullptr, 10); + } + break; + case 'n': + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to -n" << endl; + error = true; + } else { + n = strtoul(argv[i], nullptr, 10); + } + break; + case 's': + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to -s" << endl; + error = true; + } else { + config.world.gen.solid_seed = strtoul(argv[i], nullptr, 10); + config.world.gen.type_seed = config.world.gen.solid_seed; + } + break; + case 't': + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to -t" << endl; + error = true; + } else { + t = strtoul(argv[i], nullptr, 10); + } + break; + case '-': + // stopper + options = false; + break; + default: + cerr << "unknown option " << arg[j] << endl; + error = true; + break; + } + } + } + } else { + cerr << "unable to interpret argument " + << i << " (" << arg << ")" << endl; + error = true; + } + } + + if (error) { + mode = ERROR; + return; + } + + if (n > 0) { + if (t > 0) { + mode = FIXED_FRAME_LIMIT; + } else { + mode = FRAME_LIMIT; + } + } else if (t > 0) { + mode = TIME_LIMIT; + } else { + mode = NORMAL; + } +} + +int Runtime::Execute() { + if (mode == ERROR) { + return 1; + } + + Init init(config.doublebuf, config.multisampling); + + Environment env(init.window); + env.viewport.VSync(config.vsync); + + Application app(env); + + WorldState state(env, config.interface, config.world); + app.PushState(&state); + + switch (mode) { + default: + case NORMAL: + app.Run(); + break; + case FRAME_LIMIT: + app.RunN(n); + break; + case TIME_LIMIT: + app.RunT(t); + break; + case FIXED_FRAME_LIMIT: + app.RunS(n, t); + break; + } + + return 0; +} + +} diff --git a/src/ui/Interface.hpp b/src/ui/Interface.hpp index 1ade2d1..f810ff0 100644 --- a/src/ui/Interface.hpp +++ b/src/ui/Interface.hpp @@ -18,10 +18,8 @@ namespace blank { -class Assets; -class Audio; class Chunk; -class FrameCounter; +class Environment; class Viewport; class World; @@ -39,7 +37,7 @@ public: bool visual_disabled = false; }; - Interface(const Config &, const Assets &, Audio &, const FrameCounter &, World &); + Interface(const Config &, Environment &, World &); void HandlePress(const SDL_KeyboardEvent &); void HandleRelease(const SDL_KeyboardEvent &); @@ -86,8 +84,7 @@ private: void CheckAim(); private: - Audio &audio; - const FrameCounter &counter; + Environment &env; World &world; FPSController ctrl; Font font; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index 6fa7356..e53cff6 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -2,6 +2,7 @@ #include "Interface.hpp" #include "../app/Assets.hpp" +#include "../app/Environment.hpp" #include "../app/FrameCounter.hpp" #include "../app/init.hpp" #include "../audio/Audio.hpp" @@ -92,15 +93,12 @@ void HUD::Render(Viewport &viewport) noexcept { Interface::Interface( const Config &config, - const Assets &assets, - Audio &audio, - const FrameCounter &counter, + Environment &env, World &world) -: audio(audio) -, counter(counter) +: env(env) , world(world) , ctrl(world.Player()) -, font(assets.LoadFont("DejaVuSans", 16)) +, font(env.assets.LoadFont("DejaVuSans", 16)) , hud(world.BlockTypes(), font) , aim{{ 0, 0, 0 }, { 0, 0, -1 }} , aim_chunk(nullptr) @@ -116,8 +114,8 @@ Interface::Interface( , remove_timer(256) , remove(0) , selection(1) -, place_sound(assets.LoadSound("thump")) -, remove_sound(assets.LoadSound("plop")) +, place_sound(env.assets.LoadSound("thump")) +, remove_sound(env.assets.LoadSound("plop")) , fwd(0) , rev(0) { counter_text.Hide(); @@ -354,8 +352,8 @@ void Interface::ToggleDebug() { void Interface::UpdateCounter() { std::stringstream s; s << std::setprecision(3) << - "avg: " << counter.Average().running << "ms, " - "peak: " << counter.Peak().running << "ms"; + "avg: " << env.counter.Average().running << "ms, " + "peak: " << env.counter.Peak().running << "ms"; std::string text = s.str(); counter_text.Set(font, text); } @@ -416,7 +414,7 @@ void Interface::PlaceBlock() { if (config.audio_disabled) return; const Entity &player = ctrl.Controlled(); - audio.Play( + env.audio.Play( place_sound, mod_chunk->ToSceneCoords(player.ChunkCoords(), next_pos) ); @@ -429,7 +427,7 @@ void Interface::RemoveBlock() noexcept { if (config.audio_disabled) return; const Entity &player = ctrl.Controlled(); - audio.Play( + env.audio.Play( remove_sound, aim_chunk->ToSceneCoords(player.ChunkCoords(), Chunk::ToCoords(aim_block)) ); @@ -496,7 +494,7 @@ void Interface::Update(int dt) { CheckAim(); } - if (counter_text.Visible() && counter.Changed()) { + if (counter_text.Visible() && env.counter.Changed()) { UpdateCounter(); } if (position_text.Visible()) {