Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F133898
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
221 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline