#include "screens.h" #include "../assets/Assets.h" #include "../audio/audio.h" #include "../content/Content.h" #include "../core_defs.h" #include "../engine.h" #include "../graphics/core/Batch2D.h" #include "../graphics/core/GfxContext.h" #include "../graphics/core/Shader.h" #include "../graphics/core/TextureAnimation.h" #include "../graphics/render/WorldRenderer.h" #include "../graphics/ui/elements/containers.h" #include "../graphics/ui/GUI.h" #include "../logic/ChunksController.h" #include "../logic/LevelController.h" #include "../logic/scripting/scripting_hud.h" #include "../logic/scripting/scripting.h" #include "../logic/scripting/Environment.h" #include "../objects/Player.h" #include "../physics/Hitbox.h" #include "../util/stringutil.h" #include "../voxels/Block.h" #include "../voxels/Chunk.h" #include "../voxels/Chunks.h" #include "../window/Camera.h" #include "../window/Events.h" #include "../window/input.h" #include "../world/Level.h" #include "../world/World.h" #include "ContentGfxCache.h" #include "hud.h" #include "LevelFrontend.h" #include "menu/menu.h" #include #include #include #include #include #include #include Screen::Screen(Engine* engine) : engine(engine), batch(new Batch2D(1024)) { } Screen::~Screen() { } MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { auto menu = engine->getGUI()->getMenu(); menu->reset(); menus::refresh_menus(engine); menu->setPage("main"); uicamera.reset(new Camera(glm::vec3(), Window::height)); uicamera->perspective = false; uicamera->flipped = true; } MenuScreen::~MenuScreen() { } void MenuScreen::update(float delta) { } void MenuScreen::draw(float delta) { Window::clear(); Window::setBgColor(glm::vec3(0.2f)); uicamera->setFov(Window::height); Shader* uishader = engine->getAssets()->getShader("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); uint width = Window::width; uint height = Window::height; batch->begin(); batch->texture(engine->getAssets()->getTexture("gui/menubg")); batch->rect( 0, 0, width, height, 0, 0, 0, UVRegion(0, 0, width/64, height/64), false, false, glm::vec4(1.0f) ); batch->flush(); } static bool backlight; LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) { auto& settings = engine->getSettings(); auto assets = engine->getAssets(); auto menu = engine->getGUI()->getMenu(); menu->reset(); controller = std::make_unique(settings, level); frontend = std::make_unique(controller.get(), assets); worldRenderer = std::make_unique(engine, frontend.get(), controller->getPlayer()); hud = std::make_unique(engine, frontend.get(), controller->getPlayer()); backlight = settings.graphics.backlight; animator = std::make_unique(); animator->addAnimations(assets->getAnimations()); auto content = level->content; for (auto& entry : content->getPacks()) { auto pack = entry.second.get(); const ContentPack& info = pack->getInfo(); fs::path scriptFile = info.folder/fs::path("scripts/hud.lua"); if (fs::is_regular_file(scriptFile)) { scripting::load_hud_script(pack->getEnvironment()->getId(), info.id, scriptFile); } } scripting::on_frontend_init(hud.get()); } LevelScreen::~LevelScreen() { scripting::on_frontend_close(); controller->onWorldQuit(); engine->getPaths()->setWorldFolder(fs::path()); } void LevelScreen::updateHotkeys() { auto& settings = engine->getSettings(); if (Events::jpressed(keycode::O)) { settings.graphics.frustumCulling = !settings.graphics.frustumCulling; } if (Events::jpressed(keycode::F1)) { hudVisible = !hudVisible; } if (Events::jpressed(keycode::F3)) { controller->getPlayer()->debug = !controller->getPlayer()->debug; } if (Events::jpressed(keycode::F5)) { controller->getLevel()->chunks->saveAndClear(); } } void LevelScreen::update(float delta) { gui::GUI* gui = engine->getGUI(); bool inputLocked = hud->isPause() || hud->isInventoryOpen() || gui->isFocusCaught(); if (!gui->isFocusCaught()) { updateHotkeys(); } auto player = controller->getPlayer(); auto camera = player->camera; bool paused = hud->isPause(); audio::get_channel("regular")->setPaused(paused); audio::get_channel("ambient")->setPaused(paused); audio::set_listener( camera->position-camera->dir, player->hitbox->velocity, camera->dir, camera->up ); // TODO: subscribe for setting change EngineSettings& settings = engine->getSettings(); controller->getPlayer()->camera->setFov(glm::radians(settings.camera.fov)); if (settings.graphics.backlight != backlight) { controller->getLevel()->chunks->saveAndClear(); backlight = settings.graphics.backlight; } if (!hud->isPause()) { controller->getLevel()->world->updateTimers(delta); animator->update(delta); } controller->update(delta, !inputLocked, hud->isPause()); hud->update(hudVisible); } void LevelScreen::draw(float delta) { auto camera = controller->getPlayer()->currentCamera; Viewport viewport(Window::width, Window::height); GfxContext ctx(nullptr, viewport, batch.get()); worldRenderer->draw(ctx, camera.get(), hudVisible); if (hudVisible) { hud->draw(ctx); } } void LevelScreen::onEngineShutdown() { controller->saveWorld(); } LevelController* LevelScreen::getLevelController() const { return controller.get(); }