feat: Initial console implementation

This commit is contained in:
Vsevolod Kremianskii 2020-09-25 23:59:24 +07:00
parent 95b04b7f59
commit c0f5d7f347
5 changed files with 224 additions and 2 deletions

View file

@ -59,6 +59,7 @@ set(HEADERS
src/game/blueprint/trigger.h
src/game/blueprint/waypoint.h
src/game/characters.h
src/game/console.h
src/game/dialog.h
src/game/game.h
src/game/gui/classsel.h
@ -187,6 +188,7 @@ set(SOURCES
src/game/blueprint/trigger.cpp
src/game/blueprint/waypoint.cpp
src/game/characters.cpp
src/game/console.cpp
src/game/dialog.cpp
src/game/game.cpp
src/game/gui/classsel.cpp

151
src/game/console.cpp Normal file
View file

@ -0,0 +1,151 @@
/*
* Copyright © 2020 Vsevolod Kremianskii
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "console.h"
#include "glm/ext.hpp"
#include "SDL2/SDL_opengl.h"
#include "../core/log.h"
#include "../render/font.h"
#include "../render/mesh/guiquad.h"
#include "../render/shaders.h"
#include "../resources/resources.h"
using namespace std;
using namespace reone::render;
namespace reone {
namespace game {
static const int kLineCount = 10;
Console::Console(const GraphicsOptions &opts) : _opts(opts) {
}
void Console::load() {
_font = Resources.findFont("fnt_d16x16");
assert(_font);
}
bool Console::handle(const SDL_Event &event) {
switch (event.type) {
case SDL_KEYDOWN:
return handleKeyDown(event.key);
case SDL_KEYUP:
return handleKeyUp(event.key);
default:
return false;
}
}
bool Console::handleKeyDown(const SDL_KeyboardEvent &event) {
if (!_open) return false;
bool shift = event.keysym.mod & KMOD_SHIFT;
bool digit = event.keysym.sym >= SDLK_0 && event.keysym.sym <= SDLK_9;
bool letter = event.keysym.sym >= SDLK_a && event.keysym.sym <= SDLK_z;
bool underscore = event.keysym.sym == SDLK_MINUS && shift;
if (digit || letter || underscore ||
event.keysym.sym == SDLK_SPACE ||
event.keysym.sym == SDLK_PERIOD) {
if (underscore) {
_inputText += SDLK_UNDERSCORE;
} else if (letter && shift) {
_inputText += toupper(event.keysym.sym);
} else {
_inputText += event.keysym.sym;
}
return true;
} else if (event.keysym.sym == SDLK_BACKSPACE) {
if (!_inputText.empty()) {
_inputText.resize(_inputText.size() - 1);
}
}
return false;
}
bool Console::handleKeyUp(const SDL_KeyboardEvent &event) {
if (_open) {
switch (event.keysym.sym) {
case SDLK_BACKQUOTE:
_open = false;
return true;
case SDLK_RETURN:
if (!_inputText.empty()) {
executeInputText();
_inputText.clear();
}
return true;
default:
return false;
}
} else {
switch (event.keysym.sym) {
case SDLK_BACKQUOTE:
_open = true;
return true;
default:
return false;
}
}
}
void Console::executeInputText() {
debug(boost::format("Console: execute \"%s\"") % _inputText);
}
void Console::render() const {
float height = kLineCount * _font->height();
glm::mat4 model(1.0f);
model = glm::scale(model, glm::vec3(_opts.width, height, 1.0f));
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.setUniform("model", model);
shaders.setUniform("color", glm::vec3(0.0f));
shaders.setUniform("alpha", 0.5f);
TheGUIQuad.render(GL_TRIANGLES);
string text("> " + _inputText);
glm::mat4 transform(1.0f);
transform = glm::translate(transform, glm::vec3(3.0f, height - 0.5f * _font->height(), 0.0f));
_font->render(text, transform, glm::vec3(1.0f), TextGravity::Right);
}
bool Console::isOpen() const {
return _open;
}
} // namespace game
} // namespace reone

59
src/game/console.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright © 2020 Vsevolod Kremianskii
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <functional>
#include <memory>
#include <string>
#include "SDL_events.h"
#include "../render/font.h"
#include "../render/types.h"
namespace reone {
namespace game {
class Console {
public:
Console(const render::GraphicsOptions &opts);
void load();
bool handle(const SDL_Event &event);
void render() const;
bool isOpen() const;
private:
std::shared_ptr<render::Font> _font;
render::GraphicsOptions _opts;
bool _open { false };
std::string _inputText;
Console(const Console &) = delete;
Console &operator=(const Console &) = delete;
bool handleKeyDown(const SDL_KeyboardEvent &event);
bool handleKeyUp(const SDL_KeyboardEvent &event);
void executeInputText();
};
} // namespace game
} // namespace reone

View file

@ -58,7 +58,8 @@ Game::Game(GameVersion version, const fs::path &path, const Options &opts) :
_version(version),
_path(path),
_opts(opts),
_window(opts.graphics, this) {
_window(opts.graphics, this),
_console(opts.graphics) {
initObjectFactory();
}
@ -77,6 +78,7 @@ int Game::run() {
configure();
loadCursor();
_console.load();
_window.show();
runMainLoop();
@ -431,7 +433,12 @@ void Game::drawGUI() {
switch (_screen) {
case Screen::InGame:
_debugGui->render();
if (_module->cameraType() == CameraType::ThirdPerson) _hud->render();
if (_module->cameraType() == CameraType::ThirdPerson) {
_hud->render();
}
if (_console.isOpen()) {
_console.render();
}
break;
default: {
shared_ptr<GUI> gui(currentGUI());
@ -480,6 +487,7 @@ void Game::drawCursor() {
bool Game::handle(const SDL_Event &event) {
switch (_screen) {
case Screen::InGame:
if (_console.handle(event)) return true;
if (_module->cameraType() == CameraType::ThirdPerson && _hud->handle(event)) return true;
if (_module->handle(event)) return true;
break;

View file

@ -32,6 +32,7 @@
#include "gui/portraitsel.h"
#include "area.h"
#include "console.h"
#include "module.h"
namespace reone {
@ -122,6 +123,7 @@ private:
std::string _nextEntry;
GameState _state;
std::shared_ptr<audio::SoundInstance> _music;
Console _console;
// GUI
std::shared_ptr<MainMenu> _mainMenu;