@ -1,664 +0,0 @@ | |||
/* | |||
* Copyright (C) 2017 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper Source Code. | |||
* | |||
* Antkeeper Source Code 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. | |||
* | |||
* Antkeeper Source Code 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 Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "controls.hpp" | |||
#include <sstream> | |||
#include <fstream> | |||
#include <vector> | |||
Control::Control(): | |||
deadzone(0.1f), | |||
currentValue(0.0f), | |||
previousValue(0.0f) | |||
{} | |||
Control::~Control() | |||
{} | |||
void Control::setDeadzone(float value) | |||
{ | |||
deadzone = value; | |||
} | |||
void Control::update() | |||
{ | |||
if (!boundMouseWheelAxes.empty()) | |||
{ | |||
currentValue = 0.0f; | |||
} | |||
previousValue = currentValue; | |||
} | |||
bool Control::isTriggered() const | |||
{ | |||
return currentValue > deadzone; | |||
} | |||
bool Control::wasTriggered() const | |||
{ | |||
return previousValue > deadzone; | |||
} | |||
bool Control::isUnbound() const | |||
{ | |||
return (boundKeys.empty() && boundMouseButtons.empty() && boundMouseWheelAxes.empty() && boundGamepadButtons.empty() && boundGamepadAxes.empty()); | |||
} | |||
void Control::bindKey(Keyboard* keyboard, int scancode) | |||
{ | |||
// Check if already observing this keyboard | |||
bool observing = false; | |||
for (auto it: boundKeys) | |||
{ | |||
if (it.first == keyboard) | |||
{ | |||
observing = true; | |||
break; | |||
} | |||
} | |||
if (!observing) | |||
keyboard->addKeyObserver(static_cast<KeyObserver*>(this)); | |||
boundKeys.push_back(std::pair<Keyboard*, int>(keyboard, scancode)); | |||
} | |||
void Control::bindMouseButton(Mouse* mouse, int button) | |||
{ | |||
// Checking if already observing this mouse | |||
bool observing = false; | |||
for (auto it: boundMouseButtons) | |||
{ | |||
if (it.first == mouse) | |||
{ | |||
observing = true; | |||
break; | |||
} | |||
} | |||
if (!observing) | |||
mouse->addMouseButtonObserver(static_cast<MouseButtonObserver*>(this)); | |||
boundMouseButtons.push_back(std::pair<Mouse*, int>(mouse, button)); | |||
} | |||
void Control::bindMouseWheelAxis(Mouse* mouse, MouseWheelAxis axis) | |||
{ | |||
// Checking if already observing this mouse | |||
bool observing = false; | |||
for (auto it: boundMouseWheelAxes) | |||
{ | |||
if (it.first == mouse) | |||
{ | |||
observing = true; | |||
break; | |||
} | |||
} | |||
if (!observing) | |||
mouse->addMouseWheelObserver(static_cast<MouseWheelObserver*>(this)); | |||
boundMouseWheelAxes.push_back(std::pair<Mouse*, MouseWheelAxis>(mouse, axis)); | |||
} | |||
void Control::bindGamepadButton(Gamepad* gamepad, int button) | |||
{ | |||
bool observing = false; | |||
for (auto it: boundGamepadButtons) | |||
{ | |||
if (it.first == gamepad) | |||
{ | |||
observing = true; | |||
break; | |||
} | |||
} | |||
if (!observing) | |||
gamepad->addGamepadButtonObserver(static_cast<GamepadButtonObserver*>(this)); | |||
boundGamepadButtons.push_back(std::pair<Gamepad*, int>(gamepad, button)); | |||
} | |||
void Control::bindGamepadAxis(Gamepad* gamepad, int axis, bool negative) | |||
{ | |||
bool observing = false; | |||
for (auto it: boundGamepadAxes) | |||
{ | |||
if (std::get<0>(it) == gamepad) | |||
{ | |||
observing = true; | |||
break; | |||
} | |||
} | |||
if (!observing) | |||
gamepad->addGamepadAxisObserver(static_cast<GamepadAxisObserver*>(this)); | |||
boundGamepadAxes.push_back(std::make_tuple(gamepad, axis, negative)); | |||
} | |||
void Control::bind(const InputEvent& event) | |||
{ | |||
switch (event.type) | |||
{ | |||
case InputEvent::Type::KEY: | |||
bindKey(event.key.first, event.key.second); | |||
break; | |||
case InputEvent::Type::MOUSE_BUTTON: | |||
bindMouseButton(event.mouseButton.first, event.mouseButton.second); | |||
break; | |||
case InputEvent::Type::MOUSE_WHEEL: | |||
{ | |||
int x = std::get<1>(event.mouseWheel); | |||
int y = std::get<2>(event.mouseWheel); | |||
MouseWheelAxis axis; | |||
if (x > 0) | |||
axis = MouseWheelAxis::POSITIVE_X; | |||
else if (x < 0) | |||
axis = MouseWheelAxis::NEGATIVE_X; | |||
else if (y > 0) | |||
axis = MouseWheelAxis::POSITIVE_Y; | |||
else if (y < 0) | |||
axis = MouseWheelAxis::NEGATIVE_Y; | |||
else | |||
break; | |||
bindMouseWheelAxis(std::get<0>(event.mouseWheel), axis); | |||
break; | |||
} | |||
case InputEvent::Type::GAMEPAD_BUTTON: | |||
bindGamepadButton(event.gamepadButton.first, event.gamepadButton.second); | |||
break; | |||
case InputEvent::Type::GAMEPAD_AXIS: | |||
bindGamepadAxis(std::get<0>(event.gamepadAxis), std::get<1>(event.gamepadAxis), std::get<2>(event.gamepadAxis)); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
void Control::unbind() | |||
{ | |||
while (!boundKeys.empty()) | |||
{ | |||
// Remove the first bound key and stop observing its keyboard | |||
Keyboard* keyboard = boundKeys.front().first; | |||
keyboard->removeKeyObserver(static_cast<KeyObserver*>(this)); | |||
boundKeys.pop_front(); | |||
// Remove other bound keys which are associated with the keyboard | |||
auto it = boundKeys.begin(); | |||
while (it != boundKeys.end()) | |||
{ | |||
if (it->first == keyboard) | |||
boundKeys.erase(it++); | |||
else | |||
++it; | |||
} | |||
} | |||
while (!boundMouseButtons.empty()) | |||
{ | |||
// Remove the first bound mouse button and stop observing its mouse | |||
Mouse* mouse = boundMouseButtons.front().first; | |||
mouse->removeMouseButtonObserver(static_cast<MouseButtonObserver*>(this)); | |||
boundMouseButtons.pop_front(); | |||
// Remove other bound mouse buttons which are associated with the mouse | |||
auto it = boundMouseButtons.begin(); | |||
while (it != boundMouseButtons.end()) | |||
{ | |||
if (it->first == mouse) | |||
boundMouseButtons.erase(it++); | |||
else | |||
++it; | |||
} | |||
} | |||
while (!boundMouseWheelAxes.empty()) | |||
{ | |||
// Remove the first bound mouse button and stop observing its mouse | |||
Mouse* mouse = boundMouseWheelAxes.front().first; | |||
mouse->removeMouseWheelObserver(static_cast<MouseWheelObserver*>(this)); | |||
boundMouseWheelAxes.pop_front(); | |||
// Remove other bound mouse buttons which are associated with the mouse | |||
auto it = boundMouseWheelAxes.begin(); | |||
while (it != boundMouseWheelAxes.end()) | |||
{ | |||
if (it->first == mouse) | |||
boundMouseWheelAxes.erase(it++); | |||
else | |||
++it; | |||
} | |||
} | |||
while (!boundGamepadButtons.empty()) | |||
{ | |||
// Remove the first bound gamepad button and stop observing its gamepad | |||
Gamepad* gamepad = boundGamepadButtons.front().first; | |||
gamepad->removeGamepadButtonObserver(static_cast<GamepadButtonObserver*>(this)); | |||
boundGamepadButtons.pop_front(); | |||
// Remove other bound gamepad buttons which are associated with the gamepad | |||
auto it = boundGamepadButtons.begin(); | |||
while (it != boundGamepadButtons.end()) | |||
{ | |||
if (it->first == gamepad) | |||
boundGamepadButtons.erase(it++); | |||
else | |||
++it; | |||
} | |||
} | |||
while (!boundGamepadAxes.empty()) | |||
{ | |||
// Remove the first bound gamepad axis and stop observing its gamepad | |||
Gamepad* gamepad = std::get<0>(boundGamepadAxes.front()); | |||
gamepad->removeGamepadAxisObserver(static_cast<GamepadAxisObserver*>(this)); | |||
boundGamepadAxes.pop_front(); | |||
// Remove other bound gamepad axes which are associated with the gamepad | |||
auto it = boundGamepadAxes.begin(); | |||
while (it != boundGamepadAxes.end()) | |||
{ | |||
if (std::get<0>(*it) == gamepad) | |||
boundGamepadAxes.erase(it++); | |||
else | |||
++it; | |||
} | |||
} | |||
} | |||
void Control::keyPressed(int scancode) | |||
{ | |||
for (auto it: boundKeys) | |||
{ | |||
if (it.second == scancode) | |||
{ | |||
currentValue = 1.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::keyReleased(int scancode) | |||
{ | |||
for (auto it: boundKeys) | |||
{ | |||
if (it.second == scancode) | |||
{ | |||
currentValue = 0.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::mouseButtonPressed(int button, int x, int y) | |||
{ | |||
for (auto it: boundMouseButtons) | |||
{ | |||
if (it.second == button) | |||
{ | |||
currentValue = 1.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::mouseButtonReleased(int button, int x, int y) | |||
{ | |||
for (auto it: boundMouseButtons) | |||
{ | |||
if (it.second == button) | |||
{ | |||
currentValue = 0.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::mouseWheelScrolled(int x, int y) | |||
{ | |||
for (auto it: boundMouseWheelAxes) | |||
{ | |||
if (it.second == MouseWheelAxis::POSITIVE_X && x > 0) | |||
{ | |||
currentValue += x; | |||
break; | |||
} | |||
else if (it.second == MouseWheelAxis::NEGATIVE_X && x < 0) | |||
{ | |||
currentValue -= x; | |||
break; | |||
} | |||
else if (it.second == MouseWheelAxis::POSITIVE_Y && y > 0) | |||
{ | |||
currentValue += y; | |||
break; | |||
} | |||
else if (it.second == MouseWheelAxis::NEGATIVE_Y && y < 0) | |||
{ | |||
currentValue -= y; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::gamepadButtonPressed(int button) | |||
{ | |||
for (auto it: boundGamepadButtons) | |||
{ | |||
if (it.second == button) | |||
{ | |||
currentValue = 1.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::gamepadButtonReleased(int button) | |||
{ | |||
for (auto it: boundGamepadButtons) | |||
{ | |||
if (it.second == button) | |||
{ | |||
currentValue = 0.0f; | |||
break; | |||
} | |||
} | |||
} | |||
void Control::gamepadAxisMoved(int axis, bool negative, float value) | |||
{ | |||
for (auto it: boundGamepadAxes) | |||
{ | |||
if (std::get<1>(it) == axis && std::get<2>(it) == negative) | |||
{ | |||
currentValue = value; | |||
break; | |||
} | |||
} | |||
} | |||
const std::list<std::pair<Keyboard*, int>>* Control::getBoundKeys() const | |||
{ | |||
return &boundKeys; | |||
} | |||
const std::list<std::pair<Mouse*, int>>* Control::getBoundMouseButtons() const | |||
{ | |||
return &boundMouseButtons; | |||
} | |||
const std::list<std::pair<Mouse*, MouseWheelAxis>>* Control::getBoundMouseWheelAxes() const | |||
{ | |||
return &boundMouseWheelAxes; | |||
} | |||
const std::list<std::pair<Gamepad*, int>>* Control::getBoundGamepadButtons() const | |||
{ | |||
return &boundGamepadButtons; | |||
} | |||
const std::list<std::tuple<Gamepad*, int, bool>>* Control::getBoundGamepadAxes() const | |||
{ | |||
return &boundGamepadAxes; | |||
} | |||
ControlProfile::ControlProfile(InputManager* inputManager): | |||
inputManager(inputManager) | |||
{} | |||
void ControlProfile::registerControl(const std::string& name, Control* control) | |||
{ | |||
controls[name] = control; | |||
} | |||
bool ControlProfile::save(const std::string& filename) | |||
{ | |||
// Open control profile | |||
std::ofstream file(filename.c_str()); | |||
if (!file.is_open()) | |||
{ | |||
std::cerr << std::string("Failed to open control profile \"") << filename << std::string("\"") << std::endl; | |||
return false; | |||
} | |||
for (auto it = controls.begin(); it != controls.end(); ++it) | |||
{ | |||
Control* control = it->second; | |||
const std::list<std::pair<Keyboard*, int>>* boundKeys = control->getBoundKeys(); | |||
const std::list<std::pair<Mouse*, int>>* boundMouseButtons = control->getBoundMouseButtons(); | |||
const std::list<std::pair<Mouse*, MouseWheelAxis>>* boundMouseWheelAxes = control->getBoundMouseWheelAxes(); | |||
const std::list<std::pair<Gamepad*, int>>* boundGamepadButtons = control->getBoundGamepadButtons(); | |||
const std::list<std::tuple<Gamepad*, int, bool>>* boundGamepadAxes = control->getBoundGamepadAxes(); | |||
for (auto boundKey: *boundKeys) | |||
{ | |||
int key = boundKey.second; | |||
file << std::string("control\t") << it->first << std::string("\tkeyboard\tkey\t") << key << '\n'; | |||
} | |||
for (auto boundMouseButton: *boundMouseButtons) | |||
{ | |||
int button = boundMouseButton.second; | |||
file << std::string("control\t") << it->first << std::string("\tmouse\tbutton\t") << button << '\n'; | |||
} | |||
for (auto boundMouseWheelAxis: *boundMouseWheelAxes) | |||
{ | |||
MouseWheelAxis axis = boundMouseWheelAxis.second; | |||
file << std::string("control\t") << it->first << std::string("\tmouse\twheel\t"); | |||
if (axis == MouseWheelAxis::POSITIVE_X) | |||
file << std::string("+x"); | |||
else if (axis == MouseWheelAxis::NEGATIVE_X) | |||
file << std::string("-x"); | |||
else if (axis == MouseWheelAxis::POSITIVE_Y) | |||
file << std::string("+y"); | |||
else if (axis == MouseWheelAxis::NEGATIVE_Y) | |||
file << std::string("-y"); | |||
else | |||
file << std::string("unknown"); | |||
file << '\n'; | |||
} | |||
for (auto boundGamepadButton: *boundGamepadButtons) | |||
{ | |||
const std::string& gamepadName = boundGamepadButton.first->getName(); | |||
int button = boundGamepadButton.second; | |||
file << std::string("control\t") << it->first << std::string("\tgamepad\t") << gamepadName << std::string("\tbutton\t") << button << '\n'; | |||
} | |||
for (auto boundGamepadAxis: *boundGamepadAxes) | |||
{ | |||
const std::string& gamepadName = std::get<0>(boundGamepadAxis)->getName(); | |||
int axis = std::get<1>(boundGamepadAxis); | |||
bool negative = std::get<2>(boundGamepadAxis); | |||
std::stringstream axisstream; | |||
if (negative) | |||
axisstream << std::string("-"); | |||
else | |||
axisstream << std::string("+"); | |||
axisstream << axis; | |||
file << std::string("control\t") << it->first << std::string("\tgamepad\t") << gamepadName << std::string("\taxis\t") << axisstream.str() << '\n'; | |||
} | |||
} | |||
file.close(); | |||
return true; | |||
} | |||
bool ControlProfile::load(const std::string& filename) | |||
{ | |||
// Open control profile | |||
std::ifstream file(filename.c_str()); | |||
if (!file.is_open()) | |||
{ | |||
std::cerr << std::string("Failed to open control profile \"") << filename << std::string("\"") << std::endl; | |||
return false; | |||
} | |||
// Read profile | |||
std::string line; | |||
while (file.good() && std::getline(file, line)) | |||
{ | |||
// Tokenize line (tab-delimeted) | |||
std::vector<std::string> tokens; | |||
std::string token; | |||
std::istringstream linestream(line); | |||
while (std::getline(linestream, token, '\t')) | |||
tokens.push_back(token); | |||
if (tokens.empty() || tokens[0][0] == '#') | |||
continue; | |||
if (tokens[0] == "control" && tokens.size() >= 5) | |||
{ | |||
// Use control name to get control pointer | |||
auto it = controls.find(tokens[1]); | |||
if (it == controls.end()) | |||
{ | |||
std::cerr << std::string("Attempted to load unregistered control \"") << tokens[1] << std::string("\" from control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
Control* control = it->second; | |||
// Find input device | |||
if (tokens[2] == "keyboard") | |||
{ | |||
Keyboard* keyboard = inputManager->getKeyboards()->front(); | |||
if (tokens[3] == "key") | |||
{ | |||
std::stringstream keystream(tokens[4]); | |||
int scancode = -1; | |||
keystream >> scancode; | |||
control->bindKey(keyboard, scancode); | |||
} | |||
else | |||
{ | |||
std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
} | |||
} | |||
else if (tokens[2] == "mouse") | |||
{ | |||
Mouse* mouse = inputManager->getMice()->front(); | |||
if (tokens[3] == "button") | |||
{ | |||
std::stringstream buttonstream(tokens[4]); | |||
int button = -1; | |||
buttonstream >> button; | |||
control->bindMouseButton(mouse, button); | |||
} | |||
else if (tokens[3] == "wheel") | |||
{ | |||
MouseWheelAxis axis; | |||
if (tokens[4] == "+x") | |||
axis = MouseWheelAxis::POSITIVE_X; | |||
else if (tokens[4] == "-x") | |||
axis = MouseWheelAxis::NEGATIVE_X; | |||
else if (tokens[4] == "+y") | |||
axis = MouseWheelAxis::POSITIVE_Y; | |||
else if (tokens[4] == "-y") | |||
axis = MouseWheelAxis::NEGATIVE_Y; | |||
else | |||
{ | |||
std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
control->bindMouseWheelAxis(mouse, axis); | |||
} | |||
else | |||
{ | |||
std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
} | |||
else if (tokens[2] == "gamepad") | |||
{ | |||
if (tokens.size() != 6) | |||
{ | |||
std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
Gamepad* gamepad = inputManager->getGamepad(tokens[3]); | |||
if (!gamepad) | |||
{ | |||
gamepad = new Gamepad(tokens[3]); | |||
gamepad->setDisconnected(true); | |||
inputManager->registerGamepad(gamepad); | |||
} | |||
if (tokens[4] == "button") | |||
{ | |||
std::stringstream buttonstream(tokens[5]); | |||
int button = -1; | |||
buttonstream >> button; | |||
control->bindGamepadButton(gamepad, button); | |||
} | |||
else if (tokens[4] == "axis") | |||
{ | |||
bool negative = (tokens[5][0] == '-'); | |||
std::stringstream axisstream(tokens[5].substr(1, tokens[5].length() - 1)); | |||
int axis = -1; | |||
axisstream >> axis; | |||
control->bindGamepadAxis(gamepad, axis, negative); | |||
} | |||
else | |||
{ | |||
std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
} | |||
else | |||
{ | |||
std::cerr << std::string("Unsupported input device \"") << tokens[3] << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
} | |||
} | |||
file.close(); | |||
return true; | |||
} | |||
void ControlProfile::update() | |||
{ | |||
for (auto it = controls.begin(); it != controls.end(); ++it) | |||
{ | |||
it->second->update(); | |||
} | |||
} | |||
@ -1,119 +0,0 @@ | |||
#include "biome.hpp" | |||
#include "../settings.hpp" | |||
#include <dirent.h> | |||
#include <iostream> | |||
Biome::Biome() | |||
{} | |||
Biome::~Biome() | |||
{} | |||
bool Biome::load() | |||
{ | |||
ParameterDict parameters; | |||
if (!parameters.load(filename)) | |||
{ | |||
return false; | |||
} | |||
parameters.get("name", &name); | |||
parameters.get("soil-horizon-o", &soilHorizonOFilename); | |||
parameters.get("soil-horizon-a", &soilHorizonAFilename); | |||
parameters.get("soil-horizon-b", &soilHorizonBFilename); | |||
parameters.get("soil-horizon-c", &soilHorizonCFilename); | |||
parameters.get("cubemap", &cubemapName); | |||
TextureLoader textureLoader; | |||
textureLoader.setMipmapChain(false); | |||
textureLoader.setWrapS(true); | |||
textureLoader.setWrapT(true); | |||
// Load soil horizon textures | |||
soilHorizonO = textureLoader.load2D(std::string("data/textures/") + soilHorizonOFilename); | |||
soilHorizonA = textureLoader.load2D(std::string("data/textures/") + soilHorizonAFilename); | |||
soilHorizonB = textureLoader.load2D(std::string("data/textures/") + soilHorizonBFilename); | |||
soilHorizonC = textureLoader.load2D(std::string("data/textures/") + soilHorizonCFilename); | |||
// Load diffuse cubemap | |||
textureLoader.setMipmapChain(true); | |||
textureLoader.setWrapS(false); | |||
textureLoader.setWrapT(false); | |||
textureLoader.setWrapR(false); | |||
std::string diffuseCubemapFilename = std::string("data/textures/") + cubemapName + std::string("-irradiance-m%02d.hdr"); | |||
diffuseCubemap = textureLoader.loadCube(diffuseCubemapFilename); | |||
if (!diffuseCubemap) | |||
{ | |||
std::cerr << std::string("Failed to load diffuse cubemap \"") << diffuseCubemapFilename << std::string("\"") << std::endl; | |||
} | |||
// Load specular cubemap | |||
std::string specularCubemapFilename = std::string("data/textures/") + cubemapName + std::string("-radiance-m%02d.hdr"); | |||
specularCubemap = textureLoader.loadCube(specularCubemapFilename); | |||
if (!specularCubemap) | |||
{ | |||
std::cerr << std::string("Failed to load specular cubemap \"") << specularCubemapFilename << std::string("\"") << std::endl; | |||
} | |||
return true; | |||
} | |||
bool Biosphere::load(const std::string& directory) | |||
{ | |||
// Open biomes directory | |||
DIR* dir = opendir(directory.c_str()); | |||
if (dir == nullptr) | |||
{ | |||
std::cout << std::string("Failed to open biome directory \"") << directory << std::string("\"") << std::endl; | |||
return false; | |||
} | |||
// Scan directory for .bio files | |||
for (struct dirent* entry = readdir(dir); entry != nullptr; entry = readdir(dir)) | |||
{ | |||
if (entry->d_type == DT_DIR || *entry->d_name == '.') | |||
{ | |||
continue; | |||
} | |||
std::string filename = entry->d_name; | |||
std::string::size_type delimeter = filename.find_last_of('.'); | |||
if (delimeter == std::string::npos) | |||
{ | |||
continue; | |||
} | |||
std::string extension = filename.substr(delimeter + 1); | |||
if (extension != "bio") | |||
{ | |||
continue; | |||
} | |||
// Add biome | |||
std::string name = filename.substr(0, delimeter); | |||
Biome* biome = &biomes[name]; | |||
biome->filename = directory + filename; | |||
} | |||
// Close biomes directory | |||
closedir(dir); | |||
// Load biomes | |||
for (std::map<std::string, Biome>::iterator it = biomes.begin(); it != biomes.end(); ++it) | |||
{ | |||
Biome* biome = &it->second; | |||
if (!biome->load()) | |||
{ | |||
std::cout << std::string("Failed to load biome \"") << biome->filename << std::string("\"") << std::endl; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("Loaded biome \"") << biome->filename << std::string("\"") << std::endl; | |||
} | |||
} | |||
return true; | |||
} |
@ -1,788 +0,0 @@ | |||
/* | |||
* Copyright (C) 2017 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper Source Code. | |||
* | |||
* Antkeeper Source Code 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. | |||
* | |||
* Antkeeper Source Code 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 Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "input.hpp" | |||
#include <iostream> | |||
InputDevice::InputDevice(const std::string& name): | |||
name(name), | |||
disconnected(true) | |||
{} | |||
void InputDevice::setDisconnected(bool disconnected) | |||
{ | |||
this->disconnected = disconnected; | |||
} | |||
Keyboard::Keyboard(const std::string& name): | |||
InputDevice(name) | |||
{} | |||
Keyboard::~Keyboard() | |||
{} | |||
void Keyboard::addKeyObserver(KeyObserver* observer) | |||
{ | |||
keyObservers.push_back(observer); | |||
} | |||
void Keyboard::removeKeyObserver(KeyObserver* observer) | |||
{ | |||
keyObservers.remove(observer); | |||
} | |||
void Keyboard::removeKeyObservers() | |||
{ | |||
keyObservers.clear(); | |||
} | |||
void Keyboard::press(int scancode) | |||
{ | |||
for (auto observer: keyObservers) | |||
{ | |||
observer->keyPressed(scancode); | |||
} | |||
} | |||
void Keyboard::release(int scancode) | |||
{ | |||
for (auto observer: keyObservers) | |||
{ | |||
observer->keyReleased(scancode); | |||
} | |||
} | |||
Mouse::Mouse(const std::string& name): | |||
InputDevice(name), | |||
notifyingMotionObservers(false), | |||
notifyingButtonObservers(false), | |||
notifyingWheelObservers(false) | |||
{} | |||
Mouse::~Mouse() | |||
{} | |||
void Mouse::addMouseMotionObserver(MouseMotionObserver* observer) | |||
{ | |||
if (notifyingMotionObservers) | |||
{ | |||
additionFlaggedMotionObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
motionObservers.push_back(observer); | |||
} | |||
} | |||
void Mouse::addMouseButtonObserver(MouseButtonObserver* observer) | |||
{ | |||
if (notifyingButtonObservers) | |||
{ | |||
additionFlaggedButtonObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
buttonObservers.push_back(observer); | |||
} | |||
} | |||
void Mouse::addMouseWheelObserver(MouseWheelObserver* observer) | |||
{ | |||
if (notifyingWheelObservers) | |||
{ | |||
additionFlaggedWheelObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
wheelObservers.push_back(observer); | |||
} | |||
} | |||
void Mouse::removeMouseMotionObserver(MouseMotionObserver* observer) | |||
{ | |||
if (notifyingMotionObservers) | |||
{ | |||
removalFlaggedMotionObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
motionObservers.remove(observer); | |||
} | |||
} | |||
void Mouse::removeMouseButtonObserver(MouseButtonObserver* observer) | |||
{ | |||
if (notifyingButtonObservers) | |||
{ | |||
removalFlaggedButtonObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
buttonObservers.remove(observer); | |||
} | |||
} | |||
void Mouse::removeMouseWheelObserver(MouseWheelObserver* observer) | |||
{ | |||
if (notifyingWheelObservers) | |||
{ | |||
removalFlaggedWheelObservers.push_back(observer); | |||
} | |||
else | |||
{ | |||
wheelObservers.remove(observer); | |||
} | |||
} | |||
void Mouse::removeMouseMotionObservers() | |||
{ | |||
motionObservers.clear(); | |||
} | |||
void Mouse::removeMouseButtonObservers() | |||
{ | |||
buttonObservers.clear(); | |||
} | |||
void Mouse::removeMouseWheelObservers() | |||
{ | |||
wheelObservers.clear(); | |||
} | |||
void Mouse::press(int button, int x, int y) | |||
{ | |||
// Notify observers | |||
notifyingButtonObservers = true; | |||
for (auto observer: buttonObservers) | |||
{ | |||
observer->mouseButtonPressed(button, x, y); | |||
} | |||
notifyingButtonObservers = false; | |||
// Process flags | |||
processFlaggedButtonObservers(); | |||
} | |||
void Mouse::release(int button, int x, int y) | |||
{ | |||
// Notify observers | |||
notifyingButtonObservers = true; | |||
for (auto observer: buttonObservers) | |||
{ | |||
observer->mouseButtonReleased(button, x, y); | |||
} | |||
notifyingButtonObservers = false; | |||
// Process flags | |||
processFlaggedButtonObservers(); | |||
} | |||
void Mouse::move(int x, int y) | |||
{ | |||
previousPosition = currentPosition; | |||
currentPosition = glm::ivec2(x, y); | |||
// Notify observers | |||
notifyingMotionObservers = true; | |||
for (auto observer: motionObservers) | |||
{ | |||
observer->mouseMoved(x, y); | |||
} | |||
notifyingMotionObservers = false; | |||
// Process flags | |||
processFlaggedMotionObservers(); | |||
} | |||
void Mouse::scroll(int x, int y) | |||
{ | |||
// Notify observers | |||
notifyingWheelObservers = true; | |||
for (auto observer: wheelObservers) | |||
{ | |||
observer->mouseWheelScrolled(x, y); | |||
} | |||
notifyingWheelObservers = false; | |||
// Process flags | |||
processFlaggedWheelObservers(); | |||
} | |||
void Mouse::processFlaggedMotionObservers() | |||
{ | |||
// Remove observers which are flagged for removal | |||
for (auto observer: removalFlaggedMotionObservers) | |||
{ | |||
motionObservers.remove(observer); | |||
} | |||
removalFlaggedMotionObservers.clear(); | |||
// Add observers which are flagged for addition | |||
for (auto observer: additionFlaggedMotionObservers) | |||
{ | |||
motionObservers.push_back(observer); | |||
} | |||
additionFlaggedMotionObservers.clear(); | |||
} | |||
void Mouse::processFlaggedButtonObservers() | |||
{ | |||
// Remove observers which are flagged for removal | |||
for (auto observer: removalFlaggedButtonObservers) | |||
{ | |||
buttonObservers.remove(observer); | |||
} | |||
removalFlaggedButtonObservers.clear(); | |||
// Add observers which are flagged for addition | |||
for (auto observer: additionFlaggedButtonObservers) | |||
{ | |||
buttonObservers.push_back(observer); | |||
} | |||
additionFlaggedButtonObservers.clear(); | |||
} | |||
void Mouse::processFlaggedWheelObservers() | |||
{ | |||
// Remove observers which are flagged for removal | |||
for (auto observer: removalFlaggedWheelObservers) | |||
{ | |||
wheelObservers.remove(observer); | |||
} | |||
removalFlaggedWheelObservers.clear(); | |||
// Add observers which are flagged for addition | |||
for (auto observer: additionFlaggedWheelObservers) | |||
{ | |||
wheelObservers.push_back(observer); | |||
} | |||
additionFlaggedWheelObservers.clear(); | |||
} | |||
Gamepad::Gamepad(const std::string& name): | |||
InputDevice(name) | |||
{} | |||
Gamepad::~Gamepad() | |||
{} | |||
void Gamepad::addGamepadButtonObserver(GamepadButtonObserver* observer) | |||
{ | |||
buttonObservers.push_back(observer); | |||
} | |||
void Gamepad::removeGamepadButtonObserver(GamepadButtonObserver* observer) | |||
{ | |||
buttonObservers.remove(observer); | |||
} | |||
void Gamepad::removeGamepadButtonObservers() | |||
{ | |||
buttonObservers.clear(); | |||
} | |||
void Gamepad::addGamepadAxisObserver(GamepadAxisObserver* observer) | |||
{ | |||
axisObservers.push_back(observer); | |||
} | |||
void Gamepad::removeGamepadAxisObserver(GamepadAxisObserver* observer) | |||
{ | |||
axisObservers.remove(observer); | |||
} | |||
void Gamepad::removeGamepadAxisObservers() | |||
{ | |||
axisObservers.clear(); | |||
} | |||
void Gamepad::press(int button) | |||
{ | |||
for (auto observer: buttonObservers) | |||
{ | |||
observer->gamepadButtonPressed(button); | |||
} | |||
} | |||
void Gamepad::release(int button) | |||
{ | |||
for (auto observer: buttonObservers) | |||
{ | |||
observer->gamepadButtonReleased(button); | |||
} | |||
} | |||
void Gamepad::move(int axis, bool negative, float value) | |||
{ | |||
for (auto observer: axisObservers) | |||
{ | |||
observer->gamepadAxisMoved(axis, negative, value); | |||
} | |||
} | |||
InputEvent::InputEvent(): | |||
type(InputEvent::Type::NONE) | |||
{} | |||
InputManager::InputManager(): | |||
closed(false) | |||
{} | |||
void InputManager::addWindowObserver(WindowObserver* observer) | |||
{ | |||
windowObservers.push_back(observer); | |||
} | |||
void InputManager::removeWindowObserver(WindowObserver* observer) | |||
{ | |||
windowObservers.remove(observer); | |||
} | |||
void InputManager::removeWindowObservers() | |||
{ | |||
windowObservers.clear(); | |||
} | |||
void InputManager::registerKeyboard(Keyboard* keyboard) | |||
{ | |||
keyboards.push_back(keyboard); | |||
} | |||
void InputManager::registerMouse(Mouse* mouse) | |||
{ | |||
mice.push_back(mouse); | |||
} | |||
void InputManager::registerGamepad(Gamepad* gamepad) | |||
{ | |||
gamepads.push_back(gamepad); | |||
} | |||
void InputManager::unregisterKeyboard(Keyboard* keyboard) | |||
{ | |||
keyboards.remove(keyboard); | |||
} | |||
void InputManager::unregisterMouse(Mouse* mouse) | |||
{ | |||
mice.remove(mouse); | |||
} | |||
void InputManager::unregisterGamepad(Gamepad* gamepad) | |||
{ | |||
gamepads.remove(gamepad); | |||
} | |||
bool InputManager::isRegistered(const Keyboard* keyboard) const | |||
{ | |||
for (auto it = keyboards.begin(); it != keyboards.end(); ++it) | |||
{ | |||
if (*it == keyboard) | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool InputManager::isRegistered(const Mouse* mouse) const | |||
{ | |||
for (auto it = mice.begin(); it != mice.end(); ++it) | |||
{ | |||
if (*it == mouse) | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool InputManager::isRegistered(const Gamepad* gamepad) const | |||
{ | |||
for (auto it = gamepads.begin(); it != gamepads.end(); ++it) | |||
{ | |||
if (*it == gamepad) | |||
return true; | |||
} | |||
return false; | |||
} | |||
const Gamepad* InputManager::getGamepad(const std::string& name) const | |||
{ | |||
for (auto gamepad: gamepads) | |||
{ | |||
if (gamepad->getName() == name) | |||
return gamepad; | |||
} | |||
return nullptr; | |||
} | |||
Gamepad* InputManager::getGamepad(const std::string& name) | |||
{ | |||
for (auto gamepad: gamepads) | |||
{ | |||
if (gamepad->getName() == name) | |||
return gamepad; | |||
} | |||
return nullptr; | |||
} | |||
SDLInputManager::SDLInputManager() | |||
{ | |||
keyboard = new Keyboard("Default Keyboard"); | |||
mouse = new Mouse("Default Mouse"); | |||
registerKeyboard(keyboard); | |||
registerMouse(mouse); | |||
keyboard->setDisconnected(false); | |||
mouse->setDisconnected(false); | |||
} | |||
SDLInputManager::~SDLInputManager() | |||
{ | |||
unregisterKeyboard(keyboard); | |||
unregisterMouse(mouse); | |||
for (auto gamepad: allocatedGamepads) | |||
{ | |||
unregisterGamepad(gamepad); | |||
delete gamepad; | |||
} | |||
delete keyboard; | |||
delete mouse; | |||
} | |||
void SDLInputManager::update() | |||
{ | |||
while (SDL_PollEvent(&event)) | |||
{ | |||
switch (event.type) | |||
{ | |||
case SDL_KEYDOWN: | |||
{ | |||
int scancode = event.key.keysym.scancode; | |||
keyboard->press(scancode); | |||
break; | |||
} | |||
case SDL_KEYUP: | |||
{ | |||
int scancode = event.key.keysym.scancode; | |||
keyboard->release(scancode); | |||
break; | |||
} | |||
case SDL_MOUSEMOTION: | |||
{ | |||
int x = event.motion.x; | |||
int y = event.motion.y; | |||
mouse->move(x, y); | |||
break; | |||
} | |||
case SDL_MOUSEBUTTONDOWN: | |||
{ | |||
int button = event.button.button; | |||
mouse->press(button, event.button.x, event.button.y); | |||
break; | |||
} | |||
case SDL_MOUSEBUTTONUP: | |||
{ | |||
int button = event.button.button; | |||
mouse->release(button, event.button.x, event.button.y); | |||
break; | |||
} | |||
case SDL_MOUSEWHEEL: | |||
{ | |||
int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1; | |||
int x = event.wheel.x * direction; | |||
int y = event.wheel.y * direction; | |||
mouse->scroll(x, y); | |||
break; | |||
} | |||
case SDL_CONTROLLERBUTTONDOWN: | |||
{ | |||
int instanceID = event.cbutton.which; | |||
auto it = gamepadMap.find(instanceID); | |||
if (it == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Received event from invalid gamepad") << std::endl; | |||
break; | |||
} | |||
Gamepad* gamepad = it->second; | |||
int button = event.cbutton.button; | |||
gamepad->press(button); | |||
break; | |||
} | |||
case SDL_CONTROLLERBUTTONUP: | |||
{ | |||
int instanceID = event.cbutton.which; | |||
auto it = gamepadMap.find(instanceID); | |||
if (it == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Received event from invalid gamepad") << std::endl; | |||
break; | |||
} | |||
Gamepad* gamepad = it->second; | |||
int button = event.cbutton.button; | |||
gamepad->release(button); | |||
break; | |||
} | |||
case SDL_CONTROLLERAXISMOTION: | |||
{ | |||
int instanceID = event.caxis.which; | |||
auto it = gamepadMap.find(instanceID); | |||
if (it == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Received event from invalid gamepad") << std::endl; | |||
break; | |||
} | |||
Gamepad* gamepad = it->second; | |||
int axis = event.caxis.axis; | |||
bool negative; | |||
float value; | |||
if (event.caxis.value < 0) | |||
{ | |||
negative = true; | |||
value = (float)event.caxis.value / -32768.0f; | |||
} | |||
else | |||
{ | |||
negative = false; | |||
value = (float)event.caxis.value / 32767.0f; | |||
} | |||
gamepad->move(axis, negative, value); | |||
break; | |||
} | |||
case SDL_CONTROLLERDEVICEADDED: | |||
{ | |||
SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which); | |||
if (controller != nullptr) | |||
{ | |||
// Find controller's joystick instance ID | |||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); | |||
int instanceID = SDL_JoystickInstanceID(joystick); | |||
// Determine gamepad name | |||
std::string name = SDL_GameControllerName(controller); | |||
if (name.empty()) | |||
{ | |||
name = "Unknown Gamepad"; | |||
} | |||
bool reconnected = false; | |||
const std::list<Gamepad*>* gamepads = getGamepads(); | |||
for (auto it = gamepads->begin(); it != gamepads->end(); ++it) | |||
{ | |||
// Check if this gamepad was previously connected | |||
if ((*it)->isDisconnected() && (*it)->getName() == name) | |||
{ | |||
// Map to new instance ID | |||
Gamepad* gamepad = *it; | |||
gamepadMap[instanceID] = gamepad; | |||
gamepad->setDisconnected(false); | |||
reconnected = true; | |||
std::cout << std::string("Reconnected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl; | |||
break; | |||
} | |||
} | |||
if (!reconnected) | |||
{ | |||
// Create new gamepad | |||
Gamepad* gamepad = new Gamepad(name); | |||
// Add to list of allocated gamepads | |||
allocatedGamepads.push_back(gamepad); | |||
// Register with the input manager | |||
registerGamepad(gamepad); | |||
// Map instance ID to gamepad pointer | |||
gamepadMap[instanceID] = gamepad; | |||
// Connect gamepad | |||
gamepad->setDisconnected(false); | |||
std::cout << std::string("Connected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl; | |||
} | |||
} | |||
break; | |||
} | |||
case SDL_CONTROLLERDEVICEREMOVED: | |||
{ | |||
int instanceID = event.cdevice.which; | |||
// Find gamepad | |||
auto mapIt = gamepadMap.find(instanceID); | |||
if (mapIt == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Attempted to remove nonexistent gamepad with ID ") << instanceID << std::endl; | |||
break; | |||
} | |||
Gamepad* gamepad = mapIt->second; | |||
// Remove from gamepad map | |||
gamepadMap.erase(mapIt); | |||
// Set disconnected flag | |||
gamepad->setDisconnected(true); | |||
std::cout << std::string("Disconnected gamepad \"") << gamepad->getName() << std::string("\" with ID ") << instanceID << std::endl; | |||
break; | |||
} | |||
case SDL_WINDOWEVENT: | |||
{ | |||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) | |||
{ | |||
for (auto observer: windowObservers) | |||
{ | |||
observer->windowResized(event.window.data1, event.window.data2); | |||
} | |||
} | |||
else if (event.window.event == SDL_WINDOWEVENT_CLOSE) | |||
{ | |||
closed = true; | |||
for (auto observer: windowObservers) | |||
{ | |||
observer->windowClosed(); | |||
} | |||
} | |||
break; | |||
} | |||
case SDL_QUIT: | |||
{ | |||
closed = true; | |||
for (auto observer: windowObservers) | |||
{ | |||
observer->windowClosed(); | |||
} | |||
break; | |||
} | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
void SDLInputManager::listen(InputEvent* inputEvent) | |||
{ | |||
int eventCount; | |||
// Gather events | |||
SDL_PumpEvents(); | |||
// Check for key events | |||
eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN); | |||
if (eventCount) | |||
{ | |||
int scancode = event.key.keysym.scancode; | |||
inputEvent->type = InputEvent::Type::KEY; | |||
inputEvent->key.first = keyboard; | |||
inputEvent->key.second = scancode; | |||
return; | |||
} | |||
// Check for mouse button events | |||
eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN); | |||
if (eventCount) | |||
{ | |||
int button = event.button.button; | |||
inputEvent->type = InputEvent::Type::MOUSE_BUTTON; | |||
inputEvent->mouseButton.first = mouse; | |||
inputEvent->mouseButton.second = button; | |||
return; | |||
} | |||
// Check for mouse wheel events | |||
eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEWHEEL, SDL_MOUSEWHEEL); | |||
if (eventCount) | |||
{ | |||
int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1; | |||
int x = event.wheel.x * direction; | |||
int y = event.wheel.y * direction; | |||
inputEvent->type = InputEvent::Type::MOUSE_WHEEL; | |||
std::get<0>(inputEvent->mouseWheel) = mouse; | |||
std::get<1>(inputEvent->mouseWheel) = x; | |||
std::get<2>(inputEvent->mouseWheel) = y; | |||
return; | |||
} | |||
// Check for gamepad button events | |||
eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONDOWN); | |||
if (eventCount) | |||
{ | |||
int instanceID = event.cbutton.which; | |||
auto it = gamepadMap.find(instanceID); | |||
if (it == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Received event from invalid gamepad") << std::endl; | |||
return; | |||
} | |||
Gamepad* gamepad = it->second; | |||
int button = event.cbutton.button; | |||
inputEvent->type = InputEvent::Type::GAMEPAD_BUTTON; | |||
inputEvent->gamepadButton.first = gamepad; | |||
inputEvent->gamepadButton.second = button; | |||
return; | |||
} | |||
// Check for gamepad axis events | |||
eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION); | |||
if (eventCount) | |||
{ | |||
int instanceID = event.caxis.which; | |||
auto it = gamepadMap.find(instanceID); | |||
if (it == gamepadMap.end()) | |||
{ | |||
std::cerr << std::string("Received event from invalid gamepad") << std::endl; | |||
return; | |||
} | |||
Gamepad* gamepad = it->second; | |||
int axis = event.caxis.axis; | |||
bool negative = event.caxis.value < 0; | |||
inputEvent->type = InputEvent::Type::GAMEPAD_AXIS; | |||
std::get<0>(inputEvent->gamepadAxis) = gamepad; | |||
std::get<1>(inputEvent->gamepadAxis) = axis; | |||
std::get<2>(inputEvent->gamepadAxis) = negative; | |||
return; | |||
} | |||
} |
@ -1,92 +0,0 @@ | |||
/* | |||
* Copyright (C) 2017 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper Source Code. | |||
* | |||
* Antkeeper Source Code 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. | |||
* | |||
* Antkeeper Source Code 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 Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "settings.hpp" | |||
#include <fstream> | |||
#include <sstream> | |||
#include <vector> | |||
#include <iostream> | |||
bool ParameterDict::load(const std::string& filename) | |||
{ | |||
// Open parameter dict file | |||
std::ifstream file(filename.c_str()); | |||
if (!file.is_open()) | |||
{ | |||
std::cerr << std::string("Failed to open file \"") << filename << std::string("\"") << std::endl; | |||
return false; | |||
} | |||
// Read file | |||
std::string line; | |||
std::size_t lineNumber = 0; | |||
while (file.good() && std::getline(file, line)) | |||
{ | |||
++lineNumber; | |||
if (!line.empty() && line[line.size() - 1] == '\r') | |||
{ | |||
line = line.substr(0, line.size() - 1); | |||
} | |||
// Tokenize line (tab-delimeted) | |||
std::vector<std::string> tokens; | |||
std::string token; | |||
std::istringstream linestream(line); | |||
while (std::getline(linestream, token, '\t')) | |||
tokens.push_back(token); | |||
if (tokens.empty() || tokens[0][0] == '#') | |||
continue; | |||
if (tokens.size() != 2) | |||
{ | |||
std::cerr << std::string("Invalid line \"") << lineNumber << std::string("\" in file \"") << filename << std::string("\"") << std::endl; | |||
continue; | |||
} | |||
parameters[tokens[0]] = tokens[1]; | |||
} | |||
file.close(); | |||
return true; | |||
} | |||
bool ParameterDict::save(const std::string& filename) | |||
{ | |||
std::ofstream file(filename.c_str()); | |||
if (!file.is_open()) | |||
{ | |||
std::cerr << std::string("Failed to open file \"") << filename << std::string("\"") << std::endl; | |||
return false; | |||
} | |||
for (auto it = parameters.begin(); it != parameters.end(); ++it) | |||
file << it->first << std::string("\t") << it->second << std::endl; | |||
file.close(); | |||
return true; | |||
} | |||
void ParameterDict::clear() | |||
{ | |||
parameters.clear(); | |||
} |
@ -1,128 +0,0 @@ | |||
/* | |||
* Copyright (C) 2017 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper Source Code. | |||
* | |||
* Antkeeper Source Code 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. | |||
* | |||
* Antkeeper Source Code 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 Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "loading-state.hpp" | |||
#include "../application.hpp" | |||
#include "splash-state.hpp" | |||
#include "title-state.hpp" | |||
LoadingState::LoadingState(Application* application): | |||
ApplicationState(application) | |||
{} | |||
LoadingState::~LoadingState() | |||
{} | |||
void LoadingState::enter() | |||
{ | |||
bool failure = false; | |||
std::cout << std::string("Loading controls... "); | |||
if (!application->loadControls()) | |||
{ | |||
std::cout << std::string("failed") << std::endl; | |||
failure = true; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("success") << std::endl; | |||
} | |||
std::cout << std::string("Loading scene... "); | |||
if (!application->loadScene()) | |||
{ | |||
std::cout << std::string("failed") << std::endl; | |||
failure = true; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("success") << std::endl; | |||
} | |||
std::cout << std::string("Loading models... "); | |||
if (!application->loadModels()) | |||
{ | |||
std::cout << std::string("failed") << std::endl; | |||
failure = true; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("success") << std::endl; | |||
} | |||
std::cout << std::string("Loading game... "); | |||
if (!application->loadGame()) | |||
{ | |||
std::cout << std::string("failed") << std::endl; | |||
failure = true; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("success") << std::endl; | |||
} | |||
std::cout << std::string("Loading UI... "); | |||
if (!application->loadUI()) | |||
{ | |||
std::cout << std::string("failed") << std::endl; | |||
failure = true; | |||
} | |||
else | |||
{ | |||
std::cout << std::string("success") << std::endl; | |||
} | |||
if (failure) | |||
{ | |||
application->close(EXIT_FAILURE); | |||
} | |||
application->splashBackgroundImage->setVisible(true); | |||
} | |||
void LoadingState::execute() | |||
{ | |||
// Check for splash screen and title skip settings | |||
bool skipSplash = false; | |||
bool skipTitle = false; | |||
application->settings.get("skip_splash", &skipSplash); | |||
//application->settings.get("skip_title", &skipTitle); | |||
// Determine next state | |||
ApplicationState* nextState = application->splashState; | |||
if (skipSplash) | |||
{ | |||
nextState = application->titleState; | |||
/* | |||
if (skipTitle) | |||
{ | |||
nextState = application->mainMenuState; | |||
} | |||
*/ | |||
} | |||
// Change state | |||
application->changeState(nextState); | |||
} | |||
void LoadingState::exit() | |||
{ | |||
application->splashBackgroundImage->setVisible(false); | |||
} |