@ -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); | |||||
} |