Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
221 KB
Referenced Files
None
Subscribers
None
diff --git a/util/configuration.cpp b/util/configuration.cpp
index a43e74a6..29927d3b 100644
--- a/util/configuration.cpp
+++ b/util/configuration.cpp
@@ -1,1007 +1,1007 @@
#include "configuration.h"
#include "input/keyboard.h"
#include "exceptions/load_exception.h"
#include "tokenreader.h"
#include "token.h"
#include "file-system.h"
#include "input/input.h"
#include "debug.h"
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <map>
#ifdef USE_SDL
#if SDL_VERSION_ATLEAST(1, 3, 0)
static const std::string INPUT_TYPE = "SDL1.3";
#else
static const std::string INPUT_TYPE = "SDL";
#endif
#endif
#ifdef USE_ALLEGRO
static const std::string INPUT_TYPE = "Allegro";
#endif
#ifdef USE_ALLEGRO5
static const std::string INPUT_TYPE = "Allegro5";
#endif
bool Configuration::save = true;
Util::ReferenceCount<Token> Configuration::data;
/* text that appears in the config file */
#define define_config(n,str) static const char * config_##n = str
define_config(attack1, "attack1");
define_config(attack2, "attack2");
define_config(attack3, "attack3");
define_config(attack4, "attack4");
define_config(attack5, "attack5");
define_config(attack6, "attack6");
define_config(configuration, "configuration");
define_config(cooperative, "cooperative");
// define_config(current_game, "current-game");
define_config(down, "down");
define_config(free_for_all, "free-for-all");
define_config(fullscreen, "fullscreen");
define_config(game_speed, "game-speed");
define_config(invincible, "invincible");
define_config(jump, "jump");
define_config(quit, "quit");
define_config(keyboard_configuration, "keyboard-configuration");
define_config(input, "input");
define_config(joystick_configuration, "joystick-configuration");
define_config(left, "left");
define_config(lives, "lives");
define_config(menu_font, "menu-font");
define_config(menu_font_width, "menu-font-width");
define_config(menu_font_height, "menu-font-height");
define_config(npc_buddies, "npc-buddies");
define_config(number, "number");
define_config(play_mode, "play-mode");
define_config(right, "right");
define_config(screen_size, "screen-size");
define_config(sound, "sound");
define_config(music, "music");
define_config(up, "up");
define_config(quality_filter, "quality-filter");
define_config(fps, "frames-per-second");
define_config(language, "language");
define_config(mugen_motif, "mugen-motif");
/* version of the game: 3.3, 3.4, 4.24 */
define_config(version, "version");
#undef def_config
using namespace std;
static const int InvalidKey = 0;
static const Joystick::Key InvalidJoystick = Joystick::Invalid;
/* don't save the configuration while loading it */
class Disable{
public:
Disable(){
last = Configuration::getSave();
Configuration::disableSave();
}
~Disable(){
Configuration::setSave(last);
}
bool last;
};
/* FIXME: move this to some utils module */
static std::vector<std::string> split(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
static std::string last(const vector<string> & what){
return what.at(what.size() - 1);
}
/* Create a token that contains the entire path.
* path = "foo/bar/baz"
* out = (foo (bar (baz)))
*/
static Token * createToken(const string & path){
vector<string> paths = split(path, '/');
Token * out = new Token();
Token * current = out;
for (vector<string>::iterator it = paths.begin(); it != paths.end(); it++){
current->addToken(new Token(*it, false));
if (paths.end() - it > 1){
Token * next = new Token();
current->addToken(next);
current = next;
}
}
return out;
}
/* Create a token with the given path and give it a value */
template <class Value>
static Token * createToken(const string & path, const Value & value){
Token * out = createToken(path);
*out << value;
return out;
}
template <class Value, class Value2>
static Token * createToken(const string & path, const Value & value, const Value2 & value2){
Token * out = createToken(path);
*out << value;
*out << value2;
return out;
}
/* remove a path if it exists */
static void removeToken(Token * data, const std::string & path){
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
}
}
static void updateToken(Token * data, const std::string & path, Token * add){
if (data == NULL){
delete add;
}
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
parent->addToken(add);
} else {
const vector<string> paths = split(path, '/');
Token * start = data;
for (unsigned int index = 1; index < paths.size() - 1; index++){
string where = paths[index];
Token * next = start->findToken(string("_/") + where);
if (next == NULL){
ostringstream out;
bool first = true;
for (int from = index; from < paths.size(); from++){
if (!first){
out << "/";
}
out << paths[from];
first = false;
}
/* If we run out of found paths then create a token with an empty
* value for the unfound paths we have so far and call updateToken
* again. This time the entire path will be there
* so the 'found = ...' logic will work.
*/
start->addToken(createToken(out.str(), string("")));
updateToken(data, path, add);
return;
} else {
start = next;
}
}
/* It probably shouldn't be possible to get here. If the entire
* path was there then the findToken() logic above should have worked.
*/
start->addToken(add);
}
}
template <class Value>
static void updateToken(Token * data, const string & path, const Value & value){
if (data == NULL){
return;
}
updateToken(data, path, createToken(last(split(path, '/')), value));
}
void Configuration::setProperty(const string & name, const string & value){
updateToken(getRawData(), string(config_configuration) + "/" + name, value);
saveConfiguration();
}
static Token * getPropertyX(Token * data, const std::string & path){
return data->findToken(string(config_configuration) + "/" + path);
}
template <class Out>
static Out getPropertyX(Token * data, const std::string & path, const Out & defaultValue){
if (data == NULL){
return defaultValue;
}
Out out;
if (data->match(string(config_configuration) + "/" + path, out)){
return out;
}
updateToken(data, string(config_configuration) + "/" + path, defaultValue);
return defaultValue;
}
void Configuration::setDefaultKeys(int config){
/* Set the keys token to an empty value */
ostringstream path;
path << config_input << "/" << config << "/keys";
setProperty(path.str(), createToken("keys"));
/* Call the get methods to reset the defaults */
int ignore;
ignore = getRight(config);
ignore = getLeft(config);
ignore = getUp(config);
ignore = getDown(config);
ignore = getAttack1(config);
ignore = getAttack2(config);
ignore = getAttack3(config);
ignore = getAttack4(config);
ignore = getAttack5(config);
ignore = getAttack6(config);
ignore = getJump(config);
}
/* hopefully this is only used right before setting all the values
* since the key mappings are bogus in here'
*/
Configuration::Configuration(){
}
Configuration::Configuration(const Configuration & config){
menuFont = config.menuFont;
}
Configuration & Configuration::operator=(const Configuration & config){
Disable disable;
setMenuFont(config.getMenuFont());
return *this;
}
Configuration::~Configuration(){
}
Util::ReferenceCount<Menu::FontInfo> Configuration::getMenuFont(){
return menuFont;
}
bool Configuration::hasMenuFont(){
return menuFont != NULL;
}
void Configuration::setMenuFont(const Util::ReferenceCount<Menu::FontInfo> & info){
menuFont = info;
saveConfiguration();
}
void Configuration::setMenuFontWidth(int x){
setProperty(config_menu_font_width, x);
saveConfiguration();
}
int Configuration::getMenuFontWidth(){
return getProperty(config_menu_font_width, 24);
}
void Configuration::setMenuFontHeight(int x){
setProperty(config_menu_font_height, x);
saveConfiguration();
}
int Configuration::getMenuFontHeight(){
return getProperty(config_menu_font_height, 24);
}
static string joystickKeyName(Joystick::Key key){
switch (key){
case Joystick::Up: return "up";
case Joystick::Down: return "down";
case Joystick::Left: return "left";
case Joystick::Right: return "right";
case Joystick::Button1: return "button1";
case Joystick::Button2: return "button2";
case Joystick::Button3: return "button3";
case Joystick::Button4: return "button4";
case Joystick::Button5: return "button5";
case Joystick::Button6: return "button6";
case Joystick::Start: return "start";
case Joystick::Quit: return "quit";
case Joystick::Invalid: return "invalid";
}
return "?";
}
static string removeQuotes(string input){
size_t find = input.find('"');
while (find != string::npos){
input.erase(find, 1);
}
return input;
}
static string joystickPath(Joystick::Key key, int config, const std::string & name){
ostringstream base;
base << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/";
base << "joystick" << "/" << config << "/";
base << removeQuotes(name) << "/" << joystickKeyName(key);
return base.str();
}
void Configuration::setCustomButton(Joystick::Key key, int config, const std::string & name, int button){
if (key != Joystick::Invalid){
std::string base = joystickPath(key, config, name);
removeToken(getRawData(), base);
updateToken(getRawData(), base + "/button", button);
saveConfiguration();
}
}
bool Configuration::getCustomButton(Joystick::Key key, int config, const std::string & name, int & button){
return getRawData()->match(joystickPath(key, config, name) + "/button", button);
}
bool Configuration::getCustomAxis(Joystick::Key key, int config, const std::string & name, int & stick, int & axis, double & low, double & high){
std::string base = joystickPath(key, config, name);
return getRawData()->match(base + "/stick", stick) &&
getRawData()->match(base + "/axis", axis) &&
getRawData()->match(base + "/low", low) &&
getRawData()->match(base + "/high", high);
}
void Configuration::setCustomAxis(Joystick::Key key, int config, const string & name, int stick, int axis, double low, double high){
if (key != Joystick::Invalid){
std::string base = joystickPath(key, config, name);
removeToken(getRawData(), base);
updateToken(getRawData(), base + "/stick", stick);
updateToken(getRawData(), base + "/axis", axis);
updateToken(getRawData(), base + "/low", low);
updateToken(getRawData(), base + "/high", high);
saveConfiguration();
}
}
void Configuration::setKey(int config, const string & name, int value){
if (value != InvalidKey){
ostringstream path;
- path << config_configuration << "/" << config_input << "/" << config << "/keys/" << name;
+ path << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/" << config << "/keys/" << name;
updateToken(getRawData(), path.str(), value);
saveConfiguration();
}
}
void Configuration::setRight(int config, int i){
setKey(config, "right", i);
}
void Configuration::setLeft(int config, int i){
setKey(config, "left", i);
}
void Configuration::setUp(int config, int i){
setKey(config, "up", i);
}
void Configuration::setDown(int config, int i){
setKey(config, "down", i);
}
void Configuration::setAttack1(int config, int i){
setKey(config, "attack1", i);
}
void Configuration::setAttack2(int config, int i){
setKey(config, "attack2", i);
}
void Configuration::setAttack3(int config, int i){
setKey(config, "attack3", i);
}
void Configuration::setAttack4(int config, int i){
setKey(config, "attack4", i);
}
void Configuration::setAttack5(int config, int i){
setKey(config, "attack5", i);
}
void Configuration::setAttack6(int config, int i){
setKey(config, "attack6", i);
}
void Configuration::setJump(int config, int i){
setKey(config, "jump", i);
}
int Configuration::getKey(int config, const string & name, int defaultValue){
ostringstream path;
path << config_input << "/" << INPUT_TYPE << "/" << config << "/keys/" << name;
return getProperty(path.str(), defaultValue);
}
/* this nonsense is just to convert a regular integer into an enum */
/*
static Configuration::JoystickInput intToJoystick(int a){
switch (a){
case Joystick::Up : return Joystick::Up;
case Joystick::Down : return Joystick::Down;
case Joystick::Left : return Joystick::Left;
case Joystick::Right : return Joystick::Right;
case Joystick::Button1 : return Joystick::Button1;
case Joystick::Button2 : return Joystick::Button2;
case Joystick::Button3 : return Joystick::Button3;
case Joystick::Button4 : return Joystick::Button4;
case Joystick::Button5 : return Joystick::Button5;
case Joystick::Button6 : return Joystick::Button6;
case Joystick::Start : return Joystick::Start;
case Joystick::Quit : return Joystick::Quit;
}
return Joystick::Invalid;
}
*/
/*
Configuration::JoystickInput Configuration::getJoystickKey(int config, const string & name, JoystickInput defaultValue){
ostringstream path;
path << config_input << "/" << config << "/joystick/" << name;
return intToJoystick(getProperty(path.str(), defaultValue));
}
*/
int Configuration::getRight(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_RIGHT; break;
case 1: normal = Keyboard::Key_L; break;
}
return getKey(config, "right", normal);
}
int Configuration::getLeft(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_LEFT; break;
case 1: normal = Keyboard::Key_J; break;
}
return getKey(config, "left", normal);
}
int Configuration::getUp(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_UP; break;
case 1: normal = Keyboard::Key_I; break;
}
return getKey(config, "up", normal);
}
int Configuration::getDown(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_DOWN; break;
case 1: normal = Keyboard::Key_COMMA; break;
}
return getKey(config, "down", normal);
}
int Configuration::getAttack1(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_A; break;
case 1: normal = Keyboard::Key_R; break;
}
return getKey(config, "attack1", normal);
}
int Configuration::getAttack2(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_S; break;
case 1: normal = Keyboard::Key_T; break;
}
return getKey(config, "attack2", normal);
}
int Configuration::getAttack3(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_D; break;
case 1: normal = Keyboard::Key_Y; break;
}
return getKey(config, "attack3", normal);
}
int Configuration::getAttack4(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_Z; break;
case 1: normal = Keyboard::Key_F; break;
}
return getKey(config, "attack4", normal);
}
int Configuration::getAttack5(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_X; break;
case 1: normal = Keyboard::Key_G; break;
}
return getKey(config, "attack5", normal);
}
int Configuration::getAttack6(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_C; break;
case 1: normal = Keyboard::Key_H; break;
}
return getKey(config, "attack6", normal);
}
int Configuration::getJump(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_SPACE; break;
case 1: normal = Keyboard::Key_B; break;
}
return getKey(config, "jump", normal);
}
/*
void Configuration::setJoystickKey(int config, const std::string & name, const Configuration::JoystickInput & what){
if (what != Joystick::Invalid){
ostringstream path;
path << config_configuration << "/" << config_input << "/" << config << "/joystick/" << name;
updateToken(data.raw(), path.str(), what);
saveConfiguration();
}
}
void Configuration::setJoystickRight(int config, Configuration::JoystickInput i){
setJoystickKey(config, "right", i);
}
void Configuration::setJoystickLeft(int config, Configuration::JoystickInput i){
setJoystickKey(config, "left", i);
}
void Configuration::setJoystickUp(int config, Configuration::JoystickInput i){
setJoystickKey(config, "up", i);
}
void Configuration::setJoystickDown(int config, Configuration::JoystickInput i){
setJoystickKey(config, "down", i);
}
void Configuration::setJoystickAttack1(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack1", i);
}
void Configuration::setJoystickAttack2(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack2", i);
}
void Configuration::setJoystickAttack3(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack3", i);
}
void Configuration::setJoystickAttack4(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack4", i);
}
void Configuration::setJoystickAttack5(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack5", i);
}
void Configuration::setJoystickAttack6(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack6", i);
}
void Configuration::setJoystickJump(int config, Configuration::JoystickInput i){
setJoystickKey(config, "jump", i);
}
void Configuration::setJoystickQuit(int config, Configuration::JoystickInput i){
setJoystickKey(config, "quit", i);
}
void Configuration::setJoystickStart(int config, Configuration::JoystickInput i){
setJoystickKey(config, "start", i);
}
Configuration::JoystickInput Configuration::getJoystickRight(int config){
return getJoystickKey(config, "right", Joystick::Right);
}
Configuration::JoystickInput Configuration::getJoystickLeft(int config){
return getJoystickKey(config, "left", Joystick::Left);
}
Configuration::JoystickInput Configuration::getJoystickUp(int config){
return getJoystickKey(config, "up", Joystick::Up);
}
Configuration::JoystickInput Configuration::getJoystickDown(int config){
return getJoystickKey(config, "down", Joystick::Down);
}
Configuration::JoystickInput Configuration::getJoystickAttack1(int config){
return getJoystickKey(config, "attack1", Joystick::Button1);
}
Configuration::JoystickInput Configuration::getJoystickAttack2(int config){
return getJoystickKey(config, "attack2", Joystick::Button2);
}
Configuration::JoystickInput Configuration::getJoystickAttack3(int config){
return getJoystickKey(config, "attack3", Joystick::Button3);
}
Configuration::JoystickInput Configuration::getJoystickAttack4(int config){
return getJoystickKey(config, "attack4", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickAttack5(int config){
return getJoystickKey(config, "attack5", Joystick::Button5);
}
Configuration::JoystickInput Configuration::getJoystickAttack6(int config){
return getJoystickKey(config, "attack6", Joystick::Button6);
}
Configuration::JoystickInput Configuration::getJoystickJump(int config){
return getJoystickKey(config, "jump", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickQuit(int config){
return getJoystickKey(config, "quit", Joystick::Quit);
}
Configuration::JoystickInput Configuration::getJoystickStart(int config){
return getJoystickKey(config, "start", Joystick::Start);
}
*/
/*
string Configuration::getCurrentGame(){
return getProperty(config_current_game, string(""));
}
/ * assumes the directory is readable and has a dir/dir.txt in it * /
void Configuration::setCurrentGame(const std::string & str){
setProperty(config_current_game, str);
saveConfiguration();
}
*/
void Configuration::disableSave(){
save = false;
}
void Configuration::setSave(bool what){
save = what;
}
bool Configuration::getSave(){
return save;
}
static Token * removeDuplicates(Token * token){
/* TODO */
return token;
}
Token * Configuration::getRawData(){
if (data == NULL){
loadConfigurations();
// data = new Token();
}
return data.raw();
}
void Configuration::loadConfigurations(){
data = new Token();
*data << config_configuration;
try{
Filesystem::AbsolutePath file = Storage::instance().configFile();
TokenReader tr;
Token * head = tr.readTokenFromFile(file.path());
if (*head != config_configuration){
throw LoadException(__FILE__, __LINE__, string("Config file ") + Storage::instance().configFile().path() + " does not use the configuration format" );
}
/* Store the entire configuration tree */
data = removeDuplicates(head->copy());
} catch ( const LoadException & le ){
Global::debug( 0 ) << "Notice: Could not load configuration file " << Storage::instance().configFile().path() << ": " << le.getTrace() << endl;
} catch ( const TokenException & t ){
Global::debug( 0 ) << "Notice: could not open configuration file '" << Storage::instance().configFile().path() << "': " << t.getTrace() << endl;
}
}
void Configuration::saveConfiguration(){
if (!save){
return;
}
if (data != NULL){
ofstream out(Storage::instance().configFile().path().c_str(), ios::trunc | ios::out);
if (! out.bad()){
data->toString(out, string(""));
out << endl;
out.close();
}
}
}
Util::ReferenceCount<Menu::FontInfo> Configuration::menuFont;
bool Configuration::joystickEnabled = true;
int Configuration::getProperty(const std::string & path, int defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, int value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
void Configuration::setProperty(const std::string & path, Token * value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
Token * Configuration::getProperty(const std::string & path){
return getPropertyX(getRawData(),path);
}
double Configuration::getProperty(const std::string & path, double defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, double value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
bool Configuration::getProperty(const std::string & path, bool defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, bool value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
std::string Configuration::getProperty(const std::string & path, const std::string & defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
double Configuration::getGameSpeed(){
return getProperty(config_game_speed, 1.0);
}
void Configuration::setGameSpeed(double s){
setProperty(config_game_speed, s);
saveConfiguration();
}
bool Configuration::getInvincible(){
return getProperty(config_invincible, false);
}
void Configuration::setInvincible(bool i){
setProperty(config_invincible, i);
saveConfiguration();
}
bool Configuration::getFullscreen(){
/* Defaults for all configuration options */
#if defined(PS3) || defined(ANDROID) || defined(IPHONE)
return getProperty(config_fullscreen, true);
#else
return getProperty(config_fullscreen, false);
#endif
}
void Configuration::setFullscreen(bool f){
setProperty(config_fullscreen, f);
saveConfiguration();
}
int Configuration::getLives(){
return getProperty(config_lives, 4);
}
void Configuration::setLives(int l){
setProperty(config_lives, l);
saveConfiguration();
}
int Configuration::getNpcBuddies(){
return getProperty(config_npc_buddies, 1);
}
void Configuration::setNpcBuddies(int i){
setProperty(config_npc_buddies,i);
saveConfiguration();
}
Configuration::PlayMode Configuration::getPlayMode(){
string mode = getProperty("play-mode", string(config_cooperative));
if (mode == config_cooperative){
return Cooperative;
}
if (mode == config_free_for_all){
return FreeForAll;
}
return Cooperative;
}
void Configuration::setPlayMode(Configuration::PlayMode mode){
if (mode == Configuration::Cooperative){
setProperty("play-mode", string(config_cooperative));
} else if (mode == Configuration::FreeForAll){
setProperty("play-mode", string(config_free_for_all));
}
}
std::string Configuration::getLanguage(){
return getProperty("language", string());
}
void Configuration::setLanguage(const std::string & str){
setProperty("language", str);
saveConfiguration();
}
/* In case this is ever useful again */
/*
#ifdef MINPSPW
// default resolution for the psp is 480x272
int Configuration::screen_width = 480;
int Configuration::screen_height = 272;
#else
int Configuration::screen_width = 640;
int Configuration::screen_height = 480;
#endif
*/
#ifdef GCW0
static int DefaultWidth = 320;
static int DefaultHeight = 240;
#else
static int DefaultWidth = 640;
static int DefaultHeight = 480;
#endif
/* TODO: All the screen width/height stuff shares a lot of code. Refactor */
void Configuration::setScreenWidth(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
width = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenWidth(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return width;
}
void Configuration::setScreenHeight(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
height = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenHeight(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return height;
}
int Configuration::getSoundVolume(){
return getProperty(config_sound, 70);
}
void Configuration::setSoundVolume(int volume){
setProperty(config_sound, volume);
saveConfiguration();
}
int Configuration::getMusicVolume(){
return getProperty(config_music, 70);
}
void Configuration::setMusicVolume(int volume){
setProperty(config_music, volume);
saveConfiguration();
}
bool Configuration::isJoystickEnabled(){
return joystickEnabled;
}
void Configuration::setJoystickEnabled(bool enabled){
joystickEnabled = enabled;
saveConfiguration();
}
std::string Configuration::getQualityFilter(){
return getProperty(config_quality_filter, string("none"));
}
void Configuration::setQualityFilter(const std::string & filter){
setProperty(config_quality_filter, filter);
saveConfiguration();
}
int Configuration::getFps(){
return getProperty(config_fps, 50);
}
void Configuration::setFps(int what){
setProperty(config_fps, what);
saveConfiguration();
}
diff --git a/util/events.cpp b/util/events.cpp
index 7cdbdaeb..bfeb14e2 100644
--- a/util/events.cpp
+++ b/util/events.cpp
@@ -1,628 +1,634 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include <vector>
#include <map>
#include "graphics/bitmap.h"
#include "events.h"
#include "exceptions/shutdown_exception.h"
#include "configuration.h"
#include "debug.h"
#include "funcs.h"
#include "thread.h"
#include "init.h"
#include "parameter.h"
#include "input/keyboard.h"
#include "input/joystick.h"
#include "input/input-manager.h"
#include "input/input-source.h"
#include "system.h"
using std::map;
namespace Util{
int do_shutdown = 0;
bool shutdown(){
return do_shutdown > 0;
}
EventManager::EventManager():
bufferKeys(false),
deferResize(false){
resize.enable = false;
#ifdef USE_ALLEGRO5
queue = al_create_event_queue();
if (al_is_keyboard_installed()){
al_register_event_source(queue, al_get_keyboard_event_source());
}
if (al_is_joystick_installed()){
al_register_event_source(queue, al_get_joystick_event_source());
}
if (Graphics::the_display != NULL){
al_register_event_source(queue, al_get_display_event_source(Graphics::the_display));
}
#endif
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->hatMotion(motion);
}
#if 0
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
#endif
}
static void handleJoystickButtonDown(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, map<int, ReferenceCount<Joystick> > joysticks){
keyboard.poll();
for (map<int, ReferenceCount<Joystick> >::iterator it = joysticks.begin(); it != joysticks.end(); it++){
ReferenceCount<Joystick> joystick = it->second;
if (joystick != NULL){
joystick->poll();
}
}
SDL_Event event;
/* FIXME: android gets into an infinite loop while reading events */
#ifdef ANDROID
// int good = SDL_PollEvent(&event);
// for (int check = 0; check < 10 && good; check++, good = SDL_PollEvent(&event)){
// if (SDL_PollEvent(&event) == 1){
while (SDL_PollEvent(&event) == 1){
#else
while (SDL_PollEvent(&event) == 1){
#endif
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
handleJoystickButtonDown(joysticks, event);
break;
}
case SDL_JOYHATMOTION : {
handleJoystickHat(joysticks, event);
break;
}
case SDL_JOYBUTTONUP: {
handleJoystickButtonUp(joysticks, event);
break;
}
case SDL_JOYAXISMOTION: {
handleJoystickAxis(joysticks, event);
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
/*
double ratio = (double) 640 / (double) 480;
if (width > height){
height = (int)((double) width / ratio);
} else {
width = (int)((double) height * ratio);
}
*/
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, map<int, ReferenceCount<Joystick> > joystick){
keyboard.poll();
}
#endif
#ifdef USE_ALLEGRO5
static void handleKeyDown(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.press(event.keyboard.keycode, event.keyboard.unichar);
}
static void handleKeyUp(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.release(event.keyboard.keycode);
}
static void handleResize(const ALLEGRO_EVENT & event){
double width = event.display.width;
double height = event.display.height;
/*
if (width < 640){
width = 640;
}
if (height < 480){
height = 480;
}
*/
/* to keep the perspective correct
* 640/480 = 1.33333
*/
/*
double ratio = (double) 640 / (double) 480;
if (width > height){
height = width / ratio;
} else {
width = height * ratio;
}
*/
ALLEGRO_DISPLAY * display = event.display.source;
al_acknowledge_resize(display);
Configuration::setScreenWidth((int) width);
Configuration::setScreenHeight((int) height);
al_resize_display(display, (int) width, (int) height);
Graphics::getScreenBuffer()->clear();
/*
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
// al_scale_transform(&transformation, (double) al_get_display_width(display) / (double) GFX_X, (double) al_get_display_height(display) / (double) GFX_Y);
al_scale_transform(&transformation, (double) width / (double) GFX_X, (double) height / (double) GFX_Y);
al_set_target_bitmap(Graphics::getScreenBuffer()->getData()->getBitmap());
al_use_transform(&transformation);
*/
}
void EventManager::runAllegro5(Keyboard & keyboard, const map<int, ReferenceCount<Joystick> > & joysticks){
keyboard.poll();
for (map<int, ReferenceCount<Joystick> >::const_iterator it = joysticks.begin(); it != joysticks.end(); it++){
ReferenceCount<Joystick> joystick = it->second;
if (joystick != NULL){
joystick->poll();
}
}
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
/*
case ALLEGRO_EVENT_KEY_DOWN: {
Global::debug(0) << "Key down " << event.keyboard.keycode << std::endl;
handleKeyDown(keyboard, event);
break;
}
*/
case ALLEGRO_EVENT_DISPLAY_RESIZE: {
handleResize(event);
break;
}
case ALLEGRO_EVENT_DISPLAY_CLOSE: {
throw ShutdownException();
break;
}
case ALLEGRO_EVENT_KEY_UP: {
handleKeyUp(keyboard, event);
break;
}
case ALLEGRO_EVENT_KEY_CHAR : {
// Global::debug(0) << "Key char " << event.keyboard.keycode << " unicode " << event.keyboard.unichar << std::endl;
- handleKeyDown(keyboard, event);
+ bool ok = true;
+ if (event.keyboard.repeat){
+ ok = Keyboard::getRepeatState();
+ }
+ if (ok){
+ handleKeyDown(keyboard, event);
+ }
break;
}
case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: {
/* FIXME: tell input manager to reconfigure joysticks */
// al_reconfigure_joysticks();
break;
}
}
}
/*
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/ * to keep the perspective correct
* 640/480 = 1.33333
* /
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
*/
}
#endif
void EventManager::run(Keyboard & keyboard, std::map<int, ReferenceCount<Joystick> > joysticks){
#ifdef USE_SDL
runSDL(keyboard, joysticks);
#elif USE_ALLEGRO
runAllegro(keyboard, joysticks);
#elif USE_ALLEGRO5
runAllegro5(keyboard, joysticks);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
#ifdef USE_ALLEGRO5
al_destroy_event_queue(queue);
#endif
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
if (deferResize){
resize.type = ResizeScreen;
resize.width = arg1;
resize.height = arg2;
resize.enable = true;
} else {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
if (Graphics::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
}
break;
}
default: break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
void EventManager::deferResizeEvents(bool defer){
deferResize = defer;
if (!deferResize && resize.enable){
dispatch(resize.type, resize.width, resize.height);
resize.enable = false;
}
}
class LoopDone: public std::exception {
public:
LoopDone(){
}
~LoopDone() throw () {
}
};
Logic::~Logic(){
}
Draw::Draw():
frames(0),
second_counter(Global::second_counter),
fps(0){
}
void Draw::drawFirst(const Graphics::Bitmap & screen){
draw(screen);
}
Draw::~Draw(){
}
double Draw::getFps() const {
return fps;
}
void Draw::updateFrames(){
if (second_counter != Global::second_counter){
int difference = Global::second_counter - second_counter;
double alpha = 0.2;
/* unlikely, but just in case */
if (difference == 0){
difference = 1;
}
fps = (alpha * fps) + ((1 - alpha) * (double) frames / difference);
// fps[fps_index] = (double) frames / (double) difference;
// fps_index = (fps_index+1) % max_fps_index;
second_counter = Global::second_counter;
frames = 0;
}
frames += 1;
}
static void changeScreenMode(){
Configuration::setFullscreen(!Configuration::getFullscreen());
int gfx = (Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED);
Graphics::changeGraphicsMode(gfx, Graphics::Bitmap::getScreenWidth(), Graphics::Bitmap::getScreenHeight());
}
static void checkFullscreen(){
InputMap<int> input;
input.set(Keyboard::Key_F11, 0, true, 5);
std::vector<InputMap<int>::InputEvent> events = InputManager::getEvents(input, InputSource(true));
for (std::vector<InputMap<int>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
InputMap<int>::InputEvent event = *it;
if (!event.enabled){
continue;
}
if (event.out == 5){
changeScreenMode();
}
}
}
static void doStandardLoop(Logic & logic, Draw & draw){
if (Graphics::screenParameter.current() == NULL){
throw Exception::Base(__FILE__, __LINE__);
}
const Graphics::Bitmap & screen = *Graphics::screenParameter.current();
screen.clear();
draw.drawFirst(screen.aspectRatio(640, 480));
screen.BlitToScreen();
Global::speed_counter4 = 0;
double runCounter = 0;
try{
const int maxCount = 20;
int frameCount = 0;
uint64_t frameTime = 0;
int logicCount = 0;
uint64_t logicTime = 0;
while (!logic.done()){
if (Global::speed_counter4 > 0){
// Global::debug(0) << "Speed counter " << Global::speed_counter4 << std::endl;
runCounter += logic.ticks(Global::speed_counter4);
Global::speed_counter4 = 0;
bool need_draw = false;
while (runCounter >= 1.0){
need_draw = true;
InputManager::poll();
checkFullscreen();
runCounter -= 1;
logicCount += 1;
uint64_t now = System::currentMilliseconds();
logic.run();
uint64_t later = System::currentMilliseconds();
logicTime += (later - now);
if (logicCount >= maxCount){
// Global::debug(0) << "Logic average " << (logicTime / logicCount) << "ms" << std::endl;
logicCount = 0;
logicTime = 0;
}
if (shutdown()){
throw ShutdownException();
}
if (logic.done()){
/* quit the loop immediately */
throw LoopDone();
}
}
if (need_draw){
frameCount += 1;
draw.updateFrames();
uint64_t now = System::currentMilliseconds();
screen.clear();
draw.draw(screen.aspectRatio(640, 480));
screen.BlitToScreen();
uint64_t later = System::currentMilliseconds();
frameTime += (later - now);
if (frameCount >= maxCount){
// Global::debug(0) << "Draw average " << (frameTime / frameCount) << "ms" << std::endl;
frameCount = 0;
frameTime = 0;
}
}
}
while (Global::speed_counter4 == 0){
/* if the fps is limited then don't keep redrawing */
if (Global::rateLimit){
rest(1);
} else {
draw.updateFrames();
screen.clear();
draw.draw(screen.aspectRatio(640, 480));
screen.BlitToScreen();
}
}
}
} catch (const LoopDone & done){
}
}
void standardLoop(Logic & logic, Draw & draw){
/* if a screen already exists (because we have nested standardLoops) then
* leave this parameter alone, otherwise set a new parameter.
*/
/*
if (Parameter<Graphics::Bitmap*>::current() == NULL){
doStandardLoop(logic, draw);
} else {
doStandardLoop(logic, draw);
}
*/
doStandardLoop(logic, draw);
}
}
diff --git a/util/input/allegro/keyboard.cpp b/util/input/allegro/keyboard.cpp
index 33cee77e..32cc621d 100644
--- a/util/input/allegro/keyboard.cpp
+++ b/util/input/allegro/keyboard.cpp
@@ -1,325 +1,325 @@
#include <allegro.h>
#ifdef WINDOWS
#include <winalleg.h>
#endif
#include "../keyboard.h"
#include "util/thread.h"
#include "util/funcs.h"
#include <iostream>
#include <vector>
#include <map>
using namespace std;
-const int Keyboard::Key_A = ::KEY_A;
-const int Keyboard::Key_B = ::KEY_B;
-const int Keyboard::Key_C = ::KEY_C;
-const int Keyboard::Key_D = ::KEY_D;
-const int Keyboard::Key_E = ::KEY_E;
-const int Keyboard::Key_F = ::KEY_F;
-const int Keyboard::Key_G = ::KEY_G;
-const int Keyboard::Key_H = ::KEY_H;
-const int Keyboard::Key_I = ::KEY_I;
-const int Keyboard::Key_J = ::KEY_J;
-const int Keyboard::Key_K = ::KEY_K;
-const int Keyboard::Key_L = ::KEY_L;
-const int Keyboard::Key_M = ::KEY_M;
-const int Keyboard::Key_N = ::KEY_N;
-const int Keyboard::Key_O = ::KEY_O;
-const int Keyboard::Key_P = ::KEY_P;
-const int Keyboard::Key_Q = ::KEY_Q;
-const int Keyboard::Key_R = ::KEY_R;
-const int Keyboard::Key_S = ::KEY_S;
-const int Keyboard::Key_T = ::KEY_T;
-const int Keyboard::Key_U = ::KEY_U;
-const int Keyboard::Key_V = ::KEY_V;
-const int Keyboard::Key_W = ::KEY_W;
-const int Keyboard::Key_X = ::KEY_X;
-const int Keyboard::Key_Y = ::KEY_Y;
-const int Keyboard::Key_Z = ::KEY_Z;
-const int Keyboard::Key_0 = ::KEY_0;
-const int Keyboard::Key_1 = ::KEY_1;
-const int Keyboard::Key_2 = ::KEY_2;
-const int Keyboard::Key_3 = ::KEY_3;
-const int Keyboard::Key_4 = ::KEY_4;
-const int Keyboard::Key_5 = ::KEY_5;
-const int Keyboard::Key_6 = ::KEY_6;
-const int Keyboard::Key_7 = ::KEY_7;
-const int Keyboard::Key_8 = ::KEY_8;
-const int Keyboard::Key_9 = ::KEY_9;
-const int Keyboard::Key_0_PAD = ::KEY_0_PAD;
-const int Keyboard::Key_1_PAD = ::KEY_1_PAD;
-const int Keyboard::Key_2_PAD = ::KEY_2_PAD;
-const int Keyboard::Key_3_PAD = ::KEY_3_PAD;
-const int Keyboard::Key_4_PAD = ::KEY_4_PAD;
-const int Keyboard::Key_5_PAD = ::KEY_5_PAD;
-const int Keyboard::Key_6_PAD = ::KEY_6_PAD;
-const int Keyboard::Key_7_PAD = ::KEY_7_PAD;
-const int Keyboard::Key_8_PAD = ::KEY_8_PAD;
-const int Keyboard::Key_9_PAD = ::KEY_9_PAD;
-const int Keyboard::Key_F1 = ::KEY_F1;
-const int Keyboard::Key_F2 = ::KEY_F2;
-const int Keyboard::Key_F3 = ::KEY_F3;
-const int Keyboard::Key_F4 = ::KEY_F4;
-const int Keyboard::Key_F5 = ::KEY_F5;
-const int Keyboard::Key_F6 = ::KEY_F6;
-const int Keyboard::Key_F7 = ::KEY_F7;
-const int Keyboard::Key_F8 = ::KEY_F8;
-const int Keyboard::Key_F9 = ::KEY_F9;
-const int Keyboard::Key_F10 = ::KEY_F10;
-const int Keyboard::Key_F11 = ::KEY_F11;
-const int Keyboard::Key_F12 = ::KEY_F12;
-const int Keyboard::Key_ESC = ::KEY_ESC;
-const int Keyboard::Key_TILDE = ::KEY_TILDE;
-const int Keyboard::Key_MINUS = ::KEY_MINUS;
-const int Keyboard::Key_EQUALS = ::KEY_EQUALS;
-const int Keyboard::Key_BACKSPACE = ::KEY_BACKSPACE;
-const int Keyboard::Key_TAB = ::KEY_TAB;
-const int Keyboard::Key_OPENBRACE = ::KEY_OPENBRACE;
-const int Keyboard::Key_CLOSEBRACE = ::KEY_CLOSEBRACE;
-const int Keyboard::Key_ENTER = ::KEY_ENTER;
-const int Keyboard::Key_COLON = ::KEY_COLON;
-const int Keyboard::Key_QUOTE = ::KEY_QUOTE;
-const int Keyboard::Key_BACKSLASH = ::KEY_BACKSLASH;
-const int Keyboard::Key_BACKSLASH2 = ::KEY_BACKSLASH2;
-const int Keyboard::Key_COMMA = ::KEY_COMMA;
-const int Keyboard::Key_STOP = ::KEY_STOP;
-const int Keyboard::Key_SLASH = ::KEY_SLASH;
-const int Keyboard::Key_SPACE = ::KEY_SPACE;
-const int Keyboard::Key_INSERT = ::KEY_INSERT;
-const int Keyboard::Key_DEL = ::KEY_DEL;
-const int Keyboard::Key_HOME = ::KEY_HOME;
-const int Keyboard::Key_END = ::KEY_END;
-const int Keyboard::Key_PGUP = ::KEY_PGUP;
-const int Keyboard::Key_PGDN = ::KEY_PGDN;
-const int Keyboard::Key_LEFT = ::KEY_LEFT;
-const int Keyboard::Key_RIGHT = ::KEY_RIGHT;
-const int Keyboard::Key_UP = ::KEY_UP;
-const int Keyboard::Key_DOWN = ::KEY_DOWN;
-const int Keyboard::Key_SLASH_PAD = ::KEY_SLASH_PAD;
-const int Keyboard::Key_ASTERISK = ::KEY_ASTERISK;
-const int Keyboard::Key_MINUS_PAD = ::KEY_MINUS_PAD;
-const int Keyboard::Key_PLUS_PAD = ::KEY_PLUS_PAD;
-const int Keyboard::Key_DEL_PAD = ::KEY_DEL_PAD;
-const int Keyboard::Key_ENTER_PAD = ::KEY_ENTER_PAD;
-const int Keyboard::Key_PRTSCR = ::KEY_PRTSCR;
-const int Keyboard::Key_PAUSE = ::KEY_PAUSE;
-const int Keyboard::Key_ABNT_C1 = ::KEY_ABNT_C1;
-const int Keyboard::Key_YEN = ::KEY_YEN;
-const int Keyboard::Key_KANA = ::KEY_KANA;
-const int Keyboard::Key_CONVERT = ::KEY_CONVERT;
-const int Keyboard::Key_NOCONVERT = ::KEY_NOCONVERT;
-const int Keyboard::Key_AT = ::KEY_AT;
-const int Keyboard::Key_CIRCUMFLEX = ::KEY_CIRCUMFLEX;
-const int Keyboard::Key_COLON2 = ::KEY_COLON2;
-const int Keyboard::Key_KANJI = ::KEY_KANJI;
-const int Keyboard::Key_EQUALS_PAD = ::KEY_EQUALS_PAD;
-const int Keyboard::Key_BACKQUOTE = ::KEY_BACKQUOTE;
-const int Keyboard::Key_SEMICOLON = ::KEY_SEMICOLON;
-const int Keyboard::Key_COMMAND = ::KEY_COMMAND;
+const Keyboard::KeyType Keyboard::Key_A = ::KEY_A;
+const Keyboard::KeyType Keyboard::Key_B = ::KEY_B;
+const Keyboard::KeyType Keyboard::Key_C = ::KEY_C;
+const Keyboard::KeyType Keyboard::Key_D = ::KEY_D;
+const Keyboard::KeyType Keyboard::Key_E = ::KEY_E;
+const Keyboard::KeyType Keyboard::Key_F = ::KEY_F;
+const Keyboard::KeyType Keyboard::Key_G = ::KEY_G;
+const Keyboard::KeyType Keyboard::Key_H = ::KEY_H;
+const Keyboard::KeyType Keyboard::Key_I = ::KEY_I;
+const Keyboard::KeyType Keyboard::Key_J = ::KEY_J;
+const Keyboard::KeyType Keyboard::Key_K = ::KEY_K;
+const Keyboard::KeyType Keyboard::Key_L = ::KEY_L;
+const Keyboard::KeyType Keyboard::Key_M = ::KEY_M;
+const Keyboard::KeyType Keyboard::Key_N = ::KEY_N;
+const Keyboard::KeyType Keyboard::Key_O = ::KEY_O;
+const Keyboard::KeyType Keyboard::Key_P = ::KEY_P;
+const Keyboard::KeyType Keyboard::Key_Q = ::KEY_Q;
+const Keyboard::KeyType Keyboard::Key_R = ::KEY_R;
+const Keyboard::KeyType Keyboard::Key_S = ::KEY_S;
+const Keyboard::KeyType Keyboard::Key_T = ::KEY_T;
+const Keyboard::KeyType Keyboard::Key_U = ::KEY_U;
+const Keyboard::KeyType Keyboard::Key_V = ::KEY_V;
+const Keyboard::KeyType Keyboard::Key_W = ::KEY_W;
+const Keyboard::KeyType Keyboard::Key_X = ::KEY_X;
+const Keyboard::KeyType Keyboard::Key_Y = ::KEY_Y;
+const Keyboard::KeyType Keyboard::Key_Z = ::KEY_Z;
+const Keyboard::KeyType Keyboard::Key_0 = ::KEY_0;
+const Keyboard::KeyType Keyboard::Key_1 = ::KEY_1;
+const Keyboard::KeyType Keyboard::Key_2 = ::KEY_2;
+const Keyboard::KeyType Keyboard::Key_3 = ::KEY_3;
+const Keyboard::KeyType Keyboard::Key_4 = ::KEY_4;
+const Keyboard::KeyType Keyboard::Key_5 = ::KEY_5;
+const Keyboard::KeyType Keyboard::Key_6 = ::KEY_6;
+const Keyboard::KeyType Keyboard::Key_7 = ::KEY_7;
+const Keyboard::KeyType Keyboard::Key_8 = ::KEY_8;
+const Keyboard::KeyType Keyboard::Key_9 = ::KEY_9;
+const Keyboard::KeyType Keyboard::Key_0_PAD = ::KEY_0_PAD;
+const Keyboard::KeyType Keyboard::Key_1_PAD = ::KEY_1_PAD;
+const Keyboard::KeyType Keyboard::Key_2_PAD = ::KEY_2_PAD;
+const Keyboard::KeyType Keyboard::Key_3_PAD = ::KEY_3_PAD;
+const Keyboard::KeyType Keyboard::Key_4_PAD = ::KEY_4_PAD;
+const Keyboard::KeyType Keyboard::Key_5_PAD = ::KEY_5_PAD;
+const Keyboard::KeyType Keyboard::Key_6_PAD = ::KEY_6_PAD;
+const Keyboard::KeyType Keyboard::Key_7_PAD = ::KEY_7_PAD;
+const Keyboard::KeyType Keyboard::Key_8_PAD = ::KEY_8_PAD;
+const Keyboard::KeyType Keyboard::Key_9_PAD = ::KEY_9_PAD;
+const Keyboard::KeyType Keyboard::Key_F1 = ::KEY_F1;
+const Keyboard::KeyType Keyboard::Key_F2 = ::KEY_F2;
+const Keyboard::KeyType Keyboard::Key_F3 = ::KEY_F3;
+const Keyboard::KeyType Keyboard::Key_F4 = ::KEY_F4;
+const Keyboard::KeyType Keyboard::Key_F5 = ::KEY_F5;
+const Keyboard::KeyType Keyboard::Key_F6 = ::KEY_F6;
+const Keyboard::KeyType Keyboard::Key_F7 = ::KEY_F7;
+const Keyboard::KeyType Keyboard::Key_F8 = ::KEY_F8;
+const Keyboard::KeyType Keyboard::Key_F9 = ::KEY_F9;
+const Keyboard::KeyType Keyboard::Key_F10 = ::KEY_F10;
+const Keyboard::KeyType Keyboard::Key_F11 = ::KEY_F11;
+const Keyboard::KeyType Keyboard::Key_F12 = ::KEY_F12;
+const Keyboard::KeyType Keyboard::Key_ESC = ::KEY_ESC;
+const Keyboard::KeyType Keyboard::Key_TILDE = ::KEY_TILDE;
+const Keyboard::KeyType Keyboard::Key_MINUS = ::KEY_MINUS;
+const Keyboard::KeyType Keyboard::Key_EQUALS = ::KEY_EQUALS;
+const Keyboard::KeyType Keyboard::Key_BACKSPACE = ::KEY_BACKSPACE;
+const Keyboard::KeyType Keyboard::Key_TAB = ::KEY_TAB;
+const Keyboard::KeyType Keyboard::Key_OPENBRACE = ::KEY_OPENBRACE;
+const Keyboard::KeyType Keyboard::Key_CLOSEBRACE = ::KEY_CLOSEBRACE;
+const Keyboard::KeyType Keyboard::Key_ENTER = ::KEY_ENTER;
+const Keyboard::KeyType Keyboard::Key_COLON = ::KEY_COLON;
+const Keyboard::KeyType Keyboard::Key_QUOTE = ::KEY_QUOTE;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH = ::KEY_BACKSLASH;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH2 = ::KEY_BACKSLASH2;
+const Keyboard::KeyType Keyboard::Key_COMMA = ::KEY_COMMA;
+const Keyboard::KeyType Keyboard::Key_STOP = ::KEY_STOP;
+const Keyboard::KeyType Keyboard::Key_SLASH = ::KEY_SLASH;
+const Keyboard::KeyType Keyboard::Key_SPACE = ::KEY_SPACE;
+const Keyboard::KeyType Keyboard::Key_INSERT = ::KEY_INSERT;
+const Keyboard::KeyType Keyboard::Key_DEL = ::KEY_DEL;
+const Keyboard::KeyType Keyboard::Key_HOME = ::KEY_HOME;
+const Keyboard::KeyType Keyboard::Key_END = ::KEY_END;
+const Keyboard::KeyType Keyboard::Key_PGUP = ::KEY_PGUP;
+const Keyboard::KeyType Keyboard::Key_PGDN = ::KEY_PGDN;
+const Keyboard::KeyType Keyboard::Key_LEFT = ::KEY_LEFT;
+const Keyboard::KeyType Keyboard::Key_RIGHT = ::KEY_RIGHT;
+const Keyboard::KeyType Keyboard::Key_UP = ::KEY_UP;
+const Keyboard::KeyType Keyboard::Key_DOWN = ::KEY_DOWN;
+const Keyboard::KeyType Keyboard::Key_SLASH_PAD = ::KEY_SLASH_PAD;
+const Keyboard::KeyType Keyboard::Key_ASTERISK = ::KEY_ASTERISK;
+const Keyboard::KeyType Keyboard::Key_MINUS_PAD = ::KEY_MINUS_PAD;
+const Keyboard::KeyType Keyboard::Key_PLUS_PAD = ::KEY_PLUS_PAD;
+const Keyboard::KeyType Keyboard::Key_DEL_PAD = ::KEY_DEL_PAD;
+const Keyboard::KeyType Keyboard::Key_ENTER_PAD = ::KEY_ENTER_PAD;
+const Keyboard::KeyType Keyboard::Key_PRTSCR = ::KEY_PRTSCR;
+const Keyboard::KeyType Keyboard::Key_PAUSE = ::KEY_PAUSE;
+const Keyboard::KeyType Keyboard::Key_ABNT_C1 = ::KEY_ABNT_C1;
+const Keyboard::KeyType Keyboard::Key_YEN = ::KEY_YEN;
+const Keyboard::KeyType Keyboard::Key_KANA = ::KEY_KANA;
+const Keyboard::KeyType Keyboard::Key_CONVERT = ::KEY_CONVERT;
+const Keyboard::KeyType Keyboard::Key_NOCONVERT = ::KEY_NOCONVERT;
+const Keyboard::KeyType Keyboard::Key_AT = ::KEY_AT;
+const Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = ::KEY_CIRCUMFLEX;
+const Keyboard::KeyType Keyboard::Key_COLON2 = ::KEY_COLON2;
+const Keyboard::KeyType Keyboard::Key_KANJI = ::KEY_KANJI;
+const Keyboard::KeyType Keyboard::Key_EQUALS_PAD = ::KEY_EQUALS_PAD;
+const Keyboard::KeyType Keyboard::Key_BACKQUOTE = ::KEY_BACKQUOTE;
+const Keyboard::KeyType Keyboard::Key_SEMICOLON = ::KEY_SEMICOLON;
+const Keyboard::KeyType Keyboard::Key_COMMAND = ::KEY_COMMAND;
/*
const int Keyboard::Key_UNKNOWN1 = ::KEY_UNKNOWN1;
const int Keyboard::Key_UNKNOWN2 = ::KEY_UNKNOWN2;
const int Keyboard::Key_UNKNOWN3 = ::KEY_UNKNOWN3;
const int Keyboard::Key_UNKNOWN4 = ::KEY_UNKNOWN4;
const int Keyboard::Key_UNKNOWN5 = ::KEY_UNKNOWN5;
const int Keyboard::Key_UNKNOWN6 = ::KEY_UNKNOWN6;
const int Keyboard::Key_UNKNOWN7 = ::KEY_UNKNOWN7;
const int Keyboard::Key_UNKNOWN8 = ::KEY_UNKNOWN8;
*/
-const int Keyboard::Key_MODIFIERS = ::KEY_MODIFIERS;
-const int Keyboard::Key_LSHIFT = ::KEY_LSHIFT;
-const int Keyboard::Key_RSHIFT = ::KEY_RSHIFT;
-const int Keyboard::Key_LCONTROL = ::KEY_LCONTROL;
-const int Keyboard::Key_RCONTROL = ::KEY_RCONTROL;
-const int Keyboard::Key_ALT = ::KEY_ALT;
-const int Keyboard::Key_ALTGR = ::KEY_ALTGR;
-const int Keyboard::Key_LWIN = ::KEY_LWIN;
-const int Keyboard::Key_RWIN = ::KEY_RWIN;
-const int Keyboard::Key_MENU = ::KEY_MENU;
-const int Keyboard::Key_SCRLOCK = ::KEY_SCRLOCK;
-const int Keyboard::Key_NUMLOCK = ::KEY_NUMLOCK;
-const int Keyboard::Key_CAPSLOCK = ::KEY_CAPSLOCK;
+const Keyboard::KeyType Keyboard::Key_MODIFIERS = ::KEY_MODIFIERS;
+const Keyboard::KeyType Keyboard::Key_LSHIFT = ::KEY_LSHIFT;
+const Keyboard::KeyType Keyboard::Key_RSHIFT = ::KEY_RSHIFT;
+const Keyboard::KeyType Keyboard::Key_LCONTROL = ::KEY_LCONTROL;
+const Keyboard::KeyType Keyboard::Key_RCONTROL = ::KEY_RCONTROL;
+const Keyboard::KeyType Keyboard::Key_ALT = ::KEY_ALT;
+const Keyboard::KeyType Keyboard::Key_ALTGR = ::KEY_ALTGR;
+const Keyboard::KeyType Keyboard::Key_LWIN = ::KEY_LWIN;
+const Keyboard::KeyType Keyboard::Key_RWIN = ::KEY_RWIN;
+const Keyboard::KeyType Keyboard::Key_MENU = ::KEY_MENU;
+const Keyboard::KeyType Keyboard::Key_SCRLOCK = ::KEY_SCRLOCK;
+const Keyboard::KeyType Keyboard::Key_NUMLOCK = ::KEY_NUMLOCK;
+const Keyboard::KeyType Keyboard::Key_CAPSLOCK = ::KEY_CAPSLOCK;
static Util::Thread::Lock keyboardData;
static vector<Keyboard::KeyData> stolenKeys;
static int steal_keys(int unicode, int * scancode){
// Global::debug(0) << "Steal key " << unicode << " " << *scancode << endl;
Util::Thread::acquireLock(&keyboardData);
stolenKeys.push_back(Keyboard::KeyData(*scancode, unicode, true));
Util::Thread::releaseLock(&keyboardData);
return unicode;
}
static map<int, bool> stolenPresses;
static void steal_scancode(int scancode){
Util::Thread::acquireLock(&keyboardData);
if (scancode & 0x80){
stolenPresses[scancode & 0x7f] = false;
} else {
stolenPresses[scancode & 0x7f] = true;
}
Util::Thread::releaseLock(&keyboardData);
}
Keyboard::Keyboard():
enableBuffer(false){
/*
for ( int q = 0; q < KEY_MAX; q++ ){
my_keys[ q ] = 0;
}
*/
setAllDelay(0);
Util::Thread::initializeLock(&keyboardData);
::keyboard_ucallback = steal_keys;
::keyboard_lowlevel_callback = steal_scancode;
}
/* KEY_MAX is defined in allegro at
* allegro/include/allegro/keyboard.h
*/
void Keyboard::poll(){
buffer.clear();
// keyState.clear();
Util::Thread::acquireLock(&keyboardData);
for (vector<KeyData>::iterator it = stolenKeys.begin(); it != stolenKeys.end(); it++){
const KeyData & data = *it;
keyState[data.key] = data;
}
stolenKeys.clear();
for (map<int, bool>::iterator it = stolenPresses.begin(); it != stolenPresses.end(); it++){
int key = it->first;
bool pressed = it->second;
keyState[key].enabled = pressed;
if (pressed){
press(key, keyState[key].unicode);
} else {
release(key);
}
}
stolenPresses.clear();
Util::Thread::releaseLock(&keyboardData);
/*
::poll_keyboard();
keyState.clear();
while (::keypressed()){
int unicode;
int key = ::ureadkey(&unicode);
keyState[key] = KeyData(key, unicode, true);
}
*/
#if 0
for ( int q = 0; q < KEY_MAX; q++ ){
// my_keys[ q ] = key[ q ];
if ( key[ q ] ){
/* my_keys[ q ] becomes negative so that the key
* can be pressed the first time without having
* to wait for a delay
*/
if ( my_keys[ q ] <= 0 ){
my_keys[ q ] -= 1;
} else {
my_keys[ q ] += 1;
}
// printf( "Key %d = %d\n", q, my_keys[ q ] );
} else {
my_keys[ q ] = 0;
}
}
#endif
}
#if 0
std::vector<Keyboard::KeyData> Keyboard::readData(){
std::vector<Keyboard::KeyData> out;
/* TODO */
return out;
}
std::vector<Keyboard::unicode_t> Keyboard::readText(){
std::vector<Keyboard::unicode_t> out;
/* TODO */
return out;
}
#endif
void Keyboard::enableKeyRepeat(){
/* these numbers come from the allergo source, src/keyboard.c */
set_keyboard_rate(250, 33);
}
void Keyboard::disableKeyRepeat(){
set_keyboard_rate(0, 0);
}
void Keyboard::readKeys( vector< int > & all_keys ){
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
all_keys.push_back(key);
}
}
/*
for ( map<int,int>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
const int & key = it->first;
const int & delay = it->second;
if ( delay != 0 ){
Global::debug( 6 ) << "Key " << key << " delay " << delay << " key_delay " << key_delay[ key ] << endl;
}
if ( delay < 0 ){
all_keys.push_back( key );
my_keys[ key ] = 1;
} else if ( delay > key_delay[ key ] ){
all_keys.push_back( key );
my_keys[ key ] = 1;
}
}
*/
}
/*
int Keyboard::readKey(){
return ::readkey() >> 8;
}
*/
void Keyboard::wait(){
clear();
poll();
while ( keypressed() ){
poll();
Util::rest( 1 );
}
}
bool Keyboard::keypressed(){
return ::keypressed();
/*
for ( map<int,int>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
const int & n = (*it).second;
if ( n < 0 || n > key_delay[ it->first ] ){
return true;
}
}
return false;
*/
}
void Keyboard::clear(){
::clear_keybuf();
buffer.clear();
keyState.clear();
// my_keys.clear();
}
diff --git a/util/input/allegro5/keyboard.cpp b/util/input/allegro5/keyboard.cpp
index f5c9f0c7..219af47d 100644
--- a/util/input/allegro5/keyboard.cpp
+++ b/util/input/allegro5/keyboard.cpp
@@ -1,170 +1,170 @@
#include "../keyboard.h"
#include <allegro5/keycodes.h>
-const int Keyboard::Key_A = ALLEGRO_KEY_A;
-const int Keyboard::Key_B = ALLEGRO_KEY_B;
-const int Keyboard::Key_C = ALLEGRO_KEY_C;
-const int Keyboard::Key_D = ALLEGRO_KEY_D;
-const int Keyboard::Key_E = ALLEGRO_KEY_E;
-const int Keyboard::Key_F = ALLEGRO_KEY_F;
-const int Keyboard::Key_G = ALLEGRO_KEY_G;
-const int Keyboard::Key_H = ALLEGRO_KEY_H;
-const int Keyboard::Key_I = ALLEGRO_KEY_I;
-const int Keyboard::Key_J = ALLEGRO_KEY_J;
-const int Keyboard::Key_K = ALLEGRO_KEY_K;
-const int Keyboard::Key_L = ALLEGRO_KEY_L;
-const int Keyboard::Key_M = ALLEGRO_KEY_M;
-const int Keyboard::Key_N = ALLEGRO_KEY_N;
-const int Keyboard::Key_O = ALLEGRO_KEY_O;
-const int Keyboard::Key_P = ALLEGRO_KEY_P;
-const int Keyboard::Key_Q = ALLEGRO_KEY_Q;
-const int Keyboard::Key_R = ALLEGRO_KEY_R;
-const int Keyboard::Key_S = ALLEGRO_KEY_S;
-const int Keyboard::Key_T = ALLEGRO_KEY_T;
-const int Keyboard::Key_U = ALLEGRO_KEY_U;
-const int Keyboard::Key_V = ALLEGRO_KEY_V;
-const int Keyboard::Key_W = ALLEGRO_KEY_W;
-const int Keyboard::Key_X = ALLEGRO_KEY_X;
-const int Keyboard::Key_Y = ALLEGRO_KEY_Y;
-const int Keyboard::Key_Z = ALLEGRO_KEY_Z;
-const int Keyboard::Key_0 = ALLEGRO_KEY_0;
-const int Keyboard::Key_1 = ALLEGRO_KEY_1;
-const int Keyboard::Key_2 = ALLEGRO_KEY_2;
-const int Keyboard::Key_3 = ALLEGRO_KEY_3;
-const int Keyboard::Key_4 = ALLEGRO_KEY_4;
-const int Keyboard::Key_5 = ALLEGRO_KEY_5;
-const int Keyboard::Key_6 = ALLEGRO_KEY_6;
-const int Keyboard::Key_7 = ALLEGRO_KEY_7;
-const int Keyboard::Key_8 = ALLEGRO_KEY_8;
-const int Keyboard::Key_9 = ALLEGRO_KEY_9;
-const int Keyboard::Key_0_PAD = ALLEGRO_KEY_PAD_0;
-const int Keyboard::Key_1_PAD = ALLEGRO_KEY_PAD_1;
-const int Keyboard::Key_2_PAD = ALLEGRO_KEY_PAD_2;
-const int Keyboard::Key_3_PAD = ALLEGRO_KEY_PAD_3;
-const int Keyboard::Key_4_PAD = ALLEGRO_KEY_PAD_4;
-const int Keyboard::Key_5_PAD = ALLEGRO_KEY_PAD_5;
-const int Keyboard::Key_6_PAD = ALLEGRO_KEY_PAD_6;
-const int Keyboard::Key_7_PAD = ALLEGRO_KEY_PAD_7;
-const int Keyboard::Key_8_PAD = ALLEGRO_KEY_PAD_8;
-const int Keyboard::Key_9_PAD = ALLEGRO_KEY_PAD_9;
-const int Keyboard::Key_F1 = ALLEGRO_KEY_F1;
-const int Keyboard::Key_F2 = ALLEGRO_KEY_F2;
-const int Keyboard::Key_F3 = ALLEGRO_KEY_F3;
-const int Keyboard::Key_F4 = ALLEGRO_KEY_F4;
-const int Keyboard::Key_F5 = ALLEGRO_KEY_F5;
-const int Keyboard::Key_F6 = ALLEGRO_KEY_F6;
-const int Keyboard::Key_F7 = ALLEGRO_KEY_F7;
-const int Keyboard::Key_F8 = ALLEGRO_KEY_F8;
-const int Keyboard::Key_F9 = ALLEGRO_KEY_F9;
-const int Keyboard::Key_F10 = ALLEGRO_KEY_F10;
-const int Keyboard::Key_F11 = ALLEGRO_KEY_F11;
-const int Keyboard::Key_F12 = ALLEGRO_KEY_F12;
-const int Keyboard::Key_ESC = ALLEGRO_KEY_ESCAPE;
-const int Keyboard::Key_TILDE = ALLEGRO_KEY_TILDE;
-const int Keyboard::Key_MINUS = ALLEGRO_KEY_MINUS;
-const int Keyboard::Key_EQUALS = ALLEGRO_KEY_EQUALS;
-const int Keyboard::Key_BACKSPACE = ALLEGRO_KEY_BACKSPACE;
-const int Keyboard::Key_TAB = ALLEGRO_KEY_TAB;
-const int Keyboard::Key_OPENBRACE = ALLEGRO_KEY_OPENBRACE;
-const int Keyboard::Key_CLOSEBRACE = ALLEGRO_KEY_CLOSEBRACE;
-const int Keyboard::Key_ENTER = ALLEGRO_KEY_ENTER;
-const int Keyboard::Key_COLON = ALLEGRO_KEY_SEMICOLON2;
-const int Keyboard::Key_QUOTE = ALLEGRO_KEY_QUOTE;
-const int Keyboard::Key_BACKSLASH = ALLEGRO_KEY_BACKSLASH;
-const int Keyboard::Key_BACKSLASH2 = ALLEGRO_KEY_BACKSLASH2;
-const int Keyboard::Key_COMMA = ALLEGRO_KEY_COMMA;
-const int Keyboard::Key_STOP = ALLEGRO_KEY_FULLSTOP;
-const int Keyboard::Key_SLASH = ALLEGRO_KEY_SLASH;
-const int Keyboard::Key_SPACE = ALLEGRO_KEY_SPACE;
-const int Keyboard::Key_INSERT = ALLEGRO_KEY_INSERT;
-const int Keyboard::Key_DEL = ALLEGRO_KEY_DELETE;
-const int Keyboard::Key_HOME = ALLEGRO_KEY_HOME;
-const int Keyboard::Key_END = ALLEGRO_KEY_END;
-const int Keyboard::Key_PGUP = ALLEGRO_KEY_PGUP;
-const int Keyboard::Key_PGDN = ALLEGRO_KEY_PGDN;
-const int Keyboard::Key_LEFT = ALLEGRO_KEY_LEFT;
-const int Keyboard::Key_RIGHT = ALLEGRO_KEY_RIGHT;
-const int Keyboard::Key_UP = ALLEGRO_KEY_UP;
-const int Keyboard::Key_DOWN = ALLEGRO_KEY_DOWN;
-const int Keyboard::Key_SLASH_PAD = ALLEGRO_KEY_PAD_SLASH;
-const int Keyboard::Key_ASTERISK = ALLEGRO_KEY_PAD_ASTERISK;
-const int Keyboard::Key_MINUS_PAD = ALLEGRO_KEY_PAD_MINUS;
-const int Keyboard::Key_PLUS_PAD = ALLEGRO_KEY_PAD_PLUS;
-const int Keyboard::Key_DEL_PAD = ALLEGRO_KEY_PAD_DELETE;
-const int Keyboard::Key_ENTER_PAD = ALLEGRO_KEY_PAD_ENTER;
-const int Keyboard::Key_PRTSCR = ALLEGRO_KEY_PRINTSCREEN;
-const int Keyboard::Key_PAUSE = ALLEGRO_KEY_PAUSE;
-const int Keyboard::Key_ABNT_C1 = ALLEGRO_KEY_ABNT_C1;
-const int Keyboard::Key_YEN = ALLEGRO_KEY_YEN;
-const int Keyboard::Key_KANA = ALLEGRO_KEY_KANA;
-const int Keyboard::Key_CONVERT = ALLEGRO_KEY_CONVERT;
-const int Keyboard::Key_NOCONVERT = ALLEGRO_KEY_NOCONVERT;
-const int Keyboard::Key_AT = ALLEGRO_KEY_AT;
-const int Keyboard::Key_CIRCUMFLEX = ALLEGRO_KEY_CIRCUMFLEX;
-const int Keyboard::Key_COLON2 = ALLEGRO_KEY_COLON2;
-const int Keyboard::Key_KANJI = ALLEGRO_KEY_KANJI;
-const int Keyboard::Key_EQUALS_PAD = ALLEGRO_KEY_PAD_EQUALS;
-const int Keyboard::Key_BACKQUOTE = ALLEGRO_KEY_BACKQUOTE;
-const int Keyboard::Key_SEMICOLON = ALLEGRO_KEY_SEMICOLON;
-const int Keyboard::Key_COMMAND = ALLEGRO_KEY_COMMAND;
+const Keyboard::KeyType Keyboard::Key_A = ALLEGRO_KEY_A;
+const Keyboard::KeyType Keyboard::Key_B = ALLEGRO_KEY_B;
+const Keyboard::KeyType Keyboard::Key_C = ALLEGRO_KEY_C;
+const Keyboard::KeyType Keyboard::Key_D = ALLEGRO_KEY_D;
+const Keyboard::KeyType Keyboard::Key_E = ALLEGRO_KEY_E;
+const Keyboard::KeyType Keyboard::Key_F = ALLEGRO_KEY_F;
+const Keyboard::KeyType Keyboard::Key_G = ALLEGRO_KEY_G;
+const Keyboard::KeyType Keyboard::Key_H = ALLEGRO_KEY_H;
+const Keyboard::KeyType Keyboard::Key_I = ALLEGRO_KEY_I;
+const Keyboard::KeyType Keyboard::Key_J = ALLEGRO_KEY_J;
+const Keyboard::KeyType Keyboard::Key_K = ALLEGRO_KEY_K;
+const Keyboard::KeyType Keyboard::Key_L = ALLEGRO_KEY_L;
+const Keyboard::KeyType Keyboard::Key_M = ALLEGRO_KEY_M;
+const Keyboard::KeyType Keyboard::Key_N = ALLEGRO_KEY_N;
+const Keyboard::KeyType Keyboard::Key_O = ALLEGRO_KEY_O;
+const Keyboard::KeyType Keyboard::Key_P = ALLEGRO_KEY_P;
+const Keyboard::KeyType Keyboard::Key_Q = ALLEGRO_KEY_Q;
+const Keyboard::KeyType Keyboard::Key_R = ALLEGRO_KEY_R;
+const Keyboard::KeyType Keyboard::Key_S = ALLEGRO_KEY_S;
+const Keyboard::KeyType Keyboard::Key_T = ALLEGRO_KEY_T;
+const Keyboard::KeyType Keyboard::Key_U = ALLEGRO_KEY_U;
+const Keyboard::KeyType Keyboard::Key_V = ALLEGRO_KEY_V;
+const Keyboard::KeyType Keyboard::Key_W = ALLEGRO_KEY_W;
+const Keyboard::KeyType Keyboard::Key_X = ALLEGRO_KEY_X;
+const Keyboard::KeyType Keyboard::Key_Y = ALLEGRO_KEY_Y;
+const Keyboard::KeyType Keyboard::Key_Z = ALLEGRO_KEY_Z;
+const Keyboard::KeyType Keyboard::Key_0 = ALLEGRO_KEY_0;
+const Keyboard::KeyType Keyboard::Key_1 = ALLEGRO_KEY_1;
+const Keyboard::KeyType Keyboard::Key_2 = ALLEGRO_KEY_2;
+const Keyboard::KeyType Keyboard::Key_3 = ALLEGRO_KEY_3;
+const Keyboard::KeyType Keyboard::Key_4 = ALLEGRO_KEY_4;
+const Keyboard::KeyType Keyboard::Key_5 = ALLEGRO_KEY_5;
+const Keyboard::KeyType Keyboard::Key_6 = ALLEGRO_KEY_6;
+const Keyboard::KeyType Keyboard::Key_7 = ALLEGRO_KEY_7;
+const Keyboard::KeyType Keyboard::Key_8 = ALLEGRO_KEY_8;
+const Keyboard::KeyType Keyboard::Key_9 = ALLEGRO_KEY_9;
+const Keyboard::KeyType Keyboard::Key_0_PAD = ALLEGRO_KEY_PAD_0;
+const Keyboard::KeyType Keyboard::Key_1_PAD = ALLEGRO_KEY_PAD_1;
+const Keyboard::KeyType Keyboard::Key_2_PAD = ALLEGRO_KEY_PAD_2;
+const Keyboard::KeyType Keyboard::Key_3_PAD = ALLEGRO_KEY_PAD_3;
+const Keyboard::KeyType Keyboard::Key_4_PAD = ALLEGRO_KEY_PAD_4;
+const Keyboard::KeyType Keyboard::Key_5_PAD = ALLEGRO_KEY_PAD_5;
+const Keyboard::KeyType Keyboard::Key_6_PAD = ALLEGRO_KEY_PAD_6;
+const Keyboard::KeyType Keyboard::Key_7_PAD = ALLEGRO_KEY_PAD_7;
+const Keyboard::KeyType Keyboard::Key_8_PAD = ALLEGRO_KEY_PAD_8;
+const Keyboard::KeyType Keyboard::Key_9_PAD = ALLEGRO_KEY_PAD_9;
+const Keyboard::KeyType Keyboard::Key_F1 = ALLEGRO_KEY_F1;
+const Keyboard::KeyType Keyboard::Key_F2 = ALLEGRO_KEY_F2;
+const Keyboard::KeyType Keyboard::Key_F3 = ALLEGRO_KEY_F3;
+const Keyboard::KeyType Keyboard::Key_F4 = ALLEGRO_KEY_F4;
+const Keyboard::KeyType Keyboard::Key_F5 = ALLEGRO_KEY_F5;
+const Keyboard::KeyType Keyboard::Key_F6 = ALLEGRO_KEY_F6;
+const Keyboard::KeyType Keyboard::Key_F7 = ALLEGRO_KEY_F7;
+const Keyboard::KeyType Keyboard::Key_F8 = ALLEGRO_KEY_F8;
+const Keyboard::KeyType Keyboard::Key_F9 = ALLEGRO_KEY_F9;
+const Keyboard::KeyType Keyboard::Key_F10 = ALLEGRO_KEY_F10;
+const Keyboard::KeyType Keyboard::Key_F11 = ALLEGRO_KEY_F11;
+const Keyboard::KeyType Keyboard::Key_F12 = ALLEGRO_KEY_F12;
+const Keyboard::KeyType Keyboard::Key_ESC = ALLEGRO_KEY_ESCAPE;
+const Keyboard::KeyType Keyboard::Key_TILDE = ALLEGRO_KEY_TILDE;
+const Keyboard::KeyType Keyboard::Key_MINUS = ALLEGRO_KEY_MINUS;
+const Keyboard::KeyType Keyboard::Key_EQUALS = ALLEGRO_KEY_EQUALS;
+const Keyboard::KeyType Keyboard::Key_BACKSPACE = ALLEGRO_KEY_BACKSPACE;
+const Keyboard::KeyType Keyboard::Key_TAB = ALLEGRO_KEY_TAB;
+const Keyboard::KeyType Keyboard::Key_OPENBRACE = ALLEGRO_KEY_OPENBRACE;
+const Keyboard::KeyType Keyboard::Key_CLOSEBRACE = ALLEGRO_KEY_CLOSEBRACE;
+const Keyboard::KeyType Keyboard::Key_ENTER = ALLEGRO_KEY_ENTER;
+const Keyboard::KeyType Keyboard::Key_COLON = ALLEGRO_KEY_SEMICOLON2;
+const Keyboard::KeyType Keyboard::Key_QUOTE = ALLEGRO_KEY_QUOTE;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH = ALLEGRO_KEY_BACKSLASH;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH2 = ALLEGRO_KEY_BACKSLASH2;
+const Keyboard::KeyType Keyboard::Key_COMMA = ALLEGRO_KEY_COMMA;
+const Keyboard::KeyType Keyboard::Key_STOP = ALLEGRO_KEY_FULLSTOP;
+const Keyboard::KeyType Keyboard::Key_SLASH = ALLEGRO_KEY_SLASH;
+const Keyboard::KeyType Keyboard::Key_SPACE = ALLEGRO_KEY_SPACE;
+const Keyboard::KeyType Keyboard::Key_INSERT = ALLEGRO_KEY_INSERT;
+const Keyboard::KeyType Keyboard::Key_DEL = ALLEGRO_KEY_DELETE;
+const Keyboard::KeyType Keyboard::Key_HOME = ALLEGRO_KEY_HOME;
+const Keyboard::KeyType Keyboard::Key_END = ALLEGRO_KEY_END;
+const Keyboard::KeyType Keyboard::Key_PGUP = ALLEGRO_KEY_PGUP;
+const Keyboard::KeyType Keyboard::Key_PGDN = ALLEGRO_KEY_PGDN;
+const Keyboard::KeyType Keyboard::Key_LEFT = ALLEGRO_KEY_LEFT;
+const Keyboard::KeyType Keyboard::Key_RIGHT = ALLEGRO_KEY_RIGHT;
+const Keyboard::KeyType Keyboard::Key_UP = ALLEGRO_KEY_UP;
+const Keyboard::KeyType Keyboard::Key_DOWN = ALLEGRO_KEY_DOWN;
+const Keyboard::KeyType Keyboard::Key_SLASH_PAD = ALLEGRO_KEY_PAD_SLASH;
+const Keyboard::KeyType Keyboard::Key_ASTERISK = ALLEGRO_KEY_PAD_ASTERISK;
+const Keyboard::KeyType Keyboard::Key_MINUS_PAD = ALLEGRO_KEY_PAD_MINUS;
+const Keyboard::KeyType Keyboard::Key_PLUS_PAD = ALLEGRO_KEY_PAD_PLUS;
+const Keyboard::KeyType Keyboard::Key_DEL_PAD = ALLEGRO_KEY_PAD_DELETE;
+const Keyboard::KeyType Keyboard::Key_ENTER_PAD = ALLEGRO_KEY_PAD_ENTER;
+const Keyboard::KeyType Keyboard::Key_PRTSCR = ALLEGRO_KEY_PRINTSCREEN;
+const Keyboard::KeyType Keyboard::Key_PAUSE = ALLEGRO_KEY_PAUSE;
+const Keyboard::KeyType Keyboard::Key_ABNT_C1 = ALLEGRO_KEY_ABNT_C1;
+const Keyboard::KeyType Keyboard::Key_YEN = ALLEGRO_KEY_YEN;
+const Keyboard::KeyType Keyboard::Key_KANA = ALLEGRO_KEY_KANA;
+const Keyboard::KeyType Keyboard::Key_CONVERT = ALLEGRO_KEY_CONVERT;
+const Keyboard::KeyType Keyboard::Key_NOCONVERT = ALLEGRO_KEY_NOCONVERT;
+const Keyboard::KeyType Keyboard::Key_AT = ALLEGRO_KEY_AT;
+const Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = ALLEGRO_KEY_CIRCUMFLEX;
+const Keyboard::KeyType Keyboard::Key_COLON2 = ALLEGRO_KEY_COLON2;
+const Keyboard::KeyType Keyboard::Key_KANJI = ALLEGRO_KEY_KANJI;
+const Keyboard::KeyType Keyboard::Key_EQUALS_PAD = ALLEGRO_KEY_PAD_EQUALS;
+const Keyboard::KeyType Keyboard::Key_BACKQUOTE = ALLEGRO_KEY_BACKQUOTE;
+const Keyboard::KeyType Keyboard::Key_SEMICOLON = ALLEGRO_KEY_SEMICOLON;
+const Keyboard::KeyType Keyboard::Key_COMMAND = ALLEGRO_KEY_COMMAND;
/*
const int Keyboard::Key_UNKNOWN1 = ALLEGRO_KEY_UNKNOWN1;
const int Keyboard::Key_UNKNOWN2 = ALLEGRO_KEY_UNKNOWN2;
const int Keyboard::Key_UNKNOWN3 = ALLEGRO_KEY_UNKNOWN3;
const int Keyboard::Key_UNKNOWN4 = ALLEGRO_KEY_UNKNOWN4;
const int Keyboard::Key_UNKNOWN5 = ALLEGRO_KEY_UNKNOWN5;
const int Keyboard::Key_UNKNOWN6 = ALLEGRO_KEY_UNKNOWN6;
const int Keyboard::Key_UNKNOWN7 = ALLEGRO_KEY_UNKNOWN7;
const int Keyboard::Key_UNKNOWN8 = ALLEGRO_KEY_UNKNOWN8;
*/
-const int Keyboard::Key_MODIFIERS = ALLEGRO_KEY_MODIFIERS;
-const int Keyboard::Key_LSHIFT = ALLEGRO_KEY_LSHIFT;
-const int Keyboard::Key_RSHIFT = ALLEGRO_KEY_RSHIFT;
-const int Keyboard::Key_LCONTROL = ALLEGRO_KEY_LCTRL;
-const int Keyboard::Key_RCONTROL = ALLEGRO_KEY_RCTRL;
-const int Keyboard::Key_ALT = ALLEGRO_KEY_ALT;
-const int Keyboard::Key_ALTGR = ALLEGRO_KEY_ALTGR;
-const int Keyboard::Key_LWIN = ALLEGRO_KEY_LWIN;
-const int Keyboard::Key_RWIN = ALLEGRO_KEY_RWIN;
-const int Keyboard::Key_MENU = ALLEGRO_KEY_MENU;
-const int Keyboard::Key_SCRLOCK = ALLEGRO_KEY_SCROLLLOCK;
-const int Keyboard::Key_NUMLOCK = ALLEGRO_KEY_NUMLOCK;
-const int Keyboard::Key_CAPSLOCK = ALLEGRO_KEY_CAPSLOCK;
+const Keyboard::KeyType Keyboard::Key_MODIFIERS = ALLEGRO_KEY_MODIFIERS;
+const Keyboard::KeyType Keyboard::Key_LSHIFT = ALLEGRO_KEY_LSHIFT;
+const Keyboard::KeyType Keyboard::Key_RSHIFT = ALLEGRO_KEY_RSHIFT;
+const Keyboard::KeyType Keyboard::Key_LCONTROL = ALLEGRO_KEY_LCTRL;
+const Keyboard::KeyType Keyboard::Key_RCONTROL = ALLEGRO_KEY_RCTRL;
+const Keyboard::KeyType Keyboard::Key_ALT = ALLEGRO_KEY_ALT;
+const Keyboard::KeyType Keyboard::Key_ALTGR = ALLEGRO_KEY_ALTGR;
+const Keyboard::KeyType Keyboard::Key_LWIN = ALLEGRO_KEY_LWIN;
+const Keyboard::KeyType Keyboard::Key_RWIN = ALLEGRO_KEY_RWIN;
+const Keyboard::KeyType Keyboard::Key_MENU = ALLEGRO_KEY_MENU;
+const Keyboard::KeyType Keyboard::Key_SCRLOCK = ALLEGRO_KEY_SCROLLLOCK;
+const Keyboard::KeyType Keyboard::Key_NUMLOCK = ALLEGRO_KEY_NUMLOCK;
+const Keyboard::KeyType Keyboard::Key_CAPSLOCK = ALLEGRO_KEY_CAPSLOCK;
Keyboard::Keyboard():
enableBuffer(false){
}
void Keyboard::disableKeyRepeat(){
/* TODO */
}
void Keyboard::enableKeyRepeat(){
/* TODO */
}
void Keyboard::readKeys(std::vector<int> & all_keys){
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
all_keys.push_back(key);
}
}
}
bool Keyboard::keypressed(){
/* TODO */
return false;
}
void Keyboard::poll(){
buffer.clear();
}
void Keyboard::clear(){
buffer.clear();
keyState.clear();
}
diff --git a/util/input/keyboard.cpp b/util/input/keyboard.cpp
index 5598b3c0..71a3489b 100644
--- a/util/input/keyboard.cpp
+++ b/util/input/keyboard.cpp
@@ -1,469 +1,477 @@
#ifdef USE_ALLEGRO
#include "allegro/keyboard.cpp"
#endif
#ifdef USE_SDL
#include "sdl/keyboard.cpp"
#endif
#ifdef USE_ALLEGRO5
#include "allegro5/keyboard.cpp"
#endif
std::vector<bool> Keyboard::repeatState;
std::set<KeyboardListener*> Keyboard::listeners;
bool Keyboard::isNumber( int key ){
return key == Key_0 ||
key == Key_1 ||
key == Key_2 ||
key == Key_3 ||
key == Key_4 ||
key == Key_5 ||
key == Key_6 ||
key == Key_7 ||
key == Key_8 ||
key == Key_9;
}
bool Keyboard::isChar( int key ){
return key == Key_A ||
key == Key_B ||
key == Key_C ||
key == Key_D ||
key == Key_E ||
key == Key_F ||
key == Key_G ||
key == Key_H ||
key == Key_I ||
key == Key_J ||
key == Key_K ||
key == Key_L ||
key == Key_M ||
key == Key_N ||
key == Key_O ||
key == Key_P ||
key == Key_Q ||
key == Key_R ||
key == Key_S ||
key == Key_T ||
key == Key_U ||
key == Key_V ||
key == Key_W ||
key == Key_X ||
key == Key_Y ||
key == Key_Z ||
key == Key_MINUS;
}
bool Keyboard::isAlpha( int key ){
return isNumber( key ) || isChar( key );
}
const char * Keyboard::keyToName( int key ){
switch ( key ){
case Keyboard::Key_A : return "A";
case Keyboard::Key_B : return "B";
case Keyboard::Key_C : return "C";
case Keyboard::Key_D : return "D";
case Keyboard::Key_E : return "E";
case Keyboard::Key_F : return "F";
case Keyboard::Key_G : return "G";
case Keyboard::Key_H : return "H";
case Keyboard::Key_I : return "I";
case Keyboard::Key_J : return "J";
case Keyboard::Key_K : return "K";
case Keyboard::Key_L : return "L";
case Keyboard::Key_M : return "M";
case Keyboard::Key_N : return "N";
case Keyboard::Key_O : return "O";
case Keyboard::Key_P : return "P";
case Keyboard::Key_Q : return "Q";
case Keyboard::Key_R : return "R";
case Keyboard::Key_S : return "S";
case Keyboard::Key_T : return "T";
case Keyboard::Key_U : return "U";
case Keyboard::Key_V : return "V";
case Keyboard::Key_W : return "W";
case Keyboard::Key_X : return "X";
case Keyboard::Key_Y : return "Y";
case Keyboard::Key_Z : return "Z";
case Keyboard::Key_0 : return "0";
case Keyboard::Key_1 : return "1";
case Keyboard::Key_2 : return "2";
case Keyboard::Key_3 : return "3";
case Keyboard::Key_4 : return "4";
case Keyboard::Key_5 : return "5";
case Keyboard::Key_6 : return "6";
case Keyboard::Key_7 : return "7";
case Keyboard::Key_8 : return "8";
case Keyboard::Key_9 : return "9";
case Keyboard::Key_0_PAD : return "0_PAD";
case Keyboard::Key_1_PAD : return "1_PAD";
case Keyboard::Key_2_PAD : return "2_PAD";
case Keyboard::Key_3_PAD : return "3_PAD";
case Keyboard::Key_4_PAD : return "4_PAD";
case Keyboard::Key_5_PAD : return "5_PAD";
case Keyboard::Key_6_PAD : return "6_PAD";
case Keyboard::Key_7_PAD : return "7_PAD";
case Keyboard::Key_8_PAD : return "8_PAD";
case Keyboard::Key_9_PAD : return "9_PAD";
case Keyboard::Key_F1 : return "F1";
case Keyboard::Key_F2 : return "F2";
case Keyboard::Key_F3 : return "F3";
case Keyboard::Key_F4 : return "F4";
case Keyboard::Key_F5 : return "F5";
case Keyboard::Key_F6 : return "F6";
case Keyboard::Key_F7 : return "F7";
case Keyboard::Key_F8 : return "F8";
case Keyboard::Key_F9 : return "F9";
case Keyboard::Key_F10 : return "F10";
case Keyboard::Key_F11 : return "F11";
case Keyboard::Key_F12 : return "F12";
case Keyboard::Key_ESC : return "ESC";
case Keyboard::Key_TILDE : return "~";
case Keyboard::Key_MINUS : return "-";
case Keyboard::Key_EQUALS : return "=";
case Keyboard::Key_BACKSPACE : return "BACKSPACE";
case Keyboard::Key_TAB : return "TAB";
case Keyboard::Key_OPENBRACE : return "OPENBRACE";
case Keyboard::Key_CLOSEBRACE : return "CLOSEBRACE";
case Keyboard::Key_ENTER : return "ENTER";
case Keyboard::Key_COLON : return "COLON";
case Keyboard::Key_QUOTE : return "QUOTE";
case Keyboard::Key_BACKSLASH : return "BACKSLASH";
case Keyboard::Key_BACKSLASH2 : return "BACKSLASH2";
case Keyboard::Key_COMMA : return "COMMA";
case Keyboard::Key_STOP : return ".";
case Keyboard::Key_SLASH : return "SLASH";
case Keyboard::Key_SPACE : return "SPACE";
case Keyboard::Key_INSERT : return "INSERT";
case Keyboard::Key_DEL : return "DEL";
case Keyboard::Key_HOME : return "HOME";
case Keyboard::Key_END : return "END";
case Keyboard::Key_PGUP : return "PGUP";
case Keyboard::Key_PGDN : return "PGDN";
case Keyboard::Key_LEFT : return "LEFT";
case Keyboard::Key_RIGHT : return "RIGHT";
case Keyboard::Key_UP : return "UP";
case Keyboard::Key_DOWN : return "DOWN";
case Keyboard::Key_SLASH_PAD : return "SLASH_PAD";
case Keyboard::Key_ASTERISK : return "ASTERISK";
case Keyboard::Key_MINUS_PAD : return "MINUS_PAD";
case Keyboard::Key_PLUS_PAD : return "PLUS_PAD";
case Keyboard::Key_DEL_PAD : return "DEL_PAD";
case Keyboard::Key_ENTER_PAD : return "ENTER_PAD";
case Keyboard::Key_PRTSCR : return "PRTSCR";
case Keyboard::Key_PAUSE : return "PAUSE";
case Keyboard::Key_ABNT_C1 : return "ABNT_C1";
case Keyboard::Key_YEN : return "YEN";
case Keyboard::Key_KANA : return "KANA";
case Keyboard::Key_CONVERT : return "CONVERT";
case Keyboard::Key_NOCONVERT : return "NOCONVERT";
case Keyboard::Key_AT : return "AT";
case Keyboard::Key_CIRCUMFLEX : return "CIRCUMFLEX";
case Keyboard::Key_COLON2 : return "COLON2";
case Keyboard::Key_KANJI : return "KANJI";
case Keyboard::Key_EQUALS_PAD : return "EQUALS_PAD";
case Keyboard::Key_BACKQUOTE : return "BACKQUOTE";
case Keyboard::Key_SEMICOLON : return "SEMICOLON";
case Keyboard::Key_COMMAND : return "COMMAND";
/*
case Keyboard::Key_UNKNOWN1 : return "UNKNOWN1";
case Keyboard::Key_UNKNOWN2 : return "UNKNOWN2";
case Keyboard::Key_UNKNOWN3 : return "UNKNOWN3";
case Keyboard::Key_UNKNOWN4 : return "UNKNOWN4";
case Keyboard::Key_UNKNOWN5 : return "UNKNOWN5";
case Keyboard::Key_UNKNOWN6 : return "UNKNOWN6";
case Keyboard::Key_UNKNOWN7 : return "UNKNOWN7";
case Keyboard::Key_UNKNOWN8 : return "UNKNOWN8";
*/
// case Keyboard::Key_MODIFIERS : return "MODIFIERS";
case Keyboard::Key_LSHIFT : return "LSHIFT";
case Keyboard::Key_RSHIFT : return "RSHIFT";
case Keyboard::Key_LCONTROL : return "LCONTROL";
case Keyboard::Key_RCONTROL : return "RCONTROL";
case Keyboard::Key_ALT : return "ALT";
case Keyboard::Key_ALTGR : return "ALTGR";
case Keyboard::Key_LWIN : return "LWIN";
case Keyboard::Key_RWIN : return "RWIN";
case Keyboard::Key_MENU : return "MENU";
case Keyboard::Key_SCRLOCK : return "SCRLOCK";
case Keyboard::Key_NUMLOCK : return "NUMLOCK";
case Keyboard::Key_CAPSLOCK : return "CAPSLOCK";
default : return "Unknown key";
}
}
void Keyboard::setDelay( const int key, const int delay ){
key_delay[ key ] = delay;
}
void Keyboard::setAllDelay( const int delay ){
setDelay( Key_A, delay );
setDelay( Key_B, delay );
setDelay( Key_C, delay );
setDelay( Key_D, delay );
setDelay( Key_E, delay );
setDelay( Key_F, delay );
setDelay( Key_G, delay );
setDelay( Key_H, delay );
setDelay( Key_I, delay );
setDelay( Key_J, delay );
setDelay( Key_K, delay );
setDelay( Key_L, delay );
setDelay( Key_M, delay );
setDelay( Key_N, delay );
setDelay( Key_O, delay );
setDelay( Key_P, delay );
setDelay( Key_Q, delay );
setDelay( Key_R, delay );
setDelay( Key_S, delay );
setDelay( Key_T, delay );
setDelay( Key_U, delay );
setDelay( Key_V, delay );
setDelay( Key_W, delay );
setDelay( Key_X, delay );
setDelay( Key_Y, delay );
setDelay( Key_Z, delay );
setDelay( Key_0, delay );
setDelay( Key_1, delay );
setDelay( Key_2, delay );
setDelay( Key_3, delay );
setDelay( Key_4, delay );
setDelay( Key_5, delay );
setDelay( Key_6, delay );
setDelay( Key_7, delay );
setDelay( Key_8, delay );
setDelay( Key_9, delay );
setDelay( Key_0_PAD, delay );
setDelay( Key_1_PAD, delay );
setDelay( Key_2_PAD, delay );
setDelay( Key_3_PAD, delay );
setDelay( Key_4_PAD, delay );
setDelay( Key_5_PAD, delay );
setDelay( Key_6_PAD, delay );
setDelay( Key_7_PAD, delay );
setDelay( Key_8_PAD, delay );
setDelay( Key_9_PAD, delay );
setDelay( Key_F1, delay );
setDelay( Key_F2, delay );
setDelay( Key_F3, delay );
setDelay( Key_F4, delay );
setDelay( Key_F5, delay );
setDelay( Key_F6, delay );
setDelay( Key_F7, delay );
setDelay( Key_F8, delay );
setDelay( Key_F9, delay );
setDelay( Key_F10, delay );
setDelay( Key_F11, delay );
setDelay( Key_F12, delay );
setDelay( Key_ESC, delay );
setDelay( Key_TILDE, delay );
setDelay( Key_MINUS, delay );
setDelay( Key_EQUALS, delay );
setDelay( Key_BACKSPACE, delay );
setDelay( Key_TAB, delay );
setDelay( Key_OPENBRACE, delay );
setDelay( Key_CLOSEBRACE, delay );
setDelay( Key_ENTER, delay );
setDelay( Key_COLON, delay );
setDelay( Key_QUOTE, delay );
setDelay( Key_BACKSLASH, delay );
setDelay( Key_BACKSLASH2, delay );
setDelay( Key_COMMA, delay );
setDelay( Key_STOP, delay );
setDelay( Key_SLASH, delay );
setDelay( Key_SPACE, delay );
setDelay( Key_INSERT, delay );
setDelay( Key_DEL, delay );
setDelay( Key_HOME, delay );
setDelay( Key_END, delay );
setDelay( Key_PGUP, delay );
setDelay( Key_PGDN, delay );
setDelay( Key_LEFT, delay );
setDelay( Key_RIGHT, delay );
setDelay( Key_UP, delay );
setDelay( Key_DOWN, delay );
setDelay( Key_SLASH_PAD, delay );
setDelay( Key_ASTERISK, delay );
setDelay( Key_MINUS_PAD, delay );
setDelay( Key_PLUS_PAD, delay );
setDelay( Key_DEL_PAD, delay );
setDelay( Key_ENTER_PAD, delay );
setDelay( Key_PRTSCR, delay );
setDelay( Key_PAUSE, delay );
setDelay( Key_ABNT_C1, delay );
setDelay( Key_YEN, delay );
setDelay( Key_KANA, delay );
setDelay( Key_CONVERT, delay );
setDelay( Key_NOCONVERT, delay );
setDelay( Key_AT, delay );
setDelay( Key_CIRCUMFLEX, delay );
setDelay( Key_COLON2, delay );
setDelay( Key_KANJI, delay );
setDelay( Key_EQUALS_PAD, delay );
setDelay( Key_BACKQUOTE, delay );
setDelay( Key_SEMICOLON, delay );
setDelay( Key_COMMAND, delay );
/*
setDelay( Key_UNKNOWN1, delay );
setDelay( Key_UNKNOWN2, delay );
setDelay( Key_UNKNOWN3, delay );
setDelay( Key_UNKNOWN4, delay );
setDelay( Key_UNKNOWN5, delay );
setDelay( Key_UNKNOWN6, delay );
setDelay( Key_UNKNOWN7, delay );
setDelay( Key_UNKNOWN8, delay );
*/
setDelay( Key_MODIFIERS, delay );
setDelay( Key_LSHIFT, delay );
setDelay( Key_RSHIFT, delay );
setDelay( Key_LCONTROL, delay );
setDelay( Key_RCONTROL, delay );
setDelay( Key_ALT, delay );
setDelay( Key_ALTGR, delay );
setDelay( Key_LWIN, delay );
setDelay( Key_RWIN, delay );
setDelay( Key_MENU, delay );
setDelay( Key_SCRLOCK, delay );
setDelay( Key_NUMLOCK, delay );
setDelay( Key_CAPSLOCK, delay );
}
void Keyboard::press(KeyType key, unicode_t unicode){
std::set<KeyboardListener*> listeners = getListeners();
for (std::set<KeyboardListener*>::iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->press(this, key, unicode);
}
keyState[key].key = key;
keyState[key].unicode = unicode;
keyState[key].enabled = true;
// if (enableBuffer){
buffer.push_back(keyState[key]);
// }
/*
KeyData data(key, unicode, true);
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
Observer observer = (*it);
observer.callback(data, observer.extra);
}
*/
}
void Keyboard::release(KeyType key){
std::set<KeyboardListener*> listeners = getListeners();
for (std::set<KeyboardListener*>::iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->release(this, key);
}
keyState[key].enabled = false;
buffer.push_back(keyState[key]);
/*
KeyData data(key, 0, false);
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
Observer observer = (*it);
observer.callback(data, observer.extra);
}
*/
}
void Keyboard::readBufferedKeys(std::vector<int> & keys){
for (std::vector<KeyData>::iterator it = buffer.begin(); it != buffer.end(); it++){
const KeyData & data = *it;
keys.push_back(data.key);
}
}
std::vector<Keyboard::KeyData> Keyboard::readData(){
std::vector<Keyboard::KeyData> out;
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
out.push_back(data);
}
}
return out;
}
std::vector<Keyboard::unicode_t> Keyboard::readText(){
std::vector<Keyboard::unicode_t> out;
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
out.push_back(data.unicode);
}
}
return out;
}
+bool Keyboard::getRepeatState(){
+ if (repeatState.size() > 0){
+ return repeatState.back();
+ }
+
+ return true;
+}
+
void Keyboard::pushRepeatState(bool enabled){
if (enabled){
enableKeyRepeat();
} else {
disableKeyRepeat();
}
repeatState.push_back(enabled);
}
void Keyboard::popRepeatState(){
if (repeatState.size() > 0){
bool last = repeatState.back();
repeatState.pop_back();
bool enabled = true;
if (repeatState.size() > 0){
enabled = repeatState.back();
}
if (enabled != last){
if (enabled){
enableKeyRepeat();
} else {
disableKeyRepeat();
}
}
}
}
bool Keyboard::haveKeyboard(){
#if defined(WII) || defined(PS3) || defined(XENON)
return false;
#endif
return true;
}
KeyboardListener::KeyboardListener(){
}
KeyboardListener::~KeyboardListener(){
}
void Keyboard::addListener(KeyboardListener * listener){
listeners.insert(listener);
}
void Keyboard::removeListener(KeyboardListener * listener){
listeners.erase(listener);
}
const std::set<KeyboardListener*> & Keyboard::getListeners(){
return listeners;
}
/*
void Keyboard::addObserver(ObserverCallback observer, void * data){
observers.push_back(Observer(observer, data));
}
void Keyboard::removeObserver(ObserverCallback observer, void * data){
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
const Observer & what = *it;
if (what.callback == observer && what.extra == data){
observers.erase(it);
break;
}
}
}
*/
diff --git a/util/input/keyboard.h b/util/input/keyboard.h
index 7fb0198f..c60a0f4b 100644
--- a/util/input/keyboard.h
+++ b/util/input/keyboard.h
@@ -1,296 +1,297 @@
#ifndef _paintown_keyboard_h
#define _paintown_keyboard_h
#include <map>
#include <vector>
#include <set>
#include <stdint.h>
/* FIXME: use a namespace here. Input maybe? */
class KeyboardListener;
/* handles allegro key[] array better than keypressed()
* and readkey()
*/
class Keyboard{
private:
Keyboard();
public:
friend class InputManager;
- typedef const int KeyType;
+ typedef int KeyType;
typedef uint32_t unicode_t;
struct KeyData{
KeyData():
key(-1),
unicode(-1),
enabled(false){
}
KeyData(int key, unicode_t unicode, bool enabled):
key(key),
unicode(unicode),
enabled(enabled){
}
int key;
/* Converted to a unicode character in UTF-32 */
unicode_t unicode;
/* whether the key is being pressed */
bool enabled;
};
/*
typedef void (*ObserverCallback)(const KeyData & data, void * extra);
struct Observer{
Observer():
callback(NULL),
extra(NULL){
}
Observer(ObserverCallback callback, void * extra):
callback(callback),
extra(extra){
}
ObserverCallback callback;
void * extra;
};
*/
/* poll:
* Put the keys in Allegro's key[] array into our map of int -> bool
*/
void poll();
/* wait for all keys to be released */
void wait();
/* []:
* Extract a boolean value given a key number
*/
#if 0
inline bool operator[] ( const int i ){
/* if the key has been pressed for the first time return true */
if ( my_keys[ i ] < 0 ){
my_keys[ i ] = 1;
return true;
}
bool b = my_keys[ i ] > key_delay[ i ];
if ( b ){
my_keys[ i ] = 1;
}
return b;
}
#endif
/* keypressed:
* Returns true if a key is pressed
*/
bool keypressed();
/* readKeys:
* Store all pressed keys in a user supplied vector
*/
void readKeys(std::vector< int > & all_keys);
void readBufferedKeys(std::vector<int> & keys);
std::vector<KeyData> readData();
std::vector<unicode_t> readText();
// int readKey();
void clear();
/* sets the latest repeat state. popping the state restores the previous state */
static void pushRepeatState(bool enabled);
static void popRepeatState();
+ static bool getRepeatState();
/* true on systems that probably have a keyboard, like pc.
* false on ps3, wii, etc.
*/
static bool haveKeyboard();
void setDelay( const int key, const int delay );
void setAllDelay( const int delay );
inline const std::vector<KeyData> & getBufferedKeys() const {
return buffer;
}
static const char * keyToName( int key );
static bool isNumber( int key );
static bool isChar( int key );
static bool isAlpha( int key );
- static KeyType Key_A;
- static KeyType Key_B;
- static KeyType Key_C;
- static KeyType Key_D;
- static KeyType Key_E;
- static KeyType Key_F;
- static KeyType Key_G;
- static KeyType Key_H;
- static KeyType Key_I;
- static KeyType Key_J;
- static KeyType Key_K;
- static KeyType Key_L;
- static KeyType Key_M;
- static KeyType Key_N;
- static KeyType Key_O;
- static KeyType Key_P;
- static KeyType Key_Q;
- static KeyType Key_R;
- static KeyType Key_S;
- static KeyType Key_T;
- static KeyType Key_U;
- static KeyType Key_V;
- static KeyType Key_W;
- static KeyType Key_X;
- static KeyType Key_Y;
- static KeyType Key_Z;
- static KeyType Key_0;
- static KeyType Key_1;
- static KeyType Key_2;
- static KeyType Key_3;
- static KeyType Key_4;
- static KeyType Key_5;
- static KeyType Key_6;
- static KeyType Key_7;
- static KeyType Key_8;
- static KeyType Key_9;
- static KeyType Key_0_PAD;
- static KeyType Key_1_PAD;
- static KeyType Key_2_PAD;
- static KeyType Key_3_PAD;
- static KeyType Key_4_PAD;
- static KeyType Key_5_PAD;
- static KeyType Key_6_PAD;
- static KeyType Key_7_PAD;
- static KeyType Key_8_PAD;
- static KeyType Key_9_PAD;
- static KeyType Key_F1;
- static KeyType Key_F2;
- static KeyType Key_F3;
- static KeyType Key_F4;
- static KeyType Key_F5;
- static KeyType Key_F6;
- static KeyType Key_F7;
- static KeyType Key_F8;
- static KeyType Key_F9;
- static KeyType Key_F10;
- static KeyType Key_F11;
- static KeyType Key_F12;
- static KeyType Key_ESC;
- static KeyType Key_TILDE;
- static KeyType Key_MINUS;
- static KeyType Key_EQUALS;
- static KeyType Key_BACKSPACE;
- static KeyType Key_TAB;
- static KeyType Key_OPENBRACE;
- static KeyType Key_CLOSEBRACE;
- static KeyType Key_ENTER;
- static KeyType Key_COLON;
- static KeyType Key_QUOTE;
- static KeyType Key_BACKSLASH;
- static KeyType Key_BACKSLASH2;
- static KeyType Key_COMMA;
- static KeyType Key_STOP;
- static KeyType Key_SLASH;
- static KeyType Key_SPACE;
- static KeyType Key_INSERT;
- static KeyType Key_DEL;
- static KeyType Key_HOME;
- static KeyType Key_END;
- static KeyType Key_PGUP;
- static KeyType Key_PGDN;
- static KeyType Key_LEFT;
- static KeyType Key_RIGHT;
- static KeyType Key_UP;
- static KeyType Key_DOWN;
- static KeyType Key_SLASH_PAD;
- static KeyType Key_ASTERISK;
- static KeyType Key_MINUS_PAD;
- static KeyType Key_PLUS_PAD;
- static KeyType Key_DEL_PAD;
- static KeyType Key_ENTER_PAD;
- static KeyType Key_PRTSCR;
- static KeyType Key_PAUSE;
- static KeyType Key_ABNT_C1;
- static KeyType Key_YEN;
- static KeyType Key_KANA;
- static KeyType Key_CONVERT;
- static KeyType Key_NOCONVERT;
- static KeyType Key_AT;
- static KeyType Key_CIRCUMFLEX;
- static KeyType Key_COLON2;
- static KeyType Key_KANJI;
- static KeyType Key_EQUALS_PAD;
- static KeyType Key_BACKQUOTE;
- static KeyType Key_SEMICOLON;
- static KeyType Key_COMMAND;
+ static const KeyType Key_A;
+ static const KeyType Key_B;
+ static const KeyType Key_C;
+ static const KeyType Key_D;
+ static const KeyType Key_E;
+ static const KeyType Key_F;
+ static const KeyType Key_G;
+ static const KeyType Key_H;
+ static const KeyType Key_I;
+ static const KeyType Key_J;
+ static const KeyType Key_K;
+ static const KeyType Key_L;
+ static const KeyType Key_M;
+ static const KeyType Key_N;
+ static const KeyType Key_O;
+ static const KeyType Key_P;
+ static const KeyType Key_Q;
+ static const KeyType Key_R;
+ static const KeyType Key_S;
+ static const KeyType Key_T;
+ static const KeyType Key_U;
+ static const KeyType Key_V;
+ static const KeyType Key_W;
+ static const KeyType Key_X;
+ static const KeyType Key_Y;
+ static const KeyType Key_Z;
+ static const KeyType Key_0;
+ static const KeyType Key_1;
+ static const KeyType Key_2;
+ static const KeyType Key_3;
+ static const KeyType Key_4;
+ static const KeyType Key_5;
+ static const KeyType Key_6;
+ static const KeyType Key_7;
+ static const KeyType Key_8;
+ static const KeyType Key_9;
+ static const KeyType Key_0_PAD;
+ static const KeyType Key_1_PAD;
+ static const KeyType Key_2_PAD;
+ static const KeyType Key_3_PAD;
+ static const KeyType Key_4_PAD;
+ static const KeyType Key_5_PAD;
+ static const KeyType Key_6_PAD;
+ static const KeyType Key_7_PAD;
+ static const KeyType Key_8_PAD;
+ static const KeyType Key_9_PAD;
+ static const KeyType Key_F1;
+ static const KeyType Key_F2;
+ static const KeyType Key_F3;
+ static const KeyType Key_F4;
+ static const KeyType Key_F5;
+ static const KeyType Key_F6;
+ static const KeyType Key_F7;
+ static const KeyType Key_F8;
+ static const KeyType Key_F9;
+ static const KeyType Key_F10;
+ static const KeyType Key_F11;
+ static const KeyType Key_F12;
+ static const KeyType Key_ESC;
+ static const KeyType Key_TILDE;
+ static const KeyType Key_MINUS;
+ static const KeyType Key_EQUALS;
+ static const KeyType Key_BACKSPACE;
+ static const KeyType Key_TAB;
+ static const KeyType Key_OPENBRACE;
+ static const KeyType Key_CLOSEBRACE;
+ static const KeyType Key_ENTER;
+ static const KeyType Key_COLON;
+ static const KeyType Key_QUOTE;
+ static const KeyType Key_BACKSLASH;
+ static const KeyType Key_BACKSLASH2;
+ static const KeyType Key_COMMA;
+ static const KeyType Key_STOP;
+ static const KeyType Key_SLASH;
+ static const KeyType Key_SPACE;
+ static const KeyType Key_INSERT;
+ static const KeyType Key_DEL;
+ static const KeyType Key_HOME;
+ static const KeyType Key_END;
+ static const KeyType Key_PGUP;
+ static const KeyType Key_PGDN;
+ static const KeyType Key_LEFT;
+ static const KeyType Key_RIGHT;
+ static const KeyType Key_UP;
+ static const KeyType Key_DOWN;
+ static const KeyType Key_SLASH_PAD;
+ static const KeyType Key_ASTERISK;
+ static const KeyType Key_MINUS_PAD;
+ static const KeyType Key_PLUS_PAD;
+ static const KeyType Key_DEL_PAD;
+ static const KeyType Key_ENTER_PAD;
+ static const KeyType Key_PRTSCR;
+ static const KeyType Key_PAUSE;
+ static const KeyType Key_ABNT_C1;
+ static const KeyType Key_YEN;
+ static const KeyType Key_KANA;
+ static const KeyType Key_CONVERT;
+ static const KeyType Key_NOCONVERT;
+ static const KeyType Key_AT;
+ static const KeyType Key_CIRCUMFLEX;
+ static const KeyType Key_COLON2;
+ static const KeyType Key_KANJI;
+ static const KeyType Key_EQUALS_PAD;
+ static const KeyType Key_BACKQUOTE;
+ static const KeyType Key_SEMICOLON;
+ static const KeyType Key_COMMAND;
/*
static KeyType Key_UNKNOWN1;
static KeyType Key_UNKNOWN2;
static KeyType Key_UNKNOWN3;
static KeyType Key_UNKNOWN4;
static KeyType Key_UNKNOWN5;
static KeyType Key_UNKNOWN6;
static KeyType Key_UNKNOWN7;
static KeyType Key_UNKNOWN8;
*/
- static KeyType Key_MODIFIERS;
- static KeyType Key_LSHIFT;
- static KeyType Key_RSHIFT;
- static KeyType Key_LCONTROL;
- static KeyType Key_RCONTROL;
- static KeyType Key_ALT;
- static KeyType Key_ALTGR;
- static KeyType Key_LWIN;
- static KeyType Key_RWIN;
- static KeyType Key_MENU;
- static KeyType Key_SCRLOCK;
- static KeyType Key_NUMLOCK;
- static KeyType Key_CAPSLOCK;
+ static const KeyType Key_MODIFIERS;
+ static const KeyType Key_LSHIFT;
+ static const KeyType Key_RSHIFT;
+ static const KeyType Key_LCONTROL;
+ static const KeyType Key_RCONTROL;
+ static const KeyType Key_ALT;
+ static const KeyType Key_ALTGR;
+ static const KeyType Key_LWIN;
+ static const KeyType Key_RWIN;
+ static const KeyType Key_MENU;
+ static const KeyType Key_SCRLOCK;
+ static const KeyType Key_NUMLOCK;
+ static const KeyType Key_CAPSLOCK;
void press(KeyType key, unicode_t unicode);
void release(KeyType key);
/*
virtual void addObserver(ObserverCallback observer, void * extra);
virtual void removeObserver(ObserverCallback observer, void * extra);
*/
static void addListener(KeyboardListener * listener);
static void removeListener(KeyboardListener * listener);
const std::set<KeyboardListener*> & getListeners();
protected:
static void disableKeyRepeat();
static void enableKeyRepeat();
static std::set<KeyboardListener*> listeners;
// std::map<int,int> my_keys;
std::map<int,int> key_delay;
// std::vector<Observer> observers;
std::map<KeyType, KeyData> keyState;
std::vector<KeyData> buffer;
bool enableBuffer;
static std::vector<bool> repeatState;
};
class KeyboardListener{
public:
KeyboardListener();
virtual ~KeyboardListener();
virtual void press(Keyboard * from, Keyboard::KeyType key, Keyboard::unicode_t unicode) = 0;
virtual void release(Keyboard * from, Keyboard::KeyType key) = 0;
};
#endif
diff --git a/util/input/sdl/keyboard.cpp b/util/input/sdl/keyboard.cpp
index 3c65e249..3af728e1 100644
--- a/util/input/sdl/keyboard.cpp
+++ b/util/input/sdl/keyboard.cpp
@@ -1,218 +1,218 @@
#include <SDL.h>
#include "../keyboard.h"
#include "../input-manager.h"
#include "util/funcs.h"
#if SDL_VERSION_ATLEAST(1, 3, 0)
Uint8 * getKeyState(int * keys){
return SDL_GetKeyboardState(keys);
}
#else
Uint8 * getKeyState(int * keys){
return SDL_GetKeyState(keys);
}
#endif
Keyboard::Keyboard():
enableBuffer(false){
}
void Keyboard::poll(){
buffer.clear();
SDL_PumpEvents();
}
void Keyboard::wait(){
while (keypressed()){
Util::rest(1);
poll();
}
}
bool Keyboard::keypressed(){
int keys = 0;
Uint8 * state = getKeyState(&keys);
for (int i = 0; i < keys; i++){
if (i != SDLK_NUMLOCK && state[i] == 1){
return true;
}
}
return false;
}
void Keyboard::disableKeyRepeat(){
SDL_EnableKeyRepeat(0, 0);
}
void Keyboard::enableKeyRepeat(){
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
}
#if 0
void Keyboard::readKeys( std::vector<int> & all_keys ){
int keys = 0;
Uint8 * state = getKeyState(&keys);
/* FIXME: the mapping between SDLK_* and our keyboard values are not 1-1 so
* use a function here that returns the right mapping.
*/
for (int i = 0; i < keys; i++){
if (i != SDLK_NUMLOCK && state[i] == 1){
all_keys.push_back(i);
}
}
}
#endif
void Keyboard::readKeys(std::vector<int> & all_keys){
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
all_keys.push_back(key);
}
}
}
/*
int Keyboard::readKey(){
std::vector<int> keys;
do{
readKeys(keys);
Util::rest(1);
InputManager::poll();
poll();
} while (keys.size() == 0);
return keys.front();
}
*/
void Keyboard::clear(){
buffer.clear();
keyState.clear();
}
-Keyboard::KeyType Keyboard::Key_A = SDLK_a;
-Keyboard::KeyType Keyboard::Key_B = SDLK_b;
-Keyboard::KeyType Keyboard::Key_C = SDLK_c;
-Keyboard::KeyType Keyboard::Key_D = SDLK_d;
-Keyboard::KeyType Keyboard::Key_E = SDLK_e;
-Keyboard::KeyType Keyboard::Key_F = SDLK_f;
-Keyboard::KeyType Keyboard::Key_G = SDLK_g;
-Keyboard::KeyType Keyboard::Key_H = SDLK_h;
-Keyboard::KeyType Keyboard::Key_I = SDLK_i;
-Keyboard::KeyType Keyboard::Key_J = SDLK_j;
-Keyboard::KeyType Keyboard::Key_K = SDLK_k;
-Keyboard::KeyType Keyboard::Key_L = SDLK_l;
-Keyboard::KeyType Keyboard::Key_M = SDLK_m;
-Keyboard::KeyType Keyboard::Key_N = SDLK_n;
-Keyboard::KeyType Keyboard::Key_O = SDLK_o;
-Keyboard::KeyType Keyboard::Key_P = SDLK_p;
-Keyboard::KeyType Keyboard::Key_Q = SDLK_q;
-Keyboard::KeyType Keyboard::Key_R = SDLK_r;
-Keyboard::KeyType Keyboard::Key_S = SDLK_s;
-Keyboard::KeyType Keyboard::Key_T = SDLK_t;
-Keyboard::KeyType Keyboard::Key_U = SDLK_u;
-Keyboard::KeyType Keyboard::Key_V = SDLK_v;
-Keyboard::KeyType Keyboard::Key_W = SDLK_w;
-Keyboard::KeyType Keyboard::Key_X = SDLK_x;
-Keyboard::KeyType Keyboard::Key_Y = SDLK_y;
-Keyboard::KeyType Keyboard::Key_Z = SDLK_z;
-Keyboard::KeyType Keyboard::Key_0 = SDLK_0;
-Keyboard::KeyType Keyboard::Key_1 = SDLK_1;
-Keyboard::KeyType Keyboard::Key_2 = SDLK_2;
-Keyboard::KeyType Keyboard::Key_3 = SDLK_3;
-Keyboard::KeyType Keyboard::Key_4 = SDLK_4;
-Keyboard::KeyType Keyboard::Key_5 = SDLK_5;
-Keyboard::KeyType Keyboard::Key_6 = SDLK_6;
-Keyboard::KeyType Keyboard::Key_7 = SDLK_7;
-Keyboard::KeyType Keyboard::Key_8 = SDLK_8;
-Keyboard::KeyType Keyboard::Key_9 = SDLK_9;
-Keyboard::KeyType Keyboard::Key_0_PAD = SDLK_KP0;
-Keyboard::KeyType Keyboard::Key_1_PAD = SDLK_KP1;
-Keyboard::KeyType Keyboard::Key_2_PAD = SDLK_KP2;
-Keyboard::KeyType Keyboard::Key_3_PAD = SDLK_KP3;
-Keyboard::KeyType Keyboard::Key_4_PAD = SDLK_KP4;
-Keyboard::KeyType Keyboard::Key_5_PAD = SDLK_KP5;
-Keyboard::KeyType Keyboard::Key_6_PAD = SDLK_KP6;
-Keyboard::KeyType Keyboard::Key_7_PAD = SDLK_KP7;
-Keyboard::KeyType Keyboard::Key_8_PAD = SDLK_KP8;
-Keyboard::KeyType Keyboard::Key_9_PAD = SDLK_KP9;
-Keyboard::KeyType Keyboard::Key_F1 = SDLK_F1;
-Keyboard::KeyType Keyboard::Key_F2 = SDLK_F2;
-Keyboard::KeyType Keyboard::Key_F3 = SDLK_F3;
-Keyboard::KeyType Keyboard::Key_F4 = SDLK_F4;
-Keyboard::KeyType Keyboard::Key_F5 = SDLK_F5;
-Keyboard::KeyType Keyboard::Key_F6 = SDLK_F6;
-Keyboard::KeyType Keyboard::Key_F7 = SDLK_F7;
-Keyboard::KeyType Keyboard::Key_F8 = SDLK_F8;
-Keyboard::KeyType Keyboard::Key_F9 = SDLK_F9;
-Keyboard::KeyType Keyboard::Key_F10 = SDLK_F10;
-Keyboard::KeyType Keyboard::Key_F11 = SDLK_F11;
-Keyboard::KeyType Keyboard::Key_F12 = SDLK_F12;
+const Keyboard::KeyType Keyboard::Key_A = SDLK_a;
+const Keyboard::KeyType Keyboard::Key_B = SDLK_b;
+const Keyboard::KeyType Keyboard::Key_C = SDLK_c;
+const Keyboard::KeyType Keyboard::Key_D = SDLK_d;
+const Keyboard::KeyType Keyboard::Key_E = SDLK_e;
+const Keyboard::KeyType Keyboard::Key_F = SDLK_f;
+const Keyboard::KeyType Keyboard::Key_G = SDLK_g;
+const Keyboard::KeyType Keyboard::Key_H = SDLK_h;
+const Keyboard::KeyType Keyboard::Key_I = SDLK_i;
+const Keyboard::KeyType Keyboard::Key_J = SDLK_j;
+const Keyboard::KeyType Keyboard::Key_K = SDLK_k;
+const Keyboard::KeyType Keyboard::Key_L = SDLK_l;
+const Keyboard::KeyType Keyboard::Key_M = SDLK_m;
+const Keyboard::KeyType Keyboard::Key_N = SDLK_n;
+const Keyboard::KeyType Keyboard::Key_O = SDLK_o;
+const Keyboard::KeyType Keyboard::Key_P = SDLK_p;
+const Keyboard::KeyType Keyboard::Key_Q = SDLK_q;
+const Keyboard::KeyType Keyboard::Key_R = SDLK_r;
+const Keyboard::KeyType Keyboard::Key_S = SDLK_s;
+const Keyboard::KeyType Keyboard::Key_T = SDLK_t;
+const Keyboard::KeyType Keyboard::Key_U = SDLK_u;
+const Keyboard::KeyType Keyboard::Key_V = SDLK_v;
+const Keyboard::KeyType Keyboard::Key_W = SDLK_w;
+const Keyboard::KeyType Keyboard::Key_X = SDLK_x;
+const Keyboard::KeyType Keyboard::Key_Y = SDLK_y;
+const Keyboard::KeyType Keyboard::Key_Z = SDLK_z;
+const Keyboard::KeyType Keyboard::Key_0 = SDLK_0;
+const Keyboard::KeyType Keyboard::Key_1 = SDLK_1;
+const Keyboard::KeyType Keyboard::Key_2 = SDLK_2;
+const Keyboard::KeyType Keyboard::Key_3 = SDLK_3;
+const Keyboard::KeyType Keyboard::Key_4 = SDLK_4;
+const Keyboard::KeyType Keyboard::Key_5 = SDLK_5;
+const Keyboard::KeyType Keyboard::Key_6 = SDLK_6;
+const Keyboard::KeyType Keyboard::Key_7 = SDLK_7;
+const Keyboard::KeyType Keyboard::Key_8 = SDLK_8;
+const Keyboard::KeyType Keyboard::Key_9 = SDLK_9;
+const Keyboard::KeyType Keyboard::Key_0_PAD = SDLK_KP0;
+const Keyboard::KeyType Keyboard::Key_1_PAD = SDLK_KP1;
+const Keyboard::KeyType Keyboard::Key_2_PAD = SDLK_KP2;
+const Keyboard::KeyType Keyboard::Key_3_PAD = SDLK_KP3;
+const Keyboard::KeyType Keyboard::Key_4_PAD = SDLK_KP4;
+const Keyboard::KeyType Keyboard::Key_5_PAD = SDLK_KP5;
+const Keyboard::KeyType Keyboard::Key_6_PAD = SDLK_KP6;
+const Keyboard::KeyType Keyboard::Key_7_PAD = SDLK_KP7;
+const Keyboard::KeyType Keyboard::Key_8_PAD = SDLK_KP8;
+const Keyboard::KeyType Keyboard::Key_9_PAD = SDLK_KP9;
+const Keyboard::KeyType Keyboard::Key_F1 = SDLK_F1;
+const Keyboard::KeyType Keyboard::Key_F2 = SDLK_F2;
+const Keyboard::KeyType Keyboard::Key_F3 = SDLK_F3;
+const Keyboard::KeyType Keyboard::Key_F4 = SDLK_F4;
+const Keyboard::KeyType Keyboard::Key_F5 = SDLK_F5;
+const Keyboard::KeyType Keyboard::Key_F6 = SDLK_F6;
+const Keyboard::KeyType Keyboard::Key_F7 = SDLK_F7;
+const Keyboard::KeyType Keyboard::Key_F8 = SDLK_F8;
+const Keyboard::KeyType Keyboard::Key_F9 = SDLK_F9;
+const Keyboard::KeyType Keyboard::Key_F10 = SDLK_F10;
+const Keyboard::KeyType Keyboard::Key_F11 = SDLK_F11;
+const Keyboard::KeyType Keyboard::Key_F12 = SDLK_F12;
#ifdef ANDROID
-Keyboard::KeyType Keyboard::Key_ESC = SDLK_AC_BACK;
+const Keyboard::KeyType Keyboard::Key_ESC = SDLK_AC_BACK;
#else
-Keyboard::KeyType Keyboard::Key_ESC = SDLK_ESCAPE;
+const Keyboard::KeyType Keyboard::Key_ESC = SDLK_ESCAPE;
#endif
-Keyboard::KeyType Keyboard::Key_TILDE = SDLK_BACKQUOTE;
-Keyboard::KeyType Keyboard::Key_MINUS = SDLK_MINUS;
-Keyboard::KeyType Keyboard::Key_EQUALS = SDLK_EQUALS;
-Keyboard::KeyType Keyboard::Key_BACKSPACE = SDLK_BACKSPACE;
-Keyboard::KeyType Keyboard::Key_TAB = SDLK_TAB;
-Keyboard::KeyType Keyboard::Key_OPENBRACE = SDLK_LEFTBRACKET;
-Keyboard::KeyType Keyboard::Key_CLOSEBRACE = SDLK_RIGHTBRACKET;
-Keyboard::KeyType Keyboard::Key_ENTER = SDLK_RETURN;
-Keyboard::KeyType Keyboard::Key_COLON = SDLK_COLON;
-Keyboard::KeyType Keyboard::Key_QUOTE = SDLK_QUOTEDBL;
-Keyboard::KeyType Keyboard::Key_BACKSLASH = SDLK_BACKSLASH;
-Keyboard::KeyType Keyboard::Key_BACKSLASH2 = 999; /* FIXME */
-Keyboard::KeyType Keyboard::Key_COMMA = SDLK_COMMA;
-Keyboard::KeyType Keyboard::Key_STOP = SDLK_PERIOD;
-Keyboard::KeyType Keyboard::Key_SLASH = SDLK_SLASH;
-Keyboard::KeyType Keyboard::Key_SPACE = SDLK_SPACE;
-Keyboard::KeyType Keyboard::Key_INSERT = SDLK_INSERT;
-Keyboard::KeyType Keyboard::Key_DEL = SDLK_DELETE;
-Keyboard::KeyType Keyboard::Key_HOME = SDLK_HOME;
-Keyboard::KeyType Keyboard::Key_END = SDLK_END;
-Keyboard::KeyType Keyboard::Key_PGUP = SDLK_PAGEUP;
-Keyboard::KeyType Keyboard::Key_PGDN = SDLK_PAGEDOWN;
-Keyboard::KeyType Keyboard::Key_LEFT = SDLK_LEFT;
-Keyboard::KeyType Keyboard::Key_RIGHT = SDLK_RIGHT;
-Keyboard::KeyType Keyboard::Key_UP = SDLK_UP;
-Keyboard::KeyType Keyboard::Key_DOWN = SDLK_DOWN;
-Keyboard::KeyType Keyboard::Key_SLASH_PAD = SDLK_KP_DIVIDE;
-Keyboard::KeyType Keyboard::Key_ASTERISK = SDLK_ASTERISK;
-Keyboard::KeyType Keyboard::Key_MINUS_PAD = SDLK_KP_MINUS;
-Keyboard::KeyType Keyboard::Key_PLUS_PAD = SDLK_KP_PLUS;
-Keyboard::KeyType Keyboard::Key_DEL_PAD = 1000; /* FIXME */
-Keyboard::KeyType Keyboard::Key_ENTER_PAD = SDLK_KP_ENTER;
-Keyboard::KeyType Keyboard::Key_PRTSCR = SDLK_PRINT;
-Keyboard::KeyType Keyboard::Key_PAUSE = SDLK_PAUSE;
-Keyboard::KeyType Keyboard::Key_ABNT_C1 = 1001; /* FIXME */
-Keyboard::KeyType Keyboard::Key_YEN = 1002;
-Keyboard::KeyType Keyboard::Key_KANA = 1003;
-Keyboard::KeyType Keyboard::Key_CONVERT = 1004;
-Keyboard::KeyType Keyboard::Key_NOCONVERT = 1005;
-Keyboard::KeyType Keyboard::Key_AT = SDLK_AT;
-Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = SDLK_CARET;
-Keyboard::KeyType Keyboard::Key_COLON2 = 1006;
-Keyboard::KeyType Keyboard::Key_KANJI = 1007;
-Keyboard::KeyType Keyboard::Key_EQUALS_PAD = SDLK_KP_EQUALS;
-Keyboard::KeyType Keyboard::Key_BACKQUOTE = 1008;
-Keyboard::KeyType Keyboard::Key_SEMICOLON = SDLK_SEMICOLON;
-Keyboard::KeyType Keyboard::Key_COMMAND = 1009;
+const Keyboard::KeyType Keyboard::Key_TILDE = SDLK_BACKQUOTE;
+const Keyboard::KeyType Keyboard::Key_MINUS = SDLK_MINUS;
+const Keyboard::KeyType Keyboard::Key_EQUALS = SDLK_EQUALS;
+const Keyboard::KeyType Keyboard::Key_BACKSPACE = SDLK_BACKSPACE;
+const Keyboard::KeyType Keyboard::Key_TAB = SDLK_TAB;
+const Keyboard::KeyType Keyboard::Key_OPENBRACE = SDLK_LEFTBRACKET;
+const Keyboard::KeyType Keyboard::Key_CLOSEBRACE = SDLK_RIGHTBRACKET;
+const Keyboard::KeyType Keyboard::Key_ENTER = SDLK_RETURN;
+const Keyboard::KeyType Keyboard::Key_COLON = SDLK_COLON;
+const Keyboard::KeyType Keyboard::Key_QUOTE = SDLK_QUOTEDBL;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH = SDLK_BACKSLASH;
+const Keyboard::KeyType Keyboard::Key_BACKSLASH2 = 999; /* FIXME */
+const Keyboard::KeyType Keyboard::Key_COMMA = SDLK_COMMA;
+const Keyboard::KeyType Keyboard::Key_STOP = SDLK_PERIOD;
+const Keyboard::KeyType Keyboard::Key_SLASH = SDLK_SLASH;
+const Keyboard::KeyType Keyboard::Key_SPACE = SDLK_SPACE;
+const Keyboard::KeyType Keyboard::Key_INSERT = SDLK_INSERT;
+const Keyboard::KeyType Keyboard::Key_DEL = SDLK_DELETE;
+const Keyboard::KeyType Keyboard::Key_HOME = SDLK_HOME;
+const Keyboard::KeyType Keyboard::Key_END = SDLK_END;
+const Keyboard::KeyType Keyboard::Key_PGUP = SDLK_PAGEUP;
+const Keyboard::KeyType Keyboard::Key_PGDN = SDLK_PAGEDOWN;
+const Keyboard::KeyType Keyboard::Key_LEFT = SDLK_LEFT;
+const Keyboard::KeyType Keyboard::Key_RIGHT = SDLK_RIGHT;
+const Keyboard::KeyType Keyboard::Key_UP = SDLK_UP;
+const Keyboard::KeyType Keyboard::Key_DOWN = SDLK_DOWN;
+const Keyboard::KeyType Keyboard::Key_SLASH_PAD = SDLK_KP_DIVIDE;
+const Keyboard::KeyType Keyboard::Key_ASTERISK = SDLK_ASTERISK;
+const Keyboard::KeyType Keyboard::Key_MINUS_PAD = SDLK_KP_MINUS;
+const Keyboard::KeyType Keyboard::Key_PLUS_PAD = SDLK_KP_PLUS;
+const Keyboard::KeyType Keyboard::Key_DEL_PAD = 1000; /* FIXME */
+const Keyboard::KeyType Keyboard::Key_ENTER_PAD = SDLK_KP_ENTER;
+const Keyboard::KeyType Keyboard::Key_PRTSCR = SDLK_PRINT;
+const Keyboard::KeyType Keyboard::Key_PAUSE = SDLK_PAUSE;
+const Keyboard::KeyType Keyboard::Key_ABNT_C1 = 1001; /* FIXME */
+const Keyboard::KeyType Keyboard::Key_YEN = 1002;
+const Keyboard::KeyType Keyboard::Key_KANA = 1003;
+const Keyboard::KeyType Keyboard::Key_CONVERT = 1004;
+const Keyboard::KeyType Keyboard::Key_NOCONVERT = 1005;
+const Keyboard::KeyType Keyboard::Key_AT = SDLK_AT;
+const Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = SDLK_CARET;
+const Keyboard::KeyType Keyboard::Key_COLON2 = 1006;
+const Keyboard::KeyType Keyboard::Key_KANJI = 1007;
+const Keyboard::KeyType Keyboard::Key_EQUALS_PAD = SDLK_KP_EQUALS;
+const Keyboard::KeyType Keyboard::Key_BACKQUOTE = 1008;
+const Keyboard::KeyType Keyboard::Key_SEMICOLON = SDLK_SEMICOLON;
+const Keyboard::KeyType Keyboard::Key_COMMAND = 1009;
-Keyboard::KeyType Keyboard::Key_MODIFIERS = 1010;
-Keyboard::KeyType Keyboard::Key_LSHIFT = SDLK_LSHIFT;
-Keyboard::KeyType Keyboard::Key_RSHIFT = SDLK_RSHIFT;
-Keyboard::KeyType Keyboard::Key_LCONTROL = SDLK_LCTRL;
-Keyboard::KeyType Keyboard::Key_RCONTROL = SDLK_RCTRL;
-Keyboard::KeyType Keyboard::Key_ALT = SDLK_LALT;
-Keyboard::KeyType Keyboard::Key_ALTGR = SDLK_RALT;
-Keyboard::KeyType Keyboard::Key_LWIN = SDLK_LMETA;
-Keyboard::KeyType Keyboard::Key_RWIN = SDLK_RMETA;
-Keyboard::KeyType Keyboard::Key_MENU = SDLK_HELP;
-Keyboard::KeyType Keyboard::Key_SCRLOCK = SDLK_SCROLLOCK;
-Keyboard::KeyType Keyboard::Key_NUMLOCK = SDLK_NUMLOCK;
-Keyboard::KeyType Keyboard::Key_CAPSLOCK = SDLK_CAPSLOCK;
+const Keyboard::KeyType Keyboard::Key_MODIFIERS = 1010;
+const Keyboard::KeyType Keyboard::Key_LSHIFT = SDLK_LSHIFT;
+const Keyboard::KeyType Keyboard::Key_RSHIFT = SDLK_RSHIFT;
+const Keyboard::KeyType Keyboard::Key_LCONTROL = SDLK_LCTRL;
+const Keyboard::KeyType Keyboard::Key_RCONTROL = SDLK_RCTRL;
+const Keyboard::KeyType Keyboard::Key_ALT = SDLK_LALT;
+const Keyboard::KeyType Keyboard::Key_ALTGR = SDLK_RALT;
+const Keyboard::KeyType Keyboard::Key_LWIN = SDLK_LMETA;
+const Keyboard::KeyType Keyboard::Key_RWIN = SDLK_RMETA;
+const Keyboard::KeyType Keyboard::Key_MENU = SDLK_HELP;
+const Keyboard::KeyType Keyboard::Key_SCRLOCK = SDLK_SCROLLOCK;
+const Keyboard::KeyType Keyboard::Key_NUMLOCK = SDLK_NUMLOCK;
+const Keyboard::KeyType Keyboard::Key_CAPSLOCK = SDLK_CAPSLOCK;
diff --git a/util/menu/options.cpp b/util/menu/options.cpp
index ad83aacc..3fabf4b0 100644
--- a/util/menu/options.cpp
+++ b/util/menu/options.cpp
@@ -1,2926 +1,3035 @@
#include "util/graphics/bitmap.h"
#include "options.h"
#include "util/token.h"
#include "util/input/input-source.h"
#include "util/parameter.h"
#include "util/tokenreader.h"
#include "menu.h"
#include "util/configuration.h"
#include "util/exceptions/load_exception.h"
#include "menu-exception.h"
#include "util/init.h"
#include "util/events.h"
#include "util/version.h"
#include "optionfactory.h"
#include "util/sound/music.h"
#include "util/input/keyboard.h"
#include "util/funcs.h"
#include "util/file-system.h"
#include "util/system.h"
#include "util/font_factory.h"
#include "util/exceptions/shutdown_exception.h"
#include "util/exceptions/exception.h"
#include "util/font.h"
#include "util/gui/box.h"
#include "util/thread.h"
#include "util/loading.h"
#include "util/input/input-map.h"
#include "util/input/input-manager.h"
#include <sstream>
#include <algorithm>
#include <time.h>
#include <math.h>
using namespace std;
using namespace Gui;
/* true if the arguments passed in match todays date.
* pass 0 for any argument that you don't care about (it will match any date)
*/
static bool todaysDate(int month, int day, int year){
time_t result = time(NULL);
struct tm * local = localtime(&result);
return (month == 0 || month == (local->tm_mon + 1)) &&
(day == 0 || day == local->tm_mday) &&
(year == 0 || year == local->tm_year + 1900);
}
static bool jonBirthday(){
return todaysDate(3, 25, 0);
}
static bool miguelBirthday(){
return todaysDate(8, 11, 0);
}
OptionCredits::Block::Block(const std::string & title):
title(title),
titleColorOverride(false),
titleColor(Graphics::makeColor(0,255,255)),
colorOverride(false),
color(Graphics::makeColor(255,255,255)),
spacing(0){
}
OptionCredits::Block::Block(const Token * token):
titleColorOverride(false),
titleColor(Graphics::makeColor(0,255,255)),
colorOverride(false),
color(Graphics::makeColor(255,255,255)),
topWidth(0),
topHeight(0),
bottomWidth(0),
bottomHeight(0),
spacing(0){
if ( *token != "block" ){
throw LoadException(__FILE__, __LINE__, "Not a credit block");
}
TokenView view = token->view();
while (view.hasMore()){
std::string match;
try{
const Token * tok;
view >> tok;
if ( *tok == "title" ) {
tok->view() >> title;
} else if (*tok == "credit"){
std::string credit;
tok->view() >> credit;
credits.push_back(credit);
} else if ( *tok == "titlecolor" ) {
try{
int r,b,g;
tok->view() >> r >> g >> b;
titleColor = Graphics::makeColor( r, g, b );
titleColorOverride = true;
} catch (const TokenException & ex){
}
} else if ( *tok == "color" ) {
try{
int r,b,g;
tok->view() >> r >> g >> b;
color = Graphics::makeColor( r, g, b );
colorOverride = true;
} catch (const TokenException & ex){
}
} else if ( *tok == "animation" ) {
TokenView animView = tok->view();
while (animView.hasMore()){
const Token * animTok;
animView >> animTok;
if (*animTok == "top"){
tok->match("_/width", topWidth);
tok->match("_/height", topHeight);
topAnimation = Util::ReferenceCount<Gui::Animation>(new Animation(tok));
} else if (*animTok == "bottom"){
tok->match("_/width", bottomWidth);
tok->match("_/height", bottomHeight);
bottomAnimation = Util::ReferenceCount<Gui::Animation>(new Animation(tok));
}
}
} else if (*tok == "spacing"){
tok->view() >> spacing;
} else {
Global::debug( 3 ) <<"Unhandled Credit Block attribute: "<<endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Credit Block parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
OptionCredits::Block::Block(const OptionCredits::Block & copy):
title(copy.title),
credits(copy.credits),
titleColorOverride(copy.titleColorOverride),
titleColor(copy.titleColor),
colorOverride(copy.colorOverride),
color(copy.color),
topAnimation(copy.topAnimation),
topWidth(copy.topWidth),
topHeight(copy.topHeight),
bottomAnimation(copy.bottomAnimation),
bottomWidth(copy.bottomWidth),
bottomHeight(copy.bottomHeight),
spacing(copy.spacing){
}
OptionCredits::Block::~Block(){
}
const OptionCredits::Block & OptionCredits::Block::operator=(const OptionCredits::Block & copy){
title = copy.title;
credits = copy.credits;
titleColor = copy.titleColor;
titleColorOverride = copy.titleColorOverride;
color = copy.color;
colorOverride = copy.colorOverride;
topAnimation = copy.topAnimation;
topWidth =copy.topWidth;
topHeight = copy.topHeight;
bottomAnimation = copy.bottomAnimation;
bottomWidth = copy.bottomWidth;
bottomHeight = copy.bottomHeight;
spacing = copy.spacing;
return *this;
}
void OptionCredits::Block::addCredit(const std::string & credit){
credits.push_back(credit);
}
void OptionCredits::Block::act(){
// Top animation
if (topAnimation != NULL){
topAnimation->act();
}
// Bottom animation
if (bottomAnimation != NULL){
bottomAnimation->act();
}
}
int OptionCredits::Block::print(int x, int y, Graphics::Color defaultTitleColor, Graphics::Color defaultColor, const Font & font, const Graphics::Bitmap & work, const Justification & justification) const {
int currentY = y;
// Top animation
if (topAnimation != NULL){
int xmod = 0;
switch (justification){
default:
case Left:
xmod = 0;
break;
case Center:
xmod = topWidth/2;
break;
case Right:
xmod = topWidth;
break;
}
// FIXME temporary solution
const Graphics::Bitmap temp(topWidth, topHeight);
//topAnimation->draw(x - xmod, y, topWidth, topHeight, work);
topAnimation->draw(0, 0, topWidth, topHeight, temp);
temp.translucent().draw(x-xmod, y, work);
currentY += topHeight;
}
if (!title.empty()){
int xmod = 0;
switch (justification){
default:
case Left:
xmod = 0;
break;
case Center:
xmod = font.textLength(title.c_str())/2;
break;
case Right:
xmod = font.textLength(title.c_str());
break;
}
font.printf(x - xmod, currentY, (titleColorOverride ? titleColor : defaultTitleColor), work, title, 0);
currentY += font.getHeight();
}
for (std::vector<std::string>::const_iterator i = credits.begin(); i != credits.end(); ++i){
const std::string & credit = *i;
int xmod = 0;
switch (justification){
default:
case Left:
xmod = 0;
break;
case Center:
xmod = font.textLength(credit.c_str())/2;
break;
case Right:
xmod = font.textLength(credit.c_str());
break;
}
font.printf(x - xmod, currentY, (colorOverride ? color : defaultColor), work, credit, 0);
currentY += font.getHeight();
}
// Bottom animation
if (bottomAnimation != NULL){
int xmod = 0;
switch (justification){
default:
case Left:
xmod = 0;
break;
case Center:
xmod = bottomWidth/2;
break;
case Right:
xmod = bottomWidth;
break;
}
// FIXME temporary solution
const Graphics::Bitmap temp(topWidth, topHeight);
//bottomAnimation->draw(x - xmod, y, bottomWidth, bottomHeight, work);
bottomAnimation->draw(0, 0, bottomWidth, bottomHeight, temp);
temp.translucent().draw(x-xmod, y, work);
currentY += bottomHeight;
}
currentY += font.getHeight() + spacing;
return currentY;
}
const int OptionCredits::Block::size(const Font & font) const{
// Counts title and space in between
int total = 0;
if (topAnimation != NULL){
total += topHeight;
}
if (!title.empty()){
total+= font.getHeight();
}
total += credits.size() * font.getHeight();
if (bottomAnimation != NULL){
total += bottomHeight;
}
total += font.getHeight();
total += spacing;
return total;
}
OptionCredits::Sequence::Sequence(const Token * token):
type(Primary),
x(0),
y(0),
startx(0),
endx(0),
starty(0),
endy(0),
ticks(0),
duration(250),
speed(0),
alpha(0),
alphaMultiplier(0),
justification(Block::Center),
current(0),
done(false),
creditLength(0){
if ( *token != "sequence" ){
throw LoadException(__FILE__, __LINE__, "Not a credit sequence");
}
TokenView view = token->view();
while (view.hasMore()){
std::string match;
try{
const Token * tok;
view >> tok;
if (*tok == "type"){
std::string sequenceType;
tok->view() >> sequenceType;
if (sequenceType == "roll"){
type = Roll;
} else if (sequenceType == "primary"){
type = Primary;
}
} else if (*tok == "start-x"){
tok->view() >> startx;
} else if (*tok == "end-x"){
tok->view() >> endx;
} else if (*tok == "start-y"){
tok->view() >> starty;
} else if (*tok == "end-y"){
tok->view() >> endy;
} else if (*tok == "duration"){
tok->view() >> duration;
} else if (*tok == "speed"){
tok->view() >> speed;
} else if (*tok == "alpha-multiplier"){
tok->view() >> alphaMultiplier;
} else if ( *tok == "justification" ) {
std::string justify;
tok->view() >> justify;
if (justify == "left"){
justification = Block::Left;
} else if (justify == "center"){
justification = Block::Center;
} else if (justify == "right"){
justification = Block::Right;
}
} else if (*tok == "block"){
credits.push_back(Block(tok));
} else {
Global::debug( 3 ) <<"Unhandled Credit Sequence attribute: "<<endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Credit Sequence parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
// Initial
reset();
for (std::vector<OptionCredits::Block>::const_iterator i = credits.begin(); i != credits.end(); ++i){
const OptionCredits::Block & block = *i;
creditLength += block.size(Menu::menuFontParameter.current()->get());
}
}
OptionCredits::Sequence::Sequence(const Sequence & copy):
type(copy.type),
x(copy.x),
y(copy.y),
startx(copy.startx),
endx(copy.endx),
starty(copy.starty),
endy(copy.endy),
ticks(copy.ticks),
duration(copy.duration),
speed(copy.speed),
alpha(copy.alpha),
alphaMultiplier(copy.alphaMultiplier),
justification(copy.justification),
credits(copy.credits),
current(copy.current),
done(false),
creditLength(copy.creditLength){
}
OptionCredits::Sequence::~Sequence(){
}
const OptionCredits::Sequence & OptionCredits::Sequence::operator=(const OptionCredits::Sequence & copy){
type = copy.type;
x = copy.x;
y = copy.y;
startx = copy.startx;
endx = copy.endx;
starty = copy.starty;
endy = copy.endy;
ticks = copy.ticks;
duration = copy.duration;
speed = copy.speed;
alpha = copy.alpha;
alphaMultiplier = copy.alphaMultiplier;
justification = copy.justification;
credits = copy.credits;
current = copy.current;
done = false;
creditLength = copy.creditLength;
return *this;
}
static int alphaClamp(int x, double multiplier){
int clamp = x * multiplier;
if (clamp < 0){
clamp = 0;
} else if (clamp > 255){
clamp = 255;
}
return clamp;
}
void OptionCredits::Sequence::act(){
if (!done && !credits.empty()){
if (type == Roll){
y += speed;
if (starty > endy){
if ((y + (creditLength * 1.1)) < endy){
done = true;
}
} else if (starty < endy){
if ((y * 1.1) > endy){
done = true;
}
}
} else if (type == Primary){
credits[current].act();
if (startx != endx){
x += speed;
if (startx > endx){
const double midpoint = (startx+endx)/2;
const int mid = x > midpoint ? startx -x : x - endx;
alpha = alphaClamp(mid, alphaMultiplier);
if (x < endx){
next();
}
} else if (startx < endx){
const double midpoint = (startx+endx)/2;
const int mid = x < midpoint ? x - startx : endx - x;
alpha = alphaClamp(mid, alphaMultiplier);
//Global::debug(0) << "alpha: " << alpha << " midpoint: " << midpoint << " mid: " << mid << std::endl;
if (x > endx){
next();
}
}
} else {
const double midpoint = duration/2;
const int mid = ticks < midpoint ? ticks : duration - ticks;
alpha = alphaClamp(mid, alphaMultiplier);
ticks++;
if (ticks >= duration){
ticks = 0;
next();
}
}
}
}
}
void OptionCredits::Sequence::draw(Graphics::Color title, Graphics::Color color, const Graphics::Bitmap & work){
if (!done && !credits.empty()){
if (type == Roll){
int rollY = (int) y;
for (std::vector<OptionCredits::Block>::const_iterator i = credits.begin(); i != credits.end(); ++i){
const OptionCredits::Block & block = *i;
rollY = block.print(x, rollY, title, color, Menu::menuFontParameter.current()->get(), work, justification);
}
} else if (type == Primary){
Graphics::Bitmap::transBlender(0, 0, 0, alpha);
credits[current].print(x, y, title, color, Menu::menuFontParameter.current()->get(), work.translucent(), justification);
}
}
}
void OptionCredits::Sequence::reset(){
done = false;
current = 0;
ticks = 0;
if (!credits.empty()){
if (type == Roll){
x = startx;
y = starty;
} else if (type == Primary){
x = startx;
y = starty - (credits[current].size(Menu::menuFontParameter.current()->get())/2);
}
}
}
void OptionCredits::Sequence::next(){
if (type == Primary){
if (current < credits.size()){
current++;
if (current == credits.size()){
done = true;
} else {
x = startx;
y = starty - (credits[current].size(Menu::menuFontParameter.current()->get())/2);
}
}
}
}
static std::string defaultPositions(){
const int width = Configuration::getScreenWidth();
const int height = Configuration::getScreenHeight();
std::ostringstream out;
out << "(start-x " << width/2.3 << ") (end-x " << width/1.8 << ") (start-y " << height/2 << ") ";
//out << "(start-x " << width/2 << ") (end-x " << width/2 << ") (start-y " << height/2 << ") (duration 250) ";
return out.str();
}
OptionCredits::OptionCredits(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token),
creditsContext(new Menu::Context()),
music(""),
color(Graphics::makeColor(255,255,255)),
title(Graphics::makeColor(0,255,255)),
clearColor(Graphics::makeColor(0,0,0)){
std::string defaultSequence = "(sequence (type primary) (speed 0.3) (alpha-multiplier 20) (justification center) " + defaultPositions();
/* Always */
if (jonBirthday()){
defaultSequence += "(block (title \"Happy birthday, Jon!\"))";
}
if (miguelBirthday()){
defaultSequence += "(block (title \"Happy birthday, Miguel!\"))";
}
if (Storage::instance().exists(Filesystem::RelativePath("sprites/paintown.png"))){
defaultSequence += "(block (animation (top) (width 350) (height 65) (image 0 \"sprites/paintown.png\") (frame (image 0) (time -1))) (credit \"Version " + Version::getVersionString() + "\"))";
} else {
defaultSequence += "(block (title \"PAINTOWN\") (credit \"Version " + Version::getVersionString() + "\"))";
}
defaultSequence += "(block (title \"Programming\") (credit \"Jon Rafkind\") (credit \"Miguel Gavidia\"))";
defaultSequence += "(block (title \"Level design\") (credit \"Jon Rafkind\") (credit \"Miguel Gavidia\"))";
defaultSequence += "(block (title \"Contact\") (credit \"Website: http://paintown.org\") (credit \"Email: jon@rafkind.com\")))";
TokenReader reader;
Sequence sequence(reader.readTokenFromString(defaultSequence));
sequences.push_back(sequence);
//Global::debug(0) << defaultSequence << std::endl;
if ( *token != "credits" ){
throw LoadException(__FILE__, __LINE__, "Not a credit menu");
}
readName(token);
TokenView view = token->view();
// NOTE Use this to handle legacy additional blocks for the time being
Block legacyAdditional("");
bool additionalTitle = true;
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if ( *tok == "music" ) {
/* Set music for credits */
tok->view() >> music;
} else if ( *tok == "background" ) {
/* Create an image and push it back on to vector */
std::string temp;
tok->view() >> temp;
creditsContext->addBackground(temp);
} else if ( *tok == "anim" || *tok == "animation" ){
creditsContext->addBackground(tok);
} else if ( *tok == "additional" ) {
std::string str;
TokenView additionalView = tok->view();
while (additionalView.hasMore()){
additionalView >> str;
if (additionalTitle){
legacyAdditional = Block(str);
additionalTitle = false;
} else {
legacyAdditional.addCredit(str);
}
}
} else if (*tok == "sequence"){
sequences.push_back(OptionCredits::Sequence(tok));
} else if ( *tok == "titlecolor" ) {
int r,b,g;
tok->view() >> r >> g >> b;
title = Graphics::makeColor( r, g, b );
} else if ( *tok == "color" ) {
int r,b,g;
tok->view() >> r >> g >> b;
color = Graphics::makeColor( r, g, b );
} else if ( *tok == "clear-color" ) {
int r,b,g;
tok->view() >> r >> g >> b;
clearColor = Graphics::makeColor( r, g, b );
} else {
Global::debug( 3 ) <<"Unhandled menu attribute: "<<endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
if (!legacyAdditional.empty()){
//creditsRoll.push_back(legacyAdditional);
}
input.set(Keyboard::Key_ESC, 0, true, Exit);
input.set(Joystick::Button2, 0, true, Exit);
}
OptionCredits::~OptionCredits(){
}
void OptionCredits::logic(){
}
class CreditsLogicDraw : public Util::Logic, public Util::Draw {
public:
CreditsLogicDraw(std::vector<OptionCredits::Sequence> & sequences, Graphics::Color clearColor, Graphics::Color title, Graphics::Color color, const Font & font, InputMap<OptionCredits::CreditKey> & input, Menu::Context & context):
sequences(sequences),
clearColor(clearColor),
title(title),
color(color),
font(font),
input(input),
quit(false),
context(context),
current(0){
}
std::vector<OptionCredits::Sequence> & sequences;
Graphics::Color clearColor, title, color;
const Font & font;
InputMap<OptionCredits::CreditKey> & input;
bool quit;
Menu::Context & context;
unsigned int current;
void run(){
vector<InputMap<OptionCredits::CreditKey>::InputEvent> out = InputManager::getEvents(input, InputSource(true));
for (vector<InputMap<OptionCredits::CreditKey>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
const InputMap<OptionCredits::CreditKey>::InputEvent & event = *it;
if (event.enabled){
if (event.out == OptionCredits::Exit){
quit = true;
context.finish();
}
}
}
sequences[current].act();
if (sequences[current].isDone()){
sequences[current].reset();
current++;
if (current >= sequences.size()){
current = 0;
}
}
context.act();
}
bool done(){
return quit;
}
double ticks(double system){
return system * Global::ticksPerSecond(90);
}
void draw(const Graphics::Bitmap & buffer){
/* FIXME: hard coded resolution */
Graphics::StretchedBitmap work(640, 480, buffer, Graphics::StretchedBitmap::NoClear, Graphics::qualityFilterName(Configuration::getQualityFilter()));
work.fill(clearColor);
work.start();
//background.Blit(work);
context.render(Util::ReferenceCount<Menu::Renderer>(NULL), work);
sequences[current].draw(title, color, work);
work.finish();
// buffer.BlitToScreen();
}
};
void OptionCredits::run(const Menu::Context & context){
Menu::Context localContext(context, *creditsContext);
localContext.initialize();
if (!music.empty()){
if (Music::loadSong(Storage::instance().find(Filesystem::RelativePath(music)).path())){
Music::pause();
Music::play();
}
}
const Font & vFont = Menu::menuFontParameter.current()->get();
CreditsLogicDraw loop(sequences, clearColor, title, color, vFont, input, localContext);
Util::standardLoop(loop, loop);
InputManager::waitForRelease(input, InputSource(true), Exit);
throw Menu::Reload(__FILE__, __LINE__);
}
OptionDummy::OptionDummy(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token){
if ( *token != "dummy" ){
throw LoadException(__FILE__, __LINE__, "Not dummy option");
}
readName(token);
if (getText().empty()){
this->setText("Dummy");
}
setRunnable(false);
}
OptionDummy::OptionDummy(const Gui::ContextBox & parent, const std::string &name):
MenuOption(parent, 0){
if (name.empty()){
throw LoadException(__FILE__, __LINE__, "No name given to dummy");
}
this->setText(name);
setRunnable(false);
}
OptionDummy::~OptionDummy(){
}
void OptionDummy::logic(){
}
void OptionDummy::run(const Menu::Context & context){
}
OptionFullscreen::OptionFullscreen(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
if ( *token != "fullscreen" )
throw LoadException(__FILE__, __LINE__, "Not fullscreen option");
readName(token);
}
OptionFullscreen::~OptionFullscreen()
{
// Nothing
}
std::string OptionFullscreen::getText() const {
ostringstream out;
out << MenuOption::getText() << ": " << (Configuration::getFullscreen() ? "Yes" : "No");
return out.str();
}
void OptionFullscreen::logic(){;
}
static void changeScreenMode(){
Configuration::setFullscreen(!Configuration::getFullscreen());
int gfx = (Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED);
Graphics::changeGraphicsMode(gfx, Graphics::Bitmap::getScreenWidth(), Graphics::Bitmap::getScreenHeight());
}
void OptionFullscreen::run(const Menu::Context & context){
changeScreenMode();
}
bool OptionFullscreen::leftKey(){
changeScreenMode();
return true;
}
bool OptionFullscreen::rightKey(){
changeScreenMode();
return true;
}
OptionFps::OptionFps(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token){
readName(token);
setRunnable(false);
}
void OptionFps::logic(){
}
void OptionFps::run(const Menu::Context & context){
}
std::string OptionFps::getText() const {
ostringstream out;
out << "Frames per second: " << Global::TICS_PER_SECOND;
return out.str();
}
bool OptionFps::leftKey(){
Global::setTicksPerSecond(Global::TICS_PER_SECOND - 1);
Configuration::setFps(Global::TICS_PER_SECOND);
return true;
}
bool OptionFps::rightKey(){
Global::setTicksPerSecond(Global::TICS_PER_SECOND + 1);
Configuration::setFps(Global::TICS_PER_SECOND);
return true;
}
OptionFps::~OptionFps(){
}
OptionQualityFilter::OptionQualityFilter(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token){
readName(token);
setRunnable(false);
}
std::string OptionQualityFilter::getText() const {
ostringstream out;
out << MenuOption::getText() << ": " << Configuration::getQualityFilter();
return out.str();
}
void OptionQualityFilter::logic(){
}
bool OptionQualityFilter::leftKey(){
string quality = Configuration::getQualityFilter();
if (quality == "none"){
quality = "hqx";
} else if (quality == "hqx"){
quality = "xbr";
} else if (quality == "xbr"){
quality = "none";
}
Configuration::setQualityFilter(quality);
return true;
}
bool OptionQualityFilter::rightKey(){
string quality = Configuration::getQualityFilter();
if (quality == "none"){
quality = "xbr";
} else if (quality == "hqx"){
quality = "none";
} else if (quality == "xbr"){
quality = "hqx";
}
Configuration::setQualityFilter(quality);
return true;
}
void OptionQualityFilter::run(const Menu::Context & context){
}
OptionQualityFilter::~OptionQualityFilter(){
}
#if 0
static OptionJoystick::JoystickType convertToKey(const std::string &k){
std::string temp = k;
for(unsigned int i=0;i<temp.length();i++){
temp[i] = tolower(temp[i]);
}
if (temp == "up") return OptionJoystick::Up;
if (temp == "down") return OptionJoystick::Down;
if (temp == "left") return OptionJoystick::Left;
/*
if (temp == "right") return OptionJoystick::Right;
if (temp == "jump") return OptionJoystick::Jump;
if (temp == "attack1") return OptionJoystick::Attack1;
if (temp == "attack2") return OptionJoystick::Attack2;
if (temp == "attack3") return OptionJoystick::Attack3;
if (temp == "attack4") return OptionJoystick::Attack4;
if (temp == "attack5") return OptionJoystick::Attack5;
if (temp == "attack6") return OptionJoystick::Attack6;
return OptionJoystick::Invalidkey;
}
static Configuration::JoystickInput getKey(int player, OptionJoystick::JoystickType k){
switch(k){
case OptionJoystick::Up:
return Joystick::Up;
case OptionJoystick::Down:
return Joystick::Down;
case OptionJoystick::Left:
return Joystick::Left;
case OptionJoystick::Right:
return Joystick::Right;
case OptionJoystick::Jump:
return Joystick::Button4;
case OptionJoystick::Attack1:
return Joystick::Button1;
case OptionJoystick::Attack2:
return Joystick::Button2;
case OptionJoystick::Attack3:
return Joystick::Button3;
case OptionJoystick::Attack4:
return Joystick::Button4;
case OptionJoystick::Attack5:
return Joystick::Button5;
case OptionJoystick::Attack6:
return Joystick::Button6;
default:
break;
}
return Joystick::Up;
}
static void setKey(int player, OptionJoystick::JoystickType k, Configuration::JoystickInput key){
/ *
switch(k){
case OptionJoystick::Up:
Configuration::setJoystickUp(player, key);
break;
case OptionJoystick::Down:
Configuration::setJoystickDown(player, key);
break;
case OptionJoystick::Left:
Configuration::setJoystickLeft(player, key);
break;
case OptionJoystick::Right:
Configuration::setJoystickRight(player, key);
break;
case OptionJoystick::Jump:
Configuration::setJoystickJump(player, key);
break;
case OptionJoystick::Attack1:
Configuration::setJoystickAttack1(player, key);
break;
case OptionJoystick::Attack2:
Configuration::setJoystickAttack2(player, key);
break;
case OptionJoystick::Attack3:
Configuration::setJoystickAttack3(player, key);
break;
case OptionJoystick::Attack4:
Configuration::setJoystickAttack4(player, key);
break;
case OptionJoystick::Attack5:
Configuration::setJoystickAttack5(player, key);
break;
case OptionJoystick::Attack6:
Configuration::setJoystickAttack6(player, key);
break;
default:
break;
}
*/
}
static Configuration::JoystickInput readJoystick(){
vector<Joystick::Key> keys;
keys.push_back(Joystick::Up);
keys.push_back(Joystick::Down);
keys.push_back(Joystick::Left);
keys.push_back(Joystick::Right);
keys.push_back(Joystick::Button1);
keys.push_back(Joystick::Button2);
keys.push_back(Joystick::Button3);
keys.push_back(Joystick::Button4);
keys.push_back(Joystick::Button5);
keys.push_back(Joystick::Button6);
InputMap<Joystick::Key> input;
for (vector<Joystick::Key>::iterator it = keys.begin(); it != keys.end(); it++){
input.set(*it, 0, true, *it);
}
input.set(Keyboard::Key_ESC, 0, true, Joystick::Invalid);
while (true){
InputManager::poll();
vector<InputMap<Joystick::Key>::InputEvent> out = InputManager::getEvents(input, InputSource());
for (vector<InputMap<Joystick::Key>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
const InputMap<Joystick::Key>::InputEvent & event = *it;
if (event.enabled){
Global::debug(1) << "Press: " << event.out << std::endl;
if (event.out == Joystick::Invalid){
InputManager::waitForRelease(input, InputSource(), Joystick::Invalid);
throw Exception::Return(__FILE__, __LINE__);
}
return event.out;
}
}
Util::rest(1);
}
/* control probably shouldn't get here.. */
return Joystick::Up;
}
OptionJoystick::OptionJoystick(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
name(""),
player(-1),
type(Invalidkey),
keyCode(0){
if (*token != "joystick"){
throw LoadException(__FILE__, __LINE__, "Not joystick option");
}
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if ( *tok == "name" ){
tok->view() >> name;
} else if ( *tok == "player" ) {
tok->view() >> player;
} else if ( *tok == "type" ) {
std::string temp;
tok->view() >> temp;
type = convertToKey(temp);
} else {
Global::debug( 3 ) <<"Unhandled menu attribute: "<<endl;
tok->print(" ");
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu parse error");
} catch ( const LoadException & ex ) {
// delete current;
throw ex;
}
}
if (name.empty()){
throw LoadException(__FILE__, __LINE__, "No name set, this option should have a name!");
}
if (type == Invalidkey){
throw LoadException(__FILE__, __LINE__, "Invalid joystick button, should be up, down, left, right, up, down, jump, attack1-6!");
}
if (player == -1){
throw LoadException(__FILE__, __LINE__, "Player not specified in joystick configuration");
}
ostringstream out;
out << name << ": " << Joystick::keyToName(getKey(player, type));
setText(out.str());
}
OptionJoystick::~OptionJoystick(){
// Nothing
}
void OptionJoystick::logic(){
/*
char temp[255];
sprintf( temp, "%s: %s", name.c_str(), Joystick::keyToName(getKey(player,type)));
setText(std::string(temp));
*/
}
void OptionJoystick::run(const Menu::Context & context){
/*
//int x, y, width, height;
const Font & vFont = Menu::menuFontParameter.current()->get();
const char * message = "Press a joystick button!";
const int width = vFont.textLength(message) + 10;
const int height = vFont.getHeight() + 10;
// const int x = (getParent()->getWork()->getWidth()/2) - (width/2);
// const int y = (getParent()->getWork()->getHeight()/2) - (height/2);
const int x = Menu::Menu::Width / 2 - width/2;
const int y = Menu::Menu::Height / 2 - height/2;
Box dialog;
dialog.location.setPosition(Gui::AbsolutePoint(0,0));
dialog.location.setDimensions(vFont.textLength(message) + 10, vFont.getHeight() + 10);
dialog.transforms.setRadius(0);
dialog.colors.body = Graphics::makeColor(0,0,0);
dialog.colors.bodyAlpha = 200;
dialog.colors.border = Graphics::makeColor(255,255,255);
dialog.colors.borderAlpha = 255;
Graphics::Bitmap temp = Graphics::Bitmap::temporaryBitmap(width,height);
dialog.render(temp, vFont);
vFont.printf( 5, 5, Graphics::makeColor(255,255,255), temp, message, -1);
temp.BlitToScreen(x,y);
setKey(player, type, readJoystick());
ostringstream out;
out << name << ": " << Joystick::keyToName(getKey(player, type));
setText(out.str());
*/
Graphics::Bitmap temp(Menu::Menu::Width, Menu::Menu::Height);
// Menu::Context tempContext = context;
Menu::Context tempContext(context);
tempContext.initialize();
Menu::InfoBox keyDialog;
// keyDialog.setFont(tempContext.getFont());
//keyDialog.location.set(-1,-1,1,1);
const int width = temp.getWidth();
const int height = temp.getHeight();
const Font & font = Menu::menuFontParameter.current()->get();
const int radius = 15;
keyDialog.setText("Press a joystick button!");
keyDialog.initialize(font);
keyDialog.location.setDimensions(font.textLength("Press a joystick button!") + radius, font.getHeight() + radius);
keyDialog.location.setCenterPosition(Gui::RelativePoint(0, 0));
// keyDialog.location.setPosition(Gui::AbsolutePoint((width/2)-(keyDialog.location.getWidth()/2), (height/2)-(keyDialog.location.getHeight()/2)));
// keyDialog.location.setPosition2(Gui::AbsolutePoint((
keyDialog.transforms.setRadius(radius);
keyDialog.colors.body = Graphics::makeColor(0,0,0);
keyDialog.colors.bodyAlpha = 180;
keyDialog.colors.border = Graphics::makeColor(255,255,255);
keyDialog.colors.borderAlpha = 255;
keyDialog.open();
InputManager::waitForClear();
while (!InputManager::anyInput() && keyDialog.isActive()){
InputManager::poll();
keyDialog.act(font);
/*
if (keyDialog.isActive()){
InputManager::poll();
}
*/
tempContext.act();
tempContext.render(0, temp);
keyDialog.render(temp, font);
temp.BlitToScreen();
}
tempContext.finish();
setKey(player, type, readJoystick());
InputManager::waitForClear();
ostringstream out;
out << name << ": " << Joystick::keyToName(getKey(player, type));
setText(out.str());
/*
Keyboard key;
keyCode = readKey(key);
setKey(player,type, keyCode);
*/
}
#endif
static OptionKey::keyType convertToKeyboardKey(const std::string &k){
std::string temp = k;
for(unsigned int i=0;i<temp.length();i++){
temp[i] = tolower(temp[i]);
}
if (temp == "up") return OptionKey::up;
if (temp == "down") return OptionKey::down;
if (temp == "left") return OptionKey::left;
if (temp == "right") return OptionKey::right;
if (temp == "jump") return OptionKey::jump;
if (temp == "attack1") return OptionKey::attack1;
if (temp == "attack2") return OptionKey::attack2;
if (temp == "attack3") return OptionKey::attack3;
if (temp == "attack4") return OptionKey::attack4;
if (temp == "attack5") return OptionKey::attack5;
if (temp == "attack6") return OptionKey::attack6;
return OptionKey::invalidkey;
}
static int getKey(int player, OptionKey::keyType k){
switch(k){
case OptionKey::up:
return Configuration::getUp(player);
break;
case OptionKey::down:
return Configuration::getDown(player);
break;
case OptionKey::left:
return Configuration::getLeft(player);
break;
case OptionKey::right:
return Configuration::getRight(player);
break;
case OptionKey::jump:
return Configuration::getJump(player);
break;
case OptionKey::attack1:
return Configuration::getAttack1(player);
break;
case OptionKey::attack2:
return Configuration::getAttack2(player);
break;
case OptionKey::attack3:
return Configuration::getAttack3(player);
break;
case OptionKey::attack4:
return Configuration::getAttack4(player);
case OptionKey::attack5:
return Configuration::getAttack5(player);
case OptionKey::attack6:
return Configuration::getAttack6(player);
default:
break;
}
return 0;
}
static void setKey(int player, OptionKey::keyType k, int key){
switch(k){
case OptionKey::up:
Configuration::setUp(player, key);
break;
case OptionKey::down:
Configuration::setDown(player, key);
break;
case OptionKey::left:
Configuration::setLeft(player, key);
break;
case OptionKey::right:
Configuration::setRight(player, key);
break;
case OptionKey::jump:
Configuration::setJump(player, key);
break;
case OptionKey::attack1:
Configuration::setAttack1(player, key);
break;
case OptionKey::attack2:
Configuration::setAttack2(player, key);
break;
case OptionKey::attack3:
Configuration::setAttack3(player, key);
break;
case OptionKey::attack4:
Configuration::setAttack4(player, key);
break;
case OptionKey::attack5:
Configuration::setAttack5(player, key);
break;
case OptionKey::attack6:
Configuration::setAttack6(player, key);
break;
default:
break;
}
}
/*
static int readKey( Keyboard & key ){
int k = key.readKey();
key.wait();
return k;
}
*/
OptionKey::OptionKey(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
name(""),
player(-1),
type(invalidkey),
keyCode(0){
if ( *token != "key" )
throw LoadException(__FILE__, __LINE__, "Not key option");
TokenView view = token->view();
while (view.hasMore()) {
try {
const Token * tok;
view >> tok;
if ( *tok == "name" ) {
tok->view() >> name;
} else if ( *tok == "player" ) {
tok->view() >> player;
} else if ( *tok == "type" ) {
std::string temp;
tok->view() >> temp;
type = convertToKeyboardKey(temp);
} else {
Global::debug( 3 ) <<"Unhandled menu attribute: "<<endl;
tok->print(" ");
}
} catch ( const TokenException & ex ){
throw LoadException(__FILE__, __LINE__, ex, "Menu parse error");
} catch ( const LoadException & ex ) {
// delete current;
throw ex;
}
}
if(name.empty())throw LoadException(__FILE__, __LINE__, "No name set, this option should have a name!");
if(type == invalidkey)throw LoadException(__FILE__, __LINE__, "Invalid key, should be up, down, left, right, up, down, jump, attack1-6!");
if(player == -1)throw LoadException(__FILE__, __LINE__, "Player not specified in key configuration");
char temp[255];
sprintf( temp, "%s: %s", name.c_str(), Keyboard::keyToName(getKey(player,type)));
setText(std::string(temp));
}
OptionKey::~OptionKey(){
// Nothing
}
void OptionKey::logic(){
char temp[255];
sprintf( temp, "%s: %s", name.c_str(), Keyboard::keyToName(getKey(player,type)));
setText(std::string(temp));
}
void OptionKey::run(const Menu::Context & context){
// Do dialog
//Box::messageDialog(Menu::Menu::Width, Menu::Menu::Height, "Press a Key!",2);
+
+ class WaitForKey: public Util::Logic, public Util::Draw {
+ public:
+ WaitForKey(const Menu::Context & context):
+ font(Menu::menuFontParameter.current()->get()),
+ tempContext(context),
+ speed(30),
+ listener(*this),
+ quit(false),
+ out(Keyboard::Key_ESC){
+ tempContext.initialize();
+
+ // keyDialog.setFont(tempContext.getFont());
+ //keyDialog.location.set(-1,-1,1,1);
+ const int width = 320;
+ const int height = 240;
+ const int radius = 15;
+ keyDialog.setText("Press a Key!");
+ keyDialog.initialize(font);
+ keyDialog.location.setDimensions(font.textLength("Press a Key!") + radius, font.getHeight() + radius);
+ keyDialog.location.setCenterPosition(Gui::RelativePoint(0, 0));
+ // keyDialog.location.setPosition(Gui::AbsolutePoint((width/2)-(keyDialog.location.getWidth()/2), (height/2)-(keyDialog.location.getHeight()/2)));
+ // keyDialog.location.setPosition2(Gui::AbsolutePoint((
+ keyDialog.transforms.setRadius(radius);
+ keyDialog.colors.body = Graphics::makeColor(0,0,0);
+ keyDialog.colors.bodyAlpha = 180;
+ keyDialog.colors.border = Graphics::makeColor(255,255,255);
+ keyDialog.colors.borderAlpha = 255;
+ keyDialog.open();
+
+ Keyboard::pushRepeatState(false);
+ Keyboard::addListener(&listener);
+ }
+
+ virtual ~WaitForKey(){
+ Keyboard::removeListener(&listener);
+ Keyboard::popRepeatState();
+ }
+
+ class Listener: public KeyboardListener {
+ public:
+ Listener(WaitForKey & parent):
+ parent(parent){
+ }
+
+ WaitForKey & parent;
+
+ virtual void press(Keyboard * keyboard, Keyboard::KeyType key, Keyboard::unicode_t code){
+ parent.press(key);
+ }
+
+ virtual void release(Keyboard * keyboard, Keyboard::KeyType key){
+ parent.release(key);
+ }
+ };
+
+ const Font & font;
+ Menu::Context tempContext;
+ Menu::InfoBox keyDialog;
+ const int speed;
+ Listener listener;
+ bool quit;
+ Keyboard::KeyType out;
+
+ virtual void press(Keyboard::KeyType key){
+ quit = true;
+
+ if (key != Keyboard::Key_ESC){
+ this->out = key;
+ }
+ }
+
+ virtual void release(Keyboard::KeyType key){
+ }
+
+ virtual void run(){
+ for (int i = 0; i < 90 / speed; i++){
+ tempContext.act();
+ keyDialog.act(font);
+ }
+ }
+
+ virtual bool done(){
+ return quit;
+ }
+
+ virtual double ticks(double system){
+ return system * Global::ticksPerSecond(speed);
+ }
+
+ virtual void draw(const Graphics::Bitmap & screen){
+ Graphics::StretchedBitmap work(640, 480, screen);
+ work.start();
+ tempContext.render(Util::ReferenceCount<Menu::Renderer>(NULL), work);
+ keyDialog.render(work, font);
+ work.finish();
+ }
+ };
+
+ WaitForKey run(context);
+ Util::standardLoop(run, run);
+
+ Keyboard::KeyType key = run.out;
+ if (key != Keyboard::Key_ESC){
+ setKey(player, type, key);
+ }
+
/*
Keyboard key;
key.wait();
*/
+ /*
Graphics::Bitmap temp(Menu::Menu::Width, Menu::Menu::Height);
// Menu::Context tempContext = context;
Menu::Context tempContext(context);
tempContext.initialize();
Menu::InfoBox keyDialog;
// keyDialog.setFont(tempContext.getFont());
//keyDialog.location.set(-1,-1,1,1);
const int width = temp.getWidth();
const int height = temp.getHeight();
const Font & font = Menu::menuFontParameter.current()->get();
const int radius = 15;
keyDialog.setText("Press a Key!");
keyDialog.initialize(font);
keyDialog.location.setDimensions(font.textLength("Press a Key!") + radius, font.getHeight() + radius);
keyDialog.location.setCenterPosition(Gui::RelativePoint(0, 0));
// keyDialog.location.setPosition(Gui::AbsolutePoint((width/2)-(keyDialog.location.getWidth()/2), (height/2)-(keyDialog.location.getHeight()/2)));
// keyDialog.location.setPosition2(Gui::AbsolutePoint((
keyDialog.transforms.setRadius(radius);
keyDialog.colors.body = Graphics::makeColor(0,0,0);
keyDialog.colors.bodyAlpha = 180;
keyDialog.colors.border = Graphics::makeColor(255,255,255);
keyDialog.colors.borderAlpha = 255;
keyDialog.open();
InputManager::waitForClear();
while (!InputManager::anyInput() && keyDialog.isActive()){
InputManager::poll();
keyDialog.act(font);
- /*
+ / *
if (keyDialog.isActive()){
InputManager::poll();
}
- */
+ * /
tempContext.act();
tempContext.render(Util::ReferenceCount<Menu::Renderer>(NULL), temp);
keyDialog.render(temp, font);
temp.BlitToScreen();
}
tempContext.finish();
keyCode = InputManager::readKey();
setKey(player,type, keyCode);
InputManager::waitForClear();
+ */
}
OptionLevel::OptionLevel(const Gui::ContextBox & parent, const Token *token, int * set, int value):
MenuOption(parent, token),
set(set),
value(value){
// Nothing
}
OptionLevel::~OptionLevel(){
}
void OptionLevel::logic(){
}
void OptionLevel::run(const Menu::Context & context){
*set = value;
throw Menu::MenuException(__FILE__, __LINE__);
}
OptionMenu::OptionMenu(const Gui::ContextBox & parent, const Token *token, const Menu::OptionFactory & factory):
MenuOption(parent, token),
menu(0){
if (*token != "menu"){
throw LoadException(__FILE__, __LINE__, "Not a menu");
}
if (token->numTokens() == 1){
std::string temp;
token->view() >> temp;
menu = new Menu::Menu(Storage::instance().find(Filesystem::RelativePath(temp)), factory);
} else {
menu = new Menu::Menu(token, factory);
}
this->setText(menu->getName());
this->setInfoText(menu->getInfo());
// Lets check if this menu is going bye bye
//if ( menu->checkRemoval() ) setForRemoval(true);
}
OptionMenu::~OptionMenu(){
// Delete our menu
if (menu){
delete menu;
}
}
void OptionMenu::logic(){
// Nothing
}
void OptionMenu::run(const Menu::Context & context){
// Do our new menu
try{
menu->run(context);
} catch (const Exception::Return ignore){
throw Menu::Reload(__FILE__, __LINE__);
}
}
OptionReturn::OptionReturn(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token){
if (*token != "return"){
throw LoadException(__FILE__, __LINE__, "Not a return option");
}
readName(token);
}
void OptionReturn::logic(){
}
/* maybe this option is misnamed, but its supposed to quit the current game
* and go back to the main menu
*/
void OptionReturn::run(const Menu::Context & context){
throw Exception::Quit(__FILE__, __LINE__);
}
OptionReturn::~OptionReturn(){
}
OptionContinue::OptionContinue(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token){
if (*token != "continue"){
throw LoadException(__FILE__, __LINE__, "Not a continue option");
}
readName(token);
}
void OptionContinue::logic(){
}
void OptionContinue::run(const Menu::Context & context){
throw Exception::Return(__FILE__, __LINE__);
}
OptionContinue::~OptionContinue(){
}
OptionQuit::OptionQuit(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token){
if ( *token != "quit" ){
throw LoadException(__FILE__, __LINE__, "Not quit option");
}
readName(token);
}
OptionQuit::OptionQuit(const Gui::ContextBox & parent, const std::string &name):
MenuOption(parent, 0){
if (name.empty()){
throw LoadException(__FILE__, __LINE__, "No name given to quit");
}
this->setText(name);
}
OptionQuit::~OptionQuit(){
}
void OptionQuit::logic(){
}
void OptionQuit::run(const Menu::Context & context){
throw ShutdownException();
}
#if defined(WINDOWS) && defined(doesnt_work_yet)
#include <windows.h>
#include <stdio.h>
/* contributed by Roy Underthump from allegro.cc */
static vector<ScreenSize> getScreenResolutions(){
HWND hwnd;
HDC hdc;
// int iPixelFormat;
int descerr;
int retval;
DEVMODE d;
PIXELFORMATDESCRIPTOR pfd;
hwnd = GetDesktopWindow();
hdc = GetDC(hwnd);
vector<ScreenSize> modes;
for (int i = 0;; i++){
retval = EnumDisplaySettings(0,i,&d);
if (!retval){
break;
}
descerr = DescribePixelFormat(hdc, i+1, sizeof(pfd), &pfd);
if(!descerr){
continue;
}
/*
printf("\n#%d bpp %d width %d height %d colorbits %d fps %d",i,d.dmBitsPerPel,
d.dmPelsWidth, d.dmPelsHeight,pfd.cColorBits,d.dmDisplayFrequency);
if(pfd.dwFlags & PFD_SUPPORT_OPENGL)printf(" OGL OK");
*/
modes.push_back(ScreenSize(d.dmPelsWidth, d.dmPelsHeight));
}
if (modes.empty()){
modes.push_back(ScreenSize(640,480));
}
return modes;
}
#else
static vector<ScreenSize> getScreenResolutions(){
vector<ScreenSize> modes;
modes.push_back(ScreenSize(320, 240));
modes.push_back(ScreenSize(640, 480));
modes.push_back(ScreenSize(800, 600));
modes.push_back(ScreenSize(960, 720));
modes.push_back(ScreenSize(1024, 768));
modes.push_back(ScreenSize(1280, 960));
modes.push_back(ScreenSize(1600, 1200));
return modes;
}
#endif
static bool doSort(const ScreenSize & a, const ScreenSize & b){
return (a.w * a.h) < (b.w * b.h);
}
static vector<ScreenSize> sortResolutions(const vector<ScreenSize> & modes){
vector<ScreenSize> copy(modes);
std::sort(copy.begin(), copy.end(), doSort);
return copy;
}
OptionScreenSize::OptionScreenSize(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
name(""),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
Global::debug(1) << "Get screen resolution" << endl;
modes = sortResolutions(getScreenResolutions());
if (Global::getDebug() >= 1){
for (vector<ScreenSize>::iterator it = modes.begin(); it != modes.end(); it++){
Global::debug(1) << "Screen size: " << it->w << " x " << it->h << endl;
}
}
if ( *token != "screen-size" ){
throw LoadException(__FILE__, __LINE__, "Not a screen-size");
}
readName(token);
}
OptionScreenSize::~OptionScreenSize(){
// Nothing
}
void OptionScreenSize::logic(){
ostringstream temp;
temp << "Screen size: " << Configuration::getScreenWidth() << " x " << Configuration::getScreenHeight();
setText(temp.str());
}
void OptionScreenSize::run(const Menu::Context & context){
}
void OptionScreenSize::setMode(int width, int height){
if (width != Configuration::getScreenWidth() ||
height != Configuration::getScreenHeight()){
Global::debug(1) << "Changing mode to " << width << " x " << height << endl;
int gfx = Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED;
int ok = Graphics::changeGraphicsMode(gfx, width, height);
if (ok == 0){
Global::debug(1) << "Success" << endl;
Configuration::setScreenWidth(width);
Configuration::setScreenHeight(height);
} else {
Global::debug(1) << "Fail" << endl;
int ok = Graphics::changeGraphicsMode(gfx, Configuration::getScreenWidth(), Configuration::getScreenHeight());
Global::debug(1) << "Set mode back " << ok << endl;
}
}
}
/*
static int modes[][2] = {{640,480}, {800,600}, {1024,768}, {1280,1024}, {1600,1200}};
// static int max_modes = sizeof(modes) / sizeof(int[]);
static int max_modes = 5;
*/
int OptionScreenSize::findMode(int width, int height){
for (int mode = 0; mode < (int) modes.size(); mode++){
if (modes[mode].w == width && modes[mode].h == height){
return mode;
}
}
return -1;
}
bool OptionScreenSize::leftKey(){
int mode = findMode(Configuration::getScreenWidth(), Configuration::getScreenHeight());
if (mode >= 1 && mode < (int)modes.size()){
mode -= 1;
} else {
mode = 0;
}
setMode(modes[mode].w, modes[mode].h);
lblue = lgreen = 0;
return true;
}
bool OptionScreenSize::rightKey(){
int mode = findMode(Configuration::getScreenWidth(), Configuration::getScreenHeight());
if (mode >= 0 && mode < (int)modes.size() - 1){
mode += 1;
} else {
mode = 0;
}
setMode(modes[mode].w, modes[mode].h);
rblue = rgreen = 0;
return true;
}
static string joinPaths(const vector<Filesystem::AbsolutePath> & strings, const string & middle){
ostringstream out;
for (vector<Filesystem::AbsolutePath>::const_iterator it = strings.begin(); it != strings.end(); it++){
out << (*it).path() << middle;
}
return out.str();
}
static bool sortInfo(const Util::ReferenceCount<Menu::FontInfo> & info1,
const Util::ReferenceCount<Menu::FontInfo> & info2){
string name1 = Util::lowerCaseAll(info1->getName());
string name2 = Util::lowerCaseAll(info2->getName());
return name1 < name2;
}
static bool isWindows(){
#ifdef WINDOWS
return true;
#else
return false;
#endif
}
static bool isOSX(){
#ifdef MACOSX
return true;
#else
return false;
#endif
}
template <class X>
static vector<X> operator+(const vector<X> & v1, const vector<X> & v2){
vector<X> out;
for (typename vector<X>::const_iterator it = v1.begin(); it != v1.end(); it++){
out.push_back(*it);
}
for (typename vector<X>::const_iterator it = v2.begin(); it != v2.end(); it++){
out.push_back(*it);
}
return out;
}
static vector<Filesystem::AbsolutePath> findSystemFonts(){
if (isWindows()){
const char * windows = getenv("windir");
if (windows != NULL){
return Storage::instance().getFilesRecursive(Filesystem::AbsolutePath(string(windows) + "/fonts"), "*.ttf");
}
return vector<Filesystem::AbsolutePath>();
} else if (isOSX()){
return Storage::instance().getFilesRecursive(Filesystem::AbsolutePath("/Library/Fonts"), "*.ttf");
} else {
/* assume unix/linux conventions */
return Storage::instance().getFilesRecursive(Filesystem::AbsolutePath("/usr/share/fonts/truetype"), "*.ttf") +
Storage::instance().getFilesRecursive(Filesystem::AbsolutePath("/usr/local/share/fonts/truetype"), "*.ttf");
}
}
static vector<Util::ReferenceCount<Menu::FontInfo> > findFonts(){
vector<Util::ReferenceCount<Menu::FontInfo> > fonts;
try{
Filesystem::AbsolutePath fontsDirectory = Storage::instance().find(Filesystem::RelativePath("fonts"));
Global::debug(1, "fonts") << "Font directory " << fontsDirectory.path() << endl;
vector<Filesystem::AbsolutePath> ttfFonts = Storage::instance().getFiles(fontsDirectory, "*.ttf");
Global::debug(1, "fonts") << "Found ttf fonts " << joinPaths(ttfFonts, ", ") << endl;
vector<Filesystem::AbsolutePath> otfFonts = Storage::instance().getFiles(fontsDirectory, "*.otf");
Global::debug(1, "fonts") << "Found otf fonts " << joinPaths(otfFonts, ", ") << endl;
for (vector<Filesystem::AbsolutePath>::iterator it = ttfFonts.begin(); it != ttfFonts.end(); it++){
fonts.push_back(Util::ReferenceCount<Menu::FontInfo>(new Menu::RelativeFontInfo(Storage::instance().cleanse(*it), Configuration::getMenuFontWidth(), Configuration::getMenuFontHeight())));
}
for (vector<Filesystem::AbsolutePath>::iterator it = otfFonts.begin(); it != otfFonts.end(); it++){
fonts.push_back(Util::ReferenceCount<Menu::FontInfo>(new Menu::RelativeFontInfo(Storage::instance().cleanse(*it), Configuration::getMenuFontWidth(), Configuration::getMenuFontHeight())));
}
/* linux specific fonts */
vector<Filesystem::AbsolutePath> systemFonts = findSystemFonts();
for (vector<Filesystem::AbsolutePath>::iterator it = systemFonts.begin(); it != systemFonts.end(); it++){
Global::debug(1) << "Adding system font `" << (*it).path() << "'" << endl;
fonts.push_back(Util::ReferenceCount<Menu::FontInfo>(new Menu::AbsoluteFontInfo(*it, Configuration::getMenuFontWidth(), Configuration::getMenuFontHeight())));
}
sort(fonts.begin(), fonts.end(), sortInfo);
// DEFAULT (blank)
// fonts.insert(fonts.begin(), new Menu::DefaultFontInfo());
fonts.insert(fonts.begin(), Util::ReferenceCount<Menu::FontInfo>(NULL));
} catch (const Filesystem::NotFound & e){
throw LoadException(__FILE__, __LINE__, e, "Could not load font");
}
return fonts;
}
OptionSelectFont::OptionSelectFont(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
typeAdjust(fontName),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
if ( *token != "font-select" ){
throw LoadException(__FILE__, __LINE__, "Not a font selector");
}
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if ( *tok == "adjust" ){
std::string temp;
tok->view() >> temp;
if ( temp == "name" ) typeAdjust = fontName;
else if ( temp == "width" ) typeAdjust = fontWidth;
else if ( temp == "height" ) typeAdjust = fontHeight;
else throw LoadException(__FILE__, __LINE__, "Incorrect value \"" + temp + "\" in font-select");
} else {
Global::debug(3) << "Unhandled menu attribute: " << endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu parse error");
} catch ( const LoadException & ex ) {
// delete current;
throw ex;
}
}
}
void OptionSelectFont::open(){
// Find and set fonts now
if (typeAdjust == fontName){
fonts = findFonts();
}
}
void OptionSelectFont::close(){
if (typeAdjust == fontName){
/* the user probably loaded a bunch of different fonts that will
* never be used again, so clear the font cache
* TODO: dont clear the currently selected font
*/
FontFactory::clear();
}
}
OptionSelectFont::~OptionSelectFont(){
// Nothing
}
void OptionSelectFont::logic(){
/* FIXME Get current font and display info */
switch (typeAdjust){
case fontName:{
std::string name;
if (Configuration::hasMenuFont()){
name = Configuration::getMenuFont()->getName();
} else {
name = "Default";
}
setText("Current Font: " + name);
break;
}
case fontWidth:{
ostringstream temp;
temp << "Font Width: " << Configuration::getMenuFontWidth();
setText(temp.str());
break;
}
case fontHeight:{
ostringstream temp;
temp << "Font Height: " << Configuration::getMenuFontHeight();
setText(temp.str());
break;
}
default: break;
}
if (lblue < 255){
lblue += 5;
}
if (rblue < 255){
rblue += 5;
}
if (lgreen < 255){
lgreen += 5;
}
if (rgreen < 255){
rgreen += 5;
}
}
void OptionSelectFont::run(const Menu::Context & context){
// throw Menu::MenuException(__FILE__, __LINE__);
/* throw something to quit back to the previous menu */
}
bool OptionSelectFont::leftKey(){
switch (typeAdjust){
case fontName:
nextIndex(false);
break;
case fontWidth:
Configuration::setMenuFontWidth(Configuration::getMenuFontWidth() - 1);
break;
case fontHeight:
Configuration::setMenuFontHeight(Configuration::getMenuFontHeight() - 1);
break;
default:
break;
}
lblue = lgreen = 0;
return true;
}
bool OptionSelectFont::rightKey(){
switch (typeAdjust){
case fontName:
nextIndex(true);
break;
case fontWidth:
Configuration::setMenuFontWidth(Configuration::getMenuFontWidth() + 1);
break;
case fontHeight:
Configuration::setMenuFontHeight(Configuration::getMenuFontHeight() + 1);
break;
default:
break;
}
rblue = rgreen = 0;
return true;
}
static bool saneFont(const Util::ReferenceCount<Menu::FontInfo> & info){
class Context: public Loader::LoadingContext {
public:
Context(const Util::ReferenceCount<Menu::FontInfo> & info):
info(info),
isok(false){
}
bool ok(){
try{
const Font & font = info->get();
return font.textLength("A") != 0 &&
font.getHeight() != 0;
} catch (const Exception::Base & ignore){
return true;
}
}
virtual void load(){
isok = ok();
}
const Util::ReferenceCount<Menu::FontInfo> & info;
bool isok;
};
if (info == NULL){
return true;
}
Context context(info);
/* an empty Info object, we don't really care about it */
Loader::Info level("Loading Font", Filesystem::AbsolutePath());
Loader::loadScreen(context, level, Loader::SimpleCircle);
return context.isok;
}
void OptionSelectFont::nextIndex(bool forward){
if (fonts.size() == 0){
return;
}
int index = 0;
for (unsigned int i = 0 ; i < fonts.size() ; ++i){
if ((Configuration::getMenuFont() == NULL && fonts[i] == NULL) ||
((Configuration::getMenuFont() != NULL && fonts[i] != NULL) &&
(*Configuration::getMenuFont() == *fonts[i]))){
index = i;
}
}
if (forward){
index++;
if (index >= (int) fonts.size()){
index = 0;
}
} else {
index--;
if (index < 0){
index = (int)fonts.size()-1;
}
}
while (!saneFont(fonts[index])){
Global::debug(0) << "Warning: erasing font `" << fonts[index]->getName() << "'" << endl;
int where = 0;
vector<Util::ReferenceCount<Menu::FontInfo> >::iterator it;
for (it = fonts.begin(); it != fonts.end() && where != index; it++, where++){
}
fonts.erase(it);
if (index >= (int) fonts.size()){
index = fonts.size() - 1;
}
}
Configuration::setMenuFont(fonts[index]);
/* FIXME */
/*
if (fonts[index] == "Default"){
Configuration::setMenuFont("");
} else {
Configuration::setMenuFont(fonts[index]);
}
*/
}
OptionSpeed::OptionSpeed(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
name(""),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
if ( *token != "speed" )
throw LoadException(__FILE__, __LINE__, "Not speed option");
readName(token);
}
OptionSpeed::~OptionSpeed(){
// Nothing
}
std::string OptionSpeed::getText() const {
ostringstream out;
out << MenuOption::getText() << ": " << Configuration::getGameSpeed();
return out.str();
}
void OptionSpeed::logic(){
/*
//ostringstream temp;
char temp[255];
sprintf( temp, "%s: %0.2f", name.c_str(), MenuGlobals::getGameSpeed() );
setText(std::string(temp));
*/
}
void OptionSpeed::run(const Menu::Context & context){
}
bool OptionSpeed::leftKey(){
Configuration::setGameSpeed(Configuration::getGameSpeed() - 0.05);
if (Configuration::getGameSpeed() < 0.1){
Configuration::setGameSpeed(0.1);
}
return false;
}
bool OptionSpeed::rightKey(){
Configuration::setGameSpeed(Configuration::getGameSpeed() + 0.05);
rblue = rgreen = 0;
return false;
}
OptionTabMenu::OptionTabMenu(const Gui::ContextBox & parent, const Token *token, const Menu::OptionFactory & factory):
MenuOption(parent, token),
menu(0){
if (token->numTokens() == 1){
std::string temp;
token->view() >> temp;
menu = new Menu::Menu(Storage::instance().find(Filesystem::RelativePath(temp)), factory, Menu::Renderer::Tabbed);
} else {
menu = new Menu::Menu(token, factory, Menu::Renderer::Tabbed);
}
// this->setText(menu->getName());
// token->print("Menu: ");
const Token * tok = token->findToken("_/name");
if (tok != NULL){
std::string name;
tok->view() >> name;
// Global::debug(0, "menu") << "Menu name: " << name << endl;
this->setText(name);
} else {
// No name?
throw LoadException(__FILE__, __LINE__, "Menu has no name");
}
}
OptionTabMenu::~OptionTabMenu(){
// Delete our menu
if (menu){
delete menu;
}
}
void OptionTabMenu::logic(){
// Nothing
}
void OptionTabMenu::run(const Menu::Context & context){
// Do our new menu
// menu->run(context);
try{
menu->run(context);
} catch (const Exception::Return ignore){
throw Menu::Reload(__FILE__, __LINE__);
}
}
OptionSound::OptionSound(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
if (*token != "sound" ){
throw LoadException(__FILE__, __LINE__, "Not a sound option");
}
readName(token);
originalName = getName();
}
OptionSound::~OptionSound(){
}
void OptionSound::logic(){
ostringstream temp;
temp << originalName << ": " << Configuration::getSoundVolume();
setText(temp.str());
}
void OptionSound::run(const Menu::Context & context){
}
void OptionSound::changeSound(int much){
int volume = Configuration::getSoundVolume();
volume += much;
if (volume < 0){
volume = 0;
}
if (volume > 100){
volume = 100;
}
Configuration::setSoundVolume(volume);
}
bool OptionSound::leftKey(){
changeSound(-1);
lblue = lgreen = 0;
return true;
}
bool OptionSound::rightKey(){
changeSound(+1);
rblue = rgreen = 0;
return true;
}
OptionMusic::OptionMusic(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token),
lblue(255),
lgreen(255),
rblue(255),
rgreen(255){
setRunnable(false);
if (*token != "music" ){
throw LoadException(__FILE__, __LINE__, "Not a music option");
}
readName(token);
originalName = getName();
}
void OptionMusic::logic(){
ostringstream temp;
temp << originalName << ": " << Configuration::getMusicVolume();
setText(temp.str());
}
void OptionMusic::run(const Menu::Context & context){
}
void OptionMusic::changeMusic(int much){
int volume = Configuration::getMusicVolume();
volume += much;
if (volume < 0){
volume = 0;
}
if (volume > 100){
volume = 100;
}
Configuration::setMusicVolume(volume);
Music::setVolume((double) volume / 100.0);
}
bool OptionMusic::leftKey(){
changeMusic(-1);
lblue = lgreen = 0;
return true;
}
bool OptionMusic::rightKey(){
changeMusic(+1);
lblue = lgreen = 0;
return true;
}
OptionMusic::~OptionMusic(){
}
OptionLanguage::OptionLanguage(const Gui::ContextBox & parent, const Token * token):
MenuOption(parent, token){
readName(token);
#if 0
const Token * start = token->getRootParent();
vector<const Token*> tokens = start->findTokens("*/language");
vector<string> all;
for (vector<const Token*>::iterator it = tokens.begin(); it != tokens.end(); it++){
string language;
const Token * token = *it;
if (token->match("language", language)){
all.push_back(language);
}
}
sort(all.begin(), all.end());
unique_copy(all.begin(), all.end(), back_insert_iterator<vector<string> >(languages));
// Global::debug(0) << "Found " << languages.size() << " languages" << endl;
#endif
}
void OptionLanguage::run(const Menu::Context & context){
class LanguageOption: public MenuOption {
public:
LanguageOption(const Gui::ContextBox & parent, const string & language):
MenuOption(parent, NULL){
setText(language);
setInfoText(language);
}
virtual void logic(){
}
virtual void run(const ::Menu::Context & context){
Configuration::setLanguage(getText());
Configuration::saveConfiguration();
throw ::Menu::MenuException(__FILE__, __LINE__);
}
};
Util::NewReferenceCount<Menu::DefaultRenderer> renderer;
Menu::Menu temp(renderer.convert<Menu::Renderer>());
Util::ReferenceCount<Menu::FontInfo> info(new Menu::RelativeFontInfo(Font::getDefaultFontPath(), 24, 24));
temp.setFont(info);
const Gui::ContextBox & box = renderer->getBox();
vector<string> languages = context.getLanguages();
for (vector<string>::iterator it = languages.begin(); it != languages.end(); it++){
temp.addOption(new LanguageOption(box, *it));
}
try {
temp.run(context);
} catch (const Exception::Return & ignore){
} catch (const Menu::MenuException & ex){
}
throw Menu::Reload(__FILE__, __LINE__);
// throw Exception::Return(__FILE__, __LINE__);
}
void OptionLanguage::logic(){
}
OptionJoystick::OptionJoystick(const Gui::ContextBox & parent, const Token *token):
MenuOption(parent, token){
setRunnable(true);
if (*token != "joystick" ){
throw LoadException(__FILE__, __LINE__, "Not a joystick option");
}
readName(token);
}
void OptionJoystick::logic(){
}
class JoystickLogicDraw: public Util::Logic, public Util::Draw {
public:
enum Inputs{
Exit
};
static const int marginX = 20;
JoystickLogicDraw(int id, const Util::ReferenceCount<Joystick> & joystick, const ::Menu::Context & context):
id(id),
joystick(joystick),
quit(false),
context(context, Menu::Context()){
input.set(Keyboard::Key_ESC, Exit);
}
const int id;
Util::ReferenceCount<Joystick> joystick;
bool quit;
Menu::Context context;
InputMap<Inputs> input;
void doInput(){
vector<InputMap<Inputs>::InputEvent> out = InputManager::getEvents(input, InputSource(true));
for (vector<InputMap<Inputs>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
const InputMap<Inputs>::InputEvent & event = *it;
if (event.enabled){
if (event.out == Exit){
quit = true;
// context.finish();
}
}
}
}
virtual void run(){
doInput();
context.act();
}
bool done(){
return quit;
}
double ticks(double system){
return system * Global::ticksPerSecond(60);
}
void drawButtons(const Font & font, const Graphics::Bitmap & buffer, int y){
Graphics::Color color = Graphics::makeColor(255, 255, 255);
font.printf(marginX, y, color, buffer, "Up: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Down: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Left: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Right: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button1: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button2: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button3: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button4: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button5: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Button6: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Select: ", 0); y += font.getHeight() + 5;
font.printf(marginX, y, color, buffer, "Quit: ", 0); y += font.getHeight() + 5;
}
void draw(const Graphics::Bitmap & buffer){
const Font & font = Menu::menuFontParameter.current()->get();
Graphics::StretchedBitmap work(640, 480, buffer, Graphics::StretchedBitmap::NoClear, Graphics::qualityFilterName(Configuration::getQualityFilter()));
work.start();
context.renderBackground(work);
/* FIXME: scale the joystck name down to fit */
font.printf(marginX, 1, Graphics::makeColor(255, 255, 255), work, "Joystick %d: %s", 0, id, joystick->getName().c_str());
drawButtons(font, work, 1 + font.getHeight() + 5);
context.renderForeground(work);
work.finish();
}
};
namespace{
struct Axis{
Axis():
stick(0),
axis(0),
first(0),
set(false),
last(0),
lastMotion(0){
}
int stick;
int axis;
/* first value from this axis. we assume that
* the first value is sufficiently close to 'zero' which
* can be any value, but most likely will either be
* -1, 0, or 1
*/
double first;
/* true if first has been set */
bool set;
/* keep track of last value for this axis */
double last;
/* last time an event was produced (or at least last
* time we read it). it might be better to get the actual
* time from the event itself.
*/
uint64_t lastMotion;
};
}
static void runJoystickMenu(int joystickId, const Util::ReferenceCount<Joystick> & joystick, const ::Menu::Context & context){
Util::NewReferenceCount<Menu::DefaultRenderer> renderer;
Menu::Menu menu(renderer.convert<Menu::Renderer>());
Gui::ContextBox & box = renderer->getBox();
box.setListType(ContextBox::Normal);
Gui::ListValues attributes(box.getListValues());
attributes.setDistanceFade(false);
box.setListValues(attributes);
menu.setPosition(Gui::Coordinate(Gui::RelativePoint(-0.8, -0.3),
Gui::RelativePoint(0, 0.8)));
#define WAIT_TIME_MS (0.7 * 1000)
#define WAIT_TIME_AXIS_MS (1 * 1000)
#define AXIS_THRESHOLD 0.7
class JoystickButton: public MenuOption {
public:
JoystickButton(const Menu::Menu & menu, const Gui::ContextBox & parent, const Util::ReferenceCount<Joystick> & joystick, const string & name, Joystick::Key key):
MenuOption(parent, NULL),
menu(menu),
name(name),
joystick(joystick),
key(key){
setText(name);
setInfoText(name);
}
const Menu::Menu & menu;
string name;
Util::ReferenceCount<Joystick> joystick;
Joystick::Key key;
class ButtonListener: public JoystickListener {
public:
ButtonListener(const Util::ReferenceCount<Joystick> & joystick):
done(false),
chosen(-1),
chosenAxis(NULL){
map<int, map<int, double> > axisValues = joystick->getCurrentAxisValues();
for (map<int, map<int, double> >::iterator it = axisValues.begin(); it != axisValues.end(); it++){
int stick = it->first;
const map<int, double> & subMap = it->second;
for (map<int, double>::const_iterator it = subMap.begin(); it != subMap.end(); it++){
int axis = it->first;
double value = it->second;
Axis use;
use.stick = stick;
use.axis = axis;
use.first = value;
use.set = true;
use.last = value;
use.lastMotion = 0;
this->axis.push_back(use);
}
}
}
map<int, uint64_t> presses;
map<int, bool> pressed;
vector<Axis> axis;
bool done;
int chosen;
Axis * chosenAxis;
Axis & getAxis(int stick, int axis){
for (vector<Axis>::iterator it = this->axis.begin(); it != this->axis.end(); it++){
Axis & use = *it;
if (use.stick == stick && use.axis == axis){
return use;
}
}
Axis out;
out.stick = stick;
out.axis = axis;
this->axis.push_back(out);
return getAxis(stick, axis);
}
const vector<Axis> & getAllAxis() const {
return axis;
}
const map<int, uint64_t> & getPresses() const {
return presses;
}
int getButton() const {
return chosen;
}
Axis * getChosenAxis() const {
return chosenAxis;
}
virtual ~ButtonListener(){
}
bool isDone() const {
return (getButton() != -1 && !anyPressed()) ||
(getChosenAxis() != NULL);
}
void choose(){
uint64_t now = System::currentMilliseconds();
for (map<int, uint64_t>::const_iterator it = presses.begin(); it != presses.end(); it++){
uint64_t what = it->second;
if (what != 0 && now - what > WAIT_TIME_MS){
chosen = it->first;
}
}
for (vector<Axis>::iterator it = axis.begin(); it != axis.end(); it++){
Axis & use = *it;
if (fabs(use.last - use.first) > AXIS_THRESHOLD &&
now - use.lastMotion > WAIT_TIME_AXIS_MS){
chosenAxis = &use;
}
}
}
bool anyPressed() const {
for (map<int, bool>::const_iterator it = pressed.begin(); it != pressed.end(); it++){
if (it->second){
return true;
}
}
return false;
}
virtual void pressButton(Joystick * from, int button){
pressed[button] = true;
presses[button] = System::currentMilliseconds();
}
virtual void releaseButton(Joystick * from, int button){
presses[button] = 0;
pressed[button] = false;
}
/* either all increasing or all decreasing */
bool monotonic(const vector<double> & what){
if (what.size() == 0){
return true;
}
double first = what[0];
int direction = -1;
vector<double>::const_iterator it = what.begin();
it++;
for (/**/; it != what.end(); it++){
switch (direction){
case -1: {
if (*it < first){
direction = 1;
} else if (*it > first){
direction = 2;
}
first = *it;
break;
}
case 1: {
if (*it > first){
return false;
}
break;
}
case 2: {
if (*it < first){
return false;
}
break;
}
}
}
return true;
}
virtual void axisMotion(Joystick * from, int stick, int axis, double motion){
Axis & use = getAxis(stick, axis);
if (!use.set){
use.first = motion;
use.set = true;
}
use.last = motion;
use.lastMotion = System::currentMilliseconds();
/*
const double AXIS_THRESHOLD = 0.5;
Global::debug(0) << "stick " << stick << " axis " << axis << " first " << use.first << " last " << use.last << " diff " << fabs(use.last - use.first) << std::endl;
if (fabs(use.last - use.first) > AXIS_THRESHOLD){
Global::debug(0) << "stick " << stick << " axis " << axis << " motion " << motion << std::endl;
}
*/
}
virtual void hatMotion(Joystick * from, int motion){
}
};
void logic(){
ostringstream out;
int stick, axis;
double low, high;
if (joystick->getAxis(key, stick, axis, low, high)){
out << name << ": " << stick << "/" << axis << "/";
if (low < 0){
out << "-";
} else {
out << "+";
}
} else {
int button = joystick->getButton(key);
out << name << ": ";
if (button != -1){
out << joystick->getButton(key);
} else {
out << "unset";
}
}
setText(out.str());
}
void run(const Menu::Context & context){
class SetButton: public Util::Logic, public Util::Draw {
public:
SetButton(const Menu::Context & context, const Menu::Menu & menu, const string & name, const Util::ReferenceCount<Joystick> & joystick):
context(context),
menu(menu),
name(name),
listener(joystick),
joystick(joystick){
input.set(Keyboard::Key_ESC, 0);
joystick->addListener(&listener);
}
const Menu::Context & context;
const Menu::Menu & menu;
string name;
ButtonListener listener;
InputMap<int> input;
Util::ReferenceCount<Joystick> joystick;
~SetButton(){
joystick->removeListener(&listener);
}
void setButton(Joystick::Key key){
int button = listener.getButton();
if (button != -1){
Global::debug(1) << "Chosen button " << listener.getButton() << std::endl;
joystick->setCustomButton(listener.getButton(), key);
} else {
Axis * axis = listener.getChosenAxis();
double rangeLow = 0;
double rangeHigh = 0;
/* stick went negative and went to -1 */
if (axis->first <= 0 && axis->last < axis->first){
rangeLow = -1;
rangeHigh = -AXIS_THRESHOLD;
/* stick started at negative and went positive, possibly
* not above 0.
*/
} else if (axis->first < 0 && axis->last > axis->first){
rangeLow = 0;
rangeHigh = 1;
/* stick started positive and went to 1 */
} else if (axis->first >= 0 && axis->last > axis->first){
rangeLow = AXIS_THRESHOLD;
rangeHigh = 1;
/* stick started positive and went towards -1 */
} else if (axis->first > 0 && axis->last < axis->first){
rangeLow = -1;
rangeHigh = 0;
}
Global::debug(0) << "Set stick " << axis->stick << " axis " << axis->axis << " [" << rangeLow << ", " << rangeHigh << "]" << std::endl;
joystick->setCustomAxis(key, axis->stick, axis->axis, rangeLow, rangeHigh);
}
}
double ticks(double system){
return system * Global::ticksPerSecond(60);
}
bool done(){
return listener.isDone();
}
void run(){
vector<InputMap<int>::InputEvent> out = InputManager::getEvents(input, InputSource(true));
for (vector<InputMap<int>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
const InputMap<int>::InputEvent & event = *it;
if (event.enabled){
if (event.out == 0){
throw Exception::Return(__FILE__, __LINE__);
}
}
}
listener.choose();
}
void draw(const Graphics::Bitmap & buffer){
Graphics::StretchedBitmap work(640, 480, buffer, Graphics::StretchedBitmap::NoClear, Graphics::qualityFilterName(Configuration::getQualityFilter()));
work.start();
menu.render(context, work);
const Font & font = Menu::menuFontParameter.current()->get();
Gui::RelativePoint start(0.2, -0.3);
Gui::RelativePoint end(0.85, 0.8);
int x = start.getX();
int y = start.getY();
// font.printfWrap(x, y - font.getHeight() * 2 - 5, Graphics::makeColor(255, 255, 255), work, end.getX() - start.getX(), "Press and hold a button", 0);
font.printf(x, y - 18 - 5, 18, 18, Graphics::makeColor(255, 255, 255), work, "Press and hold a button", 0);
work.translucent(0, 0, 0, 128).rectangleFill(x, y, end.getX(), end.getY(), Graphics::makeColor(0, 0, 0));
uint64_t now = System::currentMilliseconds();
const map<int, uint64_t> & presses = listener.getPresses();
for (map<int, uint64_t>::const_iterator it = presses.begin(); it != presses.end(); it++){
int button = it->first;
uint64_t time = it->second;
if (time > 0){
int delta = now - time;
if (delta > WAIT_TIME_MS){
delta = WAIT_TIME_MS;
}
/* this shouldn't happen... */
if (delta < 0){
delta = 0;
}
Graphics::Color color;
color = Graphics::makeColor((int)(255.0 * (double) delta / (WAIT_TIME_MS)),
0, 255);
if (button == listener.getButton()){
color = Graphics::makeColor(255, 255, 255);
}
ostringstream text;
text << name << ": " << button;
font.printf(x, y, color, work, text.str(), 0);
y += font.getHeight() + 5;
}
}
const vector<Axis> & axis = listener.getAllAxis();
for (vector<Axis>::const_iterator it = axis.begin(); it != axis.end(); it++){
const Axis & use = *it;
if (fabs(use.last - use.first) > AXIS_THRESHOLD){
int delta = now - use.lastMotion;
if (delta > WAIT_TIME_AXIS_MS){
delta = WAIT_TIME_AXIS_MS;
}
/* this shouldn't happen... */
if (delta < 0){
delta = 0;
}
Graphics::Color color;
color = Graphics::makeColor((int)(255.0 * (double) delta / (WAIT_TIME_AXIS_MS)),
0, 255);
if (&use == listener.getChosenAxis()){
color = Graphics::makeColor(255, 255, 255);
}
ostringstream text;
text << name << ": stick " << use.stick << " axis " << use.axis;
if (use.last > use.first){
text << " +";
} else {
text << " -";
}
font.printf(x, y, 18, 18, color, work, text.str(), 0);
y += font.getHeight() + 5;
}
}
work.finish();
}
void wait(){
while (listener.anyPressed()){
InputManager::poll();
Util::rest(1);
}
}
};
Global::debug(1) << "Set button " << getName() << std::endl;
SetButton set(context, menu, name, joystick);
try{
Util::standardLoop(set, set);
set.setButton(key);
} catch (const Exception::Return & quit){
}
set.wait();
}
};
menu.addOption(new JoystickButton(menu, box, joystick, "Up", Joystick::Up));
menu.addOption(new JoystickButton(menu, box, joystick, "Down", Joystick::Down));
menu.addOption(new JoystickButton(menu, box, joystick, "Left", Joystick::Left));
menu.addOption(new JoystickButton(menu, box, joystick, "Right", Joystick::Right));
menu.addOption(new JoystickButton(menu, box, joystick, "Button1", Joystick::Button1));
menu.addOption(new JoystickButton(menu, box, joystick, "Button2", Joystick::Button2));
menu.addOption(new JoystickButton(menu, box, joystick, "Button3", Joystick::Button3));
menu.addOption(new JoystickButton(menu, box, joystick, "Button4", Joystick::Button4));
menu.addOption(new JoystickButton(menu, box, joystick, "Button5", Joystick::Button5));
menu.addOption(new JoystickButton(menu, box, joystick, "Button6", Joystick::Button6));
menu.addOption(new JoystickButton(menu, box, joystick, "Start", Joystick::Start));
menu.addOption(new JoystickButton(menu, box, joystick, "Quit", Joystick::Quit));
try {
menu.run(context);
} catch (const Exception::Return & ignore){
} catch (const Menu::MenuException & ex){
}
}
void OptionJoystick::run(const Menu::Context & context){
class JoystickOption: public MenuOption {
public:
JoystickOption(const Gui::ContextBox & parent, int id, const Util::ReferenceCount<Joystick> & joystick):
MenuOption(parent, NULL),
joystick(joystick),
id(id){
ostringstream out;
out << "Joystick " << (id + 1);
setText(out.str());
setInfoText(joystick->getName());
}
const Util::ReferenceCount<Joystick> joystick;
const int id;
virtual void logic(){
}
virtual void run(const ::Menu::Context & context){
runJoystickMenu(id, joystick, context);
/*
JoystickLogicDraw mainLoop(id, joystick, context);
Util::standardLoop(mainLoop, mainLoop);
*/
throw ::Menu::MenuException(__FILE__, __LINE__);
}
};
Util::NewReferenceCount<Menu::DefaultRenderer> renderer;
Menu::Menu menu(renderer.convert<Menu::Renderer>());
/*
Util::ReferenceCount<Menu::FontInfo> info(new Menu::RelativeFontInfo(Global::DEFAULT_FONT, 24, 24));
temp.setFont(info);
*/
Gui::ContextBox & box = renderer->getBox();
box.setListType(ContextBox::Normal);
map<int, Util::ReferenceCount<Joystick> > joysticks = InputManager::getJoysticks();
for (map<int, Util::ReferenceCount<Joystick> >::iterator it = joysticks.begin(); it != joysticks.end(); it++){
menu.addOption(new JoystickOption(box, it->first, it->second));
}
if (joysticks.size() == 0){
menu.addOption(new OptionDummy(box, "No joysticks found!"));
}
try {
menu.run(context);
} catch (const Exception::Return & ignore){
} catch (const Menu::MenuException & ex){
}
}
OptionJoystick::~OptionJoystick(){
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:09 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70283
Default Alt Text
(221 KB)

Event Timeline